@exaudeus/workrail 3.66.0 → 3.68.0

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 (150) hide show
  1. package/dist/application/services/compiler/template-registry.js +10 -1
  2. package/dist/application/validation.js +1 -1
  3. package/dist/cli/commands/worktrain-init.js +1 -1
  4. package/dist/console/standalone-console.js +4 -1
  5. package/dist/console-ui/assets/{index-BynU38Vu.js → index-CyzltI6D.js} +1 -1
  6. package/dist/console-ui/index.html +1 -1
  7. package/dist/coordinators/modes/full-pipeline.js +4 -4
  8. package/dist/coordinators/modes/implement-shared.js +5 -5
  9. package/dist/coordinators/modes/implement.js +4 -4
  10. package/dist/coordinators/pr-review.js +4 -4
  11. package/dist/daemon/workflow-runner.d.ts +1 -0
  12. package/dist/daemon/workflow-runner.js +1 -0
  13. package/dist/infrastructure/storage/schema-validating-workflow-storage.d.ts +21 -2
  14. package/dist/infrastructure/storage/schema-validating-workflow-storage.js +48 -0
  15. package/dist/manifest.json +41 -41
  16. package/dist/mcp/handlers/v2-workflow.js +24 -7
  17. package/dist/mcp/output-schemas.d.ts +36 -0
  18. package/dist/mcp/output-schemas.js +11 -1
  19. package/dist/mcp/workflow-protocol-contracts.js +2 -2
  20. package/dist/v2/projections/session-metrics.d.ts +1 -1
  21. package/dist/v2/projections/session-metrics.js +16 -35
  22. package/dist/v2/usecases/console-routes.d.ts +2 -2
  23. package/docs/authoring-v2.md +4 -4
  24. package/docs/changelog-recent.md +3 -3
  25. package/docs/configuration.md +1 -1
  26. package/docs/design/adaptive-coordinator-context-candidates.md +1 -1
  27. package/docs/design/adaptive-coordinator-context.md +1 -1
  28. package/docs/design/adaptive-coordinator-routing-candidates.md +18 -18
  29. package/docs/design/adaptive-coordinator-routing-review.md +1 -1
  30. package/docs/design/adaptive-coordinator-routing.md +34 -34
  31. package/docs/design/agent-cascade-protocol.md +2 -2
  32. package/docs/design/console-daemon-separation-discovery.md +323 -0
  33. package/docs/design/context-assembly-design-candidates.md +1 -1
  34. package/docs/design/context-assembly-implementation-plan.md +1 -1
  35. package/docs/design/context-assembly-layer.md +2 -2
  36. package/docs/design/context-assembly-review-findings.md +1 -1
  37. package/docs/design/coordinator-access-audit.md +293 -0
  38. package/docs/design/coordinator-architecture-audit.md +62 -0
  39. package/docs/design/coordinator-error-handling-audit.md +240 -0
  40. package/docs/design/coordinator-testability-audit.md +426 -0
  41. package/docs/design/daemon-architecture-discovery.md +1 -1
  42. package/docs/design/daemon-console-separation-discovery.md +242 -0
  43. package/docs/design/daemon-memory-audit.md +203 -0
  44. package/docs/design/design-candidates-console-daemon-separation.md +256 -0
  45. package/docs/design/design-candidates-discovery-loop-fix.md +141 -0
  46. package/docs/design/design-review-findings-console-daemon-separation.md +106 -0
  47. package/docs/design/design-review-findings-discovery-loop-fix.md +81 -0
  48. package/docs/design/discovery-loop-fix-candidates.md +161 -0
  49. package/docs/design/discovery-loop-fix-design-review.md +106 -0
  50. package/docs/design/discovery-loop-fix-validation.md +258 -0
  51. package/docs/design/discovery-loop-investigation-A.md +188 -0
  52. package/docs/design/discovery-loop-investigation-B.md +287 -0
  53. package/docs/design/exploration-workflow-candidates.md +205 -0
  54. package/docs/design/exploration-workflow-design-review.md +166 -0
  55. package/docs/design/exploration-workflow-discovery.md +443 -0
  56. package/docs/design/ide-context-files-candidates.md +231 -0
  57. package/docs/design/ide-context-files-design-review.md +85 -0
  58. package/docs/design/ide-context-files.md +615 -0
  59. package/docs/design/implementation-plan-discovery-loop-fix.md +199 -0
  60. package/docs/design/implementation-plan-queue-poll-rotation.md +102 -0
  61. package/docs/design/in-process-http-audit.md +190 -0
  62. package/docs/design/layer3b-ghost-nodes-design-candidates.md +2 -2
  63. package/docs/design/loadSessionNotes-candidates.md +108 -0
  64. package/docs/design/loadSessionNotes-test-coverage-discovery.md +297 -0
  65. package/docs/design/loadSessionNotes-test-coverage-session4.md +209 -0
  66. package/docs/design/loadSessionNotes-test-coverage-v3.md +321 -0
  67. package/docs/design/probe-session-design-candidates.md +261 -0
  68. package/docs/design/probe-session-phase0.md +490 -0
  69. package/docs/design/routines-guide.md +7 -7
  70. package/docs/design/session-metrics-attribution-candidates.md +250 -0
  71. package/docs/design/session-metrics-attribution-design-review.md +115 -0
  72. package/docs/design/session-metrics-attribution-discovery.md +319 -0
  73. package/docs/design/session-metrics-candidates.md +227 -0
  74. package/docs/design/session-metrics-design-review.md +104 -0
  75. package/docs/design/session-metrics-discovery.md +454 -0
  76. package/docs/design/spawn-session-debug.md +202 -0
  77. package/docs/design/trigger-validator-candidates.md +214 -0
  78. package/docs/design/trigger-validator-review.md +109 -0
  79. package/docs/design/trigger-validator-shaping-phase0.md +239 -0
  80. package/docs/design/trigger-validator.md +454 -0
  81. package/docs/design/v2-core-design-locks.md +2 -2
  82. package/docs/design/workflow-extension-points.md +15 -15
  83. package/docs/design/workflow-id-validation-at-startup.md +1 -1
  84. package/docs/design/workflow-id-validation-implementation-plan.md +2 -2
  85. package/docs/design/workflow-trigger-lifecycle-audit.md +175 -0
  86. package/docs/design/worktrain-task-queue-candidates.md +5 -5
  87. package/docs/design/worktrain-task-queue.md +4 -4
  88. package/docs/discovery/coordinator-script-design.md +1 -1
  89. package/docs/discovery/coordinator-ux-discovery.md +3 -3
  90. package/docs/discovery/simulation-report.md +1 -1
  91. package/docs/discovery/workflow-modernization-discovery.md +326 -0
  92. package/docs/discovery/workflow-selection-for-discovery-tasks.md +33 -33
  93. package/docs/discovery/worktrain-status-briefing.md +1 -1
  94. package/docs/discovery/wr-discovery-goal-reframing.md +1 -1
  95. package/docs/docker.md +1 -1
  96. package/docs/ideas/backlog.md +227 -0
  97. package/docs/ideas/third-party-workflow-setup-design-thinking.md +1 -1
  98. package/docs/integrations/claude-code.md +5 -5
  99. package/docs/integrations/firebender.md +1 -1
  100. package/docs/plans/agentic-orchestration-roadmap.md +2 -2
  101. package/docs/plans/mr-review-workflow-redesign.md +9 -9
  102. package/docs/plans/ui-ux-workflow-design-candidates.md +4 -4
  103. package/docs/plans/ui-ux-workflow-discovery.md +2 -2
  104. package/docs/plans/workflow-categories-candidates.md +8 -8
  105. package/docs/plans/workflow-categories-discovery.md +4 -4
  106. package/docs/plans/workflow-modernization-design.md +430 -0
  107. package/docs/plans/workflow-staleness-detection-candidates.md +11 -11
  108. package/docs/plans/workflow-staleness-detection-review.md +4 -4
  109. package/docs/plans/workflow-staleness-detection.md +9 -9
  110. package/docs/plans/workrail-platform-vision.md +3 -3
  111. package/docs/reference/agent-context-cleaner-snippet.md +1 -1
  112. package/docs/reference/agent-context-guidance.md +4 -4
  113. package/docs/reference/context-optimization.md +2 -2
  114. package/docs/roadmap/now-next-later.md +2 -2
  115. package/docs/roadmap/open-work-inventory.md +16 -16
  116. package/docs/workflows.md +31 -31
  117. package/package.json +1 -1
  118. package/spec/workflow-tags.json +47 -47
  119. package/workflows/adaptive-ticket-creation.json +16 -16
  120. package/workflows/architecture-scalability-audit.json +22 -22
  121. package/workflows/bug-investigation.agentic.v2.json +3 -3
  122. package/workflows/classify-task-workflow.json +1 -1
  123. package/workflows/coding-task-workflow-agentic.json +6 -6
  124. package/workflows/cross-platform-code-conversion.v2.json +8 -8
  125. package/workflows/document-creation-workflow.json +8 -8
  126. package/workflows/documentation-update-workflow.json +8 -8
  127. package/workflows/intelligent-test-case-generation.json +2 -2
  128. package/workflows/learner-centered-course-workflow.json +2 -2
  129. package/workflows/mr-review-workflow.agentic.v2.json +4 -4
  130. package/workflows/personal-learning-materials-creation-branched.json +8 -8
  131. package/workflows/presentation-creation.json +5 -5
  132. package/workflows/production-readiness-audit.json +1 -1
  133. package/workflows/relocation-workflow-us.json +31 -31
  134. package/workflows/routines/context-gathering.json +1 -1
  135. package/workflows/routines/design-review.json +1 -1
  136. package/workflows/routines/execution-simulation.json +1 -1
  137. package/workflows/routines/feature-implementation.json +3 -3
  138. package/workflows/routines/final-verification.json +1 -1
  139. package/workflows/routines/hypothesis-challenge.json +1 -1
  140. package/workflows/routines/ideation.json +1 -1
  141. package/workflows/routines/parallel-work-partitioning.json +3 -3
  142. package/workflows/routines/philosophy-alignment.json +2 -2
  143. package/workflows/routines/plan-analysis.json +1 -1
  144. package/workflows/routines/plan-generation.json +1 -1
  145. package/workflows/routines/tension-driven-design.json +6 -6
  146. package/workflows/scoped-documentation-workflow.json +26 -26
  147. package/workflows/ui-ux-design-workflow.json +14 -14
  148. package/workflows/workflow-diagnose-environment.json +1 -1
  149. package/workflows/workflow-for-workflows.json +32 -77
  150. package/workflows/workflow-for-workflows.v2.json +0 -788
@@ -0,0 +1,231 @@
1
+ # IDE Context Files -- Design Candidates
2
+
3
+ **Status:** Raw investigative material for main agent review. Not a final decision.
4
+ **Parent doc:** `docs/design/ide-context-files.md`
5
+
6
+ ---
7
+
8
+ ## Problem Understanding
9
+
10
+ ### Core Tensions
11
+
12
+ 1. **Literal paths vs. glob patterns.** The current `WORKSPACE_CONTEXT_CANDIDATE_PATHS` is a `readonly string[]`. The most valuable new conventions (`.cursor/rules/*.mdc`, `.windsurf/rules/*.md`, `.firebender/rules/*.mdc`) use directory-based glob patterns, not single files. Supporting them requires either a type change or a parallel mechanism.
13
+
14
+ 2. **Frontmatter stripping vs. verbatim injection.** `.mdc` files (Cursor, Firebender) and `.windsurf/rules/*.md` files have YAML frontmatter (`alwaysApply: true`, `description: "..."`, etc.). Injecting raw content would pollute the system prompt with metadata the model is not expecting. Stripping must be correct (safe no-op when no frontmatter present) and not lossy.
15
+
16
+ 3. **Type expressivity vs. simplicity.** A richer type (`{ kind: 'literal' | 'glob'; ... }`) expresses the behavioral contract but makes the array harder to read at a glance compared to plain strings.
17
+
18
+ 4. **Scope creep vs. incompleteness.** Phase A alone (literal paths only) ships fast but skips the actively-used glob paths in this environment. Phase A+B ships everything needed but is a larger PR.
19
+
20
+ ### What Makes This Hard
21
+
22
+ - The `---` YAML frontmatter delimiter is also a valid markdown horizontal rule. Stripping logic must only trigger if `---` appears at the very start of the file.
23
+ - Glob expansion order must be deterministic. Multiple `.mdc` files in `.cursor/rules/` without a defined order would produce non-deterministic context injection.
24
+ - The `as const` annotation on the current array makes it a `readonly string[]` -- adding objects requires removing `as const` and replacing with an explicit `readonly WorkspaceContextCandidate[]` type.
25
+ - The existing `loadWorkspaceContext()` loop at line 960 iterates `for (const relativePath of WORKSPACE_CONTEXT_CANDIDATE_PATHS)` -- this must be refactored to handle both literal and glob entries.
26
+
27
+ ### Likely Seam
28
+
29
+ `WORKSPACE_CONTEXT_CANDIDATE_PATHS` constant (line 180) + `loadWorkspaceContext()` function (line 955) in `src/daemon/workflow-runner.ts`. This is the correct and only seam -- no MCP code touches this.
30
+
31
+ ---
32
+
33
+ ## Philosophy Constraints
34
+
35
+ Principles from `AGENTS.md` that are directly relevant:
36
+
37
+ - **Explicit domain types over primitives** -- `string[]` is too primitive. A discriminated union expresses the behavioral differences.
38
+ - **Make illegal states unrepresentable** -- "this path needs frontmatter stripping" is state that should live in the type, not in a comment or a parallel Set.
39
+ - **Architectural fixes over patches** -- adding a parallel `Set` for strip flags is a patch; a type expansion is a fix.
40
+ - **Compose with small pure functions** -- `stripFrontmatter(content)` as a pure function is the right shape.
41
+ - **YAGNI with discipline** -- the glob paths are NOT speculative; they are confirmed present in the user's repos. YAGNI does not argue against them.
42
+ - **Errors are data** -- stripping failures (malformed frontmatter) should return original content, not throw.
43
+ - **Immutability by default** -- the new array must be `readonly WorkspaceContextCandidate[]`.
44
+
45
+ **No philosophy conflicts among the stated principles for Candidate 3.** YAGNI vs. unrepresentable-states is only a tension if the glob paths were speculative -- they are not.
46
+
47
+ ---
48
+
49
+ ## Impact Surface
50
+
51
+ Code that must remain consistent if `WORKSPACE_CONTEXT_CANDIDATE_PATHS` changes:
52
+
53
+ 1. **`loadWorkspaceContext()` (line 955):** The main consumer. Must be refactored to handle `kind: 'literal'` and `kind: 'glob'` branches.
54
+ 2. **System prompt format (line 983):** `parts.push(\`### ${relativePath}\n${content}\`)` -- the `### filename` header format must be preserved for glob entries (use the expanded file path as the header).
55
+ 3. **Console.log (line 999):** `WORKSPACE_CONTEXT_CANDIDATE_PATHS.filter(...)` -- this will need updating to log which glob patterns contributed files.
56
+ 4. **`WORKSPACE_CONTEXT_MAX_BYTES` enforcement (line 979):** Must cover glob-expanded files. The byte budget logic already handles per-file truncation correctly.
57
+
58
+ **External consumers:** None. `WORKSPACE_CONTEXT_CANDIDATE_PATHS` is not exported and not imported outside `workflow-runner.ts`. Confirmed via grep.
59
+
60
+ ---
61
+
62
+ ## Candidates
63
+
64
+ ### Candidate 1 -- Minimal literal path expansion
65
+
66
+ **Summary:** Add 3 strings to the existing `string[]`. Zero code change to `loadWorkspaceContext()`.
67
+
68
+ **New paths:**
69
+ - `CLAUDE.local.md` (Claude Code official docs, personal project prefs)
70
+ - `.cursorrules` (Cursor legacy, plain markdown, empirically confirmed)
71
+ - `.github/copilot-instructions.md` (GitHub Copilot official docs)
72
+
73
+ **Tensions resolved:** None of the structural ones.
74
+ **Tensions accepted:** All four. No glob support. No frontmatter handling. String[] stays primitive.
75
+ **Boundary solved at:** Data only (the constant array).
76
+ **Why this boundary:** Easiest possible change.
77
+ **Failure mode:** `.cursorrules` and `.cursor/rules/team-context.mdc` in Zillow repos contain the same content -- double-injection wastes context budget. Not harmful but suboptimal.
78
+ **Repo pattern:** Follows exactly.
79
+ **Gains:** Ships in minutes, zero regression risk.
80
+ **Losses:** Misses all glob-based paths that are actually present in the user's environment.
81
+ **Scope judgment:** Too narrow.
82
+ **Philosophy fit:** Honors YAGNI, immutability. Conflicts with Explicit Domain Types.
83
+
84
+ ---
85
+
86
+ ### Candidate 2 -- Literal paths + unconditional frontmatter stripper
87
+
88
+ **Summary:** Add the same 3 literal paths AND add `stripFrontmatter(content: string): string` as a pure helper. Apply it to every file before injection (safe no-op for plain markdown).
89
+
90
+ **Stripper logic:**
91
+ ```typescript
92
+ function stripFrontmatter(content: string): string {
93
+ // Only strip if file STARTS with --- (YAML frontmatter is always at file start)
94
+ if (!content.startsWith('---\n') && !content.startsWith('---\r\n')) return content;
95
+ const endIdx = content.indexOf('\n---', 4);
96
+ if (endIdx === -1) return content; // no closing delimiter -- don't strip, return as-is
97
+ return content.slice(endIdx + 4).trimStart();
98
+ }
99
+ ```
100
+
101
+ **Tensions resolved:** Frontmatter pollution (safe for all files).
102
+ **Tensions accepted:** No glob support. String[] stays primitive.
103
+ **Boundary solved at:** `loadWorkspaceContext()` function body + new pure helper.
104
+ **Why this boundary:** Extends the existing pure-function pipeline without changing the interface.
105
+ **Failure mode:** A legitimate file that starts with `---` on line 1 for a non-frontmatter reason would be incorrectly stripped. In practice: extremely unlikely for instructions/rules files that all start with a heading or paragraph.
106
+ **Repo pattern:** Adapts existing pattern (pure string transform in `loadWorkspaceContext()` pipeline).
107
+ **Gains:** Clean injection of literal paths. `stripFrontmatter()` is reusable if glob support is added later.
108
+ **Losses:** Still no glob support -- `.cursor/rules/*.mdc` remains unread.
109
+ **Scope judgment:** Best-fit for an incremental "Phase A" PR. If glob support is coming soon, this is good groundwork.
110
+ **Philosophy fit:** Honors Compose with small pure functions, Errors are data. Conflicts with Make illegal states unrepresentable (stripping not expressed in the type).
111
+
112
+ ---
113
+
114
+ ### Candidate 3 -- Discriminated union type + glob expansion + frontmatter stripping
115
+
116
+ **Summary:** Replace `string[]` with `readonly WorkspaceContextCandidate[]` (discriminated union with `kind: 'literal' | 'glob'`), expand `loadWorkspaceContext()` to handle both kinds, using `tinyglobby` (already a dependency) for glob expansion with alpha sorting.
117
+
118
+ **New type:**
119
+ ```typescript
120
+ type LiteralCandidatePath = {
121
+ readonly kind: 'literal';
122
+ readonly relativePath: string;
123
+ readonly stripFrontmatter?: boolean;
124
+ };
125
+ type GlobCandidatePath = {
126
+ readonly kind: 'glob';
127
+ readonly pattern: string; // e.g. '.cursor/rules/*.mdc'
128
+ readonly stripFrontmatter: boolean;
129
+ readonly sort: 'alpha'; // always alpha for determinism
130
+ };
131
+ type WorkspaceContextCandidate = LiteralCandidatePath | GlobCandidatePath;
132
+ ```
133
+
134
+ **Full array (in priority order):**
135
+ ```typescript
136
+ const WORKSPACE_CONTEXT_CANDIDATE_PATHS: readonly WorkspaceContextCandidate[] = [
137
+ { kind: 'literal', relativePath: '.claude/CLAUDE.md' },
138
+ { kind: 'literal', relativePath: 'CLAUDE.md' },
139
+ { kind: 'literal', relativePath: 'CLAUDE.local.md' },
140
+ { kind: 'literal', relativePath: 'AGENTS.md' },
141
+ { kind: 'literal', relativePath: '.github/AGENTS.md' },
142
+ { kind: 'literal', relativePath: '.cursorrules' },
143
+ { kind: 'glob', pattern: '.cursor/rules/*.mdc', stripFrontmatter: true, sort: 'alpha' },
144
+ { kind: 'glob', pattern: '.windsurf/rules/*.md', stripFrontmatter: true, sort: 'alpha' },
145
+ { kind: 'glob', pattern: '.firebender/rules/*.mdc', stripFrontmatter: true, sort: 'alpha' },
146
+ { kind: 'literal', relativePath: '.firebender/AGENTS.md' },
147
+ { kind: 'literal', relativePath: '.github/copilot-instructions.md' },
148
+ { kind: 'glob', pattern: '.continue/rules/*.md', stripFrontmatter: false, sort: 'alpha' },
149
+ ];
150
+ ```
151
+
152
+ **Glob expansion logic shape:**
153
+ ```typescript
154
+ // For GlobCandidatePath entries:
155
+ import { glob } from 'tinyglobby';
156
+ const matches = await glob(entry.pattern, { cwd: workspacePath, absolute: false });
157
+ const sorted = matches.sort(); // alpha sort for determinism
158
+ // Then read each, optionally strip frontmatter, accumulate under budget
159
+ ```
160
+
161
+ **Tensions resolved:** All 4 -- type is expressive, glob supported, frontmatter in contract, deterministic ordering.
162
+ **Tensions accepted:** Slightly larger PR scope.
163
+ **Boundary solved at:** `WORKSPACE_CONTEXT_CANDIDATE_PATHS` type + `loadWorkspaceContext()` function + new `stripFrontmatter()` helper.
164
+ **Why this boundary:** The discriminated union makes illegal states unrepresentable. A glob entry without `stripFrontmatter` is a TypeScript error. A literal entry without a path is a TypeScript error.
165
+ **Failure mode:** (1) Glob expansion could return many files. Mitigation: add `MAX_GLOB_FILES_PER_PATTERN = 20` cap with warning log. (2) `tinyglobby` import -- confirm API matches expected usage (it does: `glob(pattern, { cwd })` is the standard API).
166
+ **Repo pattern:** Departs from string[] but honors "Explicit domain types" and "Make illegal states unrepresentable." This is an architectural improvement, not a departure from values.
167
+ **Gains:** Complete coverage of all discovered conventions. Type contract prevents future maintainer bugs. Frontmatter stripping correct for all cases. Deterministic output.
168
+ **Losses:** Larger diff. Type change requires touching more lines in `loadWorkspaceContext()`.
169
+ **Scope judgment:** Best-fit complete solution. Fully contained in `workflow-runner.ts`.
170
+ **Philosophy fit:** Strongly honors Explicit domain types, Unrepresentable illegal states, Exhaustiveness, Compose with small pure functions. YAGNI is NOT a counter-argument here -- glob paths are confirmed present.
171
+
172
+ ---
173
+
174
+ ### Candidate 4 -- Parallel Set for strip flags (NOT recommended)
175
+
176
+ **Summary:** Keep `string[]` unchanged, add `const WORKSPACE_CONTEXT_STRIP_FRONTMATTER_PATHS = new Set<string>([...])` alongside it.
177
+
178
+ **Tensions resolved:** Backward compat (type unchanged).
179
+ **Failure mode:** Maintenance trap. Adding a new path to the array without updating the Set is a silent bug. This is precisely the illegal state a discriminated union prevents.
180
+ **Scope judgment:** Too narrow in design quality.
181
+ **Philosophy fit:** Conflicts with Architectural fixes over patches, Unrepresentable illegal states. **Eliminated.**
182
+
183
+ ---
184
+
185
+ ## Comparison and Recommendation
186
+
187
+ | Criterion | C1 | C2 | C3 | C4 |
188
+ |---|---|---|---|---|
189
+ | Covers glob paths (.cursor/rules/*.mdc) | No | No | Yes | No |
190
+ | Frontmatter stripping | No | Yes | Yes | Partial |
191
+ | Type expressivity | No | No | Yes | No |
192
+ | Backward compat | Yes | Yes | Yes (no external callers) | Yes |
193
+ | New dependency | No | No | No (tinyglobby already present) | No |
194
+ | Scope | Too narrow | Incremental | Complete | Patch |
195
+
196
+ **Recommendation: Candidate 3.**
197
+
198
+ Key deciding factors:
199
+ 1. The 3 glob paths are confirmed present in the user's actual repos (empirical, not speculative).
200
+ 2. `tinyglobby` is already a project dependency -- zero new dependency cost.
201
+ 3. `WORKSPACE_CONTEXT_CANDIDATE_PATHS` has no external callers -- type change has no coordination cost.
202
+ 4. The discriminated union is the correct architectural shape per the project's stated philosophy.
203
+
204
+ ---
205
+
206
+ ## Self-Critique
207
+
208
+ **Strongest counter-argument against C3:**
209
+ The `loadWorkspaceContext()` function grows significantly -- from a simple loop over strings to a branching loop with glob expansion, file count caps, and two code paths. A reviewer might push back on the increased complexity.
210
+ **Counter:** The complexity is necessary and localized. The alternative (C2) ships an incomplete solution that requires a follow-up PR anyway.
211
+
212
+ **What narrower option (C2) lost:**
213
+ C2 is a correct and safe incremental step. It loses because the most important paths in this environment are glob-based and present right now. Shipping C2 would leave `.cursor/rules/*.mdc` unread in an environment where it's actively in use.
214
+
215
+ **What broader option might be justified:**
216
+ Adding `alwaysApply: false` frontmatter filtering (skip rules that opt out). This would be justified if performance or context budget is a concern. Not in scope for this PR -- add as a follow-up.
217
+
218
+ **Assumption that would invalidate this design:**
219
+ If `tinyglobby`'s `glob()` API is incompatible with the expected call signature. Mitigation: verify against package docs before coding. The API is stable and widely used.
220
+
221
+ ---
222
+
223
+ ## Open Questions for the Main Agent
224
+
225
+ 1. Should glob-expanded files that have the same relative path as a literal-path entry be deduplicated? (Example: `.cursorrules` exists as both a literal entry AND could theoretically match a glob pattern.) Current design: no deduplication -- the literal entry has higher priority and the glob pattern won't match `.cursorrules` anyway.
226
+
227
+ 2. Should the `alwaysApply: false` frontmatter field be respected to skip conditional rules? Current design: strip all frontmatter and inject the body regardless. This is simpler and avoids parsing YAML. A follow-up PR could add smart filtering.
228
+
229
+ 3. What should the per-glob file count cap be? Suggested: 20 files. This is conservative -- most `.cursor/rules/` directories have 1-5 files.
230
+
231
+ 4. Should `CLAUDE.local.md` be placed before `AGENTS.md` (more specific, personal) or after (less team-critical)? Current design: after `CLAUDE.md` and before `AGENTS.md` -- reflects that local prefs are personal overrides but less authoritative than the shared AGENTS.md.
@@ -0,0 +1,85 @@
1
+ # IDE Context Files -- Design Review Findings
2
+
3
+ **Reviewing:** Candidate 3 (discriminated union + glob expansion + frontmatter stripping)
4
+ **Status:** Review complete. No blockers.
5
+
6
+ ---
7
+
8
+ ## Tradeoff Review
9
+
10
+ | Tradeoff | Verdict | Condition that invalidates it |
11
+ |---|---|---|
12
+ | `loadWorkspaceContext()` complexity grows | Acceptable | If function grows beyond ~100 lines, extract `expandGlobEntry()` helper |
13
+ | Type change `string[]` → `WorkspaceContextCandidate[]` | Safe | If constant is ever exported (currently unexported -- keep it that way) |
14
+ | `.cursorrules` + `.cursor/rules/*.mdc` may duplicate content | Acceptable | Priority order (glob first) naturally reduces duplication |
15
+
16
+ No tradeoffs violate acceptance criteria under realistic conditions.
17
+
18
+ ---
19
+
20
+ ## Failure Mode Review
21
+
22
+ | Failure Mode | Severity | Mitigation | Status |
23
+ |---|---|---|---|
24
+ | Glob returns many files (I/O cost + budget waste) | Medium | Add `MAX_GLOB_FILES_PER_PATTERN = 20` cap | Required -- add to implementation |
25
+ | `alwaysApply: false` rules injected unconditionally | Low-medium | None (Phase 1 known limitation) | Deferred to follow-up issue |
26
+ | Malformed frontmatter causes incorrect stripping | N/A (handled) | `startsWith('---\n')` guard + missing-delimiter guard | Fully handled by design |
27
+ | tinyglobby returns absolute paths | N/A (verified) | Empirically confirmed: returns relative paths | Not a risk |
28
+ | Glob traversal outside workspace | N/A | `cwd` option sandboxes to workspace | Not a risk |
29
+
30
+ **Highest-risk failure mode:** Many files per glob. **Mitigation required before shipping.**
31
+
32
+ ---
33
+
34
+ ## Runner-Up / Simpler Alternative Review
35
+
36
+ **Candidate 2 (runner-up)** contributed one element worth incorporating:
37
+ - Call `stripFrontmatter()` unconditionally on all files (not just those with `stripFrontmatter: true`). The function is a safe no-op for plain markdown files. This defends against unexpected frontmatter in any file while the `stripFrontmatter: boolean` field on the type documents which files are EXPECTED to have frontmatter.
38
+
39
+ **Simpler alternative considered:**
40
+ - Remove `sort: 'alpha'` field (rely on tinyglobby natural order). Rejected: filesystem-dependent order violates Determinism principle.
41
+
42
+ ---
43
+
44
+ ## Philosophy Alignment
45
+
46
+ 8 of 9 applicable principles satisfied. 1 needs attention:
47
+
48
+ - **NEEDS ATTENTION:** "Document why not what" -- WHY comments needed on: (a) `WorkspaceContextCandidate` type definition, (b) `MAX_GLOB_FILES_PER_PATTERN`, (c) priority order for each entry in the array.
49
+ - **Minor tension:** YAGNI vs. discriminated union expressivity. Clearly acceptable -- glob paths are empirically confirmed, not speculative.
50
+
51
+ ---
52
+
53
+ ## Findings
54
+
55
+ ### Yellow -- Documentation required
56
+
57
+ **Y1:** The `WorkspaceContextCandidate` type, `MAX_GLOB_FILES_PER_PATTERN` constant, and the priority order in `WORKSPACE_CONTEXT_CANDIDATE_PATHS` all need WHY comments explaining:
58
+ - Why `.cursor/rules/*.mdc` appears before `.cursorrules` (glob before legacy fallback)
59
+ - Why the 20-file cap exists
60
+ - Why frontmatter stripping is called unconditionally
61
+ - Source for each tool's file convention (URL or "empirical" note)
62
+
63
+ **Y2:** The `alwaysApply: false` limitation should be commented on the `GlobCandidatePath` type with a reference to the follow-up issue.
64
+
65
+ ---
66
+
67
+ ## Recommended Revisions
68
+
69
+ 1. **Add `MAX_GLOB_FILES_PER_PATTERN = 20` constant.** Cap the number of files processed per glob entry to prevent I/O cost and context budget waste in large directories. Log a warning if the cap is hit.
70
+
71
+ 2. **Call `stripFrontmatter()` unconditionally.** Apply to all files, not conditionally on the `stripFrontmatter` flag. The flag documents expected format; the implementation is unconditionally defensive.
72
+
73
+ 3. **Add WHY comments** on the type definition, the constant, and each entry in the array.
74
+
75
+ 4. **Create a follow-up GitHub issue** for `alwaysApply: false` frontmatter filtering (Phase 2 enhancement).
76
+
77
+ ---
78
+
79
+ ## Residual Concerns
80
+
81
+ 1. **`alwaysApply: false` rules:** Path-scoped Cursor rules (e.g., `frontend/*.mdc`) will inject into every WorkTrain session regardless of which files are being worked on. This is redundant context but not incorrect. Acceptable for Phase 1.
82
+
83
+ 2. **Cursor official docs inaccessible:** The `.cursor/rules/*.mdc` format was confirmed empirically (filesystem inspection of zillow-android-2) but not from official Cursor documentation (their docs site is a JavaScript SPA). If Cursor changes the format or path in a future release, the design doc will not catch it through re-research. Mitigation: note the empirical source explicitly in the design doc.
84
+
85
+ 3. **`CLAUDE.local.md` not yet validated locally:** No `CLAUDE.local.md` files were found in the local filesystem scan. The path is added based on official Claude Code documentation. Low risk.