@exaudeus/workrail 3.41.0 → 3.43.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/cli-worktrain.js +40 -11
- package/dist/console-ui/assets/{index-CQt4UhPB.js → index-Sb57DW4B.js} +1 -1
- package/dist/console-ui/index.html +1 -1
- package/dist/context-assembly/deps.d.ts +8 -0
- package/dist/context-assembly/deps.js +2 -0
- package/dist/context-assembly/index.d.ts +6 -0
- package/dist/context-assembly/index.js +50 -0
- package/dist/context-assembly/infra.d.ts +3 -0
- package/dist/context-assembly/infra.js +154 -0
- package/dist/context-assembly/types.d.ts +30 -0
- package/dist/context-assembly/types.js +2 -0
- package/dist/coordinators/pr-review.d.ts +3 -1
- package/dist/coordinators/pr-review.js +25 -4
- package/dist/daemon/workflow-runner.d.ts +11 -1
- package/dist/daemon/workflow-runner.js +82 -9
- package/dist/domain/execution/state.d.ts +6 -6
- package/dist/manifest.json +76 -44
- package/dist/mcp/handlers/v2-workflow.d.ts +2 -2
- package/dist/mcp/output-schemas.d.ts +234 -234
- package/dist/mcp/tools.d.ts +2 -2
- package/dist/mcp/v2/tools.d.ts +24 -24
- package/dist/trigger/delivery-action.d.ts +2 -0
- package/dist/trigger/delivery-action.js +24 -0
- package/dist/trigger/trigger-router.js +24 -1
- package/dist/trigger/trigger-store.js +42 -0
- package/dist/trigger/types.d.ts +3 -0
- package/dist/v2/durable-core/schemas/artifacts/assessment.d.ts +2 -2
- package/dist/v2/durable-core/schemas/artifacts/coordinator-signal.d.ts +2 -2
- package/dist/v2/durable-core/schemas/artifacts/loop-control.d.ts +6 -6
- package/dist/v2/durable-core/schemas/artifacts/review-verdict.d.ts +6 -6
- package/dist/v2/durable-core/schemas/compiled-workflow/index.d.ts +56 -56
- package/dist/v2/durable-core/schemas/execution-snapshot/blocked-snapshot.d.ts +83 -83
- package/dist/v2/durable-core/schemas/execution-snapshot/execution-snapshot.v1.d.ts +1024 -1024
- package/dist/v2/durable-core/schemas/export-bundle/index.d.ts +2336 -2336
- package/dist/v2/durable-core/schemas/session/dag-topology.d.ts +6 -6
- package/dist/v2/durable-core/schemas/session/events.d.ts +339 -339
- package/dist/v2/durable-core/schemas/session/gaps.d.ts +30 -30
- package/dist/v2/durable-core/schemas/session/manifest.d.ts +6 -6
- package/dist/v2/durable-core/schemas/session/outputs.d.ts +8 -8
- package/dist/v2/durable-core/schemas/session/validation-event.d.ts +3 -3
- 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-design-candidates.md +199 -0
- package/docs/design/context-assembly-implementation-plan.md +211 -0
- package/docs/design/context-assembly-layer-design-review.md +110 -0
- package/docs/design/context-assembly-layer.md +622 -0
- package/docs/design/context-assembly-review-findings.md +112 -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 +212 -0
- package/package.json +3 -3
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
# WorkTrain Task Queue: Design Review Findings
|
|
2
|
+
|
|
3
|
+
_Review of Candidate B (Hybrid) -- the selected direction._
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Tradeoff Review
|
|
8
|
+
|
|
9
|
+
### Tradeoff 1: Optional body section (~10-15% of issues will use it)
|
|
10
|
+
|
|
11
|
+
- Does not violate any acceptance criterion. Body section is optional; an issue with no section is valid.
|
|
12
|
+
- Hidden assumption: the `## WorkTrain` section header is stable. If it changes after v1, existing issues with the section become unparseable.
|
|
13
|
+
- Condition for failure: section is never used in practice (0% of issues). If this happens, simplify to Candidate A.
|
|
14
|
+
- **Verdict: acceptable.**
|
|
15
|
+
|
|
16
|
+
### Tradeoff 2: Body content fetched at workflow runtime (not routing time)
|
|
17
|
+
|
|
18
|
+
- Does not violate any acceptance criterion. Routing is label-only; body fetch is a workflow execution cost.
|
|
19
|
+
- Hidden assumption: upstream_spec is not a routing gate. Current evidence (Phase 0.5 runs inside coding workflow after pipeline selection) supports this.
|
|
20
|
+
- Condition for failure: coordinator is built to make routing decisions based on upstream_spec presence/absence.
|
|
21
|
+
- **Verdict: acceptable with a known extension point (`worktrain:has-spec` label) if the assumption fails.**
|
|
22
|
+
|
|
23
|
+
---
|
|
24
|
+
|
|
25
|
+
## Failure Mode Review
|
|
26
|
+
|
|
27
|
+
### FM1: Human omits required label (maturity or type)
|
|
28
|
+
|
|
29
|
+
- **Severity: Low.** Issue is not processed, not broken.
|
|
30
|
+
- Design handles it: partially. Schema defines required labels; GitHub does not enforce them.
|
|
31
|
+
- Missing mitigation: schema doc must specify coordinator behavior on missing labels (log warning, add `worktrain:needs-labels` label to issue, skip dispatch).
|
|
32
|
+
|
|
33
|
+
### FM2: Malformed `## WorkTrain` body section
|
|
34
|
+
|
|
35
|
+
- **Severity: Low.** Phase 0.5 falls back to format-agnostic search. Graceful degradation.
|
|
36
|
+
- Design handles it: yes.
|
|
37
|
+
- Missing mitigation: coordinator context-injection path (if pre-fetching upstream_spec) must also handle parse failure gracefully (log and continue, do not fail dispatch).
|
|
38
|
+
|
|
39
|
+
### FM3: upstream_spec becomes a routing signal (not enrichment)
|
|
40
|
+
|
|
41
|
+
- **Severity: High.** If the coordinator needs upstream_spec presence/absence to select the pipeline, the body must be fetched at routing time and the labels-only routing architecture breaks.
|
|
42
|
+
- Design handles it: no -- this assumption is baked in.
|
|
43
|
+
- Extension point: add `worktrain:has-spec` label. Presence signals 'an upstream spec exists in the body' without requiring a body fetch. This is the escape valve if the assumption fails. Document it as an explicit extension point in v1.
|
|
44
|
+
|
|
45
|
+
---
|
|
46
|
+
|
|
47
|
+
## Runner-Up / Simpler Alternative Review
|
|
48
|
+
|
|
49
|
+
**Runner-up: Candidate A (Labels-only)**
|
|
50
|
+
|
|
51
|
+
- A is simpler, no body section, zero added documentation weight.
|
|
52
|
+
- A satisfies all 5 success criteria if Phase 0.5's format-agnostic search is sufficient for upstream spec discovery (no coordinator-injection use case).
|
|
53
|
+
- A does NOT satisfy criterion 4 if coordinator context-injection requires deterministic extraction of upstream_spec.
|
|
54
|
+
- **Decision: B wins on criterion 4 (coordinator-injection). A is the fallback if context injection is never implemented.**
|
|
55
|
+
|
|
56
|
+
**Simplest version of B:** identical to B as specified. No simplification is available that retains the upstream_spec benefit.
|
|
57
|
+
|
|
58
|
+
---
|
|
59
|
+
|
|
60
|
+
## Philosophy Alignment
|
|
61
|
+
|
|
62
|
+
| Principle | Status |
|
|
63
|
+
|-----------|--------|
|
|
64
|
+
| Exhaustiveness everywhere | Satisfied -- closed enum for maturity/type, exhaustive routing switch |
|
|
65
|
+
| Validate at boundaries, trust inside | Satisfied -- coordinator validates labels at entry |
|
|
66
|
+
| Determinism over cleverness | Satisfied -- routing is a pure function of (maturity, type) |
|
|
67
|
+
| YAGNI with discipline | Satisfied -- no speculative required fields |
|
|
68
|
+
| Immutability by default | Satisfied -- routing table is pure, no mutable routing state |
|
|
69
|
+
| Make illegal states unrepresentable | Tension -- GitHub stringly-typed; coordinator validates at boundary as mitigation |
|
|
70
|
+
| Prefer explicit domain types | Minor tension -- body section is key: value text parsing |
|
|
71
|
+
|
|
72
|
+
Both tensions are acceptable given GitHub's stringly-typed constraints.
|
|
73
|
+
|
|
74
|
+
---
|
|
75
|
+
|
|
76
|
+
## Findings
|
|
77
|
+
|
|
78
|
+
### Red (blocking)
|
|
79
|
+
|
|
80
|
+
None.
|
|
81
|
+
|
|
82
|
+
### Orange (important, fix before production use)
|
|
83
|
+
|
|
84
|
+
**O1: Missing coordinator error behavior on absent required labels.** The schema doc does not specify what the coordinator does when maturity or type labels are absent. Without this, different coordinator implementations may handle the error differently (skip vs. full-pipeline fallback vs. error). Specify in the schema doc: add `worktrain:needs-labels` label to the issue, skip dispatch, emit structured log entry.
|
|
85
|
+
|
|
86
|
+
### Yellow (notable, address in documentation)
|
|
87
|
+
|
|
88
|
+
**Y1: `worktrain:has-spec` extension label not documented.** The schema should explicitly name this label as a known extension point for the case where upstream_spec presence/absence becomes a routing signal. Prevents a future coordinator developer from inventing an incompatible convention.
|
|
89
|
+
|
|
90
|
+
**Y2: `## WorkTrain` section header stability.** The schema doc should state that this header name is frozen after v1 and must not be changed. Issues with the section would silently break if the header name changes.
|
|
91
|
+
|
|
92
|
+
**Y3: `upstream_spec` type is unvalidated.** The body section key accepts any string. The schema doc should state that `upstream_spec` must be a valid http/https URL. Coordinator and Phase 0.5 should log a warning if the value is not a URL.
|
|
93
|
+
|
|
94
|
+
---
|
|
95
|
+
|
|
96
|
+
## Recommended Revisions
|
|
97
|
+
|
|
98
|
+
1. Add to schema doc: coordinator behavior on missing required labels (O1)
|
|
99
|
+
2. Add to schema doc: `worktrain:has-spec` as a documented extension label (Y1)
|
|
100
|
+
3. Add to schema doc: stability note for `## WorkTrain` header (Y2)
|
|
101
|
+
4. Add to schema doc: `upstream_spec` must be a valid http/https URL (Y3)
|
|
102
|
+
5. Add to Decision Log: simplify to Candidate A if coordinator-injection use case is never implemented
|
|
103
|
+
|
|
104
|
+
---
|
|
105
|
+
|
|
106
|
+
## Residual Concerns
|
|
107
|
+
|
|
108
|
+
- **The coordinator does not yet exist.** This schema is designed before its primary consumer is implemented. There is a risk that the routing table (especially the handling of `rough` vs `idea` vs `specced`) turns out to need more nuance once a real coordinator is being built. The schema should be versioned so that adding a new maturity value (e.g. `groomed`) does not break existing issues.
|
|
109
|
+
- **Label namespace collisions.** The `worktrain:` prefix namespace is informal. If WorkRail adds other labels with the same prefix for different purposes, conflicts could arise. The schema doc should be the authoritative namespace registry for `worktrain:` labels.
|
|
@@ -0,0 +1,443 @@
|
|
|
1
|
+
# WorkTrain Task Queue: GitHub Issue Schema Design
|
|
2
|
+
|
|
3
|
+
## Artifact Strategy
|
|
4
|
+
|
|
5
|
+
This document is a human-readable design record. It is NOT execution memory -- the WorkRail workflow session notes and context variables are the durable execution truth. If a rewind occurs, the session notes survive; this file may not. Treat this file as a readable summary of decisions made, not a source of truth for the workflow.
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## Context / Ask
|
|
10
|
+
|
|
11
|
+
**Stated goal:** Design the GitHub issue schema for the WorkTrain task queue -- what fields an issue needs so a future adaptive coordinator can route it correctly, without assuming the coordinator's internal design is settled.
|
|
12
|
+
|
|
13
|
+
**Reframed problem:** A WorkTrain coordinator cannot deterministically route a GitHub issue to the right pipeline (full shaping+discovery+coding, discovery+coding, or coding-only) because no issue carries the signals needed to distinguish these cases.
|
|
14
|
+
|
|
15
|
+
**Note:** The stated goal is a solution statement. The reframed problem is the actual constraint we are designing against.
|
|
16
|
+
|
|
17
|
+
---
|
|
18
|
+
|
|
19
|
+
## Path Recommendation
|
|
20
|
+
|
|
21
|
+
**Path: design_first**
|
|
22
|
+
|
|
23
|
+
The dominant risk here is defining the wrong schema -- one that is either over-specified (encoding coordinator internals in the issue) or under-specified (leaving routing ambiguous). The stated solution (YAML frontmatter + labels) is a reasonable implementation direction, but the schema contract -- which fields are required, what they mean, and how they map to pipeline decisions -- needs to be reasoned through before any format is chosen.
|
|
24
|
+
|
|
25
|
+
The Three-Workflow Pipeline and taskMaturity spectrum are already partially defined in backlog.md (Apr 15, Apr 18). The schema must align with these, not contradict them.
|
|
26
|
+
|
|
27
|
+
---
|
|
28
|
+
|
|
29
|
+
## Constraints / Anti-goals
|
|
30
|
+
|
|
31
|
+
**Constraints:**
|
|
32
|
+
- Must be readable by the existing `github_issues_poll` TriggerDefinition (via `labelFilter` / `notLabels`)
|
|
33
|
+
- Must support deterministic pipeline routing without an LLM call
|
|
34
|
+
- Human must be able to file a valid issue in under 2 minutes
|
|
35
|
+
- Schema must be stable even if the coordinator's internal implementation changes
|
|
36
|
+
|
|
37
|
+
**Anti-goals:**
|
|
38
|
+
- Not a full project management system (no sprint planning, estimation, assignee tracking)
|
|
39
|
+
- Not a replacement for docs/tickets/next-up.md for near-term groomed work
|
|
40
|
+
- Not a schema that encodes coordinator internals (keep routing signals on the issue side of the contract)
|
|
41
|
+
|
|
42
|
+
---
|
|
43
|
+
|
|
44
|
+
## Landscape Packet
|
|
45
|
+
|
|
46
|
+
### Current State
|
|
47
|
+
|
|
48
|
+
**Task queue today:** No automated task queue exists. Near-term work is tracked in `docs/tickets/next-up.md` as prose tickets (goal + blocked-on + design reference). This is a human-curated, unstructured format with no machine-readable fields.
|
|
49
|
+
|
|
50
|
+
**Transport layer (github_issues_poll):** Fully implemented and wired in `src/trigger/`. The `GitHubPollingSource` supports `labelFilter` (server-side, passed as `labels=` query param) and `notLabels` (client-side drop). The adapter (`src/trigger/adapters/github-poller.ts`) fetches `GitHubIssue` objects with: `id`, `number`, `title`, `html_url`, `updated_at`, `state`, `user.login`, `labels[].name`. **Confirmed from source: no `body` field in `GitHubIssue`.** The poller has zero awareness of issue body content. Any body-based routing requires the coordinator to make a separate `GET /repos/:owner/:repo/issues/:number` API call.
|
|
51
|
+
|
|
52
|
+
**Coordinator today:** Only `src/coordinators/pr-review.ts` exists. It dispatches MR review sessions, classifies findings, and routes by severity. It does NOT read issue bodies or maturity fields. No routing by issue content exists yet.
|
|
53
|
+
|
|
54
|
+
**Routing signals defined in backlog (not yet implemented):**
|
|
55
|
+
- `taskMaturity`: idea / rough / specced / ready / code-complete (backlog Apr 15)
|
|
56
|
+
- `existingArtifacts`: brd / designs / arch-decision / acceptance-criteria / ticket / implementation
|
|
57
|
+
- Three-Workflow Pipeline: `wr.discovery` (optional) -> `wr.shaping` (optional) -> `coding-task-workflow-agentic` (Apr 18)
|
|
58
|
+
|
|
59
|
+
**TriggerDefinition routing fields:** `workflowId` is static per trigger. To dispatch different workflows from the same trigger, the routing must happen either in a coordinator script (reads issue, decides workflowId) or via multiple triggers with different `labelFilter` values.
|
|
60
|
+
|
|
61
|
+
### Hard Constraints
|
|
62
|
+
|
|
63
|
+
1. The `github-poller.ts` fetches issue labels but NOT the issue body. A coordinator spawned by the trigger receives the `goalTemplate` context and labels, but not body content unless it makes a separate GitHub API call.
|
|
64
|
+
2. `labelFilter` is server-side (passed to GitHub API), `notLabels` is client-side. Labels are the primary dispatch-gating mechanism today.
|
|
65
|
+
3. A single trigger fires one fixed `workflowId`. Multi-pipeline routing requires either: (a) a coordinator workflow that reads the issue and spawns the right child, or (b) multiple triggers with different labels.
|
|
66
|
+
|
|
67
|
+
### Main Existing Approaches (Precedents)
|
|
68
|
+
|
|
69
|
+
- **Labels-only routing** (Dependabot, GitHub Actions): uses label taxonomies like `priority:high`, `type:bug`. Lightweight, native to GitHub UI, no body parsing.
|
|
70
|
+
- **YAML frontmatter in issue body** (Linear-style, some internal tools): structured metadata at the top of the body. Requires the coordinator to call `GET /repos/:owner/:repo/issues/:number` to fetch the body, then parse YAML.
|
|
71
|
+
- **Structured section** (e.g. `## Metadata` with `key: value` lines): same parsing cost as frontmatter, less standard, harder to validate.
|
|
72
|
+
- **Hybrid** (labels for routing dimensions + body for prose context): labels carry machine-readable fields, body carries human-readable description and upstream links.
|
|
73
|
+
|
|
74
|
+
### Obvious Contradictions
|
|
75
|
+
|
|
76
|
+
1. The poller does not fetch issue body content -- but the goal says routing signals could include `upstream_spec` (a URL/path) and `affected_files`. These cannot come from labels alone. Contradiction: if routing needs these fields, a separate API call is required.
|
|
77
|
+
2. The goal says "design the schema as if the coordinator's routing interface doesn't yet exist" -- but the backlog has a partially-settled routing interface (taskMaturity, Three-Workflow Pipeline). The schema should align with this, not ignore it.
|
|
78
|
+
|
|
79
|
+
### Evidence Gaps
|
|
80
|
+
|
|
81
|
+
- No coordinator script for issue-based routing exists yet. The schema will be designed before its primary consumer is implemented.
|
|
82
|
+
- No sample GitHub issue with WorkTrain metadata exists in the repo. The sample will be the first instance.
|
|
83
|
+
- It is unknown whether the coordinator will need body content or labels alone for routing. This is the primary uncertainty to resolve in design.
|
|
84
|
+
|
|
85
|
+
---
|
|
86
|
+
|
|
87
|
+
## Problem Frame Packet
|
|
88
|
+
|
|
89
|
+
**Goal type:** `solution_statement` -- the stated goal prescribes a specific artifact (issue schema) rather than the underlying problem.
|
|
90
|
+
|
|
91
|
+
**Reframed problem:** A coordinator dispatching GitHub issues to the three-workflow pipeline has no reliable machine-readable signal in an issue to deterministically choose which pipeline to run, so it either over-fetches context at runtime or makes wrong routing decisions.
|
|
92
|
+
|
|
93
|
+
**Alternative approaches (not pursued):**
|
|
94
|
+
- Coordinator classifies at dispatch via LLM from prose body -- no schema required, but non-deterministic
|
|
95
|
+
- GitHub labels only -- native to GitHub UI, no body parsing, but limited to flat single-dimension taxonomy
|
|
96
|
+
- External task queue (Linear, Jira) with native structured fields synced to GitHub -- richer querying but external dependency
|
|
97
|
+
|
|
98
|
+
**Why in-body schema is best match:** deterministic routing without LLM calls at routing time, stays within GitHub, forward-compatible with richer coordinator logic.
|
|
99
|
+
|
|
100
|
+
### Stakeholders
|
|
101
|
+
|
|
102
|
+
| Stakeholder | Job / Outcome | Pain Today |
|
|
103
|
+
|-------------|---------------|------------|
|
|
104
|
+
| WorkTrain coordinator script | Read next task, decide which pipeline to run, dispatch the right workflow | No structured queue. next-up.md is prose-only; coordinator cannot read it programmatically without LLM parsing. |
|
|
105
|
+
| Human developer filing issues | Communicate "here's what needs to be done" quickly, minimal ceremony | No schema. Today: write prose in next-up.md or file raw GitHub issues. |
|
|
106
|
+
| github_issues_poll trigger | Dispatch issues with label `worktrain` to the right workflow | Labels are the only filterable field. Single trigger fires one static workflowId -- cannot vary by issue content. |
|
|
107
|
+
| Future grooming coordinator | Promote backlog items to GitHub issues, set maturity/type labels | No schema to populate; no promotion criteria defined. |
|
|
108
|
+
|
|
109
|
+
### Tensions
|
|
110
|
+
|
|
111
|
+
**T1: Richness vs. filing cost** -- A schema rich enough to route unambiguously requires 5+ fields. Every required field is a filing barrier. The minimum for routing may be just `maturity` (one field maps to three-pipeline decision). Everything else is optional enrichment.
|
|
112
|
+
|
|
113
|
+
**T2: Labels vs. body schema** -- Labels are free for the trigger (no extra API call), machine-readable, native to GitHub UI. But they can only carry enumerated values -- no URLs, no file paths. `upstream_spec` (a URL) can only live in the body. If the coordinator needs it for routing, a separate API call is required. If it only needs it at runtime (not routing), body is fine and fetched lazily by the workflow.
|
|
114
|
+
|
|
115
|
+
**T3: Schema stability vs. coordinator evolution** -- If the schema anticipates future coordinator fields (e.g. `complexity`, `auto_merge`), it encodes assumptions that may be wrong when the coordinator is built. Safer default: only include fields needed for the settled routing decision (three-pipeline choice), leave everything else unspecified.
|
|
116
|
+
|
|
117
|
+
**T4: Machine-readable vs. human-natural** -- YAML frontmatter is parseable but unusual in GitHub issues. A `## WorkTrain` metadata section is more readable but requires a custom parser. Labels are native to GitHub and require no body parsing.
|
|
118
|
+
|
|
119
|
+
### Success Criteria (refined)
|
|
120
|
+
|
|
121
|
+
1. Coordinator picks pipeline deterministically from issue metadata alone -- no LLM call at routing time
|
|
122
|
+
2. Developer can file a valid WorkTrain issue in under 2 minutes with only one truly required field
|
|
123
|
+
3. Label taxonomy covers full task lifecycle: queued -> in-progress -> done / blocked
|
|
124
|
+
4. An upstream spec URL can be expressed in the issue and found by the coding workflow's Phase 0.5 context-gather step
|
|
125
|
+
5. The design document is self-contained: a developer can file a correct issue without reading backlog.md
|
|
126
|
+
|
|
127
|
+
### HMW Questions
|
|
128
|
+
|
|
129
|
+
- **HMW make routing work with labels alone for the common case**, while supporting body-carried fields like `upstream_spec` only for the cases that need them?
|
|
130
|
+
- **HMW keep the schema minimal today** while leaving room for grooming automation to enrich issues without a schema revision?
|
|
131
|
+
|
|
132
|
+
### Primary Framing Risk
|
|
133
|
+
|
|
134
|
+
**If `upstream_spec` presence/absence is itself a routing signal (not just runtime enrichment), then body content is required for every issue at routing time, and the "labels primary, body optional" assumption is broken.**
|
|
135
|
+
|
|
136
|
+
Mitigating evidence: the Three-Workflow Pipeline ADR (Apr 18) says Phase 0.5 in the coding workflow detects the upstream spec at runtime. If Phase 0.5 detects it at runtime, it is not a routing input -- the pipeline selection happens before Phase 0.5 runs. This suggests `upstream_spec` is runtime enrichment, not a routing gate, which means labels-only pipeline selection is viable.
|
|
137
|
+
|
|
138
|
+
**Challenged assumptions:**
|
|
139
|
+
|
|
140
|
+
1. **Labels alone are sufficient** -- flat label set cannot express multi-dimensional routing (maturity x type x complexity = 12+ combinations). Coordinator could classify from prose via LLM, but that is non-deterministic. *Evidence:* `GitHubPollingSource.labelFilter` handles single-dimension routing only.
|
|
141
|
+
|
|
142
|
+
2. **YAML frontmatter is the right representation** -- GitHub gives frontmatter no special treatment; it renders as raw text. A `## Metadata` section is equally parseable and more legible. *Evidence:* `github-poller.ts` does not fetch issue body regardless of format.
|
|
143
|
+
|
|
144
|
+
3. **All 5 proposed fields are routing gates at MVP** -- The Three-Workflow Pipeline ADR identifies a single routing hinge: "small, concrete, clearly scoped" task skips discovery+shaping. The routing signal may be binary at MVP. Fields like `type`, `complexity`, and `auto_merge` are context enrichment, not pipeline-selection gates. *Evidence:* backlog.md coordinator pipeline templates derive `taskComplexity`/`riskLevel` as workflow outputs during classification, not as pre-set issue fields.
|
|
145
|
+
|
|
146
|
+
---
|
|
147
|
+
|
|
148
|
+
## Candidate Directions
|
|
149
|
+
|
|
150
|
+
### Generation Expectations (design_first + THOROUGH)
|
|
151
|
+
|
|
152
|
+
The candidate set must:
|
|
153
|
+
1. Include at least one direction that **meaningfully reframes** the problem rather than only packaging obvious solutions (e.g. "what if routing is implicit in the trigger structure, not the issue?")
|
|
154
|
+
2. Span the full format space: labels-only, body-only (frontmatter), body-only (structured section), hybrid -- each as a distinct candidate
|
|
155
|
+
3. Include at least one candidate that is the minimum viable schema (smallest possible required field set)
|
|
156
|
+
4. Cover the riskiest assumption: at least one candidate that shows what changes if `type` is required alongside `maturity`
|
|
157
|
+
5. Each candidate must explicitly state its routing mechanism (how the coordinator reads it), its required vs optional fields, and its failure mode
|
|
158
|
+
|
|
159
|
+
**Key insight (added Apr 19):** Binary routing (ready vs. not-ready) is insufficient. The coordinator needs to distinguish `idea` (full discovery+shaping+coding), `specced` (shaping+coding), and `ready` (coding only). This is three labels, not one. At least one candidate must use this three-value maturity signal.
|
|
160
|
+
|
|
161
|
+
**Risky assumption to test:** `upstream_spec` is runtime enrichment, not a routing gate. At least one candidate should show what changes if this assumption is wrong.
|
|
162
|
+
|
|
163
|
+
---
|
|
164
|
+
|
|
165
|
+
### Candidate A: Labels-only routing (minimum viable schema)
|
|
166
|
+
|
|
167
|
+
**One-sentence summary:** The issue carries one required label from a closed three-value maturity enum (`worktrain:idea`, `worktrain:specced`, `worktrain:ready`) plus the base `worktrain` queue label; all other routing fields are inferred or omitted.
|
|
168
|
+
|
|
169
|
+
**Tensions resolved / accepted:**
|
|
170
|
+
- Resolves T2 (labels free at routing -- no body API call needed)
|
|
171
|
+
- Resolves T3 (schema stability -- only the settled routing signal is in the issue)
|
|
172
|
+
- Accepts T1 (filing cost is minimal: one required label)
|
|
173
|
+
- Accepts T4 (partial: GitHub label UI is native; no custom parsing needed)
|
|
174
|
+
|
|
175
|
+
**Boundary:** the trigger's `labelFilter` catches `worktrain` issues; the coordinator reads `issue.labels[].name`, maps to `TaskMaturity = 'idea' | 'specced' | 'ready'`, dispatches pipeline. Same pattern as `ReviewSeverity` in `pr-review.ts` -- a typed discriminant derived from a raw signal.
|
|
176
|
+
|
|
177
|
+
**Failure mode:** human files an issue with no maturity label (just `worktrain`). Coordinator returns `Result<TaskMaturity, 'missing_maturity'>` -- issue is held in queue unrouted until labeled. Must be documented as required field.
|
|
178
|
+
|
|
179
|
+
**Relation to repo patterns:** follows `ReviewSeverity` / `pr-review.ts` exactly. Labels -> typed discriminant -> exhaustive switch.
|
|
180
|
+
|
|
181
|
+
**Gain:** no body API call, deterministic routing, zero coordinator complexity for body parsing, label UI is native to GitHub.
|
|
182
|
+
|
|
183
|
+
**Give up:** no machine-readable `upstream_spec` URL (must be in body prose, found by Phase 0.5 at runtime), no `type` or `complexity` signals at routing time.
|
|
184
|
+
|
|
185
|
+
**Impact surface:** coordinator implementation is simple (label lookup only). Phase 0.5 in the coding workflow already does runtime spec discovery -- `upstream_spec` does not need to be a routing input.
|
|
186
|
+
|
|
187
|
+
**Scope judgment:** best-fit. Resolves the core routing problem with the minimum machinery.
|
|
188
|
+
|
|
189
|
+
**Philosophy alignment:**
|
|
190
|
+
- Honors: Make illegal states unrepresentable (closed three-value enum), Exhaustiveness everywhere (switch on TaskMaturity), YAGNI with discipline
|
|
191
|
+
- Conflicts with: none -- this is the lean path
|
|
192
|
+
|
|
193
|
+
**Label taxonomy:**
|
|
194
|
+
```
|
|
195
|
+
worktrain -- in queue (required on all WorkTrain issues)
|
|
196
|
+
worktrain:idea -- needs discovery + shaping + coding
|
|
197
|
+
worktrain:specced -- needs shaping + coding
|
|
198
|
+
worktrain:ready -- coding only
|
|
199
|
+
worktrain:in-progress -- coordinator has dispatched a pipeline for this issue
|
|
200
|
+
worktrain:done -- pipeline completed successfully
|
|
201
|
+
worktrain:blocked -- pipeline failed or requires human attention
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
**Issue body:** free-form prose. No structured metadata required. Phase 0.5 detects `upstream_spec` from body text at runtime.
|
|
205
|
+
|
|
206
|
+
---
|
|
207
|
+
|
|
208
|
+
### Candidate B: Hybrid (maturity labels + body `## WorkTrain` section)
|
|
209
|
+
|
|
210
|
+
**One-sentence summary:** Maturity labels drive routing (same three-value enum as A); the issue body optionally carries a `## WorkTrain` metadata section with `upstream_spec`, `type`, and `complexity` fields for enriching the workflow context -- not for routing.
|
|
211
|
+
|
|
212
|
+
**Tensions resolved / accepted:**
|
|
213
|
+
- Resolves T1 (richness is possible via optional body fields without increasing required fields)
|
|
214
|
+
- Resolves T2 (routing still uses labels; body is fetched lazily only when workflow starts, not at dispatch time)
|
|
215
|
+
- Resolves T4 (body section is more readable than YAML frontmatter; parsing is straightforward `key: value` lines)
|
|
216
|
+
- Accepts T3 partial: the optional body fields are enrichment-only -- adding new fields does not break the routing contract
|
|
217
|
+
|
|
218
|
+
**Boundary:** coordinator reads labels for routing; workflow reads body section at Phase 0.5 for context enrichment. Two distinct read times and two distinct read paths.
|
|
219
|
+
|
|
220
|
+
**Failure mode:** body section present but malformed (missing colon, extra whitespace). Coordinator must treat body parsing as best-effort: `Result<Partial<IssueMetadata>, never>` (always succeeds; missing fields are `undefined`). No routing decisions can depend on body fields being well-formed.
|
|
221
|
+
|
|
222
|
+
**Relation to repo patterns:** adapts existing pattern. `contextMapping` in `TriggerDefinition` already supports dot-path extraction from webhook payload -- the body `## WorkTrain` section is analogous but requires a separate API call. Follows the 'validate at boundaries, trust inside' principle: coordinator validates label at dispatch; body fields are trusted if present.
|
|
223
|
+
|
|
224
|
+
**Gain:** human can express `upstream_spec` in the issue without embedding it in prose. `type` and `complexity` are available as context hints to the workflow. Future grooming coordinator can populate these fields programmatically.
|
|
225
|
+
|
|
226
|
+
**Give up:** body API call required before Phase 0.5 runs (coordinator or workflow must fetch body). Body parsing adds a code path that must handle malformed input. The optional fields create an implicit contract that may drift as coordinator evolves.
|
|
227
|
+
|
|
228
|
+
**Impact surface:** Phase 0.5 `context-gather` step (proposed in backlog Apr 19) would benefit from a structured `upstream_spec` field -- this candidate aligns with that spec.
|
|
229
|
+
|
|
230
|
+
**Body metadata format:**
|
|
231
|
+
```markdown
|
|
232
|
+
## WorkTrain
|
|
233
|
+
|
|
234
|
+
upstream_spec: https://docs.example.com/pitch/feature-x
|
|
235
|
+
type: feature
|
|
236
|
+
complexity: Small
|
|
237
|
+
auto_merge: false
|
|
238
|
+
```
|
|
239
|
+
|
|
240
|
+
**Scope judgment:** best-fit for teams that want to express spec URLs in a machine-readable way without external tooling. Too broad if routing never needs body fields -- then the section is dead weight.
|
|
241
|
+
|
|
242
|
+
**Philosophy alignment:**
|
|
243
|
+
- Honors: Validate at boundaries (label validation at dispatch), Prefer explicit domain types (structured section over prose hunting)
|
|
244
|
+
- Conflicts with: YAGNI with discipline -- `type`/`complexity`/`auto_merge` have no concrete coordinator use case yet
|
|
245
|
+
|
|
246
|
+
---
|
|
247
|
+
|
|
248
|
+
### Candidate C: Coordinator-inferred maturity (reframe -- no required human-set fields)
|
|
249
|
+
|
|
250
|
+
**One-sentence summary:** The issue carries only `worktrain` (queue signal); the coordinator infers maturity from the issue title, body prose, and the presence/absence of linked artifacts (PR, pitch file, spec URL) -- no maturity label required from the human filer.
|
|
251
|
+
|
|
252
|
+
**Tensions resolved / accepted:**
|
|
253
|
+
- Resolves T1 fully (zero required fields beyond `worktrain` label -- lowest possible filing cost)
|
|
254
|
+
- Accepts T2 (coordinator must fetch issue body to infer maturity -- API call required)
|
|
255
|
+
- Accepts T4 (inference is probabilistic, not deterministic -- violates 'no LLM call at routing time' criterion)
|
|
256
|
+
|
|
257
|
+
**Boundary:** coordinator fetches body, makes an LLM call to classify `TaskMaturity`, then dispatches. Similar to how `parseFindingsFromNotes()` falls back to keyword scan -- but for routing, not just severity.
|
|
258
|
+
|
|
259
|
+
**Failure mode:** LLM misclassifies maturity. An `idea` is routed to coding-only because the issue title says 'implement X' even though no spec exists. The failure mode is silent and hard to detect -- the workflow runs but produces wrong output.
|
|
260
|
+
|
|
261
|
+
**Relation to repo patterns:** departs from the established pattern. `ReviewSeverity` uses structured artifacts (preferred) or keyword scan (fallback) but NEVER routes to a different workflow based on a probabilistic classification. Using LLM inference for routing would be a new and riskier pattern.
|
|
262
|
+
|
|
263
|
+
**Gain:** lowest friction for humans filing issues. No schema to learn or enforce.
|
|
264
|
+
|
|
265
|
+
**Give up:** deterministic routing (success criterion #1). Coordinator complexity increases significantly. Testing requires mocking LLM calls. Routing behavior is unpredictable.
|
|
266
|
+
|
|
267
|
+
**Scope judgment:** too broad for MVP. May be appropriate as a fallback path (if maturity label is missing, coordinator tries to infer), but should NOT be the primary routing path.
|
|
268
|
+
|
|
269
|
+
**Philosophy alignment:**
|
|
270
|
+
- Honors: YAGNI with discipline (from the human's perspective -- no required fields)
|
|
271
|
+
- Conflicts with: Determinism over cleverness (routing depends on hidden LLM state), Make illegal states unrepresentable (maturity is inferred, not declared)
|
|
272
|
+
|
|
273
|
+
**Verdict:** viable only as a fallback path, not as the primary routing mechanism. Candidate A or B should be the primary path; C could handle the missing-label case with an LLM inference step and explicit 'routing-uncertain' log output.
|
|
274
|
+
|
|
275
|
+
*(Candidates populated below)*
|
|
276
|
+
|
|
277
|
+
See docs/design/worktrain-task-queue-candidates.md for full candidate details and tradeoff analysis.
|
|
278
|
+
|
|
279
|
+
### Summary: Candidate B (Hybrid) recommended
|
|
280
|
+
|
|
281
|
+
- **A: Labels-only** -- 3 required labels (worktrain, maturity, type), no body read, minimum viable. Routing correct. No standard location for upstream_spec.
|
|
282
|
+
- **B: Hybrid** -- same labels as A for routing + optional ## WorkTrain section in body for enrichment (upstream_spec, affected_files). Routing identical to A. Body read lazily by workflows at runtime, not by coordinator.
|
|
283
|
+
- **C: YAML frontmatter** -- all metadata in body frontmatter. Rejected: body fetch required at routing time; YAML parse failure blocks routing.
|
|
284
|
+
- **D: Three-trigger** -- one trigger per pipeline path. Rejected: GitHub Issues API labels= uses OR semantics, not AND.
|
|
285
|
+
|
|
286
|
+
**B is recommended** because routing is identical to A (label-only, no extra dispatch-time API call), but B adds a standard machine-readable location for upstream_spec consumed by Phase 0.5 of the coding workflow. The section is optional.
|
|
287
|
+
|
|
288
|
+
---
|
|
289
|
+
|
|
290
|
+
## Challenge Notes
|
|
291
|
+
|
|
292
|
+
### Challenge 1: The body section is optional but documentation will make it de-facto required
|
|
293
|
+
|
|
294
|
+
Once in the sample issue, developers will copy-paste the `## WorkTrain` section into every issue. The 'optional' label will not prevent this. A future coordinator expecting structured metadata may treat issues without the section as malformed. **Verdict:** real risk. Mitigation: sample issue must explicitly demonstrate that a label-only issue (no body section) is a valid, complete WorkTrain issue.
|
|
295
|
+
|
|
296
|
+
### Challenge 2: Convergence between two independent sessions could be group-think
|
|
297
|
+
|
|
298
|
+
Both analysis sessions recommended Candidate B. Is this genuine signal or confirmation bias from the shared design doc context? **Probe:** the prior session independently identified Candidate D (three-trigger architecture) which this session missed, and made `type` a required label rather than optional. Material differences exist between the sessions despite converging on B. **Verdict:** genuine convergence across genuinely different analyses.
|
|
299
|
+
|
|
300
|
+
### Challenge 3: Is `type` required or optional?
|
|
301
|
+
|
|
302
|
+
The prior candidates file made `type` a required label. This session classified it as optional enrichment. **Resolution:** `type` changes which phases run inside the coding workflow but does NOT change pipeline selection (maturity drives the three-pipeline decision). The coordinator does not need `type` to select a pipeline. `type` is optional enrichment. **Verdict:** prior file was slightly over-specified. `type` labels are excluded from the initial taxonomy.
|
|
303
|
+
|
|
304
|
+
### Challenge 4: Does the `## WorkTrain` section actually improve over prose?
|
|
305
|
+
|
|
306
|
+
Phase 0.5 `context-gather` already extracts any URL from the task description. If the URL is in the first line of the prose body, Phase 0.5 finds it. **Verdict:** weak benefit, but real. A consistent structured location reduces false positives from URL extraction (e.g. GitHub issue links in body that are not the upstream spec).
|
|
307
|
+
|
|
308
|
+
### Challenge 5: Should `type` labels exist at all in the initial taxonomy?
|
|
309
|
+
|
|
310
|
+
If `type` is optional and the coordinator doesn't read it, creating `worktrain:type:*` labels in GitHub adds clutter with no consumer. **Resolution:** do not create `type` labels initially. Document the convention for future use. Labels are created when the coding workflow confirms it reads them.
|
|
311
|
+
|
|
312
|
+
---
|
|
313
|
+
|
|
314
|
+
## Resolution Notes
|
|
315
|
+
|
|
316
|
+
**Selected direction: Candidate B (Hybrid)**
|
|
317
|
+
|
|
318
|
+
**Adjustments from challenge:**
|
|
319
|
+
|
|
320
|
+
1. `type` label: removed from required fields and initial label taxonomy. Document as future convention only.
|
|
321
|
+
2. Sample issue body must show a label-only issue (no `## WorkTrain` section) as a valid, complete WorkTrain issue.
|
|
322
|
+
3. Multi-label conflict resolution: if an issue has multiple maturity labels (e.g. both `worktrain:idea` and `worktrain:ready`), the lowest maturity wins (idea > specced > ready). Must be documented explicitly.
|
|
323
|
+
4. `worktrain:blocked` is coordinator-set only. Humans do not set this label. Prevents the coordinator from re-picking up a blocked issue.
|
|
324
|
+
5. `upstream_spec` is the only documented optional body field in the initial schema. All other body fields (`type`, `complexity`, `auto_merge`) are excluded until a concrete coordinator use case confirms them.
|
|
325
|
+
|
|
326
|
+
**Decision criteria satisfied:**
|
|
327
|
+
|
|
328
|
+
1. Routing is deterministic (labels only, no LLM call) -- Yes
|
|
329
|
+
2. One required field maximum (filing cost < 2 minutes) -- Yes: `worktrain` + one maturity label is all that is required
|
|
330
|
+
3. Label taxonomy covers full lifecycle without combinatorial explosion -- Yes: 7 labels total
|
|
331
|
+
4. upstream_spec expressible and findable at runtime -- Yes: via optional `## WorkTrain` section
|
|
332
|
+
5. Schema stable under coordinator evolution -- Yes: routing contract is three label values; body section is optional enrichment
|
|
333
|
+
|
|
334
|
+
---
|
|
335
|
+
|
|
336
|
+
## Decision Log
|
|
337
|
+
|
|
338
|
+
### Selected direction: Candidate B (Hybrid)
|
|
339
|
+
|
|
340
|
+
**Why B won:** Routing is identical to Candidate A (label-only, no extra API call at dispatch time). B adds a standard machine-readable location (## WorkTrain section in body) for upstream_spec -- a first-class concept in the Three-Workflow Pipeline ADR. The section is optional; issues without an upstream spec omit it.
|
|
341
|
+
|
|
342
|
+
**Why A lost:** No standard location for upstream_spec. Developers with a spec put the URL in prose where Phase 0.5 must LLM-search for it. The ## WorkTrain section provides a deterministic, parseable location for the coordinator-injection use case.
|
|
343
|
+
|
|
344
|
+
**Challenges that failed to overturn B:**
|
|
345
|
+
1. Section formatting drift -- mitigated by optional nature and single-field simplicity
|
|
346
|
+
2. Type is over-required for ready issues -- valid but not blocking; uniform contract simplifies docs
|
|
347
|
+
3. Phase 0.5 already finds specs without the section -- resolved by the coordinator-injection use case that needs deterministic extraction
|
|
348
|
+
|
|
349
|
+
**Accepted tradeoffs:**
|
|
350
|
+
- Optional body section adds documentation weight; ~10-15% of issues will use it
|
|
351
|
+
- Body content fetched by workflows at runtime, not at routing time
|
|
352
|
+
|
|
353
|
+
**Identified failure modes:**
|
|
354
|
+
- Human omits required label: coordinator logs warning, skips or falls back to full pipeline
|
|
355
|
+
- Malformed ## WorkTrain section: Phase 0.5 falls back to format-agnostic search
|
|
356
|
+
- upstream_spec is a routing signal (not enrichment): would require schema revision
|
|
357
|
+
|
|
358
|
+
**Switch trigger:** If coordinator telemetry shows Phase 0.5 reliably finds upstream specs without the section, simplify to Candidate A.
|
|
359
|
+
|
|
360
|
+
---
|
|
361
|
+
|
|
362
|
+
## Final Summary
|
|
363
|
+
|
|
364
|
+
### Recommendation: Candidate B (Hybrid schema)
|
|
365
|
+
|
|
366
|
+
**Confidence band: high**
|
|
367
|
+
|
|
368
|
+
**Direction:** GitHub issues in the WorkTrain queue use labels for routing and an optional `## WorkTrain` body section for enrichment. Routing is deterministic (no LLM call). The body section is optional and never a routing gate.
|
|
369
|
+
|
|
370
|
+
### Minimum viable schema
|
|
371
|
+
|
|
372
|
+
**Required labels (routing signals):**
|
|
373
|
+
- `worktrain` -- marks issue as in the WorkTrain queue
|
|
374
|
+
- `worktrain:idea` OR `worktrain:specced` OR `worktrain:ready` -- maturity signal (exactly one required)
|
|
375
|
+
|
|
376
|
+
**Lifecycle labels (coordinator-managed):**
|
|
377
|
+
- `worktrain:in-progress` -- coordinator has dispatched a pipeline
|
|
378
|
+
- `worktrain:done` -- pipeline completed successfully
|
|
379
|
+
- `worktrain:blocked` -- pipeline failed or requires human attention (coordinator-set only)
|
|
380
|
+
- `worktrain:needs-labels` -- required maturity label is missing (coordinator-set; issue is not dispatched)
|
|
381
|
+
|
|
382
|
+
**Extension label (documented for future use):**
|
|
383
|
+
- `worktrain:has-spec` -- an upstream spec exists in the issue body (escape valve if spec presence/absence ever becomes a routing signal)
|
|
384
|
+
|
|
385
|
+
**Optional body section (enrichment, not routing):**
|
|
386
|
+
```markdown
|
|
387
|
+
## WorkTrain
|
|
388
|
+
|
|
389
|
+
upstream_spec: https://docs.example.com/pitch-feature-x
|
|
390
|
+
```
|
|
391
|
+
|
|
392
|
+
The `## WorkTrain` section header is frozen after v1. `upstream_spec` must be a valid http/https URL. Issues without the section are fully valid WorkTrain issues.
|
|
393
|
+
|
|
394
|
+
### Routing table
|
|
395
|
+
|
|
396
|
+
| Maturity label | Pipeline |
|
|
397
|
+
|----------------|----------|
|
|
398
|
+
| `worktrain:idea` | `wr.discovery` -> `wr.shaping` -> `coding-task-workflow-agentic` |
|
|
399
|
+
| `worktrain:specced` | `wr.shaping` -> `coding-task-workflow-agentic` |
|
|
400
|
+
| `worktrain:ready` | `coding-task-workflow-agentic` (Phase 0.5 searches for upstream spec at runtime) |
|
|
401
|
+
| (no maturity label) | Add `worktrain:needs-labels`, skip dispatch, emit structured log entry |
|
|
402
|
+
|
|
403
|
+
**Multi-label conflict rule:** if multiple maturity labels are present (e.g. both `worktrain:idea` and `worktrain:ready`), the lowest maturity wins (idea > specced > ready). Coordinator logs a warning.
|
|
404
|
+
|
|
405
|
+
### Coordinator behavior on missing required label
|
|
406
|
+
|
|
407
|
+
If the maturity label is absent: coordinator adds `worktrain:needs-labels` label to the issue, skips dispatch, and emits a structured log entry. No silent failure. No default routing.
|
|
408
|
+
|
|
409
|
+
### Sample issue body
|
|
410
|
+
|
|
411
|
+
```markdown
|
|
412
|
+
<!-- A complete WorkTrain issue with only a title and maturity label is valid.
|
|
413
|
+
The ## WorkTrain section below is optional. Use it when you have an external spec URL. -->
|
|
414
|
+
|
|
415
|
+
Implement rate limiting for the daemon polling scheduler
|
|
416
|
+
|
|
417
|
+
The scheduler currently has no back-off on API errors. When GitHub returns 429,
|
|
418
|
+
the scheduler should implement exponential back-off with a maximum delay of 5 minutes.
|
|
419
|
+
|
|
420
|
+
## WorkTrain
|
|
421
|
+
|
|
422
|
+
upstream_spec: https://docs.internal.example.com/specs/daemon-rate-limiting
|
|
423
|
+
```
|
|
424
|
+
|
|
425
|
+
Labels on this issue: `worktrain`, `worktrain:ready`
|
|
426
|
+
|
|
427
|
+
A label-only version (no body section) is equally valid:
|
|
428
|
+
```
|
|
429
|
+
Labels: worktrain, worktrain:specced
|
|
430
|
+
Body: <prose description only, no ## WorkTrain section>
|
|
431
|
+
```
|
|
432
|
+
|
|
433
|
+
### Residual risks
|
|
434
|
+
|
|
435
|
+
1. **Coordinator does not yet exist.** The schema is designed before its primary consumer. Maturity values may need more nuance when a real coordinator is built. If a new maturity value is needed (e.g. `groomed`), adding a label is backward-compatible for existing issues.
|
|
436
|
+
|
|
437
|
+
2. **`worktrain:` namespace is informal.** This design doc is the authoritative registry for `worktrain:` labels. Do not create labels with this prefix for other purposes.
|
|
438
|
+
|
|
439
|
+
3. **upstream_spec as a routing gate.** If the product team later decides 'ready without an upstream spec => run wr.shaping first', the coordinator must start fetching the body at routing time. The `worktrain:has-spec` label is the escape valve: set it at filing time or by a grooming coordinator, avoiding the body fetch at routing time.
|
|
440
|
+
|
|
441
|
+
### Switch to Candidate A condition
|
|
442
|
+
|
|
443
|
+
If coordinator telemetry shows Phase 0.5 reliably finds upstream specs via format-agnostic prose search (i.e. the `## WorkTrain` section is never used), simplify to Candidate A (labels-only): remove the body section from the schema documentation and sample.
|