ma-agents 3.5.3 → 3.5.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (82) hide show
  1. package/_bmad-output/implementation-artifacts/21-1-install-time-profile-prompt.md +181 -0
  2. package/_bmad-output/implementation-artifacts/21-10-profile-reconfigure.md +137 -0
  3. package/_bmad-output/implementation-artifacts/21-11-profile-uninstall.md +149 -0
  4. package/_bmad-output/implementation-artifacts/21-2-universal-instruction-block-expansion.md +98 -0
  5. package/_bmad-output/implementation-artifacts/21-3-roomodes-template-bmad-modes.md +106 -0
  6. package/_bmad-output/implementation-artifacts/21-4-agents-md-template-opencode.md +86 -0
  7. package/_bmad-output/implementation-artifacts/21-5-clinerules-template-extension.md +82 -0
  8. package/_bmad-output/implementation-artifacts/21-6-onprem-layered-guardrails.md +112 -0
  9. package/_bmad-output/implementation-artifacts/21-7-bmad-persona-phase-prefix.md +126 -0
  10. package/_bmad-output/implementation-artifacts/21-8-vllm-reference-doc-readme.md +100 -0
  11. package/_bmad-output/implementation-artifacts/21-9-tests-validation.md +97 -0
  12. package/_bmad-output/implementation-artifacts/bug-experimentalwarning-about-commonjs-loading-es-module-during-install.md +57 -0
  13. package/_bmad-output/implementation-artifacts/sprint-status.yaml +43 -1
  14. package/_bmad-output/methodology/BMAD_AI_Development_Training.pptx +0 -0
  15. package/_bmad-output/methodology/version.json +1 -1
  16. package/_bmad-output/planning-artifacts/architecture.md +52 -0
  17. package/_bmad-output/planning-artifacts/epics.md +397 -0
  18. package/_bmad-output/planning-artifacts/prd.md +46 -1
  19. package/bin/cli.js +109 -1
  20. package/docs/BMAD_AI_Development_Training.pptx +0 -0
  21. package/lib/bmad-cache/bmb/_git_preserved/index +0 -0
  22. package/lib/bmad-cache/bmb/_git_preserved/logs/HEAD +1 -1
  23. package/lib/bmad-cache/bmb/_git_preserved/logs/refs/heads/main +1 -1
  24. package/lib/bmad-cache/bmb/_git_preserved/logs/refs/remotes/origin/HEAD +1 -1
  25. package/lib/bmad-cache/bmb/_git_preserved/objects/pack/pack-554778ad4e7254827618ebd2497c3f4bce9054a4.idx +0 -0
  26. package/lib/bmad-cache/bmb/_git_preserved/objects/pack/{pack-4b395d030ca386fc5748f1b670dcf8c0ef41c94c.pack → pack-554778ad4e7254827618ebd2497c3f4bce9054a4.pack} +0 -0
  27. package/lib/bmad-cache/bmb/_git_preserved/objects/pack/pack-554778ad4e7254827618ebd2497c3f4bce9054a4.rev +0 -0
  28. package/lib/bmad-cache/bmb/_git_preserved/packed-refs +1 -1
  29. package/lib/bmad-cache/bmb/_git_preserved/refs/heads/main +1 -1
  30. package/lib/bmad-cache/bmb/_git_preserved/shallow +1 -1
  31. package/lib/bmad-cache/bmb/skills/bmad-module-builder/scripts/tests/test-scaffold-setup-skill.py +7 -0
  32. package/lib/bmad-cache/cache-manifest.json +5 -5
  33. package/lib/bmad-cache/tea/_git_preserved/index +0 -0
  34. package/lib/bmad-cache/tea/_git_preserved/objects/pack/pack-e75385cd52b693dbb8a3b2afb50058952543b3a2.idx +0 -0
  35. package/lib/bmad-cache/tea/_git_preserved/objects/pack/{pack-c79805bb3fee27fa6d8c612a971af7fc86fc80e1.pack → pack-e75385cd52b693dbb8a3b2afb50058952543b3a2.pack} +0 -0
  36. package/lib/bmad-cache/tea/_git_preserved/objects/pack/pack-e75385cd52b693dbb8a3b2afb50058952543b3a2.rev +0 -0
  37. package/lib/bmad-cache/tea/_git_preserved/packed-refs +1 -1
  38. package/lib/bmad-cache/tea/_git_preserved/refs/heads/main +1 -1
  39. package/lib/bmad-cache/tea/_git_preserved/refs/tags/v1.10.0 +1 -0
  40. package/lib/bmad-cache/tea/_git_preserved/shallow +1 -1
  41. package/lib/bmad-cache/tea/docs/explanation/tea-overview.md +2 -2
  42. package/lib/bmad-cache/tea/docs/how-to/workflows/run-atdd.md +28 -30
  43. package/lib/bmad-cache/tea/docs/reference/commands.md +4 -4
  44. package/lib/bmad-cache/tea/docs/reference/configuration.md +1 -1
  45. package/lib/bmad-cache/tea/package-lock.json +2 -2
  46. package/lib/bmad-cache/tea/package.json +1 -1
  47. package/lib/bmad-cache/tea/src/module-help.csv +1 -1
  48. package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-atdd/SKILL.md +1 -1
  49. package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-atdd/atdd-checklist-template.md +50 -27
  50. package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-atdd/checklist.md +18 -17
  51. package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-atdd/instructions.md +1 -1
  52. package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-atdd/steps-c/step-01-preflight-and-context.md +21 -3
  53. package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-atdd/steps-c/step-01b-resume.md +1 -1
  54. package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-atdd/steps-c/step-02-generation-mode.md +1 -1
  55. package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-atdd/steps-c/step-03-test-strategy.md +1 -1
  56. package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-atdd/steps-c/step-04-generate-tests.md +20 -19
  57. package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-atdd/steps-c/step-04a-subagent-api-failing.md +13 -13
  58. package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-atdd/steps-c/step-04b-subagent-e2e-failing.md +13 -13
  59. package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-atdd/steps-c/step-04c-aggregate.md +42 -18
  60. package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-atdd/steps-c/step-05-validate-and-complete.md +12 -3
  61. package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-atdd/workflow-plan.md +2 -2
  62. package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-atdd/workflow.md +2 -2
  63. package/lib/bmad-cache/tea/src/workflows/testarch/bmad-testarch-atdd/workflow.yaml +2 -2
  64. package/lib/bmad.js +25 -4
  65. package/lib/installer.js +2 -1
  66. package/lib/methodology/BMAD_AI_Development_Training.pptx +0 -0
  67. package/lib/methodology/version.json +1 -1
  68. package/lib/profile.js +107 -0
  69. package/lib/warning-filter.js +245 -0
  70. package/package.json +2 -2
  71. package/test/experimental-warning.test.js +314 -0
  72. package/test/fixtures/README.md +74 -0
  73. package/test/fixtures/empty-project/README.md +5 -0
  74. package/test/fixtures/empty-project/package.json +5 -0
  75. package/test/fixtures/onprem-profile-baseline/.gitkeep +2 -0
  76. package/test/fixtures/standard-profile-baseline/.gitkeep +2 -0
  77. package/test/onprem-injection.test.js +48 -0
  78. package/test/profile.test.js +301 -0
  79. package/lib/bmad-cache/bmb/_git_preserved/objects/pack/pack-4b395d030ca386fc5748f1b670dcf8c0ef41c94c.idx +0 -0
  80. package/lib/bmad-cache/bmb/_git_preserved/objects/pack/pack-4b395d030ca386fc5748f1b670dcf8c0ef41c94c.rev +0 -0
  81. package/lib/bmad-cache/tea/_git_preserved/objects/pack/pack-c79805bb3fee27fa6d8c612a971af7fc86fc80e1.idx +0 -0
  82. package/lib/bmad-cache/tea/_git_preserved/objects/pack/pack-c79805bb3fee27fa6d8c612a971af7fc86fc80e1.rev +0 -0
@@ -0,0 +1,106 @@
1
+ # Story 21.3: `.roomodes` Template with BMAD Mode File-Regex Restrictions
2
+
3
+ Status: backlog
4
+
5
+ ## Story
6
+
7
+ As a **chief architect**,
8
+ I want a `.roomodes` file generated for Roo Code installs defining 4 BMAD modes with `fileRegex` restrictions per phase,
9
+ So that Roo Code's application-layer enforcement (`FileRestrictionError`) prevents agents from editing code files during planning phases — independent of whether the LLM follows the prompt.
10
+
11
+ ## Acceptance Criteria
12
+
13
+ 1. New template `lib/templates/roomodes.template.yaml` exists defining four `customModes`:
14
+ - `bmad-pm` — `groups: [read, [edit, { fileRegex: "\\.md$", description: "Markdown only" }]]`
15
+ - `bmad-architect` — `groups: [read, [edit, { fileRegex: "\\.(md|xml|drawio)$", description: "Markdown and diagram files only" }]]`
16
+ - `bmad-techlead` — `groups: [read, [edit, { fileRegex: "\\.(md|json|yaml|yml)$", description: "Markdown, JSON, YAML only" }]]`
17
+ - `bmad-dev` — `groups: [read, edit, command]` (full access)
18
+ 2. Each mode includes `slug`, `name`, `roleDefinition`, `whenToUse`, and `customInstructions` fields with content matching the BMAD phase descriptions in the source playbook (`optimizing-local-llm-coding-agents-bmad.md` Section 4.3).
19
+ 3. The Roo Code agent entry in `lib/agents.js` gains an optional `extraInstructionTemplates` array. For Roo Code: `[{ template: 'roomodes.template.yaml', target: '.roomodes', merger: 'yaml-customModes' }]`.
20
+ 4. The installer reads `extraInstructionTemplates` per agent and stamps each entry. For Roo Code, `.roomodes` is written at the project root.
21
+ 5. New module `lib/merge/roomodes.js` exports `mergeRoomodes(existingYaml, templateYaml)` returning the merged YAML string. Behavior:
22
+ - If `.roomodes` does not exist, return the template content.
23
+ - If it exists, parse both, merge the `customModes` arrays such that the four ma-agents-owned slugs (`bmad-pm`, `bmad-architect`, `bmad-techlead`, `bmad-dev`) overwrite any colliding entries (with a console warning naming each colliding slug); all other user-defined `customModes` entries are preserved untouched and emitted before the ma-agents entries.
24
+ - YAML output preserves comments and field order in user-owned entries where the YAML library supports it.
25
+ 6. Re-running install produces byte-identical `.roomodes` content for the four ma-agents slugs (NFR46), with user-owned entries preserved.
26
+ 7. NFR47 contract: a unit test verifies the rendered `bmad-architect` `fileRegex` rejects paths ending in `.ts`, `.py`, `.js`, `.go`; accepts `.md`, `.xml`, `.drawio`. Verified by `RegExp(fileRegex).test(path)` — no Roo Code runtime needed.
27
+ 8. The Roo Code agent must already be registered in `lib/agents.js` (Epic 18 Story 18.1). If Epic 18 is not yet merged when this story starts, this story includes the minimal Roo Code agent registration as a prerequisite sub-task.
28
+ 9. **Slug-stomp protection.** On install, for each of the four ma-agents-owned slugs (`bmad-pm`, `bmad-architect`, `bmad-techlead`, `bmad-dev`) that already exist in the user's `.roomodes`, the installer diffs the existing slug body (`roleDefinition` + `customInstructions` + `groups`) against the current template output for the user's profile. If a non-whitespace-only diff exists, the installer ABORTS with a named error (e.g., `RoomodesSlugDivergenceError`) listing the diverged slugs and instructs the user to either (a) rename the slug (accept it as user-owned, dropping our version) or (b) rerun with `--force-roomodes-overwrite` to accept the stomp. Without `--force-roomodes-overwrite`, no overwrite happens. This supersedes the "console warning only" behavior described in AC #5's bullet about colliding slugs for the four ma-agents-owned slugs; collisions on other slugs are impossible (ma-agents only owns these four). `--yes` does NOT imply `--force-roomodes-overwrite` — silent stomps on user-edited BMAD modes would be a data-loss regression.
29
+ 10. **Overwrite audit log.** When a ma-agents-owned slug IS written or overwritten (first install, clean match of existing content, or user passed `--force-roomodes-overwrite`), the installer appends an entry to a top-level field `roomodesOverwriteLog` in `.ma-agents.json` with shape `{ slug, date: <ISO-timestamp>, previousContentHash: <sha256-of-previous-body-or-null-if-new>, profile: <value> }`. The array grows append-only and is capped at 50 entries (oldest dropped on insert beyond cap) to prevent unbounded growth of `.ma-agents.json`. Rationale: gives operators a forensic trail for "when did the BMAD mode definitions last change on this project?"
30
+
31
+ ## Tasks / Subtasks
32
+
33
+ - [ ] Task 1: Create `lib/templates/roomodes.template.yaml` per AC #1, #2
34
+ - [ ] Task 2: Add `extraInstructionTemplates` field to Roo Code entry in `lib/agents.js` (AC #3)
35
+ - [ ] Task 3: Implement `lib/merge/roomodes.js::mergeRoomodes` (AC #5)
36
+ - [ ] 3.1 Use `js-yaml` (already a dependency, verify) for parse/dump
37
+ - [ ] 3.2 Slug-collision detection + console warning
38
+ - [ ] 3.3 Preserve user entries in original order, ma-agents entries appended
39
+ - [ ] Task 4: Wire `extraInstructionTemplates` processing into `lib/installer.js` per-agent install loop (AC #4)
40
+ - [ ] Task 5: Tests in `test/roomodes-merge.test.js`
41
+ - [ ] 5.1 Empty `.roomodes` → 4 BMAD modes present
42
+ - [ ] 5.2 Existing user mode preserved when slug does not collide
43
+ - [ ] 5.3 Colliding slug overwritten with console warning
44
+ - [ ] 5.4 Idempotency: two merges produce byte-identical output (NFR46)
45
+ - [ ] 5.5 NFR47 contract — `bmad-architect` fileRegex matrix (AC #7)
46
+ - [ ] 5.6 Same matrix for `bmad-pm` (`.md` only) and `bmad-techlead` (`.md|.json|.yaml|.yml` only)
47
+ - [ ] Task 6: If Epic 18 not merged, add Roo Code agent registration as prerequisite (AC #8) — coordinate with epic execution order before starting
48
+ - [ ] Task 7: Slug-stomp protection (AC #9)
49
+ - [ ] 7.1 For each of the 4 ma-agents-owned slugs, compute diff of existing `roleDefinition`+`customInstructions`+`groups` against current template render
50
+ - [ ] 7.2 On any non-whitespace diff without `--force-roomodes-overwrite`, abort with `RoomodesSlugDivergenceError` listing diverged slugs and remediation
51
+ - [ ] 7.3 Add `--force-roomodes-overwrite` flag to `bin/cli.js` install command; document in help text that `--yes` does not imply it
52
+ - [ ] Task 8: Overwrite audit log (AC #10)
53
+ - [ ] 8.1 On write of a ma-agents-owned slug, append `{ slug, date, previousContentHash, profile }` to `.ma-agents.json::roomodesOverwriteLog`
54
+ - [ ] 8.2 `previousContentHash` is sha256 of the previous slug body (concat of `roleDefinition`+`customInstructions`+JSON.stringify(`groups`)) or `null` on first install of that slug
55
+ - [ ] 8.3 Cap array at 50 entries — oldest dropped on insert beyond cap
56
+ - [ ] 8.4 Test: install → log has 4 entries with null hashes; re-install with hand-edit + `--force-roomodes-overwrite` → log has 5 entries, 5th has non-null previous hash
57
+
58
+ ## Dev Notes
59
+
60
+ ### Architecture Compliance
61
+
62
+ - **Decision P3-3** — `.roomodes` is the highest-leverage application-layer guardrail in the design. NFR47 makes the enforcement contract testable.
63
+ - **NFR46** — Idempotent stamping. The merger is responsible for deterministic output for the ma-agents-owned slugs.
64
+
65
+ ### Source Tree Components to Touch
66
+
67
+ | File | Change |
68
+ |------|--------|
69
+ | `lib/templates/roomodes.template.yaml` | CREATE |
70
+ | `lib/merge/roomodes.js` | CREATE |
71
+ | `lib/agents.js` | MODIFY — add `extraInstructionTemplates` to Roo Code entry |
72
+ | `lib/installer.js` | MODIFY — process `extraInstructionTemplates` per agent during install |
73
+ | `test/roomodes-merge.test.js` | CREATE |
74
+
75
+ ### Dependencies
76
+
77
+ - Story 21.1 (profile API — `.roomodes` content branches on profile in Story 21.6, but stamping is unconditional)
78
+ - Story 21.2 (composition pattern — but `.roomodes` uses YAML merger, not marker-based markdown injection)
79
+ - Epic 18 Story 18.1 (Roo Code agent registration) — see AC #8
80
+
81
+ ### Reference
82
+
83
+ Source playbook: `optimizing-local-llm-coding-agents-bmad.md` Section 4.3 — full `.roomodes` example with 4 BMAD modes. Use that exactly for the template content.
84
+
85
+ ### Out of Scope
86
+
87
+ - On-prem-specific `customInstructions` additions (Story 21.6 will append on-prem rules to each mode's `customInstructions` when profile=on-prem)
88
+ - Cline-to-Roo migration (Epic 18 Story 18.4)
89
+
90
+ ## Dev Agent Record
91
+
92
+ ### Agent Model Used
93
+ _(to be filled by dev agent)_
94
+
95
+ ### Debug Log References
96
+ _(to be filled)_
97
+
98
+ ### Completion Notes List
99
+ _(to be filled)_
100
+
101
+ ### File List
102
+ _(to be filled)_
103
+
104
+ ## Change Log
105
+ - 2026-04-14: Story created (Epic 21, Story 21.3)
106
+ - 2026-04-14: Added ACs #9 and #10 for slug-stomp protection and overwrite audit log (Findings #9 and #20, corrective plan step 3). New CLI flag: `--force-roomodes-overwrite`. New `.ma-agents.json` field: `roomodesOverwriteLog` (append-only, capped at 50). AC #5's "colliding slug overwrite with console warning" is superseded for the four ma-agents-owned slugs by AC #9's abort-and-require-force behavior; AC #5 still governs behavior for user-owned slugs (preserved untouched).
@@ -0,0 +1,86 @@
1
+ # Story 21.4: Expanded `AGENTS.md` Template for OpenCode
2
+
3
+ Status: backlog
4
+
5
+ ## Story
6
+
7
+ As an **OpenCode user installing ma-agents**,
8
+ I want a comprehensive `AGENTS.md` generated at my project root covering text-vs-file rules, BMAD phase discipline, and the project's BMAD output structure,
9
+ So that OpenCode's auto-loading of `AGENTS.md` gives the agent the same guardrails Roo Code gets via `.roomodes`.
10
+
11
+ ## Acceptance Criteria
12
+
13
+ 1. New template `lib/templates/agents-md.template.md` exists containing:
14
+ - The same text-vs-file rules from the universal block (Story 21.2)
15
+ - A "never create files in `~/.claude/` or any user home directory" rule (universal for AGENTS.md regardless of profile — OpenCode + any model should respect it)
16
+ - A BMAD phase declaration section (Discovery/PM, Architecture, Tech Lead/Stories, Implementation) with phase-specific behavior rules
17
+ - The project BMAD output structure with placeholders: `{{PLANNING_DIR}}`, `{{ARCHITECTURE_DIR}}`, `{{STORIES_DIR}}` — stamped to project's actual `_bmad-output/` paths at install time
18
+ 2. The OpenCode agent entry in `lib/agents.js` gains an `extraInstructionTemplates` entry: `[{ template: 'agents-md.template.md', target: 'AGENTS.md', merger: 'markdown-markers' }]`.
19
+ 3. The marker-based markdown merger reuses the function used by Story 21.2 — content within `<!-- MA-AGENTS-START -->` / `<!-- MA-AGENTS-END -->` is rewritten; outside content preserved (NFR5, NFR46).
20
+ 4. After Story 21.4 ships, on a fresh OpenCode install:
21
+ - `AGENTS.md` is written at project root with the stamped content
22
+ - `opencode.json::instructions[]` array contains `"AGENTS.md"` if not already present (reuses Epic 9's JSON-merge function unchanged — additive only, NFR18)
23
+ 5. Re-running install produces byte-identical `AGENTS.md` marker-block content and does not duplicate the `instructions[]` entry (NFR46, NFR18).
24
+ 6. The phase declaration content is profile-agnostic in this story; on-prem-specific rules (`/no_think`, reasoning mode) come via Story 21.6 by appending to the same marker block.
25
+
26
+ ## Tasks / Subtasks
27
+
28
+ - [ ] Task 1: Create `lib/templates/agents-md.template.md` per AC #1
29
+ - [ ] Task 2: Add `extraInstructionTemplates` to OpenCode entry in `lib/agents.js` (AC #2)
30
+ - [ ] Task 3: Verify the existing OpenCode JSON-merge from Epic 9 handles the additive append idempotently (AC #4, #5) — read `lib/installer.js` JSON-merge function to confirm; no changes expected
31
+ - [ ] Task 4: Wire `markdown-markers` merger handling for `extraInstructionTemplates` (likely already handled by Story 21.3's `extraInstructionTemplates` processor — extend, do not duplicate)
32
+ - [ ] Task 5: Tests in `test/agents-md.test.js`
33
+ - [ ] 5.1 Fresh install: `AGENTS.md` created with universal rules, phase section, stamped paths
34
+ - [ ] 5.2 `opencode.json::instructions[]` contains `AGENTS.md` after install
35
+ - [ ] 5.3 Re-install: `instructions[]` not duplicated (NFR18)
36
+ - [ ] 5.4 Re-install: `AGENTS.md` marker-block content byte-identical (NFR46)
37
+ - [ ] 5.5 Existing `AGENTS.md` user content outside markers preserved
38
+ - [ ] 5.6 Path placeholders correctly stamped from project's `_bmad-output/` layout
39
+
40
+ ## Dev Notes
41
+
42
+ ### Architecture Compliance
43
+
44
+ - **Decision P3-3** — OpenCode parallel to Roo Code's `.roomodes` for application-layer guidance. OpenCode lacks file-regex enforcement (no `FileRestrictionError`), so reliance on prompt + Plan/Build mode is acceptable; this story does what's possible within OpenCode's capabilities.
45
+ - **NFR18** (Epic 9 contract) — JSON-merge into `opencode.json::instructions[]` remains additive-only.
46
+
47
+ ### Source Tree Components to Touch
48
+
49
+ | File | Change |
50
+ |------|--------|
51
+ | `lib/templates/agents-md.template.md` | CREATE |
52
+ | `lib/agents.js` | MODIFY — `extraInstructionTemplates` on OpenCode entry |
53
+ | `lib/installer.js` | MAYBE-MODIFY — extend `extraInstructionTemplates` processor (Story 21.3) for `markdown-markers` merger if not already supported |
54
+ | `test/agents-md.test.js` | CREATE |
55
+
56
+ ### Dependencies
57
+
58
+ - Story 21.2 (universal rules content — `AGENTS.md` reuses the same wording sourced from `lib/templates/instruction-block-universal.template.md` to avoid drift; consider reading the universal template and embedding it within the AGENTS.md template at stamp time, OR duplicate the rules text and add a comment marking the source of truth)
59
+ - Story 21.3 (`extraInstructionTemplates` processor pattern — extend if needed)
60
+ - Epic 9 (OpenCode JSON-merge — reused unchanged)
61
+
62
+ ### Reference
63
+
64
+ Source playbook: `optimizing-local-llm-coding-agents-bmad.md` Section 5.3 — full `AGENTS.md` example with phase rules.
65
+
66
+ ### Out of Scope
67
+
68
+ - On-prem-specific additions (Story 21.6)
69
+ - BMAD persona phase prefix in customize-loader (Story 21.7)
70
+
71
+ ## Dev Agent Record
72
+
73
+ ### Agent Model Used
74
+ _(to be filled by dev agent)_
75
+
76
+ ### Debug Log References
77
+ _(to be filled)_
78
+
79
+ ### Completion Notes List
80
+ _(to be filled)_
81
+
82
+ ### File List
83
+ _(to be filled)_
84
+
85
+ ## Change Log
86
+ - 2026-04-14: Story created (Epic 21, Story 21.4)
@@ -0,0 +1,82 @@
1
+ # Story 21.5: Expanded `.clinerules` Template
2
+
3
+ Status: backlog
4
+
5
+ ## Story
6
+
7
+ As a **Cline user**,
8
+ I want `.clinerules` to include BMAD phase discipline and text-vs-file rules,
9
+ So that Cline (which already supports `.clinerules` natively) gets the same universal guardrails.
10
+
11
+ ## Acceptance Criteria
12
+
13
+ 1. New template `lib/templates/clinerules.template.md` exists containing the universal text-vs-file rules and BMAD phase rules formatted for the Cline `.clinerules` convention (one rule per line or short paragraph blocks — Cline's documented format).
14
+ 2. Both `.cline/clinerules.md` and `.clinerules` (Cline writes both per `lib/agents.js`) receive the expanded content via the existing marker-based injection.
15
+ 3. Existing user content outside `<!-- MA-AGENTS-START -->` / `<!-- MA-AGENTS-END -->` markers is preserved (NFR5).
16
+ 4. Re-running install produces byte-identical marker-block content in both files (NFR46).
17
+ 5. Mention Cline-specific concept: "Use Cline's Architect mode for BMAD planning phases (PM, Architect, Tech Lead). Switch to Code mode only for the implementation phase." This is universal guidance, not on-prem-specific.
18
+ 6. **Dual-file drift detection.** The installer writes both `.cline/clinerules.md` and `.clinerules` from the SAME template render. Before writing, it reads both existing files (if present) and compares their marker-block contents. If the two marker blocks diverge (non-whitespace diff), the installer ABORTS with a named error (e.g., `ClinerulesDualFileDriftError`) naming both files and their diff, instructing the user to reconcile manually before retrying. `--yes` does NOT bypass this check — reconciliation between the two Cline rule files is user work, and silently picking a "winner" could discard intentional edits. This is an explicit, documented exception to the usual `--yes` bypass convention.
19
+
20
+ ## Tasks / Subtasks
21
+
22
+ - [ ] Task 1: Create `lib/templates/clinerules.template.md` per AC #1, #5
23
+ - [ ] Task 2: Verify Cline's `extraInstructionTemplates` (or equivalent existing injection path) writes both `.cline/clinerules.md` and `.clinerules` consistently (AC #2)
24
+ - [ ] Task 3: Confirm the universal block from Story 21.2 already covers most of the content; this story may simply add Cline-specific framing (Architect mode mention) and rely on `composeInstructionBlock` for the rest. Decide between two implementations:
25
+ - **Option A**: Cline-only template that wraps `composeInstructionBlock` output with Cline-specific intro/outro
26
+ - **Option B**: Inline Cline-specific rules directly into `lib/templates/clinerules.template.md` and skip `composeInstructionBlock` for Cline
27
+ - Pick Option A — single source of truth for the universal rules
28
+ - [ ] Task 4: Tests in `test/clinerules.test.js`
29
+ - [ ] 4.1 Both `.clinerules` and `.cline/clinerules.md` contain universal rules + Architect-mode guidance
30
+ - [ ] 4.2 User content outside markers preserved
31
+ - [ ] 4.3 Idempotent re-install (NFR46)
32
+ - [ ] 4.4 Both files have identical marker-block content
33
+ - [ ] Task 5: Dual-file drift detection (AC #6)
34
+ - [ ] 5.1 Before write, compare marker-block contents of `.cline/clinerules.md` and `.clinerules` when both exist
35
+ - [ ] 5.2 On non-whitespace diff, abort with `ClinerulesDualFileDriftError` naming both files and emitting the diff
36
+ - [ ] 5.3 Verify `--yes` does NOT bypass this check; document in CLI help text as an explicit exception
37
+
38
+ ## Dev Notes
39
+
40
+ ### Architecture Compliance
41
+
42
+ - **Decision P3-3** — Cline parallel to Roo Code/OpenCode. Cline's Architect mode is the application-layer enforcement we leverage via prompt guidance.
43
+ - **NFR46** — idempotent stamping for both Cline output files.
44
+
45
+ ### Source Tree Components to Touch
46
+
47
+ | File | Change |
48
+ |------|--------|
49
+ | `lib/templates/clinerules.template.md` | CREATE |
50
+ | `lib/installer.js` | MAYBE-MODIFY — verify Cline extraInstructionTemplates behavior |
51
+ | `test/clinerules.test.js` | CREATE |
52
+
53
+ ### Dependencies
54
+
55
+ - Story 21.2 (universal block — composed via `composeInstructionBlock` for the shared rules)
56
+
57
+ ### Reference
58
+
59
+ Source playbook: `optimizing-local-llm-coding-agents-bmad.md` Section 3.3 — `.clinerules` example.
60
+
61
+ ### Out of Scope
62
+
63
+ - Cline-to-Roo migration (Epic 18 Story 18.4)
64
+ - On-prem-specific additions (Story 21.6 — appended to the same marker block when profile=on-prem)
65
+
66
+ ## Dev Agent Record
67
+
68
+ ### Agent Model Used
69
+ _(to be filled by dev agent)_
70
+
71
+ ### Debug Log References
72
+ _(to be filled)_
73
+
74
+ ### Completion Notes List
75
+ _(to be filled)_
76
+
77
+ ### File List
78
+ _(to be filled)_
79
+
80
+ ## Change Log
81
+ - 2026-04-14: Story created (Epic 21, Story 21.5)
82
+ - 2026-04-14: Added AC #6 for `.cline/clinerules.md` vs `.clinerules` drift detection (Finding #10, corrective plan step 3). `--yes` does NOT bypass this check — reconciliation is user work.
@@ -0,0 +1,112 @@
1
+ # Story 21.6: On-Prem Layered Guardrails
2
+
3
+ Status: backlog
4
+
5
+ ## Story
6
+
7
+ As an **engineer running an on-prem install**,
8
+ I want the installer to layer local-LLM-specific guardrails on top of the universal block when profile=on-prem,
9
+ So that Nemotron and other local LLMs stop hallucinating `str_replace_editor`, dumping files into `~/.claude/`, and overthinking planning prompts.
10
+
11
+ ## Acceptance Criteria
12
+
13
+ 1. New template `lib/templates/instruction-block-onprem.template.md` exists containing:
14
+ - A `/no_think` reasoning-OFF directive (as a literal line at the top of the on-prem block) intended for planning-phase use
15
+ - A "NEVER create files in `~/.claude/` or any user home directory; all files go under the project directory" rule
16
+ - A "do NOT reference or use `str_replace_editor` or any Claude Code-specific tool that may not exist in this agent" rule
17
+ - Reasoning-mode and sampling guidance per BMAD phase (planning: reasoning OFF, low temperature; implementation: reasoning ON, moderate temperature) — guidance text only, not enforced
18
+ 2. `composeInstructionBlock({ profile: 'on-prem', manifestPath })` (Story 21.2) appends this template's content within the same `<!-- MA-AGENTS-START -->` markers, after the universal content.
19
+ 3. `composeInstructionBlock({ profile: 'standard', manifestPath })` does NOT include any on-prem content. Verified by absence of the strings `/no_think`, `str_replace_editor`, `~/.claude/` in the standard-profile output (NFR44).
20
+ 4. The `.roomodes` template (Story 21.3) gains profile-conditional `customInstructions` content per mode:
21
+ - When profile=on-prem, each BMAD mode's `customInstructions` block gets appended with the on-prem rules (no-home-dir-writes, no `str_replace_editor`)
22
+ - When profile=standard, no on-prem content appears in `customInstructions`
23
+ 5. The `AGENTS.md` template (Story 21.4) gains the same profile-conditional treatment within its marker block.
24
+ 6. The `.clinerules` template (Story 21.5) gains the same profile-conditional treatment within its marker block.
25
+ 7. Re-running install with profile=on-prem produces byte-identical content in all three files (`.roomodes`, `AGENTS.md`, `.clinerules`/`.cline/clinerules.md`) for ma-agents-owned sections (NFR46).
26
+ 8. Switching profile from standard to on-prem (via the Story 21.10 `reconfigure` command — no CLI flag) updates all marker-block content and `.roomodes` `customInstructions` to include the on-prem rules; switching back to standard removes them. User content outside markers/owned slugs is preserved. NOTE: Story 21.10 (Profile Reconfigure) is a separately-tracked new story in the corrective plan; until it lands, profile switching is done by hand-editing `.ma-agents.json`.
27
+ 9. **Home-dir rule narrowed to forbid ad-hoc writes only (resolves scope-vs-rule contradiction).** The generated on-prem template content (per AC #1) must NOT contain a blanket prohibition against writes to `~/.claude/`. Instead, the rendered text must contain the narrowed phrasing (or semantic equivalent): `"Never create ad-hoc response or output files in the user home directory (~/.claude/, ~/Documents, etc.). The installer's own scoped writes to ~/.claude/ during --scope global are authorized and not covered by this rule."` Verified by grep on rendered on-prem output: presence of `Never create ad-hoc` and `installer's own scoped writes` substrings; absence of the older blanket `"NEVER create files in ~/.claude/"` phrasing. Rationale: `npx ma-agents install --scope global` legitimately writes ma-agents config under `~/.claude/`, and the previous rule phrasing contradicted a supported install mode.
28
+ 10. **Informational log for on-prem + `--scope global` combination.** When profile=on-prem AND `--scope global` is selected at install time, the installer emits exactly the following informational log line (pinned verbatim for test assertion): `Note: on-prem profile with --scope global writes ma-agents config to ~/.claude/. This is authorized. The on-prem guardrail forbids ad-hoc files there, not the installer's scoped writes.` This line is emitted after profile resolution and before the first write under `~/.claude/`. Tests may `grep`/match on it.
29
+ 11. **No numerical sampling guidance in prompt template (delegated to Story 21.8).** The rendered on-prem instruction block must NOT contain any numerical temperature/top_p values (e.g., no `temperature 0.0`, `top_p 1.0`, `temperature 0.6`, `top_p 0.95` — or any other numeric tuple) in the rendered on-prem output. Per-phase sampling numbers are a server-side concern and belong in the vLLM reference doc (Story 21.8), not in the agent prompt. The prompt may retain (a) the `/no_think` directive, which IS prompt-level and effective, and (b) qualitative textual guidance such as "use careful reasoning for implementation; skip deep reasoning for discussion." Verified by regex on rendered on-prem output: `/temperature\s*[0-9]|top[_-]?p\s*[0-9]/i` must not match. AC #1's bullet "Reasoning-mode and sampling guidance per BMAD phase (planning: reasoning OFF, low temperature; implementation: reasoning ON, moderate temperature) — guidance text only, not enforced" is narrowed by this AC: qualitative text is allowed ("low"/"moderate"); specific numbers are not.
30
+
31
+ ## Tasks / Subtasks
32
+
33
+ - [ ] Task 1: Create `lib/templates/instruction-block-onprem.template.md` per AC #1
34
+ - [ ] Task 2: Verify `composeInstructionBlock` (Story 21.2) loads on-prem content when present (AC #2, #3)
35
+ - [ ] Task 3: Extend `lib/templates/roomodes.template.yaml` (Story 21.3) with profile-conditional `customInstructions` per mode (AC #4)
36
+ - [ ] 3.1 Decide implementation: separate template for on-prem `customInstructions` blocks, OR templating placeholders within the existing template that get conditionally stamped
37
+ - [ ] 3.2 Update `mergeRoomodes` to compose conditional content based on profile
38
+ - [ ] Task 4: Extend `AGENTS.md` template stamping (Story 21.4) to append on-prem rules when profile=on-prem (AC #5)
39
+ - [ ] Task 5: Extend `.clinerules` template stamping (Story 21.5) to append on-prem rules when profile=on-prem (AC #6)
40
+ - [ ] Task 6: Profile switching (AC #8)
41
+ - [ ] 6.1 Verify profile-switch to on-prem (via reconfigure path or manual `.ma-agents.json` edit) updates all three files correctly
42
+ - [ ] 6.2 Verify profile-switch to standard (via reconfigure path or manual `.ma-agents.json` edit) removes on-prem content cleanly
43
+ - [ ] Task 7: Tests in `test/onprem-guardrails.test.js`
44
+ - [ ] 7.1 Standard profile: no on-prem strings in any output (AC #3 — NFR44)
45
+ - [ ] 7.2 On-prem profile: `/no_think`, no-home-dir, no-str_replace_editor present in all three files
46
+ - [ ] 7.3 Idempotency: same profile, two installs → byte-identical output (AC #7 — NFR46)
47
+ - [ ] 7.4 Profile switch standard→on-prem→standard restores original standard content
48
+ - [ ] 7.5 User content outside markers preserved across switches
49
+ - [ ] Task 8: Narrow home-dir rule phrasing in `instruction-block-onprem.template.md` (AC #9)
50
+ - [ ] 8.1 Replace any blanket `"NEVER create files in ~/.claude/"` phrasing with the narrowed "ad-hoc" phrasing from AC #9
51
+ - [ ] 8.2 Test: grep rendered on-prem output for `Never create ad-hoc` present and blanket phrasing absent
52
+ - [ ] Task 9: Informational log for on-prem + `--scope global` (AC #10)
53
+ - [ ] 9.1 After profile resolution, before first `~/.claude/` write, emit the pinned log line verbatim
54
+ - [ ] 9.2 Test: install with `--profile on-prem-equivalent-persisted` + `--scope global` captures stdout and asserts the pinned line
55
+ - [ ] Task 10: Strip numerical sampling from on-prem template (AC #11, Finding #12-a)
56
+ - [ ] 10.1 Review `instruction-block-onprem.template.md` for any `temperature <num>` / `top_p <num>` text; replace with qualitative phrasing only ("low"/"moderate") and keep `/no_think`
57
+ - [ ] 10.2 Test: regex `/temperature\s*[0-9]|top[_-]?p\s*[0-9]/i` against rendered on-prem output returns no match
58
+
59
+ ## Dev Notes
60
+
61
+ ### Architecture Compliance
62
+
63
+ - **Decision P3-3** — On-prem layer ships here. Universal layer (Story 21.2) + on-prem layer (this story) compose to the full on-prem experience.
64
+ - **NFR44** — Standard profile must remain free of on-prem-specific output. Test 7.1 enforces.
65
+ - **NFR46** — Deterministic stamping for both profiles.
66
+
67
+ ### Source Tree Components to Touch
68
+
69
+ | File | Change |
70
+ |------|--------|
71
+ | `lib/templates/instruction-block-onprem.template.md` | CREATE |
72
+ | `lib/templates/roomodes.template.yaml` | MODIFY — add on-prem content (conditional or via parallel template) |
73
+ | `lib/installer.js` | MODIFY — profile-conditional stamping for `.roomodes`, `AGENTS.md`, `.clinerules` per-tool extensions |
74
+ | `lib/merge/roomodes.js` | MODIFY — accept profile arg, compose `customInstructions` accordingly |
75
+ | `test/onprem-guardrails.test.js` | CREATE |
76
+
77
+ ### Dependencies
78
+
79
+ - Stories 21.1 through 21.5 (foundation + per-tool templates) all merged
80
+
81
+ ### Reference
82
+
83
+ Source playbook:
84
+ - `/no_think` directive: Section 6.1, 6.8
85
+ - `str_replace_editor` warning: Section 2.5, 6.4
86
+ - No-home-dir rule: Section 1, 5.3
87
+ - Per-phase reasoning/sampling: Section 6.1, 8 (Sampling Parameters by Phase table)
88
+
89
+ ### Out of Scope
90
+
91
+ - BMAD persona phase prefix in customize-loader (Story 21.7 — separate concern, edits `.customize.yaml` files)
92
+ - vLLM serving doc (Story 21.8)
93
+
94
+ ## Dev Agent Record
95
+
96
+ ### Agent Model Used
97
+ _(to be filled by dev agent)_
98
+
99
+ ### Debug Log References
100
+ _(to be filled)_
101
+
102
+ ### Completion Notes List
103
+ _(to be filled)_
104
+
105
+ ### File List
106
+ _(to be filled)_
107
+
108
+ ## Change Log
109
+ - 2026-04-14: Story created (Epic 21, Story 21.6)
110
+ - 2026-04-14: Removed prescriptive `--profile=` flag references from AC #8 and Task 6 subitems (flag retired; profile switch is via Story 21.10 reconfigure command once delivered, or manual `.ma-agents.json` edit until then). Aligned with P0 spec-alignment PR #34.
111
+ - 2026-04-14: Added ACs #9 and #10 reconciling on-prem home-dir rule with `--scope global` (Finding #8, corrective plan step 3). Rule narrowed to forbid ad-hoc writes only; installer's scoped writes authorized. Informational log pinned verbatim for test assertion.
112
+ - 2026-04-14: Added AC #11 forbidding numerical temperature/top_p values in the on-prem instruction block (Finding #12-a, corrective plan step 3). Narrows AC #1's "sampling guidance" bullet — qualitative text allowed, specific numbers delegated to Story 21.8's vLLM reference doc. `/no_think` (prompt-effective) is retained.
@@ -0,0 +1,126 @@
1
+ # Story 21.7: BMAD Persona Phase-Aware Prompt Prefix (On-Prem Only)
2
+
3
+ Status: backlog
4
+
5
+ ## Story
6
+
7
+ As an **engineer running an on-prem install with the BMAD module**,
8
+ I want each BMAD agent persona to receive a phase-aware system-prompt prefix steering its reasoning mode appropriately,
9
+ So that planning agents (PM, Architect, SM) stop overthinking and producing files for discussion prompts, and implementation agents (Dev) keep their reasoning mode for careful coding.
10
+
11
+ ## Acceptance Criteria
12
+
13
+ 1. Each `lib/bmad-customize/*.customize.yaml` file gains an optional `phase: planning|implementation` field. Initial classification:
14
+ - **Planning** (reasoning-OFF prefix): `bmm-pm` (John), `bmm-architect` (Winston), `bmm-sm` (Bob), `bmm-analyst` (Mary), `bmm-tech-writer` (Paige), `bmm-ux-designer` (Sally), `bmm-qa` (Gad)
15
+ - **Implementation** (reasoning-ON prefix): `bmm-dev` (Amelia), `bmm-quick-flow-solo-dev` (Barry)
16
+ 2. Each `*.customize.yaml` file gains an optional `on_prem_phase_prefix:` field containing the prefix text. The values are populated for every agent listed in AC #1; the field is absent for any agent that does not need a prefix.
17
+ 3. The BMAD customize-loader (location to be determined during Task 1 exploration — likely `lib/bmad.js` or a dedicated customize module) reads `getProfile(projectRoot)` from `lib/profile.js` and:
18
+ - When profile=on-prem AND `on_prem_phase_prefix` is set, prepends the prefix to the persona's existing `critical_actions` / system-prompt content
19
+ - When profile=standard OR `on_prem_phase_prefix` is absent, does NOT prepend anything (output identical to pre-Story-21.7 behavior)
20
+ 4. NFR44 verification: with profile=standard, the rendered `.customize.yaml` consumption produces output byte-identical to the pre-Story-21.7 baseline for every agent. Captured by snapshot tests.
21
+ 5. The phase prefix content for planning agents includes:
22
+ - A `/no_think` directive at the top
23
+ - "When the user asks a question or for an opinion, respond in TEXT in the chat. Do NOT create files."
24
+ - "You are a planning-phase agent. Do NOT skip ahead to implementation."
25
+ 6. The phase prefix content for implementation agents includes:
26
+ - "Think carefully about the implementation before writing code."
27
+ - "Reference the story or spec you are implementing before starting."
28
+ - "When asked a question, respond in text. Do not start coding unless asked."
29
+ 7. The customize-loader's prefix composition is idempotent — running the loader twice produces the same composed content (NFR46).
30
+ 8. **Phase enum extended to `{planning | implementation | mixed}` with persona reassignment (supersedes AC #1).** The `phase` field in each `*.customize.yaml` now accepts the value `mixed` in addition to `planning` and `implementation`. Final per-persona assignment is:
31
+ - **`phase: planning`** — `bmm-pm` (John), `bmm-architect` (Winston), `bmm-ux-designer` (Sally), `bmm-tech-writer` (Paige)
32
+ - **`phase: implementation`** — `bmm-dev` (Amelia), `bmm-quick-flow-solo-dev` (Barry)
33
+ - **`phase: mixed`** — `bmm-sm` (Bob), `bmm-qa` (Gad), `bmm-analyst` (Mary)
34
+ This supersedes AC #1's binary classification (which listed Bob, Gad, and Mary under `planning` and Paige under `planning`). The reason: Bob and Gad straddle planning conversations and story-file edits; Mary moves between research discussion and brief edits. A binary classification mislabels them and forces the wrong phase prefix. Each `*.customize.yaml` file must encode the `phase` value per this list.
35
+ 9. **Composite prefix for `phase: mixed`.** Personas with `phase: mixed` receive the following composite preamble as their `on_prem_phase_prefix` value (in addition to any persona-specific content): `"This persona handles both discussion and editing. Default to text responses when asked questions; only create or edit files when explicitly asked (verbs: create, write, generate, update, edit). When editing code, reason carefully; when discussing, keep responses concise without deep reasoning chains."` The customize-loader composes this prefix when profile=on-prem AND `phase: mixed`, parallel to the planning/implementation branches in AC #5/#6.
36
+ 10. **Customize-loader validator must accept `mixed`.** The Epic 15 customize-loader schema validation (wherever it lives — see Dev Notes) must recognize `mixed` as a valid `phase` value. If the current loader validator only accepts `{planning, implementation}`, a prerequisite sub-task is to extend the validator enum. This AC is satisfied when: (a) the validator accepts all three values without error, and (b) a `*.customize.yaml` file with `phase: mixed` is loaded successfully in a unit test.
37
+
38
+ ## Tasks / Subtasks
39
+
40
+ - [ ] Task 1: Locate the customize-loader code path (`lib/bmad.js`, `lib/bmad-customize/`, or a dedicated module). Document file:line in Dev Agent Record. Confirm where `critical_actions` are composed for each persona.
41
+ - [ ] Task 2: Add `phase` and `on_prem_phase_prefix` fields to the 9 affected `*.customize.yaml` files (AC #1, #2, #5, #6)
42
+ - Planning-phase content: shared text block defined once (e.g., in a comment-marked region) and pasted into each planning persona's YAML
43
+ - Implementation-phase content: same approach, pasted into the 2 implementation personas
44
+ - [ ] Task 3: Extend the customize-loader to compose the prefix when `getProfile(projectRoot) === 'on-prem'` and the YAML has `on_prem_phase_prefix` (AC #3, #7)
45
+ - [ ] Task 4: Snapshot-test baseline parity (AC #4)
46
+ - [ ] 4.1 Capture pre-Story-21.7 customize-loader output for all 11 BMAD agents (run before changes; commit snapshots to `test/snapshots/customize/`)
47
+ - [ ] 4.2 With profile=standard after Story 21.7 changes, customize-loader output matches snapshots byte-for-byte
48
+ - [ ] Task 5: Tests in `test/bmad-persona-phase-prefix.test.js`
49
+ - [ ] 5.1 Profile=on-prem: planning agents get `/no_think` + text-response prefix prepended
50
+ - [ ] 5.2 Profile=on-prem: implementation agents get careful-implementation prefix prepended
51
+ - [ ] 5.3 Profile=standard: no prefix prepended for any agent (snapshot match — AC #4)
52
+ - [ ] 5.4 Profile=on-prem with agent missing `on_prem_phase_prefix`: no prefix, no error
53
+ - [ ] 5.5 Idempotency: two loader runs produce identical composed content (NFR46)
54
+ - [ ] Task 6: Phase enum extension and persona reassignment (AC #8, #9, #10)
55
+ - [ ] 6.1 Reassign `phase` values per AC #8: Bob, Gad, Mary → `mixed`; Paige stays `planning`; others unchanged
56
+ - [ ] 6.2 Populate `on_prem_phase_prefix` for the three `mixed` personas with the composite preamble in AC #9 (plus any persona-specific tail)
57
+ - [ ] 6.3 PREREQUISITE: audit the Epic 15 customize-loader schema validator — if it enforces enum `{planning, implementation}`, extend it to `{planning, implementation, mixed}`. If the validator lives outside this story's scope, raise an Epic 15 issue/story and document the blocker in Dev Agent Record before proceeding
58
+ - [ ] 6.4 Tests: (a) profile=on-prem + `phase: mixed` → composite prefix prepended; (b) validator accepts all three enum values
59
+
60
+ ## Dev Notes
61
+
62
+ ### Architecture Compliance
63
+
64
+ - **Decision P3-3** — BMAD persona phase prefix is the on-prem-only layer that complements per-tool guardrails. Inactive on standard profile.
65
+ - **NFR44** — Standard profile customize output unchanged. Snapshot tests are the contract.
66
+
67
+ ### Source Tree Components to Touch
68
+
69
+ | File | Change |
70
+ |------|--------|
71
+ | `lib/bmad-customize/bmm-pm.customize.yaml` | MODIFY — add `phase: planning`, `on_prem_phase_prefix:` |
72
+ | `lib/bmad-customize/bmm-architect.customize.yaml` | MODIFY — same |
73
+ | `lib/bmad-customize/bmm-sm.customize.yaml` | MODIFY — same |
74
+ | `lib/bmad-customize/bmm-analyst.customize.yaml` | MODIFY — same |
75
+ | `lib/bmad-customize/bmm-tech-writer.customize.yaml` | MODIFY — same |
76
+ | `lib/bmad-customize/bmm-ux-designer.customize.yaml` | MODIFY — same |
77
+ | `lib/bmad-customize/bmm-qa.customize.yaml` | MODIFY — same (Gad — verify file name from Epic 20 SQA work) |
78
+ | `lib/bmad-customize/bmm-dev.customize.yaml` | MODIFY — `phase: implementation`, prefix |
79
+ | `lib/bmad-customize/bmm-quick-flow-solo-dev.customize.yaml` | MODIFY — same |
80
+ | `lib/bmad.js` (or customize-loader location) | MODIFY — profile-conditional prefix composition |
81
+ | `test/bmad-persona-phase-prefix.test.js` | CREATE |
82
+ | `test/snapshots/customize/*.snapshot` | CREATE — pre-change baselines for NFR44 verification |
83
+
84
+ ### Dependencies
85
+
86
+ - Story 21.1 (`getProfile` API)
87
+ - Epic 15 (BMAD 6.2.1 module restructure — customize-loader infrastructure may have changed)
88
+
89
+ ### Out of Scope
90
+
91
+ - Per-tool template content (Stories 21.2–21.6)
92
+ - vLLM serving doc (Story 21.8)
93
+ - Customize-loader refactoring beyond what's needed for prefix composition
94
+
95
+ ### Notes on Phase Enum Extension (Epic 15 Prerequisite)
96
+
97
+ **2026-04-14 audit clarification:** `lib/bmad-customize/` in this repo contains only `*.customize.yaml` artifacts — no JS loader or validator code. The customize-loader lives upstream in BMAD (bmad-method). Per the project's durable policy of overriding BMAD built-ins via extension (not upstream PRs to bmad-method), the `phase: mixed` extension is implemented by either (a) relying on BMAD's loader accepting unknown YAML fields silently (outcome 1 below — trivially satisfied) or (b) the ma-agents extension intercepting the YAML at install time and producing profile-specific variants (`*.customize.yaml` for standard, `*.customize.on-prem.yaml` for on-prem) with the installer choosing based on the persisted profile (outcome 3 below). Outcome 2 is only relevant if BMAD's loader has an enum validator that accepts `mixed` — nice to discover, no action required.
98
+
99
+ AC #10 requires the Epic 15 customize-loader schema validator to accept `mixed` as a valid `phase` value. During Task 1's loader-discovery pass, verify whether a validator is in place and what enum it enforces. Three outcomes:
100
+
101
+ 1. **No validator present** — `phase` is a free-form string today; AC #10 is trivially satisfied. Document this in Dev Agent Record.
102
+ 2. **Validator present and accepts `mixed` already** — no change needed; satisfy AC #10 with a regression test.
103
+ 3. **Validator present and rejects `mixed`** — extend the enum to `{planning, implementation, mixed}`. If the validator is owned by Epic 15 code outside this story's change scope, raise an Epic 15 issue/story as a prerequisite and block Task 6 until it lands. Document explicitly rather than letting the dev hit this at implementation time.
104
+
105
+ ### Notes on Customize-Loader Discovery
106
+
107
+ If the loader is implicit (BMAD itself reads `*.customize.yaml` directly with no ma-agents intermediation), this story's design may need adjustment. In that case, the prefix must be embedded directly into the YAML's existing `critical_actions` block under a profile-aware key, OR ma-agents must intercept the file at install time and produce two variants (`*.customize.yaml` for standard, `*.customize.on-prem.yaml` for on-prem) with the installer choosing which to deploy. Decide during Task 1 and document the chosen approach.
108
+
109
+ ## Dev Agent Record
110
+
111
+ ### Agent Model Used
112
+ _(to be filled by dev agent)_
113
+
114
+ ### Debug Log References
115
+ _(to be filled)_
116
+
117
+ ### Completion Notes List
118
+ _(to be filled)_
119
+
120
+ ### File List
121
+ _(to be filled)_
122
+
123
+ ## Change Log
124
+ - 2026-04-14: Story created (Epic 21, Story 21.7)
125
+ - 2026-04-14: Extended phase enum to `{planning, implementation, mixed}` via new ACs #8, #9, #10 (Finding #11, corrective plan step 3). Reassigned SM Bob, SQA Gad, Analyst Mary to `mixed`. AC #1's binary classification is SUPERSEDED by AC #8 but left in place to preserve the historical decision trail. Added Epic 15 validator-extension prerequisite note to Dev Notes.
126
+ - 2026-04-14: Clarified Epic 15 prerequisite — customize-loader lives upstream in BMAD, not in ma-agents. Phase enum extension implemented via BMAD-built-in override policy (extension pattern, not upstream PR). Closes corrective-plan step 6 dependency-wiring audit.
@@ -0,0 +1,100 @@
1
+ # Story 21.8: vLLM Reference Deployment Doc and README On-Prem Section
2
+
3
+ Status: backlog
4
+
5
+ ## Story
6
+
7
+ As a **DevOps engineer setting up the on-prem inference server**,
8
+ I want a single reference doc covering vLLM flags, tool-call-parser, context length, quantization, and per-phase sampling guidance,
9
+ So that I can configure Nemotron Super 49B (or similar) to behave correctly with the coding agents ma-agents installs.
10
+
11
+ ## Acceptance Criteria
12
+
13
+ 1. New file `docs/deployment/vllm-nemotron.md` exists covering:
14
+ - Recommended vLLM launch command with all critical flags: `--enable-auto-tool-choice`, `--tool-call-parser qwen3_coder`, `--max-model-len 32768`, `--enforce-eager`, `--trust-remote-code`, `--seed=1`
15
+ - Quantization tradeoffs (BF16 vs FP8 vs NVFP4) including VRAM and instruction-following quality impact — table format
16
+ - Reasoning-mode behavior: `/no_think` system-prompt directive enables reasoning-OFF; default is reasoning-ON
17
+ - Per-phase sampling parameters table (planning: temp 0.0, top_p 1.0; implementation: temp 0.6, top_p 0.95)
18
+ - The `str_replace_editor` hallucination warning and mitigation (cross-reference to the on-prem template content from Story 21.6)
19
+ - A complete sample launch command block ready to copy-paste
20
+ - Cross-reference to `optimizing-local-llm-coding-agents-bmad.md` as the source playbook
21
+ 2. `README.md` gains a new top-level section "On-Prem / Air-Gapped Deployment" containing:
22
+ - One-paragraph overview of the on-prem use case
23
+ - Explanation of the install-time profile prompt (`Is this an on-prem install?`)
24
+ - Link to `docs/deployment/vllm-nemotron.md`
25
+ - Link to the source playbook `optimizing-local-llm-coding-agents-bmad.md`
26
+ 3. The deployment doc is NOT stamped into target projects by the installer — it is repo documentation only (FR179). Verified by grep on `lib/installer.js` and `lib/templates/` for any reference to the deployment doc path.
27
+ 4. The deployment doc explicitly states it is informational only — running ma-agents does not configure or manage the vLLM server.
28
+ 5. Documentation only: this story adds NO code, NO tests beyond a docs-link sanity check.
29
+ 6. **Sampling parameters owned by the vLLM reference doc, not the prompt.** The per-phase sampling-parameters table (temperature/top_p values, e.g., planning: temp 0.0, top_p 1.0; implementation: temp 0.6, top_p 0.95) lives in `docs/deployment/vllm-nemotron.md` and nowhere else in the repo. The doc must contain an explicit statement of this ownership with a phrase along the lines of: `"The agent prompt does not control sampling; sampling is set at the vLLM request/serve layer. The table below is for operators configuring the serve or the agent's request parameters, not for end-users."` Verified by (a) presence of the sampling table in the doc, (b) presence of the ownership statement, (c) cross-referenced with Story 21.6 AC #11 which forbids numerical values in the on-prem prompt template. Finding #12 is closed by the combination of 21.6 AC #11 (no numbers in prompt) + 21.8 AC #6 (numbers only in serving doc, with ownership disclaimer).
30
+ 7. **Tool-call-parser flag provenance and cross-model validation warning.** The doc must cite the provenance of `--tool-call-parser qwen3_coder`: specifically, that this parser was validated to work with Nemotron Super 49B v1.5 per the source conversation `optimizing-local-llm-coding-agents-bmad.md` (dated April 2026). Immediately following the citation, the doc must contain a clearly-marked warning paragraph (formatted as a `NOTE:` or `WARNING:` admonition) with content along the lines of: `"NOTE: This parser flag is validated for Nemotron Super 49B v1.5. Users deploying other Nemotron versions or different local LLMs MUST validate the parser flag against their model's HuggingFace card — copy-paste of this flag to an unvalidated model risks silent tool-call corruption."` Verified by grep: presence of `Nemotron Super 49B v1.5` in the same paragraph as `qwen3_coder`, and presence of the cross-model validation warning paragraph.
31
+
32
+ ## Tasks / Subtasks
33
+
34
+ - [ ] Task 1: Create `docs/deployment/vllm-nemotron.md` per AC #1
35
+ - [ ] 1.1 Source content from `optimizing-local-llm-coding-agents-bmad.md` Section 6 (Model Deployment Optimization)
36
+ - [ ] 1.2 Include the full sample launch command from Section 6.7
37
+ - [ ] 1.3 Include the sampling table from Section 8 (Quick Reference Cheat Sheet)
38
+ - [ ] Task 2: Update `README.md` per AC #2
39
+ - [ ] 2.1 Choose insertion point — after "Installation" / before "Skill Library" reads naturally
40
+ - [ ] 2.2 Add the section with overview, profile-prompt explanation, and links
41
+ - [ ] Task 3: Sanity check (AC #3, #4, #5)
42
+ - [ ] 3.1 Grep `lib/` for any reference to the deployment doc path → must return zero matches
43
+ - [ ] 3.2 Doc explicitly disclaims installer responsibility for the inference server
44
+ - [ ] Task 4: Optional — link-check
45
+ - [ ] 4.1 If a markdown link checker is in the test suite, verify all internal links in the new doc and README section resolve
46
+ - [ ] Task 5: Sampling ownership + prompt/server boundary (AC #6)
47
+ - [ ] 5.1 Include the per-phase sampling table in the vLLM reference doc
48
+ - [ ] 5.2 Add the ownership statement ("agent prompt does not control sampling...") immediately above the table
49
+ - [ ] 5.3 Cross-reference Story 21.6 AC #11 in a short parenthetical ("Numbers deliberately omitted from the on-prem prompt template; see Story 21.6 AC #11.")
50
+ - [ ] Task 6: Tool-call-parser provenance + cross-model warning (AC #7)
51
+ - [ ] 6.1 Cite `optimizing-local-llm-coding-agents-bmad.md` (April 2026) as the source validating `--tool-call-parser qwen3_coder` for Nemotron Super 49B v1.5
52
+ - [ ] 6.2 Add the `NOTE:` admonition warning against copy-paste to unvalidated models
53
+
54
+ ## Dev Notes
55
+
56
+ ### Architecture Compliance
57
+
58
+ - **Decision P3-3** — Inference-server tuning is documentation only. The installer runs on engineer dev machines, not inference servers. Mixing concerns rejected in the architecture decision.
59
+ - **FR179** — Doc ships in the repo, not into projects.
60
+
61
+ ### Source Tree Components to Touch
62
+
63
+ | File | Change |
64
+ |------|--------|
65
+ | `docs/deployment/vllm-nemotron.md` | CREATE |
66
+ | `README.md` | MODIFY — new "On-Prem / Air-Gapped Deployment" section |
67
+ | `optimizing-local-llm-coding-agents-bmad.md` | NO CHANGE — referenced as source |
68
+
69
+ ### Dependencies
70
+
71
+ - None — pure docs story, can ship in parallel with other Epic 21 stories.
72
+
73
+ ### Reference
74
+
75
+ Entire source playbook `optimizing-local-llm-coding-agents-bmad.md` Section 6 — verbatim usable for most of the content. Adapt formatting to match repo doc conventions.
76
+
77
+ ### Out of Scope
78
+
79
+ - Any installer changes
80
+ - vLLM Docker images, Helm charts, or deployment automation
81
+ - Per-model tuning beyond Nemotron Super 49B (other local LLMs may need different parsers — out of scope; doc may include a one-line note)
82
+
83
+ ## Dev Agent Record
84
+
85
+ ### Agent Model Used
86
+ _(to be filled by dev agent)_
87
+
88
+ ### Debug Log References
89
+ _(to be filled)_
90
+
91
+ ### Completion Notes List
92
+ _(to be filled)_
93
+
94
+ ### File List
95
+ _(to be filled)_
96
+
97
+ ## Change Log
98
+ - 2026-04-14: Story created (Epic 21, Story 21.8)
99
+ - 2026-04-14: Added AC #6 making the vLLM reference doc the sole owner of per-phase sampling parameters with an explicit prompt-vs-server ownership statement (Finding #12-b, corrective plan step 3). Paired with Story 21.6 AC #11 to close Finding #12 end-to-end.
100
+ - 2026-04-14: Added AC #7 requiring parser-flag provenance citation for `--tool-call-parser qwen3_coder` (Nemotron Super 49B v1.5, per source playbook dated April 2026) and a cross-model validation warning (Finding #13, corrective plan step 3).