|
1 | 1 | # Architecture |
2 | 2 |
|
3 | | -## Goal state machine |
4 | | - |
5 | | -The orchestrator is a durable `GsdStateMachine` built around the `WorkflowState` enum |
6 | | -(`src/GsdOrchestrator/Workflows/GsdStateMachine.cs`, `Models/WorkflowState.cs`). Every issue |
7 | | -run walks the same linear path unless it is triaged out early or a state raises an unhandled |
8 | | -exception, which transitions the workflow to `Failed`. State is checkpointed to disk after |
9 | | -every transition (`FileCheckpointStore`), so `--resume <workflow-id>` can continue an |
10 | | -interrupted run instead of restarting it. |
11 | | - |
12 | | -```mermaid |
13 | | -stateDiagram-v2 |
14 | | - direction LR |
15 | | - [*] --> Idle |
16 | | - Idle --> Triaging |
17 | | - Triaging --> Analyzing: actionable issue |
18 | | - Triaging --> Done: non-actionable or --triage |
19 | | - Analyzing --> Branching |
20 | | - Branching --> Editing |
21 | | - Editing --> TestGenerating |
22 | | - TestGenerating --> Validating |
23 | | - Validating --> Committing |
24 | | - Validating --> Failed: blocking gate |
25 | | - Committing --> PrCreating |
26 | | - PrCreating --> Reviewing |
27 | | - Reviewing --> Documenting: issue mode |
28 | | - [*] --> Reviewing: --pr mode |
29 | | - Reviewing --> Done: PR-review mode |
30 | | - Documenting --> Done |
31 | | - Done --> [*] |
32 | | - Failed --> [*] |
33 | | -``` |
34 | | - |
35 | | -<!-- codex:generate-image prompt="A conveyor-belt state machine: a glowing token labeled ISSUE travels through eleven numbered gates (Idle, Triaging, Analyzing, Branching, Editing, TestGenerating, Validating, Committing, PrCreating, Reviewing, Documenting) each rendered as a small illuminated archway, ending at a checkered-flag PR gate; one side-branch peels off downward into a red Failed gate with a retry arrow looping back; isometric, enterprise blue/graphite palette" style="isometric, enterprise, clean" replaces="mermaid-above" --> |
36 | | - |
37 | | -## Failure handling on `main` today |
38 | | - |
39 | | -`ResumeAsync` checks `ctx.CurrentState == WorkflowState.Failed`: if `ctx.FailedState` is set, |
40 | | -it clears the failure and re-enters that state for a retry; if the retry fails again it maps |
41 | | -the exception to a `TerminalStopReason` (`BudgetExhausted`, `NoProgress`, `RuntimeExceeded`, |
42 | | -or `Unknown`) and halts. On the primary path, an unhandled exception during a state currently |
43 | | -rolls the workflow back through the SDLC phase map (`Discovery` → `Design` → `Change` → |
44 | | -`Assurance` → `Closure`) before settling into `Failed`, recording the *rolled-back* state as |
45 | | -`FailedState` rather than the state where the exception actually occurred. |
46 | | - |
47 | | -## Typed-failure retry/halt path (Phase 28-01 — not yet on `main`) |
48 | | - |
49 | | -Phase 28-01 hardens this: transient `McpException` failures should bypass the SDLC rollback |
50 | | -cascade entirely and persist the *actual* failed state, so `ResumeAsync` retries the state |
51 | | -that really failed (once) before halting — proven by `FaultInjectionTests.cs` and |
52 | | -`CheckpointCorruptionTests.cs` (see [`28-01-SUMMARY.md`](../../.planning/phases/28-fault-injection-recovery/28-01-SUMMARY.md) |
53 | | -in the root workstation repo for the full design). **This work exists only on a local, |
54 | | -unpushed branch (`feat/phase-28-fault-injection`) in the operator's workstation checkout — |
55 | | -it is not present on `origin/main` and there is no open PR for it yet.** Treat the failure |
56 | | -handling described in the previous section as the current state of `main` until that branch |
57 | | -is pushed and reviewed. |
58 | | - |
59 | | -## Component topology |
60 | | - |
61 | | -```mermaid |
62 | | -flowchart LR |
63 | | - subgraph Orchestrator["GSD Orchestrator (.NET 10)"] |
64 | | - SM[GsdStateMachine] |
65 | | - MCP[McpStdioClient] |
66 | | - LLM[Anthropic.SDK] |
67 | | - CP[FileCheckpointStore] |
68 | | - end |
69 | | - subgraph GitHub["GitHub"] |
70 | | - MCPS[github-mcp-server.exe] |
71 | | - GHAPI[GitHub API] |
72 | | - end |
73 | | - subgraph Anthropic["Anthropic"] |
74 | | - CLAUDE[Claude API] |
75 | | - end |
76 | | - subgraph Storage["Local Storage"] |
77 | | - CKPT[.gsd/state/] |
78 | | - end |
79 | | - SM --> MCP |
80 | | - MCP -->|stdio| MCPS |
81 | | - MCPS --> GHAPI |
82 | | - SM --> LLM |
83 | | - LLM --> CLAUDE |
84 | | - SM --> CP |
85 | | - CP --> CKPT |
86 | | -``` |
87 | | - |
88 | | -## SDLC phase mapping |
89 | | - |
90 | | -Beyond the linear states, the orchestrator maps operations to SDLC batches — `Discovery` |
91 | | -(Triaging, Analyzing), `Design`, `Change` (Branching, Editing, TestGenerating), `Assurance` |
92 | | -(Validating, Reviewing), `Closure` (Committing, PrCreating, Documenting). A `Block`-level |
93 | | -validation status triggers a `TerminalStopReason` and rolls the branch back. |
94 | | - |
95 | | -<!-- docs-verified: a01b130c98cb7833d45cc7406f6002009f33557a 2026-07-08 --> |
| 3 | + |
0 commit comments