diff --git a/README.md b/README.md index 55c5745..4385a05 100644 --- a/README.md +++ b/README.md @@ -10,7 +10,6 @@ opens a pull request with durable workflow state. **Stack:** .NET 10 (C#) · GitHub MCP Server · Anthropic Claude · Polly [![CI](https://github.com/Coding-Autopilot-System/gsd-orchestrator/actions/workflows/ci.yml/badge.svg)](https://github.com/Coding-Autopilot-System/gsd-orchestrator/actions/workflows/ci.yml) -[![Tests](https://img.shields.io/badge/tests-35%20passing-brightgreen)](https://github.com/Coding-Autopilot-System/gsd-orchestrator/actions/workflows/ci.yml) [![.NET 10](https://img.shields.io/badge/.NET-10-512BD4)](https://dotnet.microsoft.com/download/dotnet/10.0) [![License: MIT](https://img.shields.io/badge/license-MIT-green)](LICENSE) @@ -39,6 +38,18 @@ not just "AI edits code." The stronger signal is the operational model around th See [docs/portfolio-proof.md](docs/portfolio-proof.md) for a concise reviewer-oriented summary. +## Test Coverage + +The CI `Test` step runs the full xUnit suite (`src/GsdOrchestrator.Tests`) via `dotnet test` +with `--collect:"XPlat Code Coverage"` and uploads the Cobertura results as a workflow +artifact, but `main` does not yet fail the build on a coverage regression. A ratcheted +branch-coverage gate is **in progress (PR #16)**: it adds a new `coverlet.runsettings` +collector config and an "Enforce coverage" CI step that reads `branch-rate` (not line-rate) +from the produced Cobertura XML and fails closed if it drops below a ratcheted baseline +(measured at ~0.73 branch-rate in the PR, up from a ~0.69 starting point), emitting CAS JSON +telemetry on pass/fail. Until PR #16 merges, coverage is collected and published as an +artifact but not enforced. + ## How It Works ```text @@ -232,3 +243,5 @@ GithubMCP/ |-- Models/ `-- States/ ``` + + diff --git a/docs/wiki/Architecture.md b/docs/wiki/Architecture.md new file mode 100644 index 0000000..4b07dc5 --- /dev/null +++ b/docs/wiki/Architecture.md @@ -0,0 +1,95 @@ +# Architecture + +## Goal state machine + +The orchestrator is a durable `GsdStateMachine` built around the `WorkflowState` enum +(`src/GsdOrchestrator/Workflows/GsdStateMachine.cs`, `Models/WorkflowState.cs`). Every issue +run walks the same linear path unless it is triaged out early or a state raises an unhandled +exception, which transitions the workflow to `Failed`. State is checkpointed to disk after +every transition (`FileCheckpointStore`), so `--resume ` can continue an +interrupted run instead of restarting it. + +```mermaid +stateDiagram-v2 + direction LR + [*] --> Idle + Idle --> Triaging + Triaging --> Analyzing: actionable issue + Triaging --> Done: non-actionable or --triage + Analyzing --> Branching + Branching --> Editing + Editing --> TestGenerating + TestGenerating --> Validating + Validating --> Committing + Validating --> Failed: blocking gate + Committing --> PrCreating + PrCreating --> Reviewing + Reviewing --> Documenting: issue mode + [*] --> Reviewing: --pr mode + Reviewing --> Done: PR-review mode + Documenting --> Done + Done --> [*] + Failed --> [*] +``` + + + +## Failure handling on `main` today + +`ResumeAsync` checks `ctx.CurrentState == WorkflowState.Failed`: if `ctx.FailedState` is set, +it clears the failure and re-enters that state for a retry; if the retry fails again it maps +the exception to a `TerminalStopReason` (`BudgetExhausted`, `NoProgress`, `RuntimeExceeded`, +or `Unknown`) and halts. On the primary path, an unhandled exception during a state currently +rolls the workflow back through the SDLC phase map (`Discovery` → `Design` → `Change` → +`Assurance` → `Closure`) before settling into `Failed`, recording the *rolled-back* state as +`FailedState` rather than the state where the exception actually occurred. + +## Typed-failure retry/halt path (Phase 28-01 — not yet on `main`) + +Phase 28-01 hardens this: transient `McpException` failures should bypass the SDLC rollback +cascade entirely and persist the *actual* failed state, so `ResumeAsync` retries the state +that really failed (once) before halting — proven by `FaultInjectionTests.cs` and +`CheckpointCorruptionTests.cs` (see [`28-01-SUMMARY.md`](../../.planning/phases/28-fault-injection-recovery/28-01-SUMMARY.md) +in the root workstation repo for the full design). **This work exists only on a local, +unpushed branch (`feat/phase-28-fault-injection`) in the operator's workstation checkout — +it is not present on `origin/main` and there is no open PR for it yet.** Treat the failure +handling described in the previous section as the current state of `main` until that branch +is pushed and reviewed. + +## Component topology + +```mermaid +flowchart LR + subgraph Orchestrator["GSD Orchestrator (.NET 10)"] + SM[GsdStateMachine] + MCP[McpStdioClient] + LLM[Anthropic.SDK] + CP[FileCheckpointStore] + end + subgraph GitHub["GitHub"] + MCPS[github-mcp-server.exe] + GHAPI[GitHub API] + end + subgraph Anthropic["Anthropic"] + CLAUDE[Claude API] + end + subgraph Storage["Local Storage"] + CKPT[.gsd/state/] + end + SM --> MCP + MCP -->|stdio| MCPS + MCPS --> GHAPI + SM --> LLM + LLM --> CLAUDE + SM --> CP + CP --> CKPT +``` + +## SDLC phase mapping + +Beyond the linear states, the orchestrator maps operations to SDLC batches — `Discovery` +(Triaging, Analyzing), `Design`, `Change` (Branching, Editing, TestGenerating), `Assurance` +(Validating, Reviewing), `Closure` (Committing, PrCreating, Documenting). A `Block`-level +validation status triggers a `TerminalStopReason` and rolls the branch back. + + diff --git a/docs/wiki/Decisions.md b/docs/wiki/Decisions.md new file mode 100644 index 0000000..3c39a92 --- /dev/null +++ b/docs/wiki/Decisions.md @@ -0,0 +1,48 @@ +# Decisions + +## ADR convention + +`docs/adr/README.md` establishes the convention (sequential numbering, Context/Decision/ +Consequences, mandatory for major technical decisions or new dependencies) but **no numbered +ADR files exist in the repo yet** — decisions to date live in phase plans/summaries under +`.planning/phases/` instead. This index points at those until the first formal ADR is filed. + +## Phase history (`.planning/phases/`, this repo's own GSD project) + +19 phases completed in this repo's local planning history, covering foundation setup through +portfolio polish: + +| Phase | Topic | +|---|---| +| 01 | Foundation quick wins | +| 02 | CI diagrams | +| 03 | Wiki release | +| 04–05 | Promptimprover / autogen cross-repo polish | +| 06 | Coherence / personal profile | +| 07 | Emergency ci-autopilot fix | +| 08 | Secondary repos level A | +| 09–11 | Portfolio AI-reframe and cross-portfolio coherence | +| 12 | Robustness foundation | +| 13 | Smarter issue triage | +| 14 | Autonomous test generation | +| 15 | PR review loop | +| 16 | Multi-repo support | +| 17 | CI hardening | +| 18 | State/test coverage | +| 19 | Portfolio polish | + +See each `.planning/phases//*-SUMMARY.md` for the detailed record of what shipped. + +## Open decisions tracked in this Phase 36 refresh + +- **PR #16** (`feat/phase-26-coverage-gates`) — ratchets CI to a `branch-rate` coverage gate; + open, not yet merged. +- **PR #17** (`fix/checkpoint-corruption`) — checkpoint corruption/replay-error hardening; + open, not yet merged. +- **PR #18** (`ci/sha-pin-and-least-privilege`) — pins third-party GitHub Actions to commit + SHAs and adds least-privilege permissions; open, not yet merged. +- **Phase 28-01 typed-failure retry/halt path** — designed and implemented locally + (`feat/phase-28-fault-injection`, unpushed) but not yet a PR; see + [Architecture](./Architecture.md) for the current-vs-designed failure-handling contrast. + + diff --git a/docs/wiki/Home.md b/docs/wiki/Home.md new file mode 100644 index 0000000..6c7fe13 --- /dev/null +++ b/docs/wiki/Home.md @@ -0,0 +1,33 @@ +# gsd-orchestrator Wiki + +## Role in the CAS portfolio + +`gsd-orchestrator` is the **Control plane** of the Coding-Autopilot-System three-plane model +(Control / Execution / Governance — see the root [`docs/VISION.md`](https://github.com/OgeonX-Ai/cas-workstation) +architecture diagram). Its job: admit goals as typed, bounded, budgeted work items and drive +dependency-aware scheduling through a durable state machine — issue in, PR out, with every +step checkpointed so a crashed or interrupted run can be resumed rather than restarted. + +| Plane | This repo's responsibility | +|---|---| +| Control | Goal admission, state-machine scheduling, checkpoint/resume, PR lifecycle | +| Execution | *(not this repo — see `autogen`)* | +| Governance | *(not this repo — see `Promptimprover`, `cas-contracts`, `cas-evals`)* | + +## Quickstart + +- [README.md](../../README.md) — setup, `.env` configuration, running the orchestrator against a real issue +- [docs/portfolio-proof.md](../portfolio-proof.md) — concise reviewer-oriented summary +- [Architecture](./Architecture.md) — state machine, component topology, typed-failure path +- [Operations](./Operations.md) — build, test, and CI commands (verified against the live tree) +- [Decisions](./Decisions.md) — index of phase summaries and the ADR convention + +## Ecosystem links + +Part of the [Coding-Autopilot-System](https://github.com/Coding-Autopilot-System) org: +[autogen](https://github.com/Coding-Autopilot-System/autogen) (execution plane) · +[Promptimprover](https://github.com/Coding-Autopilot-System/Promptimprover) (prompt governance) · +[cas-contracts](https://github.com/Coding-Autopilot-System/cas-contracts) (shared schemas) · +[cas-evals](https://github.com/Coding-Autopilot-System/cas-evals) (evidence gate) + + diff --git a/docs/wiki/Operations.md b/docs/wiki/Operations.md new file mode 100644 index 0000000..ded80e6 --- /dev/null +++ b/docs/wiki/Operations.md @@ -0,0 +1,52 @@ +# Operations + +## Build + +```bash +dotnet restore src/GsdOrchestrator/GsdOrchestrator.csproj +dotnet build src/GsdOrchestrator/GsdOrchestrator.csproj --no-restore --configuration Release +``` + +## Test + +```bash +dotnet restore src/GsdOrchestrator.Tests/GsdOrchestrator.Tests.csproj +dotnet build src/GsdOrchestrator.Tests/GsdOrchestrator.Tests.csproj --no-restore --configuration Release +dotnet test src/GsdOrchestrator.Tests/GsdOrchestrator.Tests.csproj --configuration Release --no-build +``` + +Contract-compatibility gate only (consumer-side check against the pinned `cas-contracts` v1.1 +release, fails red on drift): + +```bash +dotnet test src/GsdOrchestrator.Tests/GsdOrchestrator.Tests.csproj --configuration Release --no-build --filter "FullyQualifiedName~ContractCompatibilityTests" +``` + +## CI (`.github/workflows/ci.yml`, `windows-latest`, 30-minute timeout) + +1. `actions/checkout@v7` +2. `actions/setup-dotnet@v5` (.NET `10.0.1xx`) +3. Restore + build `GsdOrchestrator.csproj` +4. Restore + build `GsdOrchestrator.Tests.csproj` +5. **Contract compatibility** — `ContractCompatibilityTests` filter, fails red on pinned-contract drift +6. **Test** — full suite with `--collect:"XPlat Code Coverage"`, results to `./TestResults` +7. **Upload coverage** — `actions/upload-artifact@v7`, `coverage-results` artifact (always runs) + +There is currently **no coverage-threshold enforcement step** on `main` — coverage is +collected and published as an artifact only. A ratcheted `branch-rate` gate is in progress; +see [Architecture — Test Coverage](../../README.md#test-coverage) and PR #16. + +A separate `.github/workflows/codeql.yml` runs CodeQL analysis (badge in the root `README.md`). + +## Run the orchestrator locally + +```bash +cd src/GsdOrchestrator +dotnet run -- --issue 42 +dotnet run -- --resume +``` + +Requires `.env` with `GITHUB_PERSONAL_ACCESS_TOKEN`, `ANTHROPIC_API_KEY`, +`GSD_GITHUB_OWNER`, `GSD_GITHUB_REPO` set (copy from `.env.example`). + +