@exaudeus/workrail 3.42.0 → 3.44.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.
- package/dist/console-ui/assets/{index-DwfWMKvv.js → index-Bi38ITiQ.js} +1 -1
- package/dist/console-ui/index.html +1 -1
- package/dist/daemon/workflow-runner.d.ts +15 -1
- package/dist/daemon/workflow-runner.js +86 -9
- package/dist/manifest.json +39 -23
- package/dist/trigger/adapters/github-queue-poller.d.ts +34 -0
- package/dist/trigger/adapters/github-queue-poller.js +200 -0
- package/dist/trigger/delivery-action.d.ts +2 -0
- package/dist/trigger/delivery-action.js +24 -0
- package/dist/trigger/github-queue-config.d.ts +18 -0
- package/dist/trigger/github-queue-config.js +155 -0
- package/dist/trigger/polling-scheduler.d.ts +1 -0
- package/dist/trigger/polling-scheduler.js +185 -6
- package/dist/trigger/trigger-router.js +24 -1
- package/dist/trigger/trigger-store.js +77 -2
- package/dist/trigger/types.d.ts +19 -0
- package/docs/design/adaptive-coordinator-context-candidates.md +265 -0
- package/docs/design/adaptive-coordinator-context-review.md +101 -0
- package/docs/design/adaptive-coordinator-context.md +504 -0
- package/docs/design/adaptive-coordinator-routing-candidates.md +340 -0
- package/docs/design/adaptive-coordinator-routing-design-review.md +135 -0
- package/docs/design/adaptive-coordinator-routing-review.md +156 -0
- package/docs/design/adaptive-coordinator-routing.md +660 -0
- package/docs/design/context-assembly-layer-design-review.md +110 -0
- package/docs/design/context-assembly-layer.md +622 -0
- package/docs/design/stuck-escalation-candidates.md +176 -0
- package/docs/design/stuck-escalation-design-review.md +70 -0
- package/docs/design/stuck-escalation.md +326 -0
- package/docs/design/worktrain-task-queue-candidates.md +252 -0
- package/docs/design/worktrain-task-queue-design-review.md +109 -0
- package/docs/design/worktrain-task-queue.md +443 -0
- package/docs/design/worktree-review-findings-candidates.md +101 -0
- package/docs/design/worktree-review-findings-design-review.md +65 -0
- package/docs/design/worktree-review-findings-implementation-plan.md +153 -0
- package/docs/ideas/backlog.md +148 -0
- package/package.json +3 -3
|
@@ -0,0 +1,265 @@
|
|
|
1
|
+
# Inter-Phase Context Passing: Design Candidates
|
|
2
|
+
|
|
3
|
+
*Working analysis document -- raw investigative material, not a final decision.*
|
|
4
|
+
*Produced during wr.discovery workflow for adaptive-coordinator-context.md.*
|
|
5
|
+
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
## Problem Understanding
|
|
9
|
+
|
|
10
|
+
### Core tensions
|
|
11
|
+
|
|
12
|
+
1. **Concern separation vs. convenience:** ContextAssembler is the only session injection mechanism but was designed for startup context (git diff, prior session notes), not inter-phase structured contracts. Using it for inter-phase handoff is convenient but muddles its purpose and change rate.
|
|
13
|
+
|
|
14
|
+
2. **Coupling vs. simplicity:** File-based handoff (pitch.md) is simple and already works for Shaping->Coding. Extending the pattern to all transitions requires each workflow's final step to write to a fixed `.workrail/` path -- coupling pipeline topology to workflow authoring.
|
|
15
|
+
|
|
16
|
+
3. **Uniform bridge vs. typed contracts:** Coordinator-injected freetext (assembledContextSummary) is uniform across all transitions but imprecise -- no schema enforcement. Typed artifacts per transition are precise and Zod-validated but add per-transition schema overhead.
|
|
17
|
+
|
|
18
|
+
4. **Coordinator responsibility vs. session responsibility:** Coordinator can bridge at spawn time (reads lastStepNotes, builds context, injects at spawn). Sessions can self-discover (Phase 0.5 already does this for pitch.md). Self-discovery is more robust but requires each session to know the file conventions.
|
|
19
|
+
|
|
20
|
+
### Likely seam
|
|
21
|
+
|
|
22
|
+
The problem does NOT live in ContextAssembler. The coordinator already passes arbitrary context at spawn time via the 4th parameter to `spawnSession`. The real seam is: **what to put in that context object and how to extract it from the previous phase's output.**
|
|
23
|
+
|
|
24
|
+
The problem is narrower than it appears:
|
|
25
|
+
- Shaping->Coding: already solved (Phase 0.5 + pitch.md)
|
|
26
|
+
- Review->Fix: already solved (wr.review_verdict + pr-review.ts)
|
|
27
|
+
- Remaining gap: Discovery->Shaping only
|
|
28
|
+
|
|
29
|
+
### What makes this hard
|
|
30
|
+
|
|
31
|
+
- Coordinator and session are in different systems; workflow prompt changes can silently break coordinator parsing
|
|
32
|
+
- The only injection point (`assembledContextSummary`) is a freetext markdown string, not a typed contract
|
|
33
|
+
- Two transitions need structured coordinator routing (D->S needs direction; Review->Fix already solved). Three transitions are pass-through.
|
|
34
|
+
- Silent failure is the dominant risk
|
|
35
|
+
|
|
36
|
+
---
|
|
37
|
+
|
|
38
|
+
## Philosophy Constraints
|
|
39
|
+
|
|
40
|
+
**Principles that constrain this design:**
|
|
41
|
+
- Immutability by default: all new types use `readonly`
|
|
42
|
+
- Make illegal states unrepresentable: discriminated unions for AssemblyTask; typed artifacts for coordinator contracts
|
|
43
|
+
- Errors are data: new ContextBundle sources should use `Result<T, string>`
|
|
44
|
+
- Validate at boundaries: Zod for external inputs (typed artifacts, notes parsing)
|
|
45
|
+
- Compose with small pure functions: handoff builder/parser functions must be pure
|
|
46
|
+
- Dependency injection: file reads go through CoordinatorDeps
|
|
47
|
+
- YAGNI: only add typed artifacts for transitions where coordinator branches on structured values
|
|
48
|
+
|
|
49
|
+
**Active conflict:** YAGNI vs. "make illegal states unrepresentable" -- typed artifacts everywhere would enforce all contracts but add schema overhead for 3 transitions that don't need it.
|
|
50
|
+
|
|
51
|
+
---
|
|
52
|
+
|
|
53
|
+
## Impact Surface
|
|
54
|
+
|
|
55
|
+
Must stay consistent with:
|
|
56
|
+
- `src/context-assembly/types.ts` (AssemblyTask union)
|
|
57
|
+
- `src/context-assembly/index.ts` (assemble() switch on task.kind)
|
|
58
|
+
- `src/coordinators/pr-review.ts` (CoordinatorDeps interface)
|
|
59
|
+
- `src/v2/durable-core/schemas/artifacts/` (typed artifact schemas)
|
|
60
|
+
- `workflows/wr.discovery.json` (Phase 7 -- if emitting artifact)
|
|
61
|
+
- `workflows/wr.shaping.json` (Step 1 -- if adding file search)
|
|
62
|
+
- `workflows/coding-task-workflow-agentic.json` (Phase 0.5 -- no changes expected)
|
|
63
|
+
|
|
64
|
+
---
|
|
65
|
+
|
|
66
|
+
## Candidates
|
|
67
|
+
|
|
68
|
+
### Candidate A: Goal string composition + notes injection
|
|
69
|
+
|
|
70
|
+
**Summary:** Coordinator composes a rich goal string from the previous phase's `lastStepNotes` and passes notes as `assembledContextSummary` at spawn time -- no new mechanisms required.
|
|
71
|
+
|
|
72
|
+
**Mechanism:**
|
|
73
|
+
When spawning wr.shaping, coordinator constructs:
|
|
74
|
+
```
|
|
75
|
+
goal = "Shape the following problem discovered in our discovery session:\n\n[lastStepNotes summary]"
|
|
76
|
+
context = { assembledContextSummary: lastStepNotes }
|
|
77
|
+
```
|
|
78
|
+
wr.shaping Step 1 reads from "goal text, discovery notes, tickets, user stories" -- both injection points land in session context.
|
|
79
|
+
|
|
80
|
+
**Tensions resolved:** Workflow independence, coordinator simplicity, coherence
|
|
81
|
+
|
|
82
|
+
**Tensions accepted:** No mechanism clarity, no schema validation, silent failure when notes format changes
|
|
83
|
+
|
|
84
|
+
**Boundary:** Coordinator spawn site only
|
|
85
|
+
|
|
86
|
+
**Failure mode:** wr.discovery notes format changes silently. Shaping session starts from degraded context. No error surfaced.
|
|
87
|
+
|
|
88
|
+
**Repo pattern:** Follows existing assembledContextSummary pattern. No departure.
|
|
89
|
+
|
|
90
|
+
**Gains:** Zero new code outside coordinator. Zero workflow changes. Works today.
|
|
91
|
+
**Losses:** No machine-parseable contract. Coordinator cannot extract structured fields programmatically.
|
|
92
|
+
|
|
93
|
+
**Scope judgment:** Best-fit for pass-through transitions. Too narrow for transitions where coordinator branches on structured values.
|
|
94
|
+
|
|
95
|
+
**Philosophy:** Honors YAGNI, DI. Conflicts with "make illegal states unrepresentable", "validate at boundaries".
|
|
96
|
+
|
|
97
|
+
---
|
|
98
|
+
|
|
99
|
+
### Candidate B: File convention extension (adapt pitch.md)
|
|
100
|
+
|
|
101
|
+
**Summary:** wr.discovery Phase 7 writes `.workrail/current-discovery.md`; wr.shaping Step 1 searches for it -- the same file convention that already works for Shaping->Coding.
|
|
102
|
+
|
|
103
|
+
**Mechanism:**
|
|
104
|
+
- wr.discovery Phase 7 updated to write `.workrail/current-discovery.md`
|
|
105
|
+
- wr.shaping Step 1 updated to search for `.workrail/current-discovery.md` when no goal text provides discovery context
|
|
106
|
+
- Coordinator passes correct workspacePath -- that's the only coordinator involvement
|
|
107
|
+
|
|
108
|
+
**Tensions resolved:** Discoverable handoff (session self-discovers), coordinator logic (no bridging for D->S)
|
|
109
|
+
|
|
110
|
+
**Tensions accepted:** 2 workflow changes, stale file risk (failed discovery leaves wrong file)
|
|
111
|
+
|
|
112
|
+
**Boundary:** Filesystem at `.workrail/`
|
|
113
|
+
|
|
114
|
+
**Failure mode:** Discovery fails before Phase 7. File is stale from prior session. Shaping reads wrong discovery output. No timestamp check.
|
|
115
|
+
|
|
116
|
+
**Repo pattern:** Directly adapts pitch.md convention from wr.shaping Step 9.
|
|
117
|
+
|
|
118
|
+
**Gains:** Sessions self-discover. Coordinator unchanged for D->S. Clean separation.
|
|
119
|
+
**Losses:** Two workflow changes. Stale file risk. Conventions must be maintained.
|
|
120
|
+
|
|
121
|
+
**Scope judgment:** Best-fit for D->S specifically. Over-engineered for other transitions.
|
|
122
|
+
|
|
123
|
+
**Philosophy:** Honors YAGNI, "make illegal states unrepresentable" (file presence checkable). Conflicts with "validate at boundaries" (stale file not caught at coordinator boundary).
|
|
124
|
+
|
|
125
|
+
---
|
|
126
|
+
|
|
127
|
+
### Candidate C: Coordinator-injected structured context (pure builder functions)
|
|
128
|
+
|
|
129
|
+
**Summary:** Add a pure `buildDiscoveryHandoffContext(notes: string): PhaseHandoffContext` function in the coordinator that extracts structured fields from discovery notes and passes them as spawn context.
|
|
130
|
+
|
|
131
|
+
**Type shape:**
|
|
132
|
+
```typescript
|
|
133
|
+
interface PhaseHandoffContext {
|
|
134
|
+
readonly phaseFrom: string;
|
|
135
|
+
readonly phaseTo: string;
|
|
136
|
+
readonly keyFindings: string;
|
|
137
|
+
readonly selectedDirection?: string;
|
|
138
|
+
readonly designDocPath?: string;
|
|
139
|
+
}
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
**Tensions resolved:** Coordinator simplicity (named pure function per transition), no workflow changes, coordinator owns contracts
|
|
143
|
+
|
|
144
|
+
**Tensions accepted:** Notes format still unconstrained. Builder functions must be maintained when format changes.
|
|
145
|
+
|
|
146
|
+
**Boundary:** Coordinator spawn site + named pure function (slightly better than A)
|
|
147
|
+
|
|
148
|
+
**Failure mode:** Notes format changes silently break builder. Same failure as A but slightly more visible (named function can be tested).
|
|
149
|
+
|
|
150
|
+
**Repo pattern:** Adapts parseFindingsFromNotes() pattern (pure function + coordinator uses result). Direct precedent in pr-review.ts.
|
|
151
|
+
|
|
152
|
+
**Gains:** Named, testable, pure functions. Coordinator owns contracts. No workflow changes.
|
|
153
|
+
**Losses:** Notes format still unconstrained. Per-transition builder functions as pipeline grows.
|
|
154
|
+
|
|
155
|
+
**Scope judgment:** Best-fit for coordinator-centric design with intermediate rigor.
|
|
156
|
+
|
|
157
|
+
**Philosophy:** Honors "compose with small pure functions", DI. Conflicts with "validate at boundaries", "make illegal states unrepresentable".
|
|
158
|
+
|
|
159
|
+
---
|
|
160
|
+
|
|
161
|
+
### Candidate D: Typed handoff artifact for decision-critical transitions only (wr.discovery_handoff)
|
|
162
|
+
|
|
163
|
+
**Summary:** Add a `wr.discovery_handoff` typed artifact emitted in wr.discovery Phase 7, Zod-validated by the coordinator -- applied only to D->S; all other transitions use goal string composition.
|
|
164
|
+
|
|
165
|
+
**Schema:**
|
|
166
|
+
```typescript
|
|
167
|
+
interface DiscoveryHandoffArtifactV1 {
|
|
168
|
+
readonly kind: 'wr.discovery_handoff';
|
|
169
|
+
readonly version: 1;
|
|
170
|
+
readonly selectedDirection: string;
|
|
171
|
+
readonly designDocPath: string;
|
|
172
|
+
readonly confidenceBand: 'high' | 'medium' | 'low';
|
|
173
|
+
readonly keyInvariants: readonly string[];
|
|
174
|
+
}
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
**Coordinator parsing:**
|
|
178
|
+
```typescript
|
|
179
|
+
const handoffArtifact = readDiscoveryHandoffArtifact(lastStepArtifacts, sessionHandle);
|
|
180
|
+
const spawnContext = handoffArtifact
|
|
181
|
+
? { selectedDirection: handoffArtifact.selectedDirection, designDocPath: handoffArtifact.designDocPath, assembledContextSummary: render(handoffArtifact) }
|
|
182
|
+
: { assembledContextSummary: lastStepNotes };
|
|
183
|
+
await deps.spawnSession('wr.shaping', buildShapingGoal(handoffArtifact ?? notes), workspace, spawnContext);
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
**Transition coverage:**
|
|
187
|
+
- D->S: wr.discovery_handoff (NEW)
|
|
188
|
+
- Review->Fix: wr.review_verdict (already exists)
|
|
189
|
+
- S->C: goal string + pitch.md self-discovery via Phase 0.5 (no typed artifact)
|
|
190
|
+
- C->PR: PR number in goal string (no typed artifact)
|
|
191
|
+
- PR->Review: PR number (no typed artifact)
|
|
192
|
+
|
|
193
|
+
**Tensions resolved:** Mechanism clarity (schema IS the contract), validates at boundaries (Zod), makes illegal states unrepresentable for D->S
|
|
194
|
+
|
|
195
|
+
**Tensions accepted:** 1 workflow change (wr.discovery Phase 7 must emit artifact). Two-tier fallback complexity. Schema maintenance.
|
|
196
|
+
|
|
197
|
+
**Boundary:** wr.discovery Phase 7 (emitter) + coordinator lastStepArtifacts handling (consumer)
|
|
198
|
+
|
|
199
|
+
**Failure mode:** Agent doesn't emit artifact. Coordinator falls back to notes parsing. Two-tier failure, same as wr.review_verdict today.
|
|
200
|
+
|
|
201
|
+
**Repo pattern:** Directly follows wr.review_verdict pattern in every structural detail.
|
|
202
|
+
|
|
203
|
+
**Gains:** Machine-parseable D->S contract. Coordinator can route on confidenceBand. Type-safe. Explicit failure.
|
|
204
|
+
**Losses:** 1 workflow change. Schema maintenance. Two-tier parsing. Agent must reliably emit artifact.
|
|
205
|
+
|
|
206
|
+
**Scope judgment:** Best-fit for D->S. Combined with A for other transitions = minimum typed surface.
|
|
207
|
+
|
|
208
|
+
**Philosophy:** Fully honors "make illegal states unrepresentable", "validate at boundaries", "type safety as first line of defense", YAGNI (applied only to 2 decision-critical transitions).
|
|
209
|
+
|
|
210
|
+
---
|
|
211
|
+
|
|
212
|
+
## Comparison and Recommendation
|
|
213
|
+
|
|
214
|
+
### Comparison matrix
|
|
215
|
+
|
|
216
|
+
| Criterion | A | B | C | D |
|
|
217
|
+
|-----------|---|---|---|---|
|
|
218
|
+
| Mechanism clarity | Low | Medium | Medium | High |
|
|
219
|
+
| Coordinator logic minimality | High | High | Medium | Medium |
|
|
220
|
+
| Workflow independence | High | Low | High | Medium |
|
|
221
|
+
| Coherence with existing patterns | Medium | High | Medium | High |
|
|
222
|
+
| Discoverable handoff | Low | High | Low | Low |
|
|
223
|
+
| Philosophy fit | Medium | Medium | Medium | High |
|
|
224
|
+
| Failure mode explicitness | Low | Medium | Medium | High |
|
|
225
|
+
|
|
226
|
+
### Recommendation: Hybrid D + A
|
|
227
|
+
|
|
228
|
+
**D for Discovery->Shaping:**
|
|
229
|
+
Coordinator branches on `selectedDirection` -- this is a routing decision, not just context enrichment. Mirrors the wr.review_verdict precedent. Schema overhead proportionate to decision weight.
|
|
230
|
+
|
|
231
|
+
**A for all other pass-through transitions:**
|
|
232
|
+
- Shaping->Coding: Phase 0.5 finds pitch.md automatically (confirmed in workflow prompt)
|
|
233
|
+
- Coding->PR: PR number in goal string
|
|
234
|
+
- PR->Review: pr-review.ts already handles this
|
|
235
|
+
|
|
236
|
+
**No ContextAssembler change needed:**
|
|
237
|
+
Coordinator passes `{ selectedDirection, designDocPath, assembledContextSummary }` as spawn context keys. The existing `context: Record<string, unknown>` parameter on `spawnSession` is sufficient.
|
|
238
|
+
|
|
239
|
+
---
|
|
240
|
+
|
|
241
|
+
## Self-Critique
|
|
242
|
+
|
|
243
|
+
**Strongest counter-argument against D:**
|
|
244
|
+
The workflow change to wr.discovery Phase 7 is a point of failure. If the agent emits a malformed artifact or omits it, coordinator falls back to notes parsing -- same fragility as Candidate A. The typed contract only helps when the artifact IS correctly emitted.
|
|
245
|
+
|
|
246
|
+
**Why A is a legitimate simpler answer:**
|
|
247
|
+
wr.shaping Step 1 explicitly reads "goal text, discovery notes, tickets, user stories." If coordinator goal string includes discovery summary, this may be sufficient. No structured routing on selectedDirection may be needed. Validate this when the first adaptive coordinator is written.
|
|
248
|
+
|
|
249
|
+
**Pivot condition to A:**
|
|
250
|
+
When the first adaptive coordinator is written, if wr.shaping Step 1 produces sound results without structured `selectedDirection` access, Candidate A is correct and D's overhead is unjustified.
|
|
251
|
+
|
|
252
|
+
**Broader option:**
|
|
253
|
+
D for all transitions (add wr.shaping_handoff, wr.coding_handoff). Justified only if coordinator needs to branch on pitch content or implementation scope. Not justified now.
|
|
254
|
+
|
|
255
|
+
---
|
|
256
|
+
|
|
257
|
+
## Open Questions for the Main Agent
|
|
258
|
+
|
|
259
|
+
1. Does the coordinator need to branch on `selectedDirection` from discovery, or is passing the full notes blob sufficient for wr.shaping Step 1? This determines whether D is needed at all.
|
|
260
|
+
|
|
261
|
+
2. Is there a planned use case where the adaptive coordinator skips Shaping based on discovery confidence band? If yes, D is clearly justified. If not, A may be sufficient.
|
|
262
|
+
|
|
263
|
+
3. What does the routing agent (adaptive-coordinator-routing.md) expect from context passing? Its design may have specific requirements for structured fields at routing decision time.
|
|
264
|
+
|
|
265
|
+
4. Is `.workrail/current-pitch.md` reliably found by Phase 0.5 in practice? If Phase 0.5 sometimes misses it, the coordinator may need to inject `pitchPath` explicitly.
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
# Design Review Findings: Adaptive Coordinator Context Passing
|
|
2
|
+
|
|
3
|
+
*Review of selected direction: Hybrid D + A (wr.discovery_handoff artifact for D->S + goal string/notes for other transitions)*
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Tradeoff Review
|
|
8
|
+
|
|
9
|
+
**Tradeoff 1: 1 workflow change to wr.discovery Phase 7**
|
|
10
|
+
- Acceptable. Phase 7 already has all required context variables (`selectedDirection`, `designDocPath`, `recommendationConfidenceBand`) set by prior steps. Agent can construct the artifact reliably.
|
|
11
|
+
- Safe with versioned workflows: fallback path (notes parsing) exists, so old versions degrade gracefully.
|
|
12
|
+
|
|
13
|
+
**Tradeoff 2: Two-tier fallback complexity for D->S**
|
|
14
|
+
- Acceptable. Exact same pattern as wr.review_verdict + parseFindingsFromNotes. Code structure is proven. No novel complexity.
|
|
15
|
+
|
|
16
|
+
**Tradeoff 3: Agent must emit artifact or fallback activates**
|
|
17
|
+
- Acceptable with monitoring. wr.review_verdict evidence shows agents reliably emit typed artifacts when explicitly instructed. Fallback logs a `[WARN]`, not silent.
|
|
18
|
+
|
|
19
|
+
---
|
|
20
|
+
|
|
21
|
+
## Failure Mode Review
|
|
22
|
+
|
|
23
|
+
**FM1: Agent doesn't emit artifact**
|
|
24
|
+
- Design handles it (fallback to notes). **Missing mitigation:** coordinator should check `lastStepNotes.trim().length > 50` before using notes as fallback. Without this check, an empty notes string causes shaping to start from scratch with no information.
|
|
25
|
+
- Severity: YELLOW
|
|
26
|
+
|
|
27
|
+
**FM2: Artifact emitted with wrong schema**
|
|
28
|
+
- Handled (Zod rejects, WARN logged, fallback activates). Same as wr.review_verdict. No action needed.
|
|
29
|
+
- Severity: GREEN
|
|
30
|
+
|
|
31
|
+
**FM3: pitch.md not found by Phase 0.5 (Shaping->Coding)**
|
|
32
|
+
- Phase 0.5 does active search but success is probabilistic. **Missing mitigation:** coordinator should pass `pitchPath: '.workrail/current-pitch.md'` explicitly in the Shaping->Coding spawn context. Cost: zero (trigger context injection already works). Without this, a missed Phase 0.5 search results in unnecessary design ideation.
|
|
33
|
+
- Severity: ORANGE
|
|
34
|
+
|
|
35
|
+
**FM4: Discovery session fails before Phase 7**
|
|
36
|
+
- Not a design gap. Coordinator checks session outcome (`_tag: 'success'`) before reading artifacts. Standard pattern.
|
|
37
|
+
- Severity: GREEN
|
|
38
|
+
|
|
39
|
+
**FM5: Stale context**
|
|
40
|
+
- Not a risk. Coordinator awaits discovery before reading results.
|
|
41
|
+
- Severity: GREEN
|
|
42
|
+
|
|
43
|
+
---
|
|
44
|
+
|
|
45
|
+
## Runner-Up / Simpler Alternative Review
|
|
46
|
+
|
|
47
|
+
**Runner-up (Candidate A only) strengths incorporated:**
|
|
48
|
+
- Coordinator always composes a rich goal string using `selectedDirection` from the artifact (if present) or from notes parsing (fallback). Goal string is the first orientation signal; it must be rich regardless of other context injection.
|
|
49
|
+
|
|
50
|
+
**Simpler variant (plain context key instead of Zod artifact) analysis:**
|
|
51
|
+
- Collapsed back to Candidate A with a named key. Same silent failure mode (notes format changes break the value without error). D is justified only when coordinator needs a validated `selectedDirection` string. Simpler variant is NOT simpler for decision-critical routing.
|
|
52
|
+
|
|
53
|
+
**Hybrid opportunity (implementation sequencing):**
|
|
54
|
+
- Define schema + coordinator parsing FIRST; update wr.discovery Phase 7 SECOND (after confirming structured routing is needed in practice). This prevents a premature workflow change.
|
|
55
|
+
|
|
56
|
+
---
|
|
57
|
+
|
|
58
|
+
## Philosophy Alignment
|
|
59
|
+
|
|
60
|
+
**Satisfied clearly:** Immutability, errors-as-data, dependency injection, compose-small-pure-functions, YAGNI
|
|
61
|
+
|
|
62
|
+
**Under acceptable tension:**
|
|
63
|
+
- "Make illegal states unrepresentable": fully satisfied for D-path (typed artifact); notes-based A-path is unconstrained. Acceptable because A-path transitions don't require coordinator routing decisions.
|
|
64
|
+
- "Validate at boundaries": D-path uses Zod. A-path notes fallback is a weak boundary. Acceptable: notes are informational only.
|
|
65
|
+
|
|
66
|
+
**Inherent limitation (not a design flaw):**
|
|
67
|
+
- Type safety at LLM inference boundary: trigger context keys are read by LLM inference, not TypeScript. No compile-time guarantee on how the session interprets `selectedDirection`. Monitor via prompt engineering quality.
|
|
68
|
+
|
|
69
|
+
---
|
|
70
|
+
|
|
71
|
+
## Findings
|
|
72
|
+
|
|
73
|
+
### RED (must fix before finalizing)
|
|
74
|
+
- None
|
|
75
|
+
|
|
76
|
+
### ORANGE (should fix -- meaningful risk if missed)
|
|
77
|
+
- **O1: Missing pitchPath injection for S->C transition.** Coordinator should pass `pitchPath: '.workrail/current-pitch.md'` in the Shaping->Coding spawn context to guarantee Phase 0.5 finds the pitch even if file search misses it. Zero additional code complexity; just an extra key in the spawn context.
|
|
78
|
+
|
|
79
|
+
### YELLOW (low risk, but worth noting)
|
|
80
|
+
- **Y1: Missing notes length check in fallback.** Coordinator should check `lastStepNotes.trim().length > 50` before using notes as assembledContextSummary fallback. Prevents shaping from starting completely blind if discovery notes are empty.
|
|
81
|
+
- **Y2: Implementation ordering.** Define schema and coordinator parsing code first, before updating the wr.discovery Phase 7 workflow. This avoids a premature workflow change and provides a validation checkpoint.
|
|
82
|
+
- **Y3: Trigger context injection undocumented.** The fact that ALL trigger.context keys are injected as JSON in the initial prompt (`Trigger context: { ... }`) is an important coordinator-authoring invariant that must be documented in the design doc. It is currently only visible by reading workflow-runner.ts lines 3191-3193.
|
|
83
|
+
|
|
84
|
+
---
|
|
85
|
+
|
|
86
|
+
## Recommended Revisions
|
|
87
|
+
|
|
88
|
+
1. **Add pitchPath injection** to the Shaping->Coding spawn context specification in the design doc
|
|
89
|
+
2. **Add notes length check** to the coordinator implementation requirements
|
|
90
|
+
3. **Document trigger context injection mechanism** explicitly in the design doc (it is how structured fields reach the downstream session)
|
|
91
|
+
4. **State implementation ordering** explicitly in the design doc: schema + parsing code first, workflow change second
|
|
92
|
+
|
|
93
|
+
---
|
|
94
|
+
|
|
95
|
+
## Residual Concerns
|
|
96
|
+
|
|
97
|
+
1. **LLM inference reliability** at the trigger context boundary: the downstream session must correctly interpret `selectedDirection` from the `Trigger context: { ... }` JSON block. Prompt engineering quality of the wr.shaping Step 1 prompt determines this. Not solvable at the coordinator design level; worth monitoring in early pipeline runs.
|
|
98
|
+
|
|
99
|
+
2. **Two-tier fallback debt** for D->S: the fallback (notes parsing for Discovery->Shaping) is a weak boundary that may accumulate technical debt as wr.discovery evolves. Consider adding an integration test that checks the coordinator falls back gracefully when wr.discovery Phase 7 does not emit the artifact.
|
|
100
|
+
|
|
101
|
+
3. **No contract for Coding->PR transition:** the design explicitly leaves this as "goal string with PR number." If the adaptive coordinator needs to know the PR number programmatically (to verify it was created correctly, to pass it to the review coordinator), this should be documented as a known gap rather than left implicit.
|