@exaudeus/workrail 3.67.0 → 3.68.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/application/services/compiler/template-registry.js +10 -1
- package/dist/cli/commands/worktrain-init.js +1 -1
- package/dist/console-ui/assets/{index-tOl8Vowf.js → index-DPdRJHMX.js} +1 -1
- package/dist/console-ui/index.html +1 -1
- package/dist/coordinators/modes/full-pipeline.js +4 -4
- package/dist/coordinators/modes/implement-shared.js +5 -5
- package/dist/coordinators/modes/implement.js +4 -4
- package/dist/coordinators/pr-review.js +4 -4
- package/dist/daemon/workflow-runner.d.ts +1 -0
- package/dist/daemon/workflow-runner.js +1 -0
- package/dist/manifest.json +31 -31
- package/dist/mcp/handlers/v2-context-budget.js +18 -0
- package/dist/mcp/handlers/v2-workflow.js +1 -1
- package/dist/mcp/workflow-protocol-contracts.js +2 -2
- package/dist/v2/durable-core/constants.d.ts +2 -0
- package/dist/v2/durable-core/constants.js +2 -1
- package/dist/v2/projections/session-metrics.js +1 -1
- package/docs/authoring-v2.md +4 -4
- package/docs/changelog-recent.md +3 -3
- package/docs/configuration.md +1 -1
- package/docs/design/adaptive-coordinator-context-candidates.md +1 -1
- package/docs/design/adaptive-coordinator-context.md +1 -1
- package/docs/design/adaptive-coordinator-routing-candidates.md +18 -18
- package/docs/design/adaptive-coordinator-routing-review.md +1 -1
- package/docs/design/adaptive-coordinator-routing.md +34 -34
- package/docs/design/agent-cascade-protocol.md +2 -2
- package/docs/design/console-daemon-separation-discovery.md +323 -0
- package/docs/design/context-assembly-design-candidates.md +1 -1
- package/docs/design/context-assembly-implementation-plan.md +1 -1
- package/docs/design/context-assembly-layer.md +2 -2
- package/docs/design/context-assembly-review-findings.md +1 -1
- package/docs/design/coordinator-access-audit.md +293 -0
- package/docs/design/coordinator-architecture-audit.md +62 -0
- package/docs/design/coordinator-error-handling-audit.md +240 -0
- package/docs/design/coordinator-testability-audit.md +426 -0
- package/docs/design/daemon-architecture-discovery.md +1 -1
- package/docs/design/daemon-console-separation-discovery.md +242 -0
- package/docs/design/daemon-memory-audit.md +203 -0
- package/docs/design/design-candidates-console-daemon-separation.md +256 -0
- package/docs/design/design-candidates-discovery-loop-fix.md +141 -0
- package/docs/design/design-review-findings-console-daemon-separation.md +106 -0
- package/docs/design/design-review-findings-discovery-loop-fix.md +81 -0
- package/docs/design/discovery-loop-fix-candidates.md +161 -0
- package/docs/design/discovery-loop-fix-design-review.md +106 -0
- package/docs/design/discovery-loop-fix-validation.md +258 -0
- package/docs/design/discovery-loop-investigation-A.md +188 -0
- package/docs/design/discovery-loop-investigation-B.md +287 -0
- package/docs/design/exploration-workflow-candidates.md +205 -0
- package/docs/design/exploration-workflow-design-review.md +166 -0
- package/docs/design/exploration-workflow-discovery.md +443 -0
- package/docs/design/ide-context-files-candidates.md +231 -0
- package/docs/design/ide-context-files-design-review.md +85 -0
- package/docs/design/ide-context-files.md +615 -0
- package/docs/design/implementation-plan-discovery-loop-fix.md +199 -0
- package/docs/design/implementation-plan-queue-poll-rotation.md +102 -0
- package/docs/design/in-process-http-audit.md +190 -0
- package/docs/design/layer3b-ghost-nodes-design-candidates.md +2 -2
- package/docs/design/loadSessionNotes-candidates.md +108 -0
- package/docs/design/loadSessionNotes-test-coverage-discovery.md +297 -0
- package/docs/design/loadSessionNotes-test-coverage-session4.md +209 -0
- package/docs/design/loadSessionNotes-test-coverage-v3.md +321 -0
- package/docs/design/probe-session-design-candidates.md +261 -0
- package/docs/design/probe-session-phase0.md +490 -0
- package/docs/design/routines-guide.md +7 -7
- package/docs/design/session-metrics-attribution-candidates.md +250 -0
- package/docs/design/session-metrics-attribution-design-review.md +115 -0
- package/docs/design/session-metrics-attribution-discovery.md +319 -0
- package/docs/design/session-metrics-candidates.md +227 -0
- package/docs/design/session-metrics-design-review.md +104 -0
- package/docs/design/session-metrics-discovery.md +454 -0
- package/docs/design/spawn-session-debug.md +202 -0
- package/docs/design/trigger-validator-candidates.md +214 -0
- package/docs/design/trigger-validator-review.md +109 -0
- package/docs/design/trigger-validator-shaping-phase0.md +239 -0
- package/docs/design/trigger-validator.md +454 -0
- package/docs/design/v2-core-design-locks.md +2 -2
- package/docs/design/workflow-extension-points.md +15 -15
- package/docs/design/workflow-id-validation-at-startup.md +1 -1
- package/docs/design/workflow-id-validation-implementation-plan.md +2 -2
- package/docs/design/workflow-trigger-lifecycle-audit.md +175 -0
- package/docs/design/worktrain-task-queue-candidates.md +5 -5
- package/docs/design/worktrain-task-queue.md +4 -4
- package/docs/discovery/coordinator-script-design.md +1 -1
- package/docs/discovery/coordinator-ux-discovery.md +3 -3
- package/docs/discovery/simulation-report.md +1 -1
- package/docs/discovery/workflow-modernization-discovery.md +326 -0
- package/docs/discovery/workflow-selection-for-discovery-tasks.md +33 -33
- package/docs/discovery/worktrain-status-briefing.md +1 -1
- package/docs/discovery/wr-discovery-goal-reframing.md +1 -1
- package/docs/docker.md +1 -1
- package/docs/ideas/backlog.md +227 -0
- package/docs/ideas/third-party-workflow-setup-design-thinking.md +1 -1
- package/docs/integrations/claude-code.md +5 -5
- package/docs/integrations/firebender.md +1 -1
- package/docs/plans/agentic-orchestration-roadmap.md +2 -2
- package/docs/plans/mr-review-workflow-redesign.md +9 -9
- package/docs/plans/ui-ux-workflow-design-candidates.md +4 -4
- package/docs/plans/ui-ux-workflow-discovery.md +2 -2
- package/docs/plans/workflow-categories-candidates.md +8 -8
- package/docs/plans/workflow-categories-discovery.md +4 -4
- package/docs/plans/workflow-modernization-design.md +430 -0
- package/docs/plans/workflow-staleness-detection-candidates.md +11 -11
- package/docs/plans/workflow-staleness-detection-review.md +4 -4
- package/docs/plans/workflow-staleness-detection.md +9 -9
- package/docs/plans/workrail-platform-vision.md +3 -3
- package/docs/reference/agent-context-cleaner-snippet.md +1 -1
- package/docs/reference/agent-context-guidance.md +4 -4
- package/docs/reference/context-optimization.md +2 -2
- package/docs/roadmap/now-next-later.md +2 -2
- package/docs/roadmap/open-work-inventory.md +16 -16
- package/docs/workflows.md +31 -31
- package/package.json +1 -1
- package/spec/workflow-tags.json +47 -47
- package/workflows/adaptive-ticket-creation.json +16 -16
- package/workflows/architecture-scalability-audit.json +22 -22
- package/workflows/bug-investigation.agentic.v2.json +3 -3
- package/workflows/classify-task-workflow.json +1 -1
- package/workflows/coding-task-workflow-agentic.json +6 -6
- package/workflows/cross-platform-code-conversion.v2.json +8 -8
- package/workflows/document-creation-workflow.json +8 -8
- package/workflows/documentation-update-workflow.json +8 -8
- package/workflows/intelligent-test-case-generation.json +2 -2
- package/workflows/learner-centered-course-workflow.json +2 -2
- package/workflows/mr-review-workflow.agentic.v2.json +4 -4
- package/workflows/personal-learning-materials-creation-branched.json +8 -8
- package/workflows/presentation-creation.json +5 -5
- package/workflows/production-readiness-audit.json +1 -1
- package/workflows/relocation-workflow-us.json +31 -31
- package/workflows/routines/context-gathering.json +1 -1
- package/workflows/routines/design-review.json +1 -1
- package/workflows/routines/execution-simulation.json +1 -1
- package/workflows/routines/feature-implementation.json +3 -3
- package/workflows/routines/final-verification.json +1 -1
- package/workflows/routines/hypothesis-challenge.json +1 -1
- package/workflows/routines/ideation.json +1 -1
- package/workflows/routines/parallel-work-partitioning.json +3 -3
- package/workflows/routines/philosophy-alignment.json +2 -2
- package/workflows/routines/plan-analysis.json +1 -1
- package/workflows/routines/plan-generation.json +1 -1
- package/workflows/routines/tension-driven-design.json +6 -6
- package/workflows/scoped-documentation-workflow.json +26 -26
- package/workflows/ui-ux-design-workflow.json +14 -14
- package/workflows/workflow-diagnose-environment.json +1 -1
- package/workflows/workflow-for-workflows.json +1 -1
|
@@ -15,7 +15,7 @@ async function runReviewAndVerdictCycle(deps, opts, prUrl, coordinatorStartMs, i
|
|
|
15
15
|
? `Review PR for merge: ${prUrl}`
|
|
16
16
|
: `Re-review PR after fixes (iteration ${iteration}): ${prUrl}`;
|
|
17
17
|
deps.stderr(`[review-cycle] Spawning review session (iteration=${iteration}): ${reviewGoal.slice(0, 80)}`);
|
|
18
|
-
const reviewSpawnResult = await deps.spawnSession('mr-review
|
|
18
|
+
const reviewSpawnResult = await deps.spawnSession('wr.mr-review', reviewGoal, opts.workspace, { prUrl });
|
|
19
19
|
if (reviewSpawnResult.kind === 'err') {
|
|
20
20
|
return {
|
|
21
21
|
kind: 'escalated',
|
|
@@ -86,7 +86,7 @@ async function runReviewAndVerdictCycle(deps, opts, prUrl, coordinatorStartMs, i
|
|
|
86
86
|
if (fixCutoff)
|
|
87
87
|
return fixCutoff;
|
|
88
88
|
const fixGoal = `Fix review findings: ${findings.findingSummaries.slice(0, 3).join('; ')}`;
|
|
89
|
-
const fixSpawnResult = await deps.spawnSession('coding-task
|
|
89
|
+
const fixSpawnResult = await deps.spawnSession('wr.coding-task', fixGoal, opts.workspace, { prUrl, findings: findings.findingSummaries });
|
|
90
90
|
if (fixSpawnResult.kind === 'err') {
|
|
91
91
|
return {
|
|
92
92
|
kind: 'escalated',
|
|
@@ -124,8 +124,8 @@ async function runAuditChain(deps, opts, prUrl, coordinatorStartMs, severity, fi
|
|
|
124
124
|
if (auditCutoff)
|
|
125
125
|
return auditCutoff;
|
|
126
126
|
const auditWorkflow = findings?.some((f) => f.findingCategory === 'architecture')
|
|
127
|
-
? 'architecture-scalability-audit'
|
|
128
|
-
: 'production-readiness-audit';
|
|
127
|
+
? 'wr.architecture-scalability-audit'
|
|
128
|
+
: 'wr.production-readiness-audit';
|
|
129
129
|
const auditSpawnResult = await deps.spawnSession(auditWorkflow, `Audit PR before merge: ${prUrl}`, opts.workspace, { prUrl, severity });
|
|
130
130
|
if (auditSpawnResult.kind === 'err') {
|
|
131
131
|
try {
|
|
@@ -171,7 +171,7 @@ async function runAuditChain(deps, opts, prUrl, coordinatorStartMs, severity, fi
|
|
|
171
171
|
const reReviewCutoff = (0, adaptive_pipeline_js_1.checkSpawnCutoff)(coordinatorStartMs, deps.now(), 're-review-after-audit');
|
|
172
172
|
if (reReviewCutoff)
|
|
173
173
|
return reReviewCutoff;
|
|
174
|
-
const reReviewSpawnResult = await deps.spawnSession('mr-review
|
|
174
|
+
const reReviewSpawnResult = await deps.spawnSession('wr.mr-review', `Re-review after audit: ${prUrl}`, opts.workspace, { prUrl, auditComplete: true });
|
|
175
175
|
if (reReviewSpawnResult.kind === 'err') {
|
|
176
176
|
try {
|
|
177
177
|
await deps.postToOutbox(`Adaptive pipeline escalated: re-review after audit failed to spawn`, { prUrl, phase: 're-review-after-audit', reason: reReviewSpawnResult.error });
|
|
@@ -35,11 +35,11 @@ async function runImplementPipeline(deps, opts, pitchPath, coordinatorStartMs) {
|
|
|
35
35
|
}
|
|
36
36
|
async function runImplementCore(deps, opts, pitchPath, coordinatorStartMs) {
|
|
37
37
|
if (touchesUI(opts.goal)) {
|
|
38
|
-
deps.stderr(`[implement] UX signals detected in goal, dispatching ui-ux-design
|
|
38
|
+
deps.stderr(`[implement] UX signals detected in goal, dispatching wr.ui-ux-design`);
|
|
39
39
|
const cutoffCheck = (0, adaptive_pipeline_js_1.checkSpawnCutoff)(coordinatorStartMs, deps.now(), 'ux-gate');
|
|
40
40
|
if (cutoffCheck)
|
|
41
41
|
return cutoffCheck;
|
|
42
|
-
const uxSpawnResult = await deps.spawnSession('ui-ux-design
|
|
42
|
+
const uxSpawnResult = await deps.spawnSession('wr.ui-ux-design', opts.goal, opts.workspace, {
|
|
43
43
|
pitchPath,
|
|
44
44
|
});
|
|
45
45
|
if (uxSpawnResult.kind === 'err') {
|
|
@@ -70,8 +70,8 @@ async function runImplementCore(deps, opts, pitchPath, coordinatorStartMs) {
|
|
|
70
70
|
const cutoffCheck = (0, adaptive_pipeline_js_1.checkSpawnCutoff)(coordinatorStartMs, deps.now(), 'coding');
|
|
71
71
|
if (cutoffCheck)
|
|
72
72
|
return cutoffCheck;
|
|
73
|
-
deps.stderr(`[implement] Spawning coding-task
|
|
74
|
-
const codingSpawnResult = await deps.spawnSession('coding-task
|
|
73
|
+
deps.stderr(`[implement] Spawning wr.coding-task`);
|
|
74
|
+
const codingSpawnResult = await deps.spawnSession('wr.coding-task', opts.goal, opts.workspace, {
|
|
75
75
|
pitchPath,
|
|
76
76
|
});
|
|
77
77
|
if (codingSpawnResult.kind === 'err') {
|
|
@@ -383,7 +383,7 @@ async function runPrReviewCoordinator(deps, opts) {
|
|
|
383
383
|
for (const pr of prs) {
|
|
384
384
|
const goal = `Review PR #${pr.number} "${pr.title}" before merge`;
|
|
385
385
|
if (opts.dryRun) {
|
|
386
|
-
log(` PR #${pr.number} [dry-run] would spawn mr-review
|
|
386
|
+
log(` PR #${pr.number} [dry-run] would spawn wr.mr-review`);
|
|
387
387
|
continue;
|
|
388
388
|
}
|
|
389
389
|
let spawnContext;
|
|
@@ -405,7 +405,7 @@ async function runPrReviewCoordinator(deps, opts) {
|
|
|
405
405
|
deps.stderr(`[WARN coord:context prNumber=${pr.number}] priorSessionNotes failed: ${bundle.priorSessionNotes.error}`);
|
|
406
406
|
}
|
|
407
407
|
}
|
|
408
|
-
const spawnResult = await deps.spawnSession('mr-review
|
|
408
|
+
const spawnResult = await deps.spawnSession('wr.mr-review', goal, opts.workspace, spawnContext);
|
|
409
409
|
if (spawnResult.kind === 'err') {
|
|
410
410
|
spawnErrors.set(pr.number, spawnResult.error);
|
|
411
411
|
log(` PR #${pr.number} spawn failed: ${spawnResult.error}`);
|
|
@@ -589,7 +589,7 @@ async function runFixAgentLoop(deps, opts, pr, initialFindings, initialOutcome,
|
|
|
589
589
|
};
|
|
590
590
|
}
|
|
591
591
|
log(` PR #${pr.number} -> spawning fix agent (pass ${passCount})...`);
|
|
592
|
-
const fixSpawnResult = await deps.spawnSession('coding-task
|
|
592
|
+
const fixSpawnResult = await deps.spawnSession('wr.coding-task', fixGoal, opts.workspace);
|
|
593
593
|
if (fixSpawnResult.kind === 'err') {
|
|
594
594
|
log(` PR #${pr.number} -> fix agent spawn failed: ${fixSpawnResult.error}`);
|
|
595
595
|
return {
|
|
@@ -636,7 +636,7 @@ async function runFixAgentLoop(deps, opts, pr, initialFindings, initialOutcome,
|
|
|
636
636
|
};
|
|
637
637
|
}
|
|
638
638
|
const reReviewGoal = `Re-review PR #${pr.number} after fixes (pass ${passCount})`;
|
|
639
|
-
const reReviewSpawnResult = await deps.spawnSession('mr-review
|
|
639
|
+
const reReviewSpawnResult = await deps.spawnSession('wr.mr-review', reReviewGoal, opts.workspace, reviewSpawnContext);
|
|
640
640
|
if (reReviewSpawnResult.kind === 'err') {
|
|
641
641
|
log(` PR #${pr.number} -> re-review spawn failed: ${reReviewSpawnResult.error}`);
|
|
642
642
|
return {
|
|
@@ -107,6 +107,7 @@ export declare function countOrphanStepAdvances(continueToken: string, ctx: V2To
|
|
|
107
107
|
export declare function clearQueueIssueSidecars(sessionsDir: string): Promise<void>;
|
|
108
108
|
export declare function stripFrontmatter(content: string): string;
|
|
109
109
|
export declare function loadWorkspaceContext(workspacePath: string): Promise<string | null>;
|
|
110
|
+
export declare function loadSessionNotes(continueToken: string, ctx: V2ToolContext): Promise<readonly string[]>;
|
|
110
111
|
export declare function makeContinueWorkflowTool(sessionId: string, ctx: V2ToolContext, onAdvance: (nextStepText: string, continueToken: string) => void, onComplete: (notes: string | undefined, artifacts?: readonly unknown[]) => void, schemas: Record<string, any>, _executeContinueWorkflowFn?: typeof executeContinueWorkflow, emitter?: DaemonEventEmitter, workrailSessionId?: string | null): AgentTool;
|
|
111
112
|
export declare function makeCompleteStepTool(sessionId: string, ctx: V2ToolContext, getCurrentToken: () => string, onAdvance: (nextStepText: string, continueToken: string) => void, onComplete: (notes: string | undefined, artifacts?: readonly unknown[]) => void, onTokenUpdate: (t: string) => void, schemas: Record<string, any>, _executeContinueWorkflowFn?: typeof executeContinueWorkflow, emitter?: DaemonEventEmitter, workrailSessionId?: string | null): AgentTool;
|
|
112
113
|
export declare function makeBashTool(workspacePath: string, schemas: Record<string, any>, sessionId?: string, emitter?: DaemonEventEmitter, workrailSessionId?: string | null): AgentTool;
|
|
@@ -44,6 +44,7 @@ exports.countOrphanStepAdvances = countOrphanStepAdvances;
|
|
|
44
44
|
exports.clearQueueIssueSidecars = clearQueueIssueSidecars;
|
|
45
45
|
exports.stripFrontmatter = stripFrontmatter;
|
|
46
46
|
exports.loadWorkspaceContext = loadWorkspaceContext;
|
|
47
|
+
exports.loadSessionNotes = loadSessionNotes;
|
|
47
48
|
exports.makeContinueWorkflowTool = makeContinueWorkflowTool;
|
|
48
49
|
exports.makeCompleteStepTool = makeCompleteStepTool;
|
|
49
50
|
exports.makeBashTool = makeBashTool;
|
package/dist/manifest.json
CHANGED
|
@@ -86,8 +86,8 @@
|
|
|
86
86
|
"bytes": 1168
|
|
87
87
|
},
|
|
88
88
|
"application/services/compiler/template-registry.js": {
|
|
89
|
-
"sha256": "
|
|
90
|
-
"bytes":
|
|
89
|
+
"sha256": "6df7c3b29f7eb62459e86bbafc7d279e19e95d363e820ca46ddb3e4daba6951b",
|
|
90
|
+
"bytes": 5453
|
|
91
91
|
},
|
|
92
92
|
"application/services/enhanced-error-service.d.ts": {
|
|
93
93
|
"sha256": "b6fe8fad92717f0962f87aa9c0f88277bf28fe2b5e3cfd7875612ee57eb8c684",
|
|
@@ -358,8 +358,8 @@
|
|
|
358
358
|
"bytes": 1041
|
|
359
359
|
},
|
|
360
360
|
"cli/commands/worktrain-init.js": {
|
|
361
|
-
"sha256": "
|
|
362
|
-
"bytes":
|
|
361
|
+
"sha256": "726d5b3a6252bf25d99fa53445ec543ea7e8c3d020a845c0b13c08182876fdb9",
|
|
362
|
+
"bytes": 12514
|
|
363
363
|
},
|
|
364
364
|
"cli/commands/worktrain-overview.d.ts": {
|
|
365
365
|
"sha256": "d9cb907b57aaa19ee5654c1726a33cdc6b7a54e3bd24dd8f2900d18491dd94a3",
|
|
@@ -477,12 +477,12 @@
|
|
|
477
477
|
"sha256": "40290b50e21ee7e82433efe13b1aa31c1ea608bd057a5c4e324982f284bc928b",
|
|
478
478
|
"bytes": 60673
|
|
479
479
|
},
|
|
480
|
-
"console-ui/assets/index-
|
|
481
|
-
"sha256": "
|
|
480
|
+
"console-ui/assets/index-DPdRJHMX.js": {
|
|
481
|
+
"sha256": "5d77b82c529f8adaf1ce398dbab3a2c9a74d4f3e0cb59318f13967d2b659aa5f",
|
|
482
482
|
"bytes": 767983
|
|
483
483
|
},
|
|
484
484
|
"console-ui/index.html": {
|
|
485
|
-
"sha256": "
|
|
485
|
+
"sha256": "e9b7fc1c2488485be8d965ba96d0ce2e29c1b59b7fdd09d194625341120ec404",
|
|
486
486
|
"bytes": 417
|
|
487
487
|
},
|
|
488
488
|
"console/standalone-console.d.ts": {
|
|
@@ -538,24 +538,24 @@
|
|
|
538
538
|
"bytes": 462
|
|
539
539
|
},
|
|
540
540
|
"coordinators/modes/full-pipeline.js": {
|
|
541
|
-
"sha256": "
|
|
542
|
-
"bytes":
|
|
541
|
+
"sha256": "040b412e33ecb46dcc27c9968c9c0cc5d416880a03dab6f93ed09b8f447c21aa",
|
|
542
|
+
"bytes": 13161
|
|
543
543
|
},
|
|
544
544
|
"coordinators/modes/implement-shared.d.ts": {
|
|
545
545
|
"sha256": "fbad9d91d84d2112b273175618686489a7f106385e0e62d6cab80804d6d0f2d7",
|
|
546
546
|
"bytes": 708
|
|
547
547
|
},
|
|
548
548
|
"coordinators/modes/implement-shared.js": {
|
|
549
|
-
"sha256": "
|
|
550
|
-
"bytes":
|
|
549
|
+
"sha256": "96f95d9fca1c511eb1b12247148d0e0de3dd3add5aacd72e2a8bba4b36f5995b",
|
|
550
|
+
"bytes": 13636
|
|
551
551
|
},
|
|
552
552
|
"coordinators/modes/implement.d.ts": {
|
|
553
553
|
"sha256": "23919c24d62a0bf15296a52fbc594cca8b1b34e6f8d98dcf7dede8d97ad4cabb",
|
|
554
554
|
"bytes": 347
|
|
555
555
|
},
|
|
556
556
|
"coordinators/modes/implement.js": {
|
|
557
|
-
"sha256": "
|
|
558
|
-
"bytes":
|
|
557
|
+
"sha256": "59b0dddf00587db1d565c1e460cdad1f75b4ca32687e3649452b0f4de90a3061",
|
|
558
|
+
"bytes": 5482
|
|
559
559
|
},
|
|
560
560
|
"coordinators/modes/quick-review.d.ts": {
|
|
561
561
|
"sha256": "03a4f29a07047b0bf788d84f8e0ebab63d64c8eb98aa57087943a8fb84563998",
|
|
@@ -578,8 +578,8 @@
|
|
|
578
578
|
"bytes": 3947
|
|
579
579
|
},
|
|
580
580
|
"coordinators/pr-review.js": {
|
|
581
|
-
"sha256": "
|
|
582
|
-
"bytes":
|
|
581
|
+
"sha256": "385baa9e6252dbd84060bb423ce219884d519752f4a6e9f8f04e5f503fa38b67",
|
|
582
|
+
"bytes": 32419
|
|
583
583
|
},
|
|
584
584
|
"coordinators/routing/route-task.d.ts": {
|
|
585
585
|
"sha256": "6661d21e5cfbc9dffbfd8c2f9aaaf0e30a3251997a2c69c6a1b09929343e30e3",
|
|
@@ -654,12 +654,12 @@
|
|
|
654
654
|
"bytes": 5921
|
|
655
655
|
},
|
|
656
656
|
"daemon/workflow-runner.d.ts": {
|
|
657
|
-
"sha256": "
|
|
658
|
-
"bytes":
|
|
657
|
+
"sha256": "eba5089ec9210f27a06dc1c3fc89804de4d77208fad7678df2ad824c4511636f",
|
|
658
|
+
"bytes": 8227
|
|
659
659
|
},
|
|
660
660
|
"daemon/workflow-runner.js": {
|
|
661
|
-
"sha256": "
|
|
662
|
-
"bytes":
|
|
661
|
+
"sha256": "b11fb90d06e7d2f45b76e05640475615295de4eadb89c0c3d1c18ed48d6d0cb4",
|
|
662
|
+
"bytes": 101462
|
|
663
663
|
},
|
|
664
664
|
"di/container.d.ts": {
|
|
665
665
|
"sha256": "003bb7fb7478d627524b9b1e76bd0a963a243794a687ff233b96dc0e33a06d9f",
|
|
@@ -1106,8 +1106,8 @@
|
|
|
1106
1106
|
"bytes": 674
|
|
1107
1107
|
},
|
|
1108
1108
|
"mcp/handlers/v2-context-budget.js": {
|
|
1109
|
-
"sha256": "
|
|
1110
|
-
"bytes":
|
|
1109
|
+
"sha256": "e27121c84449f8bdcbcd37a242db54c1afda4a14bc6bc50e148aaf96fecd45b3",
|
|
1110
|
+
"bytes": 8181
|
|
1111
1111
|
},
|
|
1112
1112
|
"mcp/handlers/v2-error-mapping.d.ts": {
|
|
1113
1113
|
"sha256": "4522217a754afc6a2ee3834368decb7fb22ebf9d4c72fc0de9890903d652d76c",
|
|
@@ -1234,8 +1234,8 @@
|
|
|
1234
1234
|
"bytes": 4343
|
|
1235
1235
|
},
|
|
1236
1236
|
"mcp/handlers/v2-workflow.js": {
|
|
1237
|
-
"sha256": "
|
|
1238
|
-
"bytes":
|
|
1237
|
+
"sha256": "4b12fcb52c80bf2b141c99921d2ddae92da2f543ae65abc5035c0b794bd777b6",
|
|
1238
|
+
"bytes": 28078
|
|
1239
1239
|
},
|
|
1240
1240
|
"mcp/handlers/v2-workspace-resolution.d.ts": {
|
|
1241
1241
|
"sha256": "dd4de57b4918ebe749cf8c1df70c02bf1effc50932634bae60db53c9a157e872",
|
|
@@ -1514,8 +1514,8 @@
|
|
|
1514
1514
|
"bytes": 1863
|
|
1515
1515
|
},
|
|
1516
1516
|
"mcp/workflow-protocol-contracts.js": {
|
|
1517
|
-
"sha256": "
|
|
1518
|
-
"bytes":
|
|
1517
|
+
"sha256": "bcd0a058385ab23d2ff550267bfc88ac06b5d89ed2d773086a3cf83431a86c4f",
|
|
1518
|
+
"bytes": 14344
|
|
1519
1519
|
},
|
|
1520
1520
|
"mcp/workflow-tool-edition-selector.d.ts": {
|
|
1521
1521
|
"sha256": "75194908a89aaf7dc48fb661aea099827e7032ec76daf8f2de91bd59d46764ef",
|
|
@@ -1894,12 +1894,12 @@
|
|
|
1894
1894
|
"bytes": 447
|
|
1895
1895
|
},
|
|
1896
1896
|
"v2/durable-core/constants.d.ts": {
|
|
1897
|
-
"sha256": "
|
|
1898
|
-
"bytes":
|
|
1897
|
+
"sha256": "14b721867f0866a9a2955b19f16868c39394e80dce2bd94021e6e7f6b4f62429",
|
|
1898
|
+
"bytes": 4159
|
|
1899
1899
|
},
|
|
1900
1900
|
"v2/durable-core/constants.js": {
|
|
1901
|
-
"sha256": "
|
|
1902
|
-
"bytes":
|
|
1901
|
+
"sha256": "21a7a514d3a365c7e7690c1c57dd402a25686bfd2dea38082fcc02ee6c266a5c",
|
|
1902
|
+
"bytes": 3987
|
|
1903
1903
|
},
|
|
1904
1904
|
"v2/durable-core/domain/ack-advance-append-plan.d.ts": {
|
|
1905
1905
|
"sha256": "2b4a8ad0e1d9e9066f100f958e572f19af590ab70946c2396d2d5568875bdf00",
|
|
@@ -3066,8 +3066,8 @@
|
|
|
3066
3066
|
"bytes": 730
|
|
3067
3067
|
},
|
|
3068
3068
|
"v2/projections/session-metrics.js": {
|
|
3069
|
-
"sha256": "
|
|
3070
|
-
"bytes":
|
|
3069
|
+
"sha256": "89dd4c149087234e3f4f18382340a9f855942fd96595783b7d7ad5c76449536a",
|
|
3070
|
+
"bytes": 3370
|
|
3071
3071
|
},
|
|
3072
3072
|
"v2/read-only/v1-to-v2-shim.d.ts": {
|
|
3073
3073
|
"sha256": "b122df1d4eb4119b65465baa00f157ca4466575d3bc6ac20054a361eaff48e02",
|
|
@@ -149,6 +149,24 @@ function checkContextBudget(args) {
|
|
|
149
149
|
}),
|
|
150
150
|
};
|
|
151
151
|
}
|
|
152
|
+
const rawMetricsOutcome = contextObj['metrics_outcome'];
|
|
153
|
+
if (rawMetricsOutcome !== undefined && rawMetricsOutcome !== null) {
|
|
154
|
+
if (!constants_js_1.VALID_METRICS_OUTCOME.includes(rawMetricsOutcome)) {
|
|
155
|
+
const details = {
|
|
156
|
+
kind: 'context_invalid_metrics_outcome',
|
|
157
|
+
tool: args.tool,
|
|
158
|
+
invalidValue: String(rawMetricsOutcome),
|
|
159
|
+
validValues: [...constants_js_1.VALID_METRICS_OUTCOME],
|
|
160
|
+
};
|
|
161
|
+
return {
|
|
162
|
+
ok: false,
|
|
163
|
+
error: (0, types_js_1.errNotRetryable)('VALIDATION_ERROR', `context.metrics_outcome has invalid value "${String(rawMetricsOutcome)}" for ${args.tool}. Valid values: ${constants_js_1.VALID_METRICS_OUTCOME.map(v => `"${v}"`).join(', ')}.`, {
|
|
164
|
+
suggestion: 'Set metrics_outcome to one of the valid enum values listed in validValues.',
|
|
165
|
+
details: details,
|
|
166
|
+
}),
|
|
167
|
+
};
|
|
168
|
+
}
|
|
169
|
+
}
|
|
152
170
|
return { ok: true };
|
|
153
171
|
}
|
|
154
172
|
function collectArtifactsForEvaluation(args) {
|
|
@@ -136,7 +136,7 @@ function computeWorkflowStaleness(stamp, currentVersion) {
|
|
|
136
136
|
if (stamp === undefined) {
|
|
137
137
|
return {
|
|
138
138
|
level: 'possible',
|
|
139
|
-
reason: 'This workflow has not been validated against the authoring spec via workflow-for-workflows.',
|
|
139
|
+
reason: 'This workflow has not been validated against the authoring spec via wr.workflow-for-workflows.',
|
|
140
140
|
};
|
|
141
141
|
}
|
|
142
142
|
if (stamp === currentVersion) {
|
|
@@ -61,7 +61,7 @@ exports.START_WORKFLOW_PROTOCOL = {
|
|
|
61
61
|
'Only pass context on later continue_workflow calls if facts changed.',
|
|
62
62
|
],
|
|
63
63
|
examplePayload: {
|
|
64
|
-
workflowId: 'coding-task
|
|
64
|
+
workflowId: 'wr.coding-task',
|
|
65
65
|
workspacePath: '/Users/you/git/my-project',
|
|
66
66
|
goal: 'implement OAuth refresh token rotation',
|
|
67
67
|
},
|
|
@@ -77,7 +77,7 @@ exports.START_WORKFLOW_PROTOCOL = {
|
|
|
77
77
|
'Pass goal on every call. A short sentence describing what you are trying to accomplish.',
|
|
78
78
|
],
|
|
79
79
|
examplePayload: {
|
|
80
|
-
workflowId: 'coding-task
|
|
80
|
+
workflowId: 'wr.coding-task',
|
|
81
81
|
workspacePath: '/Users/you/git/my-project',
|
|
82
82
|
goal: 'implement OAuth refresh token rotation',
|
|
83
83
|
},
|
|
@@ -86,3 +86,5 @@ export declare const AUTONOMY_MODE: {
|
|
|
86
86
|
readonly FULL_AUTO_STOP_ON_USER_DEPS: "full_auto_stop_on_user_deps";
|
|
87
87
|
};
|
|
88
88
|
export type AutonomyModeV1 = typeof AUTONOMY_MODE[keyof typeof AUTONOMY_MODE];
|
|
89
|
+
export declare const VALID_METRICS_OUTCOME: readonly ["success", "partial", "abandoned", "error"];
|
|
90
|
+
export type MetricsOutcome = (typeof VALID_METRICS_OUTCOME)[number];
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.AUTONOMY_MODE = exports.ADVANCE_INTENT = exports.MANIFEST_KIND = exports.EDGE_CAUSE = exports.ADVANCE_OUTCOME = exports.ENGINE_STATE = exports.EDGE_KIND = exports.PAYLOAD_KIND = exports.OUTPUT_CHANNEL = exports.EVENT_KIND = exports.DELIMITER_SAFE_ID_PATTERN = exports.SHA256_DIGEST_PATTERN = exports.MAX_RESUME_PREVIEW_BYTES = exports.RECOVERY_BUDGET_BYTES = exports.TRUNCATION_MARKER = exports.DEFAULT_RETRY_AFTER_MS = exports.SESSION_LOCK_RETRY_AFTER_MS = exports.MAX_OBSERVATION_PATH_LENGTH = exports.MAX_OBSERVATION_SHORT_STRING_LENGTH = exports.MAX_CONTEXT_DEPTH = exports.MAX_CONTEXT_BYTES = exports.MAX_VALIDATION_SUGGESTIONS_BYTES = exports.MAX_VALIDATION_ISSUES_BYTES = exports.MAX_VALIDATION_SUGGESTION_ITEM_BYTES = exports.MAX_VALIDATION_ISSUE_ITEM_BYTES = exports.MAX_OUTPUT_NOTES_MARKDOWN_BYTES = exports.MAX_DECISION_TRACE_TOTAL_BYTES = exports.MAX_DECISION_TRACE_ENTRY_SUMMARY_BYTES = exports.MAX_DECISION_TRACE_ENTRIES = exports.MAX_BLOCKER_SUGGESTED_FIX_BYTES = exports.MAX_BLOCKER_MESSAGE_BYTES = exports.MAX_BLOCKERS = void 0;
|
|
3
|
+
exports.VALID_METRICS_OUTCOME = exports.AUTONOMY_MODE = exports.ADVANCE_INTENT = exports.MANIFEST_KIND = exports.EDGE_CAUSE = exports.ADVANCE_OUTCOME = exports.ENGINE_STATE = exports.EDGE_KIND = exports.PAYLOAD_KIND = exports.OUTPUT_CHANNEL = exports.EVENT_KIND = exports.DELIMITER_SAFE_ID_PATTERN = exports.SHA256_DIGEST_PATTERN = exports.MAX_RESUME_PREVIEW_BYTES = exports.RECOVERY_BUDGET_BYTES = exports.TRUNCATION_MARKER = exports.DEFAULT_RETRY_AFTER_MS = exports.SESSION_LOCK_RETRY_AFTER_MS = exports.MAX_OBSERVATION_PATH_LENGTH = exports.MAX_OBSERVATION_SHORT_STRING_LENGTH = exports.MAX_CONTEXT_DEPTH = exports.MAX_CONTEXT_BYTES = exports.MAX_VALIDATION_SUGGESTIONS_BYTES = exports.MAX_VALIDATION_ISSUES_BYTES = exports.MAX_VALIDATION_SUGGESTION_ITEM_BYTES = exports.MAX_VALIDATION_ISSUE_ITEM_BYTES = exports.MAX_OUTPUT_NOTES_MARKDOWN_BYTES = exports.MAX_DECISION_TRACE_TOTAL_BYTES = exports.MAX_DECISION_TRACE_ENTRY_SUMMARY_BYTES = exports.MAX_DECISION_TRACE_ENTRIES = exports.MAX_BLOCKER_SUGGESTED_FIX_BYTES = exports.MAX_BLOCKER_MESSAGE_BYTES = exports.MAX_BLOCKERS = void 0;
|
|
4
4
|
exports.MAX_BLOCKERS = 10;
|
|
5
5
|
exports.MAX_BLOCKER_MESSAGE_BYTES = 512;
|
|
6
6
|
exports.MAX_BLOCKER_SUGGESTED_FIX_BYTES = 1024;
|
|
@@ -82,3 +82,4 @@ exports.AUTONOMY_MODE = {
|
|
|
82
82
|
FULL_AUTO_NEVER_STOP: 'full_auto_never_stop',
|
|
83
83
|
FULL_AUTO_STOP_ON_USER_DEPS: 'full_auto_stop_on_user_deps',
|
|
84
84
|
};
|
|
85
|
+
exports.VALID_METRICS_OUTCOME = ['success', 'partial', 'abandoned', 'error'];
|
|
@@ -40,7 +40,7 @@ function projectSessionMetricsV2(events) {
|
|
|
40
40
|
const durationMs = typeof d.durationMs === 'number' && Number.isFinite(d.durationMs) ? d.durationMs : undefined;
|
|
41
41
|
const captureConfidence = d.captureConfidence === 'high' ? 'high' : 'none';
|
|
42
42
|
const outcomeRaw = metricsContext['metrics_outcome'];
|
|
43
|
-
const outcome = outcomeRaw
|
|
43
|
+
const outcome = constants_js_1.VALID_METRICS_OUTCOME.includes(outcomeRaw)
|
|
44
44
|
? outcomeRaw
|
|
45
45
|
: null;
|
|
46
46
|
const prNumbers = [];
|
package/docs/authoring-v2.md
CHANGED
|
@@ -240,7 +240,7 @@ Profile selection guide:
|
|
|
240
240
|
| `"research"` | Workflow produces a finding or recommendation but no commits | Outcome-only reminder on final step only |
|
|
241
241
|
| `"none"` or absent | Meta-workflows, utilities, authoring tools | No injection -- existing behavior unchanged |
|
|
242
242
|
|
|
243
|
-
The engine does NOT derive the profile from tags automatically. Authors must set this field explicitly. When using `workflow-for-workflows` to author or modernize a workflow, the `phase-7b` step will prompt you for this decision.
|
|
243
|
+
The engine does NOT derive the profile from tags automatically. Authors must set this field explicitly. When using `wr.workflow-for-workflows` to author or modernize a workflow, the `phase-7b` step will prompt you for this decision.
|
|
244
244
|
|
|
245
245
|
**Final step detection**: The engine injects the final-step footer on the last top-level step, or on the exit step of a loop that is the last top-level step. A loop in a non-terminal position does not trigger the final-step footer on its exit step.
|
|
246
246
|
|
|
@@ -551,11 +551,11 @@ To keep authoring simple:
|
|
|
551
551
|
|
|
552
552
|
Workflows can drift out of sync with the authoring spec they were written against. WorkRail surfaces this as a `staleness` signal in `list_workflows` and `inspect_workflow` output.
|
|
553
553
|
|
|
554
|
-
**How it works:** Workflows carry an optional `validatedAgainstSpecVersion` field stamped by `workflow-for-workflows` after the quality gate passes. The engine compares this against the current `spec/authoring-spec.json` version at list/inspect time and returns:
|
|
554
|
+
**How it works:** Workflows carry an optional `validatedAgainstSpecVersion` field stamped by `wr.workflow-for-workflows` after the quality gate passes. The engine compares this against the current `spec/authoring-spec.json` version at list/inspect time and returns:
|
|
555
555
|
|
|
556
556
|
- `none` — workflow was validated against the current spec version
|
|
557
557
|
- `likely` — spec was updated since the workflow was last reviewed
|
|
558
|
-
- `possible` — workflow has never been run through `workflow-for-workflows`
|
|
558
|
+
- `possible` — workflow has never been run through `wr.workflow-for-workflows`
|
|
559
559
|
|
|
560
560
|
**Stamping a workflow:**
|
|
561
561
|
|
|
@@ -564,7 +564,7 @@ npm run stamp-workflow -- workflows/my-workflow.json
|
|
|
564
564
|
git add workflows/my-workflow.json && git commit -m "chore: stamp workflow"
|
|
565
565
|
```
|
|
566
566
|
|
|
567
|
-
The stamp must be committed to take effect. The `workflow-for-workflows` Phase 7 step includes a reminder to do this.
|
|
567
|
+
The stamp must be committed to take effect. The `wr.workflow-for-workflows` Phase 7 step includes a reminder to do this.
|
|
568
568
|
|
|
569
569
|
**Visibility:** By default, the staleness signal is only shown for user-owned/imported workflows (`personal`, `rooted_sharing`, `external`). Built-in and legacy_project workflows are excluded. Set `WORKRAIL_DEV=1` to see staleness for all categories (useful for catalog maintenance).
|
|
570
570
|
|
package/docs/changelog-recent.md
CHANGED
|
@@ -117,7 +117,7 @@ Structured migration workflow for moving code between platforms (Android to iOS,
|
|
|
117
117
|
|
|
118
118
|
Since you've created workflows yourself, these changes are directly relevant.
|
|
119
119
|
|
|
120
|
-
### `workflow-for-workflows.v2.json` was rebuilt
|
|
120
|
+
### `wr.workflow-for-workflows.v2.json` was rebuilt
|
|
121
121
|
|
|
122
122
|
The workflow used to create or modernize other workflows was significantly redesigned. The full phase structure now includes:
|
|
123
123
|
|
|
@@ -179,12 +179,12 @@ A visual catalog of every available workflow. Eight category filter pills. Click
|
|
|
179
179
|
WorkRail can now detect when a workflow hasn't been reviewed against the current authoring spec. Three signal levels:
|
|
180
180
|
|
|
181
181
|
- `none` -- validated against the current spec (has a version stamp and it's current)
|
|
182
|
-
- `possible` -- no version stamp (was never run through `workflow-for-workflows`)
|
|
182
|
+
- `possible` -- no version stamp (was never run through `wr.workflow-for-workflows`)
|
|
183
183
|
- `likely` -- has a stamp, but the spec has been updated since the workflow was last reviewed
|
|
184
184
|
|
|
185
185
|
This shows up in `list_workflows` output (agents see it) and in the CI registry validation check. It's shown only for non-built-in workflows -- built-in workflows ship with their own quality process and don't show staleness signals.
|
|
186
186
|
|
|
187
|
-
**What this means for your team:** Your team's existing workflows will show as `possible` (no stamp) until they're run through `workflow-for-workflows.v2.json`. That's expected -- it's not an error, just a signal that they haven't been through the new quality gate. Over time, as you modernize them, they'll show `none`.
|
|
187
|
+
**What this means for your team:** Your team's existing workflows will show as `possible` (no stamp) until they're run through `wr.workflow-for-workflows.v2.json`. That's expected -- it's not an error, just a signal that they haven't been through the new quality gate. Over time, as you modernize them, they'll show `none`.
|
|
188
188
|
|
|
189
189
|
---
|
|
190
190
|
|
package/docs/configuration.md
CHANGED
|
@@ -407,7 +407,7 @@ When `isComplete: true` is returned, summarize all work done across the workflow
|
|
|
407
407
|
After creating this file, the agent becomes available via the Agent tool:
|
|
408
408
|
|
|
409
409
|
```
|
|
410
|
-
Agent(subagent_type="workrail-executor", prompt="Start the bug-investigation
|
|
410
|
+
Agent(subagent_type="workrail-executor", prompt="Start the wr.bug-investigation workflow...")
|
|
411
411
|
```
|
|
412
412
|
|
|
413
413
|
### Cursor
|
|
@@ -59,7 +59,7 @@ Must stay consistent with:
|
|
|
59
59
|
- `src/v2/durable-core/schemas/artifacts/` (typed artifact schemas)
|
|
60
60
|
- `workflows/wr.discovery.json` (Phase 7 -- if emitting artifact)
|
|
61
61
|
- `workflows/wr.shaping.json` (Step 1 -- if adding file search)
|
|
62
|
-
- `workflows/coding-task
|
|
62
|
+
- `workflows/wr.coding-task.json` (Phase 0.5 -- no changes expected)
|
|
63
63
|
|
|
64
64
|
---
|
|
65
65
|
|
|
@@ -73,7 +73,7 @@ WorkTrain sessions are fully isolated. Each spawned session starts from the work
|
|
|
73
73
|
|
|
74
74
|
**1. File-based handoff (wr.shaping -> coding):**
|
|
75
75
|
- `wr.shaping` Step 9 writes `.workrail/current-pitch.md` at the workspace path
|
|
76
|
-
- `coding-task
|
|
76
|
+
- `wr.coding-task` Phase 0.5 actively searches for upstream docs via repo search, WebFetch, MCP integrations
|
|
77
77
|
- Phase 0.5 would find `.workrail/current-pitch.md` automatically
|
|
78
78
|
- **Status: effectively already works** -- no coordinator intervention needed for Shaping->Coding
|
|
79
79
|
|
|
@@ -16,9 +16,9 @@
|
|
|
16
16
|
|
|
17
17
|
3. **Monolithic coordinator vs per-mode decomposition**: `pr-review.ts` is 1462 lines for one pipeline mode. Five modes in one file would be unmanageable. The right architecture decomposes into mode files with a thin dispatcher -- but this requires deciding the seam deliberately.
|
|
18
18
|
|
|
19
|
-
4. **`recommendedPipeline` verbatim vs advisory**: If classify-task
|
|
19
|
+
4. **`recommendedPipeline` verbatim vs advisory**: If wr.classify-task's pipeline output is authoritative, the coordinator cannot apply static overrides. If advisory, the coordinator re-implements routing and classify-task's rules become redundant for common cases.
|
|
20
20
|
|
|
21
|
-
5. **Phase 0.5 vs coordinator routing for upstream context**: `coding-task
|
|
21
|
+
5. **Phase 0.5 vs coordinator routing for upstream context**: `wr.coding-task` Phase 0.5 auto-detects `pitch.md`. The coordinator's "should I skip shaping?" routing decision partially overlaps with this detection. They must agree.
|
|
22
22
|
|
|
23
23
|
### What the codebase already solves (and how)
|
|
24
24
|
|
|
@@ -29,12 +29,12 @@
|
|
|
29
29
|
- Escalation-first: every failure produces `escalated: true` + `escalationReason`, never silent substitution
|
|
30
30
|
- TRACE log before acting on routing decision
|
|
31
31
|
|
|
32
|
-
**`classify-task
|
|
32
|
+
**`wr.classify-task.json`:**
|
|
33
33
|
- Exists as of v3.40.0. Single LLM step, no tools, outputs `recommendedPipeline` as ordered workflow ID array
|
|
34
34
|
- Output format: structured text block with `recommendedPipeline: ["...", "..."]` line
|
|
35
35
|
- Note: `spawn_agent` does NOT return artifacts (v3.40.0 limitation #5) -- output must be read via `spawnSession` + `awaitSessions` + `getAgentResult` + note parsing
|
|
36
36
|
|
|
37
|
-
**Phase 0.5 (`coding-task
|
|
37
|
+
**Phase 0.5 (`wr.coding-task`):**
|
|
38
38
|
- Already detects `pitch.md` and sets `solutionFixed=true`, skipping design phases
|
|
39
39
|
- The coordinator's "IMPLEMENT mode" (skip discovery/shaping) and Phase 0.5 are complementary, not conflicting
|
|
40
40
|
|
|
@@ -78,7 +78,7 @@ From CLAUDE.md (stated) and pr-review.ts (practiced):
|
|
|
78
78
|
- `src/cli-worktrain.ts` -- needs `worktrain run pipeline` subcommand wiring
|
|
79
79
|
- `src/coordinators/pr-review.ts` -- must remain unchanged; new coordinator is additive
|
|
80
80
|
- `src/trigger/types.ts` -- if Candidate D's `pipelineMode` field is added; otherwise unchanged
|
|
81
|
-
- `workflows/classify-task
|
|
81
|
+
- `workflows/wr.classify-task.json` -- coordinator depends on its note output format; format changes break parsing
|
|
82
82
|
- `src/coordinators/routing/route-task.ts` (new) -- pure routing function; all mode selection logic lives here
|
|
83
83
|
- `src/coordinators/modes/*.ts` (new files) -- each mode's pipeline execution logic
|
|
84
84
|
- Test suite: each mode coordinator needs its own unit tests with `CoordinatorDeps` fakes
|
|
@@ -110,8 +110,8 @@ type PipelineMode =
|
|
|
110
110
|
**Per-mode pipelines:**
|
|
111
111
|
- REVIEW_ONLY: `mr-review-workflow.agentic.v2` -> route by verdict
|
|
112
112
|
- QUICK_REVIEW: same + light model config, no arch audit override
|
|
113
|
-
- IMPLEMENT: `coding-task
|
|
114
|
-
- FULL: `wr.discovery` -> `wr.shaping` -> `coding-task
|
|
113
|
+
- IMPLEMENT: `wr.coding-task` (Phase 0.5 picks up pitch) -> PR -> review -> merge
|
|
114
|
+
- FULL: `wr.discovery` -> `wr.shaping` -> `wr.coding-task` -> PR -> review -> merge
|
|
115
115
|
|
|
116
116
|
**Tensions resolved:** determinism, YAGNI, no LLM latency.
|
|
117
117
|
**Tensions accepted:** all ambiguous tasks fall to FULL (wasteful for Medium complexity tasks that don't need full discovery).
|
|
@@ -125,14 +125,14 @@ type PipelineMode =
|
|
|
125
125
|
|
|
126
126
|
---
|
|
127
127
|
|
|
128
|
-
### Candidate B: classify-task
|
|
128
|
+
### Candidate B: wr.classify-task as authoritative source
|
|
129
129
|
|
|
130
|
-
**Summary:** Always spawn `classify-task
|
|
130
|
+
**Summary:** Always spawn `wr.classify-task` first, parse `recommendedPipeline` output, execute the returned workflow sequence. Pipeline modes are not named at the coordinator level.
|
|
131
131
|
|
|
132
132
|
**Architecture:**
|
|
133
133
|
```typescript
|
|
134
134
|
async function routeTask(goal, workspace, deps): Promise<Result<readonly string[], string>> {
|
|
135
|
-
const handle = await deps.spawnSession('classify-task
|
|
135
|
+
const handle = await deps.spawnSession('wr.classify-task', `Classify: ${goal}`, workspace);
|
|
136
136
|
await deps.awaitSessions([handle], CLASSIFY_TIMEOUT_MS); // 3 minutes max
|
|
137
137
|
const agentResult = await deps.getAgentResult(handle);
|
|
138
138
|
return parseRecommendedPipeline(agentResult.recapMarkdown);
|
|
@@ -141,12 +141,12 @@ async function routeTask(goal, workspace, deps): Promise<Result<readonly string[
|
|
|
141
141
|
|
|
142
142
|
`parseRecommendedPipeline` is a pure function parsing the text block (two-tier: JSON array first, regex fallback).
|
|
143
143
|
|
|
144
|
-
**Fallback:** if parsing fails, default to `['wr.discovery', 'coding-task
|
|
144
|
+
**Fallback:** if parsing fails, default to `['wr.discovery', 'wr.coding-task', 'mr-review-workflow.agentic.v2']`.
|
|
145
145
|
|
|
146
146
|
**Tensions resolved:** intelligent routing for all tasks including ambiguous ones; single source of truth for pipeline selection rules.
|
|
147
147
|
**Tensions accepted:** non-deterministic; 5-15 second LLM latency per dispatch; no typed `PipelineMode` discriminated union (pipeline is a string[] at coordinator level).
|
|
148
|
-
**Boundary:** classify-task
|
|
149
|
-
**Failure mode:** classify-task
|
|
148
|
+
**Boundary:** wr.classify-task is the routing authority; coordinator is a runner.
|
|
149
|
+
**Failure mode:** wr.classify-task misclassifies a PR-only task and returns discovery+coding phases, wasting 30+ minutes. Recovery: add a pre-check for PR number before spawning classify-task (hybrid).
|
|
150
150
|
**Repo pattern:** departs from determinism-over-cleverness principle. No named discriminated union.
|
|
151
151
|
**Gain:** routing rules live in a workflow file -- updatable without code deployment.
|
|
152
152
|
**Give up:** determinism, transparency, typed modes, dispatch speed for obvious cases.
|
|
@@ -157,7 +157,7 @@ async function routeTask(goal, workspace, deps): Promise<Result<readonly string[
|
|
|
157
157
|
|
|
158
158
|
### Candidate C: Static-first with LLM fallback (hybrid, recommended for routing)
|
|
159
159
|
|
|
160
|
-
**Summary:** Two-tier `routeTask()`: Tier 1 applies static rules (pure, covers 80% of cases); Tier 2 falls back to classify-task
|
|
160
|
+
**Summary:** Two-tier `routeTask()`: Tier 1 applies static rules (pure, covers 80% of cases); Tier 2 falls back to wr.classify-task for ambiguous tasks and returns a `CLASSIFY_AND_RUN` mode.
|
|
161
161
|
|
|
162
162
|
**PipelineMode type (6 variants):**
|
|
163
163
|
```typescript
|
|
@@ -180,7 +180,7 @@ async function routeTask(
|
|
|
180
180
|
// Tier 1: static (pure, no I/O except filesystem check for pitch.md)
|
|
181
181
|
const staticMode = applyStaticRules(goal, workspace);
|
|
182
182
|
if (staticMode !== null) return ok(staticMode);
|
|
183
|
-
// Tier 2: classify-task
|
|
183
|
+
// Tier 2: wr.classify-task
|
|
184
184
|
const classified = await runClassification(goal, workspace, deps);
|
|
185
185
|
if (classified.kind === 'err') return err(`classification failed: ${classified.error}`);
|
|
186
186
|
return ok({ kind: 'CLASSIFY_AND_RUN', classifiedPipeline: classified.value, goal });
|
|
@@ -293,7 +293,7 @@ export async function runAdaptivePipeline(
|
|
|
293
293
|
|
|
294
294
|
### Recommendation: Candidate C (routing mechanism) + Candidate E (architecture)
|
|
295
295
|
|
|
296
|
-
**Routing (C):** Two-tier static-first with LLM fallback. Static rules cover the 4 well-defined cases at zero cost and latency. `CLASSIFY_AND_RUN` handles genuinely ambiguous tasks via classify-task
|
|
296
|
+
**Routing (C):** Two-tier static-first with LLM fallback. Static rules cover the 4 well-defined cases at zero cost and latency. `CLASSIFY_AND_RUN` handles genuinely ambiguous tasks via wr.classify-task. This precisely mirrors the `parseFindingsFromNotes` two-tier strategy already established in `pr-review.ts`.
|
|
297
297
|
|
|
298
298
|
**Architecture (E):** Per-mode coordinator files with thin dispatcher. Each mode file follows `pr-review.ts` independently. The dispatcher's `switch(mode.kind)` is exhaustive with `assertNever`. Adding a new mode is additive.
|
|
299
299
|
|
|
@@ -301,7 +301,7 @@ export async function runAdaptivePipeline(
|
|
|
301
301
|
|
|
302
302
|
### Why not A (pure static)?
|
|
303
303
|
|
|
304
|
-
Candidate A is simpler but all tasks without static signals fall to FULL (wr.discovery + wr.shaping + coding). A genuinely vague idea needs FULL. But a Medium complexity coding task with no pitch.md and no PR number -- e.g., `"refactor auth.ts to use Result types"` -- also falls to FULL, running unnecessary discovery phases. Candidate C covers this case with classify-task
|
|
304
|
+
Candidate A is simpler but all tasks without static signals fall to FULL (wr.discovery + wr.shaping + coding). A genuinely vague idea needs FULL. But a Medium complexity coding task with no pitch.md and no PR number -- e.g., `"refactor auth.ts to use Result types"` -- also falls to FULL, running unnecessary discovery phases. Candidate C covers this case with wr.classify-task returning `['wr.coding-task', 'mr-review-workflow.agentic.v2']`.
|
|
305
305
|
|
|
306
306
|
### Why not B (pure LLM)?
|
|
307
307
|
|
|
@@ -319,7 +319,7 @@ Non-deterministic routing is unacceptable for the coordinator. A PR review task
|
|
|
319
319
|
|
|
320
320
|
### Pivot conditions
|
|
321
321
|
|
|
322
|
-
1. If classify-task
|
|
322
|
+
1. If wr.classify-task format drifts and `parseRecommendedPipeline` fails more than 10% of the time -> pivot to pure static (Candidate A) and accept FULL as default for ambiguous tasks
|
|
323
323
|
2. If trigger operators need deterministic routing for automated workflows -> add `pipelineMode` to TriggerDefinition (Candidate D addition)
|
|
324
324
|
3. If context-passing agent's design requires structured handoff data from routing to mode executors -> add a `contextBundle` field to mode types (implementation change, not routing design change)
|
|
325
325
|
|
|
@@ -151,6 +151,6 @@ Even though not called at MVP, having the pure function ready preserves the upgr
|
|
|
151
151
|
|
|
152
152
|
1. **wr.discovery output standardization**: the routing design assumes wr.discovery notes are injected by the coordinator as `assembledContextSummary` for wr.shaping. But wr.discovery's `designDocPath` output location is not standardized (finding from context-passing agent's doc). The FULL mode executor must parse `lastStepNotes` from the discovery session to build the shaping context -- this is per the context-passing agent's Candidate D (coordinator-injected text). This concern is correctly owned by the context-passing design, not the routing design.
|
|
153
153
|
|
|
154
|
-
2. **classify-task
|
|
154
|
+
2. **wr.classify-task format stability**: if `parseRecommendedPipeline()` is written as a pure function now, it has no tests against real classify-task output. The function should include an integration test stub that documents the expected format.
|
|
155
155
|
|
|
156
156
|
3. **REVIEW_ONLY vs pr-review coordinator**: the existing `worktrain run pr-review` command already provides REVIEW_ONLY+QUICK_REVIEW behavior. The new `worktrain run pipeline --mode review_only` should either (a) delegate to pr-review coordinator, or (b) reimplement the same logic in `modes/review-only.ts`. Recommendation: (a) delegate -- avoid duplicating the fix-agent loop logic. Document this delegation explicitly.
|