@lumenflow/core 2.2.2 → 2.3.1

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 (213) hide show
  1. package/dist/active-wu-detector.d.ts +1 -1
  2. package/dist/active-wu-detector.js +1 -1
  3. package/dist/arg-parser.js +51 -18
  4. package/dist/backlog-generator.d.ts +4 -4
  5. package/dist/backlog-generator.js +4 -4
  6. package/dist/backlog-sync-validator.js +1 -1
  7. package/dist/cleanup-lock.d.ts +9 -2
  8. package/dist/cleanup-lock.js +17 -7
  9. package/dist/code-path-validator.d.ts +3 -3
  10. package/dist/code-path-validator.js +3 -3
  11. package/dist/compliance-parser.d.ts +1 -1
  12. package/dist/compliance-parser.js +1 -1
  13. package/dist/constants/backlog-patterns.d.ts +1 -1
  14. package/dist/constants/backlog-patterns.js +1 -1
  15. package/dist/constants/dora-constants.d.ts +1 -1
  16. package/dist/constants/dora-constants.js +1 -1
  17. package/dist/constants/gate-constants.d.ts +1 -1
  18. package/dist/constants/gate-constants.js +1 -1
  19. package/dist/constants/linter-constants.d.ts +1 -1
  20. package/dist/constants/linter-constants.js +1 -1
  21. package/dist/constants/tokenizer-constants.d.ts +1 -1
  22. package/dist/constants/tokenizer-constants.js +1 -1
  23. package/dist/context/location-resolver.js +2 -1
  24. package/dist/context-validation-integration.d.ts +1 -0
  25. package/dist/core/scope-checker.d.ts +3 -3
  26. package/dist/core/scope-checker.js +3 -3
  27. package/dist/core/tool-runner.d.ts +5 -5
  28. package/dist/core/tool-runner.js +5 -5
  29. package/dist/core/tool.constants.d.ts +1 -1
  30. package/dist/core/tool.constants.js +1 -1
  31. package/dist/core/tool.schemas.d.ts +2 -2
  32. package/dist/core/tool.schemas.js +1 -1
  33. package/dist/core/worktree-guard.d.ts +1 -1
  34. package/dist/core/worktree-guard.js +1 -1
  35. package/dist/coverage-gate.d.ts +12 -3
  36. package/dist/coverage-gate.js +15 -8
  37. package/dist/date-utils.d.ts +4 -4
  38. package/dist/date-utils.js +4 -4
  39. package/dist/dependency-graph.d.ts +6 -0
  40. package/dist/dependency-graph.js +43 -2
  41. package/dist/dependency-guard.d.ts +2 -2
  42. package/dist/dependency-guard.js +3 -3
  43. package/dist/dependency-validator.d.ts +4 -4
  44. package/dist/dependency-validator.js +4 -7
  45. package/dist/domain/orchestration.constants.d.ts +31 -10
  46. package/dist/domain/orchestration.constants.js +45 -16
  47. package/dist/domain/orchestration.schemas.d.ts +54 -28
  48. package/dist/domain/orchestration.schemas.js +2 -2
  49. package/dist/domain/orchestration.types.d.ts +2 -2
  50. package/dist/domain/orchestration.types.js +2 -2
  51. package/dist/error-handler.d.ts +10 -10
  52. package/dist/error-handler.js +10 -10
  53. package/dist/file-classifiers.d.ts +6 -6
  54. package/dist/file-classifiers.js +6 -6
  55. package/dist/gates-config.d.ts +74 -0
  56. package/dist/gates-config.js +209 -2
  57. package/dist/git-adapter.d.ts +11 -11
  58. package/dist/git-adapter.js +11 -11
  59. package/dist/git-context-extractor.d.ts +112 -0
  60. package/dist/git-context-extractor.js +559 -0
  61. package/dist/hardcoded-strings.d.ts +1 -1
  62. package/dist/hardcoded-strings.js +1 -1
  63. package/dist/incremental-lint.d.ts +1 -1
  64. package/dist/incremental-lint.js +2 -2
  65. package/dist/incremental-test.d.ts +1 -1
  66. package/dist/incremental-test.js +1 -1
  67. package/dist/index.d.ts +13 -0
  68. package/dist/index.js +25 -0
  69. package/dist/invariants/check-automated-tests.d.ts +2 -2
  70. package/dist/invariants/check-automated-tests.js +3 -3
  71. package/dist/lane-checker.d.ts +28 -7
  72. package/dist/lane-checker.js +316 -159
  73. package/dist/lane-suggest-prompt.d.ts +108 -0
  74. package/dist/lane-suggest-prompt.js +359 -0
  75. package/dist/lane-validator.d.ts +3 -3
  76. package/dist/lane-validator.js +3 -3
  77. package/dist/logs-lib.d.ts +1 -1
  78. package/dist/logs-lib.js +1 -1
  79. package/dist/lumenflow-config-schema.d.ts +162 -0
  80. package/dist/lumenflow-config-schema.js +180 -0
  81. package/dist/manual-test-validator.d.ts +2 -2
  82. package/dist/manual-test-validator.js +3 -3
  83. package/dist/merge-lock.d.ts +8 -1
  84. package/dist/merge-lock.js +16 -7
  85. package/dist/micro-worktree.d.ts +81 -13
  86. package/dist/micro-worktree.js +98 -17
  87. package/dist/migration-deployer.d.ts +1 -1
  88. package/dist/migration-deployer.js +1 -1
  89. package/dist/orchestration-advisory-loader.d.ts +2 -2
  90. package/dist/orchestration-advisory-loader.js +10 -6
  91. package/dist/orchestration-advisory.d.ts +3 -3
  92. package/dist/orchestration-advisory.js +4 -4
  93. package/dist/orchestration-di.d.ts +4 -4
  94. package/dist/orchestration-di.js +4 -4
  95. package/dist/orchestration-rules.d.ts +4 -4
  96. package/dist/orchestration-rules.js +18 -10
  97. package/dist/orphan-detector.d.ts +3 -3
  98. package/dist/orphan-detector.js +3 -3
  99. package/dist/patrol-loop.d.ts +170 -0
  100. package/dist/patrol-loop.js +186 -0
  101. package/dist/process-detector.d.ts +5 -5
  102. package/dist/process-detector.js +5 -5
  103. package/dist/rebase-artifact-cleanup.d.ts +3 -3
  104. package/dist/rebase-artifact-cleanup.js +3 -3
  105. package/dist/resolve-policy.d.ts +195 -0
  106. package/dist/resolve-policy.js +203 -0
  107. package/dist/risk-detector.d.ts +2 -2
  108. package/dist/risk-detector.js +2 -2
  109. package/dist/rollback-utils.d.ts +1 -1
  110. package/dist/rollback-utils.js +1 -1
  111. package/dist/section-headings.d.ts +1 -1
  112. package/dist/section-headings.js +1 -1
  113. package/dist/spawn-escalation.d.ts +4 -4
  114. package/dist/spawn-escalation.js +3 -3
  115. package/dist/spawn-monitor.d.ts +4 -4
  116. package/dist/spawn-monitor.js +4 -4
  117. package/dist/spawn-recovery.d.ts +3 -3
  118. package/dist/spawn-recovery.js +3 -3
  119. package/dist/spawn-registry-schema.d.ts +2 -2
  120. package/dist/spawn-registry-schema.js +2 -2
  121. package/dist/spawn-registry-store.d.ts +2 -2
  122. package/dist/spawn-registry-store.js +2 -2
  123. package/dist/spawn-strategy.d.ts +17 -11
  124. package/dist/spawn-strategy.js +47 -44
  125. package/dist/spawn-tree.d.ts +3 -3
  126. package/dist/spawn-tree.js +3 -3
  127. package/dist/state-cleanup-core.d.ts +205 -0
  128. package/dist/state-cleanup-core.js +240 -0
  129. package/dist/state-doctor-core.d.ts +168 -0
  130. package/dist/state-doctor-core.js +251 -0
  131. package/dist/stream-error-handler.d.ts +67 -0
  132. package/dist/stream-error-handler.js +94 -0
  133. package/dist/telemetry.d.ts +1 -1
  134. package/dist/telemetry.js +1 -1
  135. package/dist/template-loader.d.ts +162 -0
  136. package/dist/template-loader.js +372 -0
  137. package/dist/test-baseline.d.ts +176 -0
  138. package/dist/test-baseline.js +282 -0
  139. package/dist/usecases/get-suggestions.usecase.d.ts +1 -1
  140. package/dist/validation/command-registry.js +37 -0
  141. package/dist/validators/backlog-sync.js +4 -2
  142. package/dist/worktree-scanner.d.ts +1 -1
  143. package/dist/worktree-scanner.js +1 -1
  144. package/dist/worktree-symlink.d.ts +3 -3
  145. package/dist/worktree-symlink.js +3 -3
  146. package/dist/wu-backlog-updater.d.ts +1 -1
  147. package/dist/wu-backlog-updater.js +1 -1
  148. package/dist/wu-claim-helpers.d.ts +1 -1
  149. package/dist/wu-claim-helpers.js +1 -1
  150. package/dist/wu-claim-resume.d.ts +1 -1
  151. package/dist/wu-claim-resume.js +1 -1
  152. package/dist/wu-consistency-checker.d.ts +1 -1
  153. package/dist/wu-consistency-checker.js +17 -11
  154. package/dist/wu-constants.d.ts +73 -21
  155. package/dist/wu-constants.js +65 -22
  156. package/dist/wu-done-branch-only.d.ts +1 -1
  157. package/dist/wu-done-branch-only.js +1 -1
  158. package/dist/wu-done-docs-generate.d.ts +1 -1
  159. package/dist/wu-done-docs-generate.js +1 -1
  160. package/dist/wu-done-messages.d.ts +2 -2
  161. package/dist/wu-done-messages.js +2 -2
  162. package/dist/wu-done-metadata.d.ts +3 -3
  163. package/dist/wu-done-metadata.js +3 -3
  164. package/dist/wu-done-pr.d.ts +1 -1
  165. package/dist/wu-done-pr.js +4 -2
  166. package/dist/wu-done-preflight.d.ts +8 -0
  167. package/dist/wu-done-preflight.js +18 -2
  168. package/dist/wu-done-ui.d.ts +3 -3
  169. package/dist/wu-done-ui.js +3 -3
  170. package/dist/wu-done-validation.d.ts +30 -0
  171. package/dist/wu-done-validation.js +106 -1
  172. package/dist/wu-done-worktree.d.ts +1 -1
  173. package/dist/wu-done-worktree.js +11 -1
  174. package/dist/wu-events-cleanup.d.ts +148 -0
  175. package/dist/wu-events-cleanup.js +401 -0
  176. package/dist/wu-helpers.d.ts +2 -2
  177. package/dist/wu-helpers.js +2 -2
  178. package/dist/wu-id-generator.d.ts +58 -0
  179. package/dist/wu-id-generator.js +103 -0
  180. package/dist/wu-lint.js +1 -1
  181. package/dist/wu-preflight-validators.d.ts +13 -1
  182. package/dist/wu-preflight-validators.js +56 -1
  183. package/dist/wu-recovery.d.ts +2 -2
  184. package/dist/wu-recovery.js +4 -4
  185. package/dist/wu-repair-core.d.ts +5 -5
  186. package/dist/wu-repair-core.js +6 -6
  187. package/dist/wu-schema-normalization.d.ts +1 -1
  188. package/dist/wu-schema-normalization.js +1 -1
  189. package/dist/wu-schema.d.ts +7 -7
  190. package/dist/wu-schema.js +8 -8
  191. package/dist/wu-spawn-context.d.ts +87 -0
  192. package/dist/wu-spawn-context.js +175 -0
  193. package/dist/wu-spawn-helpers.d.ts +1 -1
  194. package/dist/wu-spawn-helpers.js +1 -1
  195. package/dist/wu-spawn.d.ts +177 -4
  196. package/dist/wu-spawn.js +694 -72
  197. package/dist/wu-state-schema.d.ts +1 -1
  198. package/dist/wu-state-schema.js +1 -1
  199. package/dist/wu-state-store.d.ts +3 -3
  200. package/dist/wu-state-store.js +3 -3
  201. package/dist/wu-status-transition.d.ts +1 -1
  202. package/dist/wu-status-transition.js +1 -1
  203. package/dist/wu-status-updater.d.ts +3 -3
  204. package/dist/wu-status-updater.js +3 -3
  205. package/dist/wu-validation-constants.d.ts +2 -2
  206. package/dist/wu-validation-constants.js +2 -2
  207. package/dist/wu-validation.d.ts +3 -3
  208. package/dist/wu-validation.js +3 -3
  209. package/dist/wu-yaml-fixer.d.ts +2 -2
  210. package/dist/wu-yaml-fixer.js +3 -3
  211. package/dist/wu-yaml.d.ts +23 -0
  212. package/dist/wu-yaml.js +76 -2
  213. package/package.json +5 -2
package/dist/wu-spawn.js CHANGED
@@ -25,7 +25,7 @@
25
25
  * Codex Mode:
26
26
  * When --codex is used, outputs a Codex/GPT-friendly Markdown prompt (no antml/XML escaping).
27
27
  *
28
- * @see {@link docs/04-operations/_frameworks/lumenflow/agent/onboarding/agent-invocation-guide.md} - Context loading templates
28
+ * @see {@link https://lumenflow.dev/reference/agent-invocation-guide/} - Context loading templates
29
29
  */
30
30
  import { existsSync, readFileSync } from 'node:fs';
31
31
  import { fileURLToPath } from 'node:url';
@@ -46,15 +46,545 @@ import { loadInvariants, INVARIANT_TYPES } from './invariants-runner.js';
46
46
  import { validateSpawnArgs, generateExecutionModeSection, generateThinkToolGuidance, recordSpawnToRegistry, formatSpawnRecordedMessage, } from './wu-spawn-helpers.js';
47
47
  // Agent skills loading removed for vendor-agnostic design
48
48
  import { validateSpawnDependencies, formatDependencyError } from './dependency-validator.js';
49
+ /**
50
+ * WU-1253/WU-1291: Template System for Spawn Prompts
51
+ *
52
+ * DECISION (WU-1291): Template system is ACTIVATED with graceful degradation.
53
+ *
54
+ * The template system loads prompt sections from .lumenflow/templates/spawn-prompt/
55
+ * with YAML frontmatter and manifest-driven assembly order. This design provides:
56
+ *
57
+ * 1. **Maintainability**: Templates in markdown files are easier to edit than code strings
58
+ * 2. **Client extensibility**: Client-specific overrides via templates.{client}/ directories
59
+ * 3. **Conditional inclusion**: Templates selected based on WU type and policy settings
60
+ * 4. **Graceful fallback**: If template loading fails, hardcoded functions are used
61
+ *
62
+ * Template loading is attempted via tryAssembleSpawnTemplates(). If it returns null
63
+ * (templates missing or assembly fails), the spawn output uses hardcoded generator
64
+ * functions (generateTDDDirective, generateBugDiscoverySection, etc.).
65
+ *
66
+ * @see template-loader.ts for the loading and assembly implementation
67
+ * @see .lumenflow/templates/manifest.yaml for the template registry
68
+ */
69
+ import { loadManifest, loadTemplatesWithOverrides, assembleTemplates, } from './template-loader.js';
70
+ import { resolvePolicy } from './resolve-policy.js';
71
+ // WU-1270: Import telemetry emit function for methodology tracking
72
+ import { emit as emitTelemetry } from './telemetry.js';
49
73
  /**
50
74
  * Mandatory agent trigger patterns.
51
- * Mirrors MANDATORY_TRIGGERS from orchestration-advisory-loader.mjs.
75
+ * Mirrors MANDATORY_TRIGGERS from orchestration.constants.ts.
76
+ *
77
+ * Note: For LumenFlow framework development, this is empty since we don't have
78
+ * application-specific concerns like PHI, auth, or RLS. Projects using LumenFlow
79
+ * should configure their own triggers based on their domain requirements.
52
80
  */
53
81
  const MANDATORY_TRIGGERS = {
54
- 'security-auditor': ['supabase/migrations/**', '**/auth/**', '**/rls/**', '**/permissions/**'],
55
- 'beacon-guardian': ['**/prompts/**', '**/classification/**', '**/detector/**', '**/llm/**'],
82
+ // No mandatory triggers for LumenFlow framework development.
56
83
  };
57
84
  const LOG_PREFIX = '[wu:spawn]';
85
+ /**
86
+ * WU-1192: Truncation prevention constants (consolidated from CLI)
87
+ *
88
+ * These constants help detect when spawn output has been truncated during
89
+ * copy-paste operations or context loading. The warning banner alerts users
90
+ * to the truncation risk, and the end sentinel allows verification that
91
+ * the full output was received.
92
+ */
93
+ export const TRUNCATION_WARNING_BANNER = `<!-- LUMENFLOW_TRUNCATION_WARNING -->
94
+ <!--
95
+ ⚠️ CRITICAL: DO NOT TRUNCATE THIS OUTPUT
96
+
97
+ This spawn prompt MUST be copied verbatim. Truncation causes:
98
+ - Missing constraints (agents ignore safety rules)
99
+ - Missing TDD directives (agents skip tests)
100
+ - Degraded agent performance
101
+
102
+ VERIFICATION: The output MUST end with: <!-- LUMENFLOW_SPAWN_END -->
103
+ If you don't see that sentinel at the end, the output was truncated.
104
+ -->
105
+ `;
106
+ export const SPAWN_END_SENTINEL = '<!-- LUMENFLOW_SPAWN_END -->';
107
+ /**
108
+ * WU-1253/WU-1291: Try to assemble spawn prompt sections from templates.
109
+ *
110
+ * This function loads templates from .lumenflow/templates/ and assembles
111
+ * them according to the manifest order. Client-specific overrides are
112
+ * supported via templates.{client}/ directories.
113
+ *
114
+ * **Decision (WU-1291)**: Template system is ACTIVATED. This function is called
115
+ * by generateTaskInvocation() and generateCodexPrompt() to attempt template-based
116
+ * generation. If it returns null (templates missing, manifest invalid, or assembly
117
+ * fails), callers fall back to hardcoded generator functions.
118
+ *
119
+ * Template coverage (as of WU-1291):
120
+ * - Methodology directives (TDD, test-after, none)
121
+ * - Architecture directives (hexagonal, layered, none)
122
+ * - Type-specific directives (documentation, visual, refactor)
123
+ * - Agent guidance (effort-scaling, parallel-tool-calls, search-heuristics, token-budget)
124
+ * - Operational guidance (bug-discovery, quick-fix-commands, lane-selection)
125
+ * - Lane-specific guidance and constraints
126
+ *
127
+ * @param baseDir - Project root directory
128
+ * @param clientName - Client name for overrides (e.g., 'claude', 'cursor')
129
+ * @param context - Context for token replacement and condition evaluation
130
+ * @returns Assembled template content, or null if templates unavailable
131
+ */
132
+ export function tryAssembleSpawnTemplates(baseDir, clientName, context) {
133
+ try {
134
+ const manifest = loadManifest(baseDir);
135
+ const templates = loadTemplatesWithOverrides(baseDir, clientName);
136
+ if (templates.size === 0) {
137
+ return null;
138
+ }
139
+ return assembleTemplates(templates, manifest, context);
140
+ }
141
+ catch {
142
+ // Template loading failed - return null for hardcoded fallback (intentional)
143
+ return null;
144
+ }
145
+ }
146
+ /**
147
+ * Build template context from WU document.
148
+ *
149
+ * @param doc - WU YAML document
150
+ * @param id - WU ID
151
+ * @returns Context for template assembly
152
+ */
153
+ export function buildTemplateContext(doc, id) {
154
+ const lane = doc.lane || '';
155
+ const laneParent = lane.split(':')[0]?.trim() || '';
156
+ return {
157
+ WU_ID: id,
158
+ LANE: lane,
159
+ TYPE: (doc.type || 'feature').toLowerCase(),
160
+ TITLE: doc.title || '',
161
+ DESCRIPTION: doc.description || '',
162
+ WORKTREE_PATH: doc.worktree_path || '',
163
+ laneParent,
164
+ // Add lowercase aliases for condition evaluation
165
+ type: (doc.type || 'feature').toLowerCase(),
166
+ lane,
167
+ worktreePath: doc.worktree_path || '',
168
+ };
169
+ }
170
+ /**
171
+ * WU-1261: Build template context with resolved policy fields.
172
+ *
173
+ * Extends buildTemplateContext() with policy.testing and policy.architecture
174
+ * fields for template condition evaluation.
175
+ *
176
+ * @param doc - WU YAML document
177
+ * @param id - WU ID
178
+ * @param policy - Resolved policy from resolvePolicy()
179
+ * @returns Context for template assembly with policy fields
180
+ */
181
+ export function buildTemplateContextWithPolicy(doc, id, policy) {
182
+ const baseContext = buildTemplateContext(doc, id);
183
+ return {
184
+ ...baseContext,
185
+ 'policy.testing': policy.testing,
186
+ 'policy.architecture': policy.architecture,
187
+ };
188
+ }
189
+ /**
190
+ * WU types that require TDD (failing test first)
191
+ * Note: Used as documentation reference. TDD is the default for any type not in other categories.
192
+ */
193
+ const _TDD_REQUIRED_TYPES = ['feature', 'bug', 'tooling', 'enhancement'];
194
+ /**
195
+ * WU types that require existing tests to pass (no new tests mandated)
196
+ */
197
+ const EXISTING_TESTS_TYPES = ['refactor'];
198
+ /**
199
+ * WU types that require smoke tests + manual QA
200
+ */
201
+ const SMOKE_TEST_TYPES = ['visual', 'design', 'ui'];
202
+ /**
203
+ * WU types that only need format checks (no TDD)
204
+ */
205
+ const DOCS_ONLY_TYPES = ['documentation', 'docs', 'config'];
206
+ /**
207
+ * Generate type-aware test guidance (WU-1142, WU-1192)
208
+ *
209
+ * Returns appropriate test guidance based on WU type:
210
+ * - feature/bug/tooling: Full TDD directive
211
+ * - documentation: Format check only
212
+ * - visual/design: Smoke test + manual QA
213
+ * - refactor: Existing tests must pass
214
+ *
215
+ * @param {string} wuType - WU type from YAML
216
+ * @returns {string} Test guidance section
217
+ */
218
+ export function generateTestGuidance(wuType) {
219
+ const type = (wuType || 'feature').toLowerCase();
220
+ // Documentation WUs - no TDD, just format checks
221
+ if (DOCS_ONLY_TYPES.includes(type)) {
222
+ return `## Documentation Standards
223
+
224
+ **Format check only** - No TDD required for documentation WUs.
225
+
226
+ ### Requirements
227
+
228
+ 1. Run \`pnpm gates --docs-only\` before completion
229
+ 2. Ensure markdown formatting is correct
230
+ 3. Verify links are valid
231
+ 4. Check spelling and grammar`;
232
+ }
233
+ // Visual/Design WUs - smoke tests + manual QA
234
+ if (SMOKE_TEST_TYPES.includes(type)) {
235
+ return `## Visual/Design Testing
236
+
237
+ **Smoke test + manual QA** - Visual WUs require different verification.
238
+
239
+ ### Requirements
240
+
241
+ 1. Create smoke test for component rendering (if applicable)
242
+ 2. Verify visual appearance manually
243
+ 3. Test responsive behavior across breakpoints
244
+ 4. Check accessibility (keyboard navigation, screen reader)
245
+ 5. Document manual QA results in completion notes`;
246
+ }
247
+ // Refactor WUs - existing tests must pass
248
+ if (EXISTING_TESTS_TYPES.includes(type)) {
249
+ return `## Refactor Testing
250
+
251
+ **Existing tests must pass** - Refactoring must not break current behavior.
252
+
253
+ ### Requirements
254
+
255
+ 1. Run all existing tests BEFORE refactoring
256
+ 2. Run all existing tests AFTER refactoring
257
+ 3. No new tests required unless behavior changes
258
+ 4. If tests fail after refactor, the refactor introduced a bug`;
259
+ }
260
+ // Default: TDD required (feature, bug, tooling, enhancement)
261
+ return generateTDDDirective();
262
+ }
263
+ /**
264
+ * Generate the TDD directive section (WU-1585, WU-1192)
265
+ *
266
+ * Positioned immediately after </task> preamble per "Lost in the Middle" research.
267
+ * Critical instructions at START and END of prompt improve adherence.
268
+ *
269
+ * @returns {string} TDD directive section
270
+ */
271
+ function generateTDDDirective() {
272
+ return `## ⛔ TDD DIRECTIVE — READ BEFORE CODING
273
+
274
+ **IF YOU WRITE IMPLEMENTATION CODE BEFORE A FAILING TEST, YOU HAVE FAILED THIS WU.**
275
+
276
+ ### Test-First Workflow (MANDATORY)
277
+
278
+ 1. Write a failing test for the acceptance criteria
279
+ 2. Run the test to confirm it fails (RED)
280
+ 3. Implement the minimum code to pass the test
281
+ 4. Run the test to confirm it passes (GREEN)
282
+ 5. Refactor if needed, keeping tests green
283
+
284
+ ### Test Ratchet Rule (WU-1253)
285
+
286
+ Gates compare test results against \`.lumenflow/test-baseline.json\`:
287
+
288
+ - **NEW failures** (not in baseline) **BLOCK** gates - you must fix them
289
+ - **Pre-existing failures** (in baseline) show **WARNING** - do not block your WU
290
+ - When tests are **fixed**, baseline auto-updates (ratchet forward)
291
+
292
+ If gates fail due to test failures:
293
+ 1. Check if failure is in baseline: \`cat .lumenflow/test-baseline.json\`
294
+ 2. If pre-existing: continue, it will warn but not block
295
+ 3. If NEW: fix the test or add to baseline with reason and fix-wu
296
+
297
+ ### Why This Matters
298
+
299
+ - Tests document expected behavior BEFORE implementation
300
+ - Prevents scope creep and over-engineering
301
+ - Ensures every feature has verification
302
+ - Failing tests prove the test actually tests something
303
+ - Ratchet pattern prevents being blocked by unrelated failures`;
304
+ }
305
+ /**
306
+ * WU-1279: Generate the Mandatory Standards section based on resolved policy
307
+ *
308
+ * Instead of hardcoding TDD/90%/Hexagonal, this function generates the
309
+ * section dynamically based on the resolved methodology policy.
310
+ *
311
+ * @param policy - Resolved policy from resolvePolicy()
312
+ * @returns Mandatory Standards section content
313
+ */
314
+ export function generateMandatoryStandards(policy) {
315
+ const lines = ['## Mandatory Standards', ''];
316
+ // LumenFlow workflow is always required
317
+ lines.push('- **LumenFlow**: Follow trunk-based flow, WIP=1, worktree discipline');
318
+ // Testing methodology based on policy
319
+ if (policy.testing === 'tdd') {
320
+ lines.push(`- **TDD**: Failing test first, then implementation, then passing test. ${policy.coverage_threshold}%+ coverage on new application code`);
321
+ }
322
+ else if (policy.testing === 'test-after') {
323
+ lines.push(`- **Test-After**: Write implementation first, then add tests. ${policy.coverage_threshold}%+ coverage on new application code`);
324
+ }
325
+ else if (policy.testing === 'none') {
326
+ lines.push('- **Testing**: Tests are optional for this project');
327
+ }
328
+ // Architecture based on policy
329
+ if (policy.architecture === 'hexagonal') {
330
+ lines.push('- **Hexagonal Architecture**: Ports-first design. No application -> infrastructure imports');
331
+ }
332
+ else if (policy.architecture === 'layered') {
333
+ lines.push('- **Layered Architecture**: Clear layer separation. Each layer can only depend on layers below it');
334
+ }
335
+ // For architecture: 'none', we don't add any architecture guidance
336
+ // Always include these standards
337
+ lines.push('- **SOLID/DRY/YAGNI/KISS**: No over-engineering, no premature abstraction');
338
+ lines.push('- **Library-First**: Search context7 before writing custom code. No reinventing wheels');
339
+ lines.push('- **Code Quality**: No string literals, no magic numbers, no brittle regexes when libraries exist');
340
+ lines.push('- **Worktree Discipline**: ALWAYS use `pnpm wu:claim` to create worktrees (never `git worktree add` directly). Work ONLY in the worktree, never edit main');
341
+ lines.push('- **Documentation**: Update tooling docs if changing tools. Keep docs in sync with code');
342
+ lines.push('- **Sub-agents**: Use Explore agent for codebase investigation. Activate mandatory agents as configured for your project');
343
+ return lines.join('\n');
344
+ }
345
+ /**
346
+ * WU-1261: Generate test guidance based on resolved policy
347
+ *
348
+ * Selects the appropriate test guidance based on policy.testing value:
349
+ * - 'tdd': Full TDD directive (failing test first)
350
+ * - 'test-after': Implementation first, then tests
351
+ * - 'none': Testing is optional
352
+ *
353
+ * Type overrides still apply (documentation WUs always get docs guidance).
354
+ *
355
+ * @param wuType - WU type from YAML (e.g., 'feature', 'documentation')
356
+ * @param policy - Resolved policy from resolvePolicy()
357
+ * @returns Test guidance section
358
+ */
359
+ export function generatePolicyBasedTestGuidance(wuType, policy) {
360
+ const type = (wuType || 'feature').toLowerCase();
361
+ // Type overrides take precedence (documentation never needs TDD)
362
+ if (DOCS_ONLY_TYPES.includes(type)) {
363
+ return `## Documentation Standards
364
+
365
+ **Format check only** - No TDD required for documentation WUs.
366
+
367
+ ### Requirements
368
+
369
+ 1. Run \`pnpm gates --docs-only\` before completion
370
+ 2. Ensure markdown formatting is correct
371
+ 3. Verify links are valid
372
+ 4. Check spelling and grammar`;
373
+ }
374
+ // Visual/Design WUs - smoke tests + manual QA
375
+ if (SMOKE_TEST_TYPES.includes(type)) {
376
+ return `## Visual/Design Testing
377
+
378
+ **Smoke test + manual QA** - Visual WUs require different verification.
379
+
380
+ ### Requirements
381
+
382
+ 1. Create smoke test for component rendering (if applicable)
383
+ 2. Verify visual appearance manually
384
+ 3. Test responsive behavior across breakpoints
385
+ 4. Check accessibility (keyboard navigation, screen reader)
386
+ 5. Document manual QA results in completion notes`;
387
+ }
388
+ // Refactor WUs - existing tests must pass
389
+ if (EXISTING_TESTS_TYPES.includes(type)) {
390
+ return `## Refactor Testing
391
+
392
+ **Existing tests must pass** - Refactoring must not break current behavior.
393
+
394
+ ### Requirements
395
+
396
+ 1. Run all existing tests BEFORE refactoring
397
+ 2. Run all existing tests AFTER refactoring
398
+ 3. No new tests required unless behavior changes
399
+ 4. If tests fail after refactor, the refactor introduced a bug`;
400
+ }
401
+ // Policy-based selection for feature/bug/enhancement/tooling types
402
+ switch (policy.testing) {
403
+ case 'test-after':
404
+ return generateTestAfterDirective(policy.coverage_threshold);
405
+ case 'none':
406
+ return generateTestingOptionalDirective();
407
+ case 'tdd':
408
+ default:
409
+ return generateTDDDirective();
410
+ }
411
+ }
412
+ /**
413
+ * WU-1261, WU-1279: Generate test-after directive
414
+ *
415
+ * @param coverageThreshold - Coverage threshold from resolved policy
416
+ * @returns Test-after guidance section
417
+ */
418
+ function generateTestAfterDirective(coverageThreshold) {
419
+ return `## Test-After Methodology
420
+
421
+ **Write implementation first, then add tests** - Focus on solving the problem, then verify.
422
+
423
+ ### Test-After Workflow
424
+
425
+ 1. Understand the acceptance criteria
426
+ 2. Write implementation first
427
+ 3. Add tests to verify behavior
428
+ 4. Aim for ${coverageThreshold}% coverage on new code
429
+
430
+ ### When This Works
431
+
432
+ - Exploratory prototyping where requirements are unclear
433
+ - Quick iterations where test-first slows discovery
434
+ - Projects configured with \`methodology.testing: 'test-after'\`
435
+
436
+ ### Requirements
437
+
438
+ - Tests must be added before \`wu:done\`
439
+ - Coverage target: ${coverageThreshold}%+ on new application code
440
+ - All existing tests must still pass`;
441
+ }
442
+ /**
443
+ * WU-1261: Generate testing optional directive
444
+ *
445
+ * @returns Testing optional guidance section
446
+ */
447
+ function generateTestingOptionalDirective() {
448
+ return `## Testing Optional
449
+
450
+ **Tests are not required** - Project is configured without test requirements.
451
+
452
+ ### Focus
453
+
454
+ - Code quality and functionality
455
+ - Run \`pnpm gates\` before completion (will skip coverage checks)
456
+
457
+ ### If You Want to Add Tests
458
+
459
+ You can still add tests for critical functionality:
460
+ \`\`\`bash
461
+ pnpm test -- --coverage
462
+ \`\`\`
463
+
464
+ But they are not required for WU completion.`;
465
+ }
466
+ /**
467
+ * WU-1261: Generate architecture guidance based on resolved policy
468
+ *
469
+ * Selects appropriate architecture guidance based on policy.architecture:
470
+ * - 'hexagonal': Ports and adapters, dependency inversion
471
+ * - 'layered': Traditional layer separation
472
+ * - 'none': No architecture constraints
473
+ *
474
+ * @param policy - Resolved policy from resolvePolicy()
475
+ * @returns Architecture guidance section, or empty string for 'none'
476
+ */
477
+ export function generatePolicyBasedArchitectureGuidance(policy) {
478
+ switch (policy.architecture) {
479
+ case 'hexagonal':
480
+ return `## Hexagonal Architecture
481
+
482
+ **Ports and Adapters** - Keep domain logic pure, infrastructure at the edges.
483
+
484
+ ### Key Principles
485
+
486
+ - **Ports**: Interfaces defining what the domain needs (inbound) or uses (outbound)
487
+ - **Adapters**: Implementations connecting ports to infrastructure
488
+ - **Domain**: Pure business logic with no infrastructure imports
489
+ - **Dependency Rule**: Domain -> Ports <- Adapters (never domain -> adapters)
490
+
491
+ ### Directory Structure
492
+
493
+ \`\`\`
494
+ src/
495
+ domain/ # Pure business logic
496
+ ports/ # Interfaces
497
+ adapters/ # Infrastructure implementations
498
+ application/ # Use cases orchestrating domain + ports
499
+ \`\`\``;
500
+ case 'layered':
501
+ return `## Layered Architecture
502
+
503
+ **Traditional layer separation** - Clear boundaries between concerns.
504
+
505
+ ### Layers (Top to Bottom)
506
+
507
+ 1. **Presentation**: UI, API controllers, CLI
508
+ 2. **Application**: Use cases, orchestration
509
+ 3. **Domain**: Business logic, entities
510
+ 4. **Infrastructure**: Database, external services
511
+
512
+ ### Dependency Rule
513
+
514
+ - Each layer can only depend on layers below it
515
+ - Presentation -> Application -> Domain -> Infrastructure
516
+ - Never skip layers (Presentation should not directly use Infrastructure)`;
517
+ case 'none':
518
+ default:
519
+ return '';
520
+ }
521
+ }
522
+ /**
523
+ * WU-1261: Generate enforcement summary from resolved policy
524
+ *
525
+ * Creates a "You will be judged by" section that summarizes the active
526
+ * enforcement rules based on the resolved policy.
527
+ *
528
+ * @param policy - Resolved policy from resolvePolicy()
529
+ * @returns Enforcement summary section
530
+ */
531
+ export function generateEnforcementSummary(policy) {
532
+ const lines = ['## You will be judged by', ''];
533
+ // Testing methodology
534
+ const testingStatus = policy.tests_required ? 'required' : 'optional';
535
+ lines.push(`- **Testing**: ${policy.testing} (tests ${testingStatus})`);
536
+ // Coverage
537
+ if (policy.coverage_mode === 'off') {
538
+ lines.push('- **Coverage**: disabled');
539
+ }
540
+ else {
541
+ const modeLabel = policy.coverage_mode === 'block' ? 'blocking' : 'warn only';
542
+ lines.push(`- **Coverage**: ${policy.coverage_threshold}% (${modeLabel})`);
543
+ }
544
+ // Architecture
545
+ if (policy.architecture !== 'none') {
546
+ lines.push(`- **Architecture**: ${policy.architecture}`);
547
+ }
548
+ return lines.join('\n');
549
+ }
550
+ /**
551
+ * Generate worktree block recovery section (WU-1192)
552
+ *
553
+ * Provides guidance when agents encounter worktree hook blocks.
554
+ *
555
+ * @param {string} worktreePath - Path to the worktree
556
+ * @returns {string} Recovery section
557
+ */
558
+ export function generateWorktreeBlockRecoverySection(worktreePath) {
559
+ return `## When Blocked by Worktree Hook
560
+
561
+ If you encounter a "worktree required" or "commit blocked" error:
562
+
563
+ 1. **Check existing worktrees**: \`git worktree list\`
564
+ 2. **Navigate to the worktree**: \`cd ${worktreePath || 'worktrees/<lane>-wu-xxx'}\`
565
+ 3. **Retry your operation** from within the worktree
566
+ 4. **Use relative paths only** (never absolute paths)
567
+
568
+ ### Common Causes
569
+
570
+ - Running \`git commit\` from main checkout instead of worktree
571
+ - Using absolute paths that bypass worktree isolation
572
+ - Forgetting to \`cd\` to worktree after \`wu:claim\`
573
+
574
+ ### Quick Fix
575
+
576
+ \`\`\`bash
577
+ # Check where you are
578
+ pwd
579
+ git worktree list
580
+
581
+ # Navigate to your worktree
582
+ cd ${worktreePath || 'worktrees/<lane>-wu-xxx'}
583
+
584
+ # Retry your commit
585
+ git add . && git commit -m "your message"
586
+ \`\`\``;
587
+ }
58
588
  /**
59
589
  * Detect mandatory agents based on code paths.
60
590
  *
@@ -209,14 +739,16 @@ function formatInvariantForOutput(inv) {
209
739
  lines.push(`**Path:** \`${inv.path}\``);
210
740
  }
211
741
  if (inv.paths) {
212
- lines.push(`**Paths:** ${inv.paths.map((p) => `\`${p}\``).join(', ')}`);
742
+ const formattedPaths = inv.paths.map((p) => `\`${p}\``).join(', ');
743
+ lines.push(`**Paths:** ${formattedPaths}`);
213
744
  }
214
745
  // WU-2254: forbidden-import specific fields
215
746
  if (inv.from) {
216
747
  lines.push(`**From:** \`${inv.from}\``);
217
748
  }
218
749
  if (inv.cannot_import && Array.isArray(inv.cannot_import)) {
219
- lines.push(`**Cannot Import:** ${inv.cannot_import.map((m) => `\`${m}\``).join(', ')}`);
750
+ const formattedImports = inv.cannot_import.map((m) => `\`${m}\``).join(', ');
751
+ lines.push(`**Cannot Import:** ${formattedImports}`);
220
752
  }
221
753
  // WU-2254: required-pattern specific fields
222
754
  if (inv.pattern &&
@@ -225,7 +757,8 @@ function formatInvariantForOutput(inv) {
225
757
  lines.push(`**Pattern:** \`${inv.pattern}\``);
226
758
  }
227
759
  if (inv.scope && Array.isArray(inv.scope)) {
228
- lines.push(`**Scope:** ${inv.scope.map((s) => `\`${s}\``).join(', ')}`);
760
+ const formattedScope = inv.scope.map((s) => `\`${s}\``).join(', ');
761
+ lines.push(`**Scope:** ${formattedScope}`);
229
762
  }
230
763
  lines.push('');
231
764
  return lines;
@@ -274,34 +807,6 @@ function generateInvariantsPriorArtSection(codePaths) {
274
807
  ];
275
808
  return lines.join('\n');
276
809
  }
277
- /**
278
- * Generate the TDD directive section (WU-1585)
279
- *
280
- * Positioned immediately after </task> preamble per "Lost in the Middle" research.
281
- * Critical instructions at START and END of prompt improve adherence.
282
- *
283
- * @returns {string} TDD directive section
284
- */
285
- function generateTDDDirective() {
286
- return `## ⛔ TDD DIRECTIVE — READ BEFORE CODING
287
-
288
- **IF YOU WRITE IMPLEMENTATION CODE BEFORE A FAILING TEST, YOU HAVE FAILED THIS WU.**
289
-
290
- ### Test-First Workflow (MANDATORY)
291
-
292
- 1. Write a failing test for the acceptance criteria
293
- 2. Run the test to confirm it fails (RED)
294
- 3. Implement the minimum code to pass the test
295
- 4. Run the test to confirm it passes (GREEN)
296
- 5. Refactor if needed, keeping tests green
297
-
298
- ### Why This Matters
299
-
300
- - Tests document expected behavior BEFORE implementation
301
- - Prevents scope creep and over-engineering
302
- - Ensures every feature has verification
303
- - Failing tests prove the test actually tests something`;
304
- }
305
810
  /**
306
811
  * Generate the context loading preamble
307
812
  *
@@ -358,7 +863,7 @@ CRITICAL RULES - ENFORCE BEFORE EVERY ACTION:
358
863
  - For ordinary errors: fix and retry autonomously (up to 3 attempts)
359
864
 
360
865
  4. VERIFY COMPLETION before reporting success
361
- - Run: node tools/lib/agent-verification.mjs ${id} (from shared checkout)
866
+ - Run: node packages/@lumenflow/agent/dist/agent-verification.js ${id} (from shared checkout)
362
867
  - Exit 0 = passed, Exit 1 = INCOMPLETE
363
868
  - Never report "done" if verification fails
364
869
 
@@ -372,32 +877,49 @@ CRITICAL RULES - ENFORCE BEFORE EVERY ACTION:
372
877
  - ALWAYS use \`git rebase origin/main\` before push
373
878
  - Push to main via \`git push origin lane/...:main\` (fast-forward only)
374
879
  - NEVER use \`git merge\` on main branch
375
- - Let \`pnpm wu:done\` handle the merge workflow
880
+ - Use \`pnpm wu:prep\` from worktree, then \`pnpm wu:done\` from main (WU-1223)
376
881
 
377
882
  7. MEMORY LAYER COORDINATION (INIT-007)
378
883
  - Use \`pnpm mem:checkpoint --wu ${id}\` to save progress before risky operations
379
884
  - Check \`pnpm mem:inbox --wu ${id}\` periodically for parallel signals from other agents
380
885
  - Checkpoint triggers (WU-1943): checkpoint after each acceptance criterion completed, checkpoint before gates, checkpoint every 30 tool calls
381
- </constraints>`;
886
+
887
+ 8. SKIP-GATES AUTONOMY (WU-1142)
888
+ - If gates fail, first check if failure is pre-existing on main: \`git checkout main && pnpm gates\`
889
+ - If failure exists on main (not your change), use: \`pnpm wu:done --id ${id} --skip-gates --reason "pre-existing on main" --fix-wu WU-XXXX\`
890
+ - Do NOT ask for approval - autonomous skip-gates for pre-existing failures is correct
891
+ - This prevents getting stuck on infrastructure debt
892
+
893
+ 9. WORKTREE DISCIPLINE (WU-1282)
894
+ - CRITICAL: PreToolUse hooks do not propagate to sub-agents spawned via Task tool
895
+ - BEFORE any Write/Edit operation, manually verify you are in a worktree:
896
+ - Run: \`pwd\` and confirm output contains \`worktrees/\`
897
+ - If not in worktree, STOP and navigate: \`cd worktrees/<lane>-wu-xxx\`
898
+ - Use RELATIVE paths only (never full absolute paths starting with root directory)
899
+ - This constraint exists because Claude Code does not inherit settings.json hooks in sub-agent sessions
900
+ </constraints>
901
+
902
+ ${SPAWN_END_SENTINEL}`;
382
903
  }
383
904
  function generateCodexConstraints(id) {
384
905
  return `## Constraints (Critical)
385
906
 
386
907
  1. **TDD checkpoint**: tests BEFORE implementation; never skip RED
387
908
  2. **Stop on errors**: if any command fails, report BLOCKED (never DONE) with the error
388
- 3. **Verify before success**: run \`pnpm gates\` in the worktree, then run \`node tools/lib/agent-verification.mjs ${id}\` (from the shared checkout)
909
+ 3. **Verify before success**: run \`pnpm gates\` in the worktree, then run \`node packages/@lumenflow/agent/dist/agent-verification.js ${id}\` (from the shared checkout)
389
910
  4. **No fabrication**: if blockers remain or verification fails, report INCOMPLETE
390
- 5. **Git workflow**: avoid merge commits; let \`pnpm wu:done\` handle completion
391
- 6. **Scope discipline**: stay within \`code_paths\`; capture out-of-scope issues via \`pnpm mem:create\``;
911
+ 5. **Git workflow**: avoid merge commits; use \`wu:prep\` from worktree, then \`wu:done\` from main
912
+ 6. **Scope discipline**: stay within \`code_paths\`; capture out-of-scope issues via \`pnpm mem:create\`
913
+ 7. **Worktree discipline (WU-1282)**: BEFORE any Write/Edit, verify \`pwd\` shows \`worktrees/\`; hooks do not propagate to sub-agents`;
392
914
  }
393
915
  /**
394
916
  * Generate mandatory agent advisory section
395
917
  *
396
918
  * @param {string[]} mandatoryAgents - Array of mandatory agent names
397
- * @param {string} id - WU ID
919
+ * @param {string} _id - WU ID (reserved for future use)
398
920
  * @returns {string} Mandatory agent section or empty string
399
921
  */
400
- function generateMandatoryAgentSection(mandatoryAgents, id) {
922
+ function generateMandatoryAgentSection(mandatoryAgents, _id) {
401
923
  if (mandatoryAgents.length === 0) {
402
924
  return '';
403
925
  }
@@ -409,7 +931,7 @@ Based on code_paths, the following agents MUST be invoked:
409
931
 
410
932
  ${agentList}
411
933
 
412
- Run: pnpm orchestrate:suggest --wu ${id}
934
+ Run: pnpm orchestrate:monitor to check agent status
413
935
  `;
414
936
  }
415
937
  /**
@@ -527,15 +1049,74 @@ When finishing, provide structured output:
527
1049
  This format enables orchestrator to track progress across waves.`;
528
1050
  }
529
1051
  /**
530
- * Generate agent coordination section (WU-1987)
1052
+ * Generate agent coordination section (WU-1987, WU-1203)
531
1053
  *
532
1054
  * Provides guidance on mem:signal for parallel agent coordination,
533
- * orchestrate:status for dashboard checks, and abandoned WU handling.
1055
+ * orchestrate:monitor for agent status checks, and abandoned WU handling.
1056
+ *
1057
+ * WU-1203: Reads progress_signals config to generate dynamic guidance.
1058
+ * When enabled:true, shows "Progress Signals (Required at Milestones)" with
1059
+ * configurable triggers. When enabled:false or not configured, shows
1060
+ * "Progress Signals (Optional)".
534
1061
  *
535
1062
  * @param {string} id - WU ID
536
1063
  * @returns {string} Agent coordination section
537
1064
  */
538
1065
  export function generateAgentCoordinationSection(id) {
1066
+ const config = getConfig();
1067
+ const progressSignals = config.memory?.progress_signals;
1068
+ // WU-1210: Default to enabled (Required at Milestones) when not explicitly configured
1069
+ // This ensures agents signal progress at key milestones by default
1070
+ const isEnabled = progressSignals?.enabled ?? true;
1071
+ // Generate milestone triggers section based on config
1072
+ const generateMilestoneTriggers = () => {
1073
+ if (!isEnabled) {
1074
+ // Disabled - show optional guidance only
1075
+ return `For long-running work, send progress signals at milestones:
1076
+
1077
+ \`\`\`bash
1078
+ pnpm mem:signal "50% complete: tests passing, implementing adapter" --wu ${id}
1079
+ pnpm mem:signal "Blocked: waiting for WU-XXX dependency" --wu ${id}
1080
+ \`\`\``;
1081
+ }
1082
+ // WU-1210: isEnabled is true (either by default or explicit config)
1083
+ // Build list of enabled triggers, using defaults when progressSignals is undefined
1084
+ const triggers = [];
1085
+ // Default all triggers to enabled when not explicitly configured
1086
+ if ((progressSignals?.on_milestone ?? true) !== false) {
1087
+ triggers.push('**After each acceptance criterion completed** - helps track progress');
1088
+ }
1089
+ if ((progressSignals?.on_tests_pass ?? true) !== false) {
1090
+ triggers.push('**When tests first pass** - indicates implementation is working');
1091
+ }
1092
+ if ((progressSignals?.before_gates ?? true) !== false) {
1093
+ triggers.push('**Before running gates** - signals imminent completion');
1094
+ }
1095
+ if ((progressSignals?.on_blocked ?? true) !== false) {
1096
+ triggers.push('**When blocked** - allows orchestrator to re-allocate or assist');
1097
+ }
1098
+ // Add frequency-based trigger if configured
1099
+ const frequency = progressSignals?.frequency ?? 0;
1100
+ let frequencyGuidance = '';
1101
+ if (frequency > 0) {
1102
+ frequencyGuidance = `\n5. **Every ${frequency} tool calls** - periodic progress update`;
1103
+ }
1104
+ const triggerList = triggers.length > 0
1105
+ ? triggers.map((t, i) => `${i + 1}. ${t}`).join('\n') + frequencyGuidance
1106
+ : 'Signal at key milestones to enable orchestrator visibility.';
1107
+ return `**Signal at these milestones** to enable orchestrator visibility:
1108
+
1109
+ ${triggerList}
1110
+
1111
+ \`\`\`bash
1112
+ pnpm mem:signal "AC1 complete: tests passing for feature X" --wu ${id}
1113
+ pnpm mem:signal "All tests passing, running gates" --wu ${id}
1114
+ pnpm mem:signal "Blocked: waiting for WU-XXX dependency" --wu ${id}
1115
+ \`\`\``;
1116
+ };
1117
+ const progressSectionTitle = isEnabled
1118
+ ? '### Progress Signals (Required at Milestones)'
1119
+ : '### Progress Signals (Optional)';
539
1120
  return `## Agent Coordination (Parallel Work)
540
1121
 
541
1122
  ### ⚠️ CRITICAL: Use mem:signal, NOT TaskOutput
@@ -557,14 +1138,9 @@ pnpm mem:inbox --since 30m
557
1138
  manually signal completion - just run \`wu:done\` and orchestrators will
558
1139
  see your signal via \`mem:inbox\`.
559
1140
 
560
- ### Progress Signals (Optional)
1141
+ ${progressSectionTitle}
561
1142
 
562
- For long-running work, send progress signals at milestones:
563
-
564
- \`\`\`bash
565
- pnpm mem:signal "50% complete: tests passing, implementing adapter" --wu ${id}
566
- pnpm mem:signal "Blocked: waiting for WU-XXX dependency" --wu ${id}
567
- \`\`\`
1143
+ ${generateMilestoneTriggers()}
568
1144
 
569
1145
  ### Checking Status
570
1146
 
@@ -594,6 +1170,31 @@ pnpm typecheck # Check TypeScript types
594
1170
 
595
1171
  **Use before gates** to catch simple issues early. These are faster than full \`pnpm gates\`.`;
596
1172
  }
1173
+ /**
1174
+ * WU-1270: Emit methodology telemetry event (opt-in)
1175
+ *
1176
+ * Emits privacy-preserving telemetry about methodology selection.
1177
+ * Only emits if telemetry.methodology.enabled is true in config.
1178
+ *
1179
+ * @param config - LumenFlow configuration
1180
+ * @param policy - Resolved methodology policy
1181
+ */
1182
+ export function emitMethodologyTelemetry(config, policy) {
1183
+ // Check if methodology telemetry is opt-in enabled
1184
+ if (!config.telemetry?.methodology?.enabled) {
1185
+ return;
1186
+ }
1187
+ const event = {
1188
+ timestamp: new Date().toISOString(),
1189
+ event_type: 'methodology.selection',
1190
+ methodology_testing: policy.testing,
1191
+ methodology_architecture: policy.architecture,
1192
+ event_context: 'spawn',
1193
+ };
1194
+ // Use the telemetry emit function from telemetry.ts
1195
+ const METHODOLOGY_LOG = '.lumenflow/telemetry/methodology.ndjson';
1196
+ emitTelemetry(METHODOLOGY_LOG, event);
1197
+ }
597
1198
  /**
598
1199
  * Generate Lane Selection section (WU-2107)
599
1200
  *
@@ -724,7 +1325,7 @@ pnpm mem:triage --wu ${id} # List discoveries for this WU
724
1325
  pnpm mem:triage --promote <node-id> --lane "<lane>" # Create Bug WU (human action)
725
1326
  \`\`\`
726
1327
 
727
- See: docs/04-operations/_frameworks/lumenflow/agent/onboarding/agent-invocation-guide.md §Bug Discovery`;
1328
+ See: https://lumenflow.dev/reference/agent-invocation-guide/ §Bug Discovery`;
728
1329
  }
729
1330
  /**
730
1331
  * Generate lane-specific guidance
@@ -817,9 +1418,15 @@ export function generateTaskInvocation(doc, id, strategy, options = {}) {
817
1418
  const codePaths = doc.code_paths || [];
818
1419
  const mandatoryAgents = detectMandatoryAgents(codePaths);
819
1420
  const preamble = generatePreamble(id, strategy);
820
- const tddDirective = generateTDDDirective();
821
1421
  const clientContext = options.client;
822
1422
  const config = options.config || getConfig();
1423
+ // WU-1279: Resolve policy and use policy-based test guidance
1424
+ const policy = resolvePolicy(config);
1425
+ const testGuidance = generatePolicyBasedTestGuidance(doc.type || 'feature', policy);
1426
+ // WU-1279: Generate enforcement summary from resolved policy
1427
+ const enforcementSummary = generateEnforcementSummary(policy);
1428
+ // WU-1279: Generate mandatory standards based on resolved policy
1429
+ const mandatoryStandards = generateMandatoryStandards(policy);
823
1430
  const clientSkillsGuidance = generateClientSkillsGuidance(clientContext);
824
1431
  const skillsSection = generateSkillsSelectionSection(doc, config, clientContext?.name) +
825
1432
  (clientSkillsGuidance ? `\n${clientSkillsGuidance}` : '');
@@ -844,6 +1451,10 @@ export function generateTaskInvocation(doc, id, strategy, options = {}) {
844
1451
  const laneSelection = generateLaneSelectionSection();
845
1452
  // WU-2362: Worktree path guidance for sub-agents
846
1453
  const worktreeGuidance = generateWorktreePathGuidance(doc.worktree_path);
1454
+ // WU-1240: Memory context section
1455
+ // Include if explicitly enabled and not disabled via noContext
1456
+ const shouldIncludeMemoryContext = options.includeMemoryContext && !options.noContext;
1457
+ const memoryContextSection = shouldIncludeMemoryContext ? options.memoryContextContent || '' : '';
847
1458
  // Generate thinking mode sections if applicable
848
1459
  const executionModeSection = generateExecutionModeSection(options);
849
1460
  const thinkToolGuidance = generateThinkToolGuidance(options);
@@ -853,14 +1464,14 @@ export function generateTaskInvocation(doc, id, strategy, options = {}) {
853
1464
  .join('\n\n---\n\n');
854
1465
  const thinkingBlock = thinkingSections ? `${thinkingSections}\n\n---\n\n` : '';
855
1466
  // Build the task prompt
856
- // TDD directive appears immediately after </task> per "Lost in the Middle" research (WU-1585)
857
- const taskPrompt = `<task>
1467
+ // WU-1192: Truncation warning at start, test guidance after </task> per "Lost in the Middle" research
1468
+ const taskPrompt = `${TRUNCATION_WARNING_BANNER}<task>
858
1469
  ${preamble}
859
1470
  </task>
860
1471
 
861
1472
  ---
862
1473
 
863
- ${tddDirective}
1474
+ ${testGuidance}
864
1475
 
865
1476
  ---
866
1477
 
@@ -888,19 +1499,13 @@ ${codePaths.length > 0 ? codePaths.map((p) => `- ${p}`).join('\n') : '- No code
888
1499
  ${mandatorySection}${invariantsPriorArt ? `---\n\n${invariantsPriorArt}\n\n` : ''}${implementationContext ? `---\n\n${implementationContext}\n\n` : ''}---
889
1500
 
890
1501
  ${thinkingBlock}${skillsSection}
891
- ---
1502
+ ${memoryContextSection ? `---\n\n${memoryContextSection}\n\n` : ''}---
892
1503
 
893
- ## Mandatory Standards
1504
+ ${mandatoryStandards}
894
1505
 
895
- - **LumenFlow**: Follow trunk-based flow, WIP=1, worktree discipline
896
- - **TDD**: Failing test first, then implementation, then passing test. 90%+ coverage on new application code
897
- - **Hexagonal Architecture**: Ports-first design. No application -> infrastructure imports
898
- - **SOLID/DRY/YAGNI/KISS**: No over-engineering, no premature abstraction
899
- - **Library-First**: Search context7 before writing custom code. No reinventing wheels
900
- - **Code Quality**: No string literals, no magic numbers, no brittle regexes when libraries exist
901
- - **Worktree Discipline**: ALWAYS use \`pnpm wu:claim\` to create worktrees (never \`git worktree add\` directly). Work ONLY in the worktree, never edit main
902
- - **Documentation**: Update tooling docs if changing tools. Keep docs in sync with code
903
- - **Sub-agents**: Use Explore agent for codebase investigation. Activate mandatory agents (security-auditor for PHI/auth, beacon-guardian for LLM/prompts)
1506
+ ---
1507
+
1508
+ ${enforcementSummary}
904
1509
 
905
1510
  ${clientBlocks ? `---\n\n${clientBlocks}\n\n` : ''}${worktreeGuidance ? `---\n\n${worktreeGuidance}\n\n` : ''}---
906
1511
 
@@ -971,7 +1576,6 @@ export function generateCodexPrompt(doc, id, strategy, options = {}) {
971
1576
  const codePaths = doc.code_paths || [];
972
1577
  const mandatoryAgents = detectMandatoryAgents(codePaths);
973
1578
  const preamble = generatePreamble(id, strategy);
974
- const tddDirective = generateTDDDirective();
975
1579
  const mandatorySection = generateMandatoryAgentSection(mandatoryAgents, id);
976
1580
  const laneGuidance = generateLaneGuidance(doc.lane);
977
1581
  const bugDiscoverySection = generateBugDiscoverySection(id);
@@ -984,6 +1588,13 @@ export function generateCodexPrompt(doc, id, strategy, options = {}) {
984
1588
  const skillsSection = generateSkillsSelectionSection(doc, config, clientContext?.name) +
985
1589
  (clientSkillsGuidance ? `\n${clientSkillsGuidance}` : '');
986
1590
  const clientBlocks = generateClientBlocksSection(clientContext);
1591
+ // WU-1290: Resolve policy and use policy-based test guidance (same as generateTaskInvocation)
1592
+ const policy = resolvePolicy(config);
1593
+ const testGuidance = generatePolicyBasedTestGuidance(doc.type || 'feature', policy);
1594
+ // WU-1290: Generate enforcement summary from resolved policy
1595
+ const enforcementSummary = generateEnforcementSummary(policy);
1596
+ // WU-1290: Generate mandatory standards based on resolved policy
1597
+ const mandatoryStandards = generateMandatoryStandards(policy);
987
1598
  const executionModeSection = generateExecutionModeSection(options);
988
1599
  const thinkToolGuidance = generateThinkToolGuidance(options);
989
1600
  const thinkingSections = [executionModeSection, thinkToolGuidance]
@@ -992,7 +1603,7 @@ export function generateCodexPrompt(doc, id, strategy, options = {}) {
992
1603
  const thinkingBlock = thinkingSections ? `${thinkingSections}\n\n---\n\n` : '';
993
1604
  return `# ${id}: ${doc.title || 'Untitled'}
994
1605
 
995
- ${tddDirective}
1606
+ ${testGuidance}
996
1607
 
997
1608
  ---
998
1609
 
@@ -1026,6 +1637,14 @@ ${formatAcceptance(doc.acceptance)}
1026
1637
 
1027
1638
  ---
1028
1639
 
1640
+ ${mandatoryStandards}
1641
+
1642
+ ---
1643
+
1644
+ ${enforcementSummary}
1645
+
1646
+ ---
1647
+
1029
1648
  ${skillsSection}
1030
1649
 
1031
1650
  ---
@@ -1039,7 +1658,7 @@ ${action}
1039
1658
  ## Verification
1040
1659
 
1041
1660
  - Run in worktree: \`pnpm gates\`
1042
- - From shared checkout: \`node tools/lib/agent-verification.mjs ${id}\`
1661
+ - From shared checkout: \`node packages/@lumenflow/agent/dist/agent-verification.js ${id}\`
1043
1662
 
1044
1663
  ---
1045
1664
 
@@ -1222,6 +1841,9 @@ async function main() {
1222
1841
  console.log(`${LOG_PREFIX} Generated Task tool invocation for ${id}`);
1223
1842
  console.log(`${LOG_PREFIX} Copy the block below to spawn a sub-agent:\n`);
1224
1843
  console.log(invocation);
1844
+ // WU-1270: Emit methodology telemetry (opt-in only)
1845
+ const policy = resolvePolicy(config);
1846
+ emitMethodologyTelemetry(config, policy);
1225
1847
  // WU-1945: Record spawn event to registry (non-blocking)
1226
1848
  // Only record if --parent-wu is provided (orchestrator context)
1227
1849
  if (args.parentWu) {