@exaudeus/workrail 3.27.0 → 3.29.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (160) hide show
  1. package/dist/console/assets/{index-FtTaDku8.js → index-BZ6HkxGf.js} +1 -1
  2. package/dist/console/index.html +1 -1
  3. package/dist/manifest.json +3 -3
  4. package/docs/README.md +57 -0
  5. package/docs/adrs/001-hybrid-storage-backend.md +38 -0
  6. package/docs/adrs/002-four-layer-context-classification.md +38 -0
  7. package/docs/adrs/003-checkpoint-trigger-strategy.md +35 -0
  8. package/docs/adrs/004-opt-in-encryption-strategy.md +36 -0
  9. package/docs/adrs/005-agent-first-workflow-execution-tokens.md +105 -0
  10. package/docs/adrs/006-append-only-session-run-event-log.md +76 -0
  11. package/docs/adrs/007-resume-and-checkpoint-only-sessions.md +51 -0
  12. package/docs/adrs/008-blocked-nodes-architectural-upgrade.md +178 -0
  13. package/docs/adrs/009-bridge-mode-single-instance-mcp.md +195 -0
  14. package/docs/adrs/010-release-pipeline.md +89 -0
  15. package/docs/architecture/README.md +7 -0
  16. package/docs/architecture/refactor-audit.md +364 -0
  17. package/docs/authoring-v2.md +527 -0
  18. package/docs/authoring.md +873 -0
  19. package/docs/changelog-recent.md +201 -0
  20. package/docs/configuration.md +505 -0
  21. package/docs/ctc-mcp-proposal.md +518 -0
  22. package/docs/design/README.md +22 -0
  23. package/docs/design/agent-cascade-protocol.md +96 -0
  24. package/docs/design/autonomous-console-design-candidates.md +253 -0
  25. package/docs/design/autonomous-console-design-review.md +111 -0
  26. package/docs/design/autonomous-platform-mvp-discovery.md +525 -0
  27. package/docs/design/claude-code-source-deep-dive.md +713 -0
  28. package/docs/design/console-cyberpunk-ui-discovery.md +504 -0
  29. package/docs/design/console-execution-trace-candidates-final.md +160 -0
  30. package/docs/design/console-execution-trace-candidates.md +211 -0
  31. package/docs/design/console-execution-trace-design-candidates-v2.md +113 -0
  32. package/docs/design/console-execution-trace-design-review.md +74 -0
  33. package/docs/design/console-execution-trace-discovery.md +394 -0
  34. package/docs/design/console-execution-trace-final-review.md +77 -0
  35. package/docs/design/console-execution-trace-review.md +92 -0
  36. package/docs/design/console-performance-discovery.md +415 -0
  37. package/docs/design/console-ui-backlog.md +280 -0
  38. package/docs/design/daemon-architecture-discovery.md +853 -0
  39. package/docs/design/daemon-design-candidates.md +318 -0
  40. package/docs/design/daemon-design-review-findings.md +119 -0
  41. package/docs/design/daemon-engine-design-candidates.md +210 -0
  42. package/docs/design/daemon-engine-design-review.md +131 -0
  43. package/docs/design/daemon-execution-engine-discovery.md +280 -0
  44. package/docs/design/daemon-gap-analysis.md +554 -0
  45. package/docs/design/daemon-owns-console-plan.md +168 -0
  46. package/docs/design/daemon-owns-console-review.md +91 -0
  47. package/docs/design/daemon-owns-console.md +195 -0
  48. package/docs/design/data-model-erd.md +11 -0
  49. package/docs/design/design-candidates-consolidate-dev-staleness.md +98 -0
  50. package/docs/design/design-candidates-walk-cache-depth-limit.md +80 -0
  51. package/docs/design/design-review-consolidate-dev-staleness.md +54 -0
  52. package/docs/design/design-review-walk-cache-depth-limit.md +48 -0
  53. package/docs/design/implementation-plan-consolidate-dev-staleness.md +142 -0
  54. package/docs/design/implementation-plan-walk-cache-depth-limit.md +141 -0
  55. package/docs/design/layer3b-ghost-nodes-design-candidates.md +229 -0
  56. package/docs/design/layer3b-ghost-nodes-design-review.md +93 -0
  57. package/docs/design/layer3b-ghost-nodes-implementation-plan.md +219 -0
  58. package/docs/design/list-workflows-latency-fix-plan.md +128 -0
  59. package/docs/design/list-workflows-latency-fix-review.md +55 -0
  60. package/docs/design/list-workflows-latency-fix.md +109 -0
  61. package/docs/design/native-context-management-api.md +11 -0
  62. package/docs/design/performance-sweep-2026-04.md +96 -0
  63. package/docs/design/routines-guide.md +219 -0
  64. package/docs/design/sequence-diagrams.md +11 -0
  65. package/docs/design/subagent-design-principles.md +220 -0
  66. package/docs/design/temporal-patterns-design-candidates.md +312 -0
  67. package/docs/design/temporal-patterns-design-review-findings.md +163 -0
  68. package/docs/design/test-isolation-from-config-file.md +335 -0
  69. package/docs/design/v2-core-design-locks.md +2746 -0
  70. package/docs/design/v2-lock-registry.json +734 -0
  71. package/docs/design/workflow-authoring-v2.md +1044 -0
  72. package/docs/design/workflow-docs-spec.md +218 -0
  73. package/docs/design/workflow-extension-points.md +687 -0
  74. package/docs/design/workrail-auto-trigger-system.md +359 -0
  75. package/docs/design/workrail-config-file-discovery.md +513 -0
  76. package/docs/docker.md +110 -0
  77. package/docs/generated/v2-lock-closure-plan.md +26 -0
  78. package/docs/generated/v2-lock-coverage.json +797 -0
  79. package/docs/generated/v2-lock-coverage.md +177 -0
  80. package/docs/ideas/backlog.md +3927 -0
  81. package/docs/ideas/design-candidates-mcp-resilience.md +208 -0
  82. package/docs/ideas/design-review-findings-mcp-resilience.md +119 -0
  83. package/docs/ideas/implementation_plan.md +249 -0
  84. package/docs/ideas/third-party-workflow-setup-design-thinking.md +1948 -0
  85. package/docs/implementation/02-architecture.md +316 -0
  86. package/docs/implementation/04-testing-strategy.md +124 -0
  87. package/docs/implementation/09-simple-workflow-guide.md +835 -0
  88. package/docs/implementation/13-advanced-validation-guide.md +874 -0
  89. package/docs/implementation/README.md +21 -0
  90. package/docs/integrations/claude-code.md +300 -0
  91. package/docs/integrations/firebender.md +315 -0
  92. package/docs/migration/v0.1.0.md +147 -0
  93. package/docs/naming-conventions.md +45 -0
  94. package/docs/planning/README.md +104 -0
  95. package/docs/planning/github-ticketing-playbook.md +195 -0
  96. package/docs/plans/README.md +24 -0
  97. package/docs/plans/agent-managed-ticketing-design.md +605 -0
  98. package/docs/plans/agentic-orchestration-roadmap.md +112 -0
  99. package/docs/plans/assessment-gates-engine-handoff.md +536 -0
  100. package/docs/plans/content-coherence-and-references.md +151 -0
  101. package/docs/plans/library-extraction-plan.md +340 -0
  102. package/docs/plans/mr-review-workflow-redesign.md +1451 -0
  103. package/docs/plans/native-context-management-epic.md +11 -0
  104. package/docs/plans/perf-fixes-design-candidates.md +225 -0
  105. package/docs/plans/perf-fixes-design-review-findings.md +61 -0
  106. package/docs/plans/perf-fixes-new-issues-candidates.md +264 -0
  107. package/docs/plans/perf-fixes-new-issues-review.md +110 -0
  108. package/docs/plans/prompt-fragments.md +53 -0
  109. package/docs/plans/ui-ux-workflow-design-candidates.md +120 -0
  110. package/docs/plans/ui-ux-workflow-discovery.md +100 -0
  111. package/docs/plans/ui-ux-workflow-review.md +48 -0
  112. package/docs/plans/v2-followup-enhancements.md +587 -0
  113. package/docs/plans/workflow-categories-candidates.md +105 -0
  114. package/docs/plans/workflow-categories-discovery.md +110 -0
  115. package/docs/plans/workflow-categories-review.md +51 -0
  116. package/docs/plans/workflow-discovery-model-candidates.md +94 -0
  117. package/docs/plans/workflow-discovery-model-discovery.md +74 -0
  118. package/docs/plans/workflow-discovery-model-review.md +48 -0
  119. package/docs/plans/workflow-source-setup-phase-1.md +245 -0
  120. package/docs/plans/workflow-source-setup-phase-2.md +361 -0
  121. package/docs/plans/workflow-staleness-detection-candidates.md +104 -0
  122. package/docs/plans/workflow-staleness-detection-review.md +58 -0
  123. package/docs/plans/workflow-staleness-detection.md +80 -0
  124. package/docs/plans/workflow-v2-design.md +69 -0
  125. package/docs/plans/workflow-v2-roadmap.md +74 -0
  126. package/docs/plans/workflow-validation-design.md +98 -0
  127. package/docs/plans/workflow-validation-roadmap.md +108 -0
  128. package/docs/plans/workrail-platform-vision.md +420 -0
  129. package/docs/reference/agent-context-cleaner-snippet.md +94 -0
  130. package/docs/reference/agent-context-guidance.md +140 -0
  131. package/docs/reference/context-optimization.md +284 -0
  132. package/docs/reference/example-workflow-repository-template/.github/workflows/validate.yml +125 -0
  133. package/docs/reference/example-workflow-repository-template/README.md +268 -0
  134. package/docs/reference/example-workflow-repository-template/workflows/example-workflow.json +80 -0
  135. package/docs/reference/external-workflow-repositories.md +916 -0
  136. package/docs/reference/feature-flags-architecture.md +472 -0
  137. package/docs/reference/feature-flags.md +349 -0
  138. package/docs/reference/god-tier-workflow-validation.md +272 -0
  139. package/docs/reference/loop-optimization.md +209 -0
  140. package/docs/reference/loop-validation.md +176 -0
  141. package/docs/reference/loops.md +465 -0
  142. package/docs/reference/mcp-platform-constraints.md +59 -0
  143. package/docs/reference/recovery.md +88 -0
  144. package/docs/reference/releases.md +177 -0
  145. package/docs/reference/troubleshooting.md +105 -0
  146. package/docs/reference/workflow-execution-contract.md +998 -0
  147. package/docs/roadmap/README.md +22 -0
  148. package/docs/roadmap/legacy-planning-status.md +103 -0
  149. package/docs/roadmap/now-next-later.md +70 -0
  150. package/docs/roadmap/open-work-inventory.md +389 -0
  151. package/docs/tickets/README.md +39 -0
  152. package/docs/tickets/next-up.md +76 -0
  153. package/docs/workflow-management.md +317 -0
  154. package/docs/workflow-templates.md +423 -0
  155. package/docs/workflow-validation.md +184 -0
  156. package/docs/workflows.md +254 -0
  157. package/package.json +3 -1
  158. package/spec/authoring-spec.json +61 -16
  159. package/workflows/workflow-for-workflows.json +252 -93
  160. package/workflows/workflow-for-workflows.v2.json +188 -77
@@ -0,0 +1,359 @@
1
+ # WorkRail Auto: Trigger System Design
2
+
3
+ **Status:** Design complete, not yet implemented.
4
+ **Workflow:** wr.discovery (completed Apr 15, 2026)
5
+ **Confidence:** High -- based on full source reading of AutoGPT and mcp-graph-workflow.
6
+
7
+ ---
8
+
9
+ ## Context / Ask
10
+
11
+ WorkRail Auto (the autonomous daemon) needs a trigger system: a way to start workflow sessions in response to external events (GitLab MR opened, Jira ticket moved to In Progress, cron schedule, etc.) without human intervention.
12
+
13
+ Two external systems were studied:
14
+ 1. **AutoGPT** (183k stars, Python, production) -- the closest reference for a production-grade trigger/block system
15
+ 2. **mcp-graph-workflow** (DiegoNogueiraDev, 29 stars, TypeScript) -- identified in the backlog as "closest external WorkRail analog," assessed here against the actual source
16
+
17
+ ---
18
+
19
+ ## AutoGPT Trigger Architecture
20
+
21
+ AutoGPT's trigger model is three layers:
22
+
23
+ ### Layer 1: Declaration (BlockWebhookConfig)
24
+
25
+ ```python
26
+ @dataclass
27
+ class BlockManualWebhookConfig:
28
+ provider: ProviderName # "github", "gitlab", "generic_webhook", etc.
29
+ webhook_type: str # "repo" (GitHub repo-level) vs "org"
30
+ event_filter_input: str # name of block input holding event selector
31
+ event_format: str # "pull_request.{event}" -> "pull_request.opened"
32
+
33
+ @dataclass
34
+ class BlockWebhookConfig(BlockManualWebhookConfig):
35
+ resource_format: str # "{owner}/{repo}" -- resolved from block inputs at registration
36
+ # Auto-setup: platform registers webhook via provider API using credentials
37
+ ```
38
+
39
+ **Key distinctions:**
40
+ - `BlockManualWebhookConfig` = user sets up the webhook themselves at the provider
41
+ - `BlockWebhookConfig` = platform auto-registers the webhook via provider API (requires credentials field on block input schema)
42
+ - Platform disables webhook blocks entirely if `platform_base_url` is not set -- no URL, no webhooks
43
+
44
+ **Event filter**: A `BaseModel` subclass where all fields are booleans (`opened: bool = False`, `closed: bool = False`, etc.). Validated at `Block.__init__` time. Example: `GithubPullRequestTriggerBlock.Input.EventsFilter` has 20+ boolean flags for PR events.
45
+
46
+ **BlockType enum** includes: `WEBHOOK` (auto-setup), `WEBHOOK_MANUAL` (user-setup), `AGENT`, `MCP_TOOL`, `HUMAN_IN_THE_LOOP`.
47
+
48
+ ### Layer 2: Registration (WebhooksManager)
49
+
50
+ Per-provider class that handles:
51
+ - `register(trigger, webhookUrl, credentials)` → registers with provider API (e.g., GitHub Webhooks API)
52
+ - `deregister(handle, credentials)` → removes the webhook at the provider
53
+ - Manual registrars: just display the webhook URL for the user to configure themselves
54
+
55
+ ### Layer 3: Execution (Block.run())
56
+
57
+ ```python
58
+ async def run(self, input_data: Input, **kwargs) -> BlockOutput:
59
+ yield "payload", input_data.payload # raw webhook payload
60
+ yield "triggered_by_user", input_data.payload["sender"]
61
+ yield "event", input_data.payload["action"]
62
+ # etc.
63
+ ```
64
+
65
+ The trigger block is stateless: raw payload in, structured output out. Output routes to the next block in the graph. The block has a hidden `payload` input that the platform injects with the webhook payload when the event arrives.
66
+
67
+ ### Credential System
68
+
69
+ AutoGPT separates credential types (OAuth2, API key, bearer token, etc.) per provider. Blocks declare required credentials with typed fields (`GithubCredentialsField`, etc.). The platform manages credential storage; blocks only declare what they need. Credentials are never embedded in block definitions -- they're resolved at runtime from the platform's credential service.
70
+
71
+ ### Multi-Tenancy
72
+
73
+ - `platform_base_url` gates whether webhook features are available at all
74
+ - Credentials are user-scoped (stored per user in the platform's credential service)
75
+ - Each block instance in a graph has its own credential binding
76
+ - `resource_format` is per-instance (e.g., a specific GitHub repo)
77
+
78
+ ---
79
+
80
+ ## Proposed WorkRail Auto Trigger Abstraction
81
+
82
+ Directly derived from AutoGPT's three-layer model with one key substitution: **execute = startWorkflow() instead of yield-to-next-block**.
83
+
84
+ ### Layer 1: TriggerDefinition
85
+
86
+ ```typescript
87
+ interface TriggerDefinition {
88
+ id: string; // UUID, stable across restarts
89
+ provider: string; // "github" | "gitlab" | "jira" | "cron" | "generic" | string
90
+ triggerType: string; // provider-specific: "repo_webhook" | "ticket" | "schedule"
91
+ resourceTemplate: string; // "{owner}/{repo}" | "*/5 * * * *"
92
+ eventFilter: Record<string, boolean>; // boolean flags per event type (optional)
93
+ eventTopicTemplate: string; // "pull_request.{event}" | "cron"
94
+ credentialRef?: string; // named ref in WorkRail keyring (never plaintext)
95
+ workflowId: string; // which workflow to start
96
+ contextMapping?: ContextMapping; // optional: map event payload → workflow context
97
+ }
98
+
99
+ interface ContextMapping {
100
+ mappings: Array<{
101
+ workflowContextKey: string; // e.g. "mrTitle"
102
+ payloadPath: string; // JSONPath against normalized payload, e.g. "$.title"
103
+ required?: boolean;
104
+ }>;
105
+ }
106
+ ```
107
+
108
+ **In MVP: `contextMapping` is optional.** If absent, the raw (normalized) payload is passed as `context.payload`.
109
+
110
+ ### Layer 2: TriggerRegistrar (per provider)
111
+
112
+ ```typescript
113
+ interface TriggerRegistrar {
114
+ register(trigger: TriggerDefinition, webhookUrl: string, credentials: Credentials): Promise<TriggerHandle>;
115
+ deregister(handle: TriggerHandle, credentials: Credentials): Promise<void>;
116
+ }
117
+
118
+ // null registrar = manual: user sets up webhook themselves, WorkRail displays the URL
119
+ // MVP ships null registrar only (generic + cron providers)
120
+ ```
121
+
122
+ ### Layer 3: TriggerRouter (execution)
123
+
124
+ ```typescript
125
+ interface TriggerRouter {
126
+ route(event: IncomingWebhookEvent): Promise<void>;
127
+ }
128
+
129
+ // Flow:
130
+ // POST /webhook/:triggerId
131
+ // → verify HMAC signature (per provider signature scheme)
132
+ // → lookup TriggerDefinition by triggerId
133
+ // → normalize raw payload to canonical form (per provider normalizer)
134
+ // → apply contextMapping (JSONPath against normalized payload)
135
+ // → enqueue to async queue (prevent webhook delivery timeout)
136
+ // → daemon.startWorkflow(trigger.workflowId, mappedContext)
137
+ ```
138
+
139
+ **Important design choices:**
140
+ - Async queue: prevents webhook delivery timeout (providers retry if no 2xx within ~10s)
141
+ - Idempotent: dedup by event delivery ID to handle provider retries
142
+ - Signature verification: per-provider (GitHub: `X-Hub-Signature-256`, GitLab: `X-Gitlab-Token`, generic: configurable HMAC)
143
+
144
+ ### Credential Model
145
+
146
+ ```typescript
147
+ // Credentials stored in WorkRail keyring -- NEVER in trigger definitions or workflow files
148
+ type CredentialRef = string; // e.g. "github-personal", "gitlab-zillow-token"
149
+
150
+ interface StoredCredential {
151
+ name: CredentialRef;
152
+ provider: string;
153
+ type: "api_key" | "oauth2" | "bearer" | "basic";
154
+ // value stored encrypted, never in plaintext
155
+ }
156
+ ```
157
+
158
+ **Two credential backends:**
159
+ - OS keychain via `keytar` (local development, macOS/Linux with keyring)
160
+ - Encrypted env-file (headless environments: Docker, CI, hosted WorkRail Auto)
161
+
162
+ The backend is configurable; the interface (`get(name)`, `set(name, value)`) is identical in both.
163
+
164
+ ### File Structure
165
+
166
+ ```
167
+ src/trigger/
168
+ ├── trigger-store.ts -- SQLite table: triggers, handles, delivery log
169
+ ├── trigger-listener.ts -- Express, separate port (default 3200)
170
+ ├── trigger-router.ts -- lookup + normalize + contextMapping + daemon.startWorkflow()
171
+ ├── credential-store.ts -- keyring abstraction (OS keychain or env-file backend)
172
+ ├── providers/
173
+ │ ├── generic.ts -- manual only: display URL, no auto-registration
174
+ │ ├── cron.ts -- node-cron: schedule-based, no external registration
175
+ │ ├── gitlab.ts -- (post-MVP) GitLab Webhooks API auto-registration
176
+ │ └── github.ts -- (post-MVP) GitHub Webhooks API auto-registration
177
+ └── index.ts -- public API: registerTrigger, listTriggers, startListener
178
+ ```
179
+
180
+ **Port:** 3200 (separate from MCP 3100 and dashboard 3456). Different security model: MCP requires session auth, webhooks require HMAC verification. Separation avoids accidental auth bypass.
181
+
182
+ **Feature flag:** `wr.features.triggers`
183
+
184
+ ### Build Order (MVP)
185
+
186
+ 1. `trigger-store.ts` -- SQLite schema (triggers table)
187
+ 2. `trigger-listener.ts` -- Express endpoint POST /webhook/:triggerId
188
+ 3. `trigger-router.ts` -- with stub DaemonInterface (testable before daemon exists)
189
+ 4. `providers/generic.ts` -- manual only, any HTTP POST becomes a trigger
190
+ 5. `providers/cron.ts` -- schedule-based, zero external dependencies
191
+ 6. MCP tools: `create_trigger`, `list_triggers`, `delete_trigger` (feature-flagged)
192
+
193
+ **The generic provider alone is a complete MVP.** It covers any webhook from any system that can send HTTP POST. GitLab, Jira, Slack, PagerDuty -- all work with a generic trigger and manual webhook configuration. Auto-registration is a post-MVP quality-of-life improvement.
194
+
195
+ ### Provider-Specific Normalizers (post-MVP)
196
+
197
+ To handle payload format changes gracefully, each provider module includes a normalizer:
198
+
199
+ ```typescript
200
+ // raw webhook payload → canonical form → contextMapping runs against canonical
201
+ interface PayloadNormalizer {
202
+ normalize(rawPayload: unknown, eventTopic: string): NormalizedPayload;
203
+ }
204
+ ```
205
+
206
+ This isolates WorkRail from provider payload schema changes. The contextMapping always runs against the canonical form.
207
+
208
+ ### Architecture Diagram
209
+
210
+ ```
211
+ External event (GitLab MR opened)
212
+ ↓ HTTP POST
213
+ trigger-listener (port 3200)
214
+ ↓ verify signature
215
+ ↓ lookup TriggerDefinition
216
+ ↓ normalize payload (provider normalizer)
217
+ ↓ apply contextMapping
218
+ ↓ async queue
219
+ trigger-router
220
+ ↓ daemon.startWorkflow(workflowId, mappedContext)
221
+ WorkRail daemon
222
+ ↓ pi-mono agentLoop
223
+ ↓ WorkRail session (HMAC-enforced steps)
224
+ ↓ output (MR comment, Jira update, etc.)
225
+ ```
226
+
227
+ ### Key Difference from AutoGPT
228
+
229
+ | Aspect | AutoGPT | WorkRail Auto |
230
+ |--------|---------|---------------|
231
+ | Execute | yield payload to next block in graph | startWorkflow(workflowId, context) |
232
+ | Multi-step | Block is one node in a DAG | Trigger starts a full enforced workflow session |
233
+ | Enforcement | None at trigger level | WorkRail HMAC token protocol applies to started session |
234
+ | Trigger complexity | Simple (one block) | Simple (one dispatcher) |
235
+ | Execution complexity | Complex (graph traversal) | Complex (full workflow with loops/conditionals) |
236
+
237
+ WorkRail's trigger is simpler at the trigger level but more powerful at the execution level.
238
+
239
+ ---
240
+
241
+ ## mcp-graph-workflow Assessment
242
+
243
+ ### What It Actually Is
244
+
245
+ **mcp-graph-workflow** (DiegoNogueiraDev, 29 stars, TypeScript, MIT) is a local-first MCP server that converts PRD documents into SQLite execution graphs. It structures all software development work into a fixed **9-phase lifecycle**: ANALYZE → DESIGN → PLAN → IMPLEMENT → VALIDATE → REVIEW → HANDOFF → DEPLOY → LISTENING.
246
+
247
+ It is NOT an analog to WorkRail. It is a **software development task manager** that uses MCP as its API layer.
248
+
249
+ ### How It Enforces Step Sequencing
250
+
251
+ mcp-graph-workflow uses a **gate system** (not tokens):
252
+
253
+ ```typescript
254
+ // unified-gate.ts: wrapToolsWithGates() wraps every MCP tool call
255
+ // 1. Read current phase from SQLite (detectCurrentPhase)
256
+ // 2. Check gate rules for this tool+phase combination
257
+ // 3. If strictness=strict AND error-severity warnings: return blocked response
258
+ // 4. If strictness=advisory: return warnings but allow tool call
259
+ // 5. force:true parameter bypasses the gate
260
+ // Every response includes _lifecycle.nextAction (guidance, not enforcement)
261
+ ```
262
+
263
+ Phase detection is derived from graph state (no tokens):
264
+ - 0 nodes → ANALYZE
265
+ - Any task `in_progress` → IMPLEMENT
266
+ - All tasks `done` → REVIEW
267
+ - All tasks done + snapshots exist → HANDOFF
268
+ - ≥50% done → VALIDATE
269
+ - No sprints assigned → PLAN
270
+ - Fallback → IMPLEMENT
271
+
272
+ ### mcp-graph-workflow vs WorkRail: Honest Comparison
273
+
274
+ | Dimension | mcp-graph-workflow | WorkRail |
275
+ |-----------|-------------------|----------|
276
+ | **Enforcement** | Advisory gates (bypassable: advisory mode, force:true) | HMAC-signed tokens (cryptographic, unbypassable without token) |
277
+ | **Step skipping** | Possible | Impossible without the token |
278
+ | **State** | SQLite (nodes, edges, events, RAG knowledge) | Append-only event log (disk) |
279
+ | **Workflow format** | Implicit: fixed 9-phase lifecycle always | Explicit JSON with loops, conditionals, routines |
280
+ | **Domain** | Software development only | Any domain |
281
+ | **Trigger system** | None | Planned (this document) |
282
+ | **Autonomous execution** | None (human-initiated MCP only) | Planned daemon with pi-mono agentLoop |
283
+ | **Context compression** | 70-85% via RAG (BM25 + ONNX embeddings, local) | None yet |
284
+ | **Code intelligence** | AST analysis, impact scoring, 13 languages | None |
285
+ | **Metrics** | DORA metrics (deploy freq, lead time, CFR, MTTR) | None |
286
+ | **PRD import** | .md, .txt, .pdf → task graph | None |
287
+ | **Portability** | SQLite required, local-only | Zero config, any environment |
288
+ | **Team mode** | SQLite lock + leaseToken (teamTask mode) | Nested subagents via delegation |
289
+
290
+ ### What mcp-graph-workflow Does Better
291
+
292
+ 1. **RAG context compression** -- 70-85% token reduction via BM25 + local ONNX embeddings. Worth studying for WorkRail's future context survival feature.
293
+ 2. **Code intelligence** -- AST-based code graph with impact analysis (which symbols are affected by a change). WorkRail doesn't touch code.
294
+ 3. **DORA metrics** -- deploy frequency, lead time, CFR, MTTR. WorkRail has no metrics.
295
+ 4. **PRD import** -- paste a product requirements document, get a task graph. WorkRail has no equivalent.
296
+ 5. **Harness Engineering** -- 7-dimension agent-readiness scoring. Unique.
297
+
298
+ ### What WorkRail Does Better
299
+
300
+ 1. **Cryptographic enforcement** -- HMAC token makes step skipping impossible. mcp-graph's gate can be bypassed with `force:true` or by switching to advisory mode.
301
+ 2. **Domain-agnostic** -- WorkRail works for any process (coding, goals, MR review, incident response). mcp-graph is software development only.
302
+ 3. **Workflow composition** -- loops, conditionals, routines, templateCall, delegation. mcp-graph has no equivalent (always the fixed 9-phase lifecycle).
303
+ 4. **Portable sessions** -- checkpoint/resume with HMAC-signed tokens. mcp-graph has SQLite state but no portable resume tokens.
304
+ 5. **Zero-config portability** -- `npx -y @exaudeus/workrail`. mcp-graph requires SQLite setup.
305
+ 6. **Autonomous execution path** -- daemon architecture designed and partially built. mcp-graph is human-initiated only.
306
+
307
+ ### Verdict: Different Quadrants, Complementary Tools
308
+
309
+ ```
310
+ ENFORCEMENT STRENGTH
311
+ Advisory (Prompt/Gate) Structural (Cryptographic)
312
+ ┌────────────────────────┬─────────────────────────────┐
313
+ Yes │ mcp-graph-workflow │ WorkRail │
314
+ DURABLE │ (SQLite, phase gates, │ (event log, HMAC tokens, │
315
+ STATE │ force:true bypass) │ unbypassable) │
316
+ ├────────────────────────┼─────────────────────────────┤
317
+ No │ CLAUDE.md files │ (empty) │
318
+ │ nexus-core │ │
319
+ └────────────────────────┴─────────────────────────────┘
320
+ ```
321
+
322
+ mcp-graph-workflow and WorkRail do not compete. A team could use both: mcp-graph-workflow for task decomposition and code-awareness during software development, WorkRail for enforcing the governance process around each development decision. They are complementary, not substitutes.
323
+
324
+ ### Backlog Correction Needed
325
+
326
+ The competitive landscape in `docs/ideas/backlog.md` currently states:
327
+ > "mcp-graph (DiegoNogueiraDev) -- SQLite-backed MCP server with graph-based step locking. Closest external analog."
328
+
329
+ This characterization is **incorrect** after reading the source. The correct description:
330
+
331
+ > "mcp-graph-workflow (DiegoNogueiraDev) -- software development task manager with advisory lifecycle phase gates (SQLite-backed, bypassable). Different quadrant from WorkRail: task management (top-left) vs process enforcement (top-right). Complementary tool, not analog. Notable: local RAG context compression (70-85% token reduction via BM25+ONNX) worth studying for WorkRail's context survival feature."
332
+
333
+ ---
334
+
335
+ ## Design Decisions Log
336
+
337
+ | Decision | Choice | Rationale |
338
+ |----------|--------|-----------|
339
+ | Architecture model | AutoGPT three-layer (declare+register+execute) | Validated by 183k-star production system. Clean separation. |
340
+ | Execute action | startWorkflow() not yield-to-next-block | WorkRail's unit of work is a multi-step session, not a single block |
341
+ | Credential model | Keyring named refs | Never plaintext in workflow files. Two backends for portability. |
342
+ | MVP providers | Generic (HTTP POST) + cron | Zero external dependencies. Generic covers any webhook. |
343
+ | Auto-registration | Post-MVP | MVP validates the abstraction; auto-setup is UX polish |
344
+ | Port | 3200 (separate from MCP 3100) | Different security model; separation prevents auth bypass |
345
+ | contextMapping | Optional in MVP | Reduces complexity; raw payload passthrough covers basic cases |
346
+ | Payload handling | Provider normalizers (raw→canonical) | Isolates WorkRail from provider schema changes |
347
+ | Docker/CI creds | env-file backend | OS keychain fails in headless environments |
348
+
349
+ ---
350
+
351
+ ## Next Actions
352
+
353
+ 1. Fix `LocalSessionLockV2` with workerId (prerequisite for daemon -- see backlog.md)
354
+ 2. Build daemon MVP (pi-mono `agentLoop` + `runWorkflow()`)
355
+ 3. Implement `src/trigger/` with generic + cron providers
356
+ 4. Wire `trigger-router.ts` to `daemon.startWorkflow()`
357
+ 5. Add MCP tools: `create_trigger`, `list_triggers`, `delete_trigger` (feature flag: `wr.features.triggers`)
358
+ 6. First real trigger: GitLab MR webhook → `wr.mr-review` → post MR comment
359
+ 7. Correct mcp-graph-workflow description in `docs/ideas/backlog.md`