From a65f773c8d091d564a371fa19d84c93e5d98e9fe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kim=20Harjam=C3=A4ki?= Date: Wed, 10 Jun 2026 14:51:22 +0300 Subject: [PATCH 1/9] docs: strengthen portfolio proof --- README.md | 178 ++++++++++++++++++---------------------- docs/portfolio-proof.md | 25 ++++++ docs/proof-points.md | 40 +++++++++ 3 files changed, 145 insertions(+), 98 deletions(-) create mode 100644 docs/portfolio-proof.md create mode 100644 docs/proof-points.md diff --git a/README.md b/README.md index 6ec411e..a92ee76 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,8 @@ # GSD Orchestrator -Autonomous GitHub agentic workflow system. Point it at a GitHub issue and it reads the issue, creates a branch, edits code, commits, and opens a PR — all without human intervention. +Autonomous GitHub issue-to-PR engine. Point it at a real issue and it reads the +task, plans the work, creates a branch, edits code, validates the result, and +opens a pull request with durable workflow state. **Stack:** .NET 10 (C#) · GitHub MCP Server · Anthropic Claude · Polly @@ -13,19 +15,37 @@ Part of the [Coding-Autopilot-System](https://github.com/Coding-Autopilot-System --- -## How it works +## Why This Repo Matters -``` -Issue → Analyzing → Branching → Editing → Validating → Committing → PR Creating → Reviewing → Documenting → Done -``` +`gsd-orchestrator` is the execution-focused flagship in the portfolio. Its value is +not just "AI edits code." The stronger signal is the operational model around that: -The state machine drives the entire flow. Each state uses GitHub MCP tools via stdio to interact with GitHub and Claude to reason about what to do next. Checkpoints are written to disk so a failed run can be resumed. +- state-machine controlled execution instead of a single opaque loop +- checkpoint and resume behavior for long-running workflows +- explicit validation gates before PR creation +- GitHub operations routed through MCP tooling rather than hard-coded scripts +- a design that can later sit behind a workstation bundle or a hosted control plane ---- +## Enterprise Proof Points + +- **Durability**: workflow state is checkpointed so interrupted runs can be resumed. +- **Guardrails**: validation blocks unsafe diffs, merge-conflict surprises, and weak test intent. +- **Operational separation**: GitHub tool access is mediated through MCP rather than being spread across ad hoc shell calls. +- **Auditability**: the lifecycle from issue to branch to PR is explicit and reproducible. + +See [docs/portfolio-proof.md](docs/portfolio-proof.md) for a concise reviewer-oriented summary. + +## How It Works + +```text +Issue -> Analyzing -> Branching -> Editing -> Validating -> Committing -> PR Creating -> Reviewing -> Documenting -> Done +``` -## Diagrams +The state machine drives the entire flow. Each state uses GitHub MCP tools via stdio +to interact with GitHub and Claude to reason about what to do next. Checkpoints are +written to disk so a failed run can be resumed. -### State Machine +## State Machine ```mermaid stateDiagram-v2 @@ -42,21 +62,19 @@ stateDiagram-v2 Documenting --> [*] ``` -**State descriptions:** +### State Responsibilities -- **Idle** — Fetches repository metadata and full issue body from GitHub via MCP. Reads labels and default branch. -- **Analyzing** — Asks Claude to produce an implementation plan: branch name, files to modify, summary, and whether tests are required. Retries up to 3 times if JSON parse fails. -- **Branching** — Creates a new feature branch from the default branch. Idempotent: if the branch already exists, resumes from it. -- **Editing** — For each file in the plan, runs a ReAct loop: reads current content, asks Claude to edit it, commits the result via `create_or_update_file`. Max 20 turns per file. -- **Validating** — Runs four gates: file safety blocklist, merge conflict pre-flight, diff size, and test coverage intent. Blocks on critical failures; warns on soft failures. -- **Committing** — Confirms the final commit SHA is present on the branch by calling `get_branch`. Records the commit URL. -- **PrCreating** — Generates a PR title and body via Claude, then opens the pull request. Idempotent: checks for an existing open PR from the same branch before creating. -- **Reviewing** — Posts a bot review comment explaining what changed and why. Requests reviewers from `GSD_REVIEWERS` env var if configured. -- **Documenting** — Updates `docs/github-mcp-tools.md` and `CHANGELOG.md` on the default branch. If `GSD_AUTO_MERGE=true`, squash-merges the PR. +- **Idle** - Fetches repository metadata and full issue body from GitHub via MCP. +- **Analyzing** - Produces an implementation plan, branch intent, file targets, and test expectations. +- **Branching** - Creates or resumes the feature branch. +- **Editing** - Runs iterative edit loops for each file in scope. +- **Validating** - Applies safety checks, merge checks, diff checks, and test-intent checks. +- **Committing** - Confirms the resulting commit is present on the branch. +- **PrCreating** - Creates or reuses the pull request for the work branch. +- **Reviewing** - Posts summary and reviewer guidance. +- **Documenting** - Updates supporting documentation and optional auto-merge flow. ---- - -### Component Topology +## Component Topology ```mermaid flowchart LR @@ -91,73 +109,67 @@ flowchart LR ## Prerequisites -- Windows (Task Scheduler integration for auto-start) +- Windows - [.NET 10 SDK](https://dotnet.microsoft.com/download/dotnet/10.0) -- `github-mcp-server.exe` — already included in the repo root +- `github-mcp-server.exe` already included in the repo root - A GitHub Personal Access Token with `repo` and `read:org` scopes -- An Anthropic API key (for the autonomous orchestrator) - ---- +- An Anthropic API key ## Setup ```bash -# 1. Clone git clone https://github.com/Coding-Autopilot-System/gsd-orchestrator.git cd gsd-orchestrator - -# 2. Create .env cp .env.example .env ``` -Edit `.env` and fill in your values: +Edit `.env` and set: ```env GITHUB_PERSONAL_ACCESS_TOKEN=ghp_... ANTHROPIC_API_KEY=sk-ant-... GSD_GITHUB_OWNER=Coding-Autopilot-System GSD_GITHUB_REPO=gsd-orchestrator -GSD_REVIEWERS= # optional, comma-separated usernames +GSD_REVIEWERS= ``` ---- - -## Run the autonomous orchestrator +## Run The Orchestrator ```bash cd src/GsdOrchestrator - -# Start a new workflow for issue #42 dotnet run -- --issue 42 - -# Resume a failed/interrupted workflow dotnet run -- --resume ``` On success: -``` -✓ PR created: https://github.com/.../pull/N -✓ Docs updated: docs/github-mcp-tools.md, CHANGELOG.md + +```text +? PR created: https://github.com/.../pull/N +? Docs updated: docs/github-mcp-tools.md, CHANGELOG.md Workflow ID: ``` -On failure the workflow ID is printed — use `--resume` to continue from the last checkpoint. +## Demo Review Path ---- +For a fast evaluation of the repo: -## Use GitHub MCP tools in AI CLIs (no orchestrator needed) +1. Read this README for the control flow and operational model. +2. Read [docs/portfolio-proof.md](docs/portfolio-proof.md) for the concise reviewer summary. +3. Inspect `src/GsdOrchestrator/Workflows/States` for the state-machine structure. +4. Inspect the GitHub MCP startup scripts to see how local CLI use and orchestrator use are separated. -The `github-mcp-server.exe` runs as an HTTP server on `localhost:8765` and exposes all GitHub tools to any MCP-compatible AI CLI. +## Use GitHub MCP Tools In AI CLIs -### Auto-start at Windows logon (run once) +The `github-mcp-server.exe` also runs as an HTTP server on `localhost:8765` and can +serve GitHub tools to any MCP-compatible AI CLI. + +### Auto-Start At Windows Logon ```powershell powershell -ExecutionPolicy Bypass -File install-autostart.ps1 ``` -This registers a Task Scheduler task that starts the MCP server at logon. - -### Manual start +### Manual Start ```powershell powershell -ExecutionPolicy Bypass -File start-mcp-server.ps1 @@ -165,8 +177,6 @@ powershell -ExecutionPolicy Bypass -File start-mcp-server.ps1 ### Claude Code -Add to `~/.claude/settings.json`: - ```json { "mcpServers": { @@ -180,54 +190,26 @@ Add to `~/.claude/settings.json`: ### Gemini CLI / Codex CLI -Point your MCP config at `http://localhost:8765/sse` (SSE transport). - ---- - -## Architecture - -``` -┌─────────────────────────────────────────────┐ -│ GSD Orchestrator (.NET 10) │ -│ │ -│ Program.cs → GsdStateMachine │ -│ ├── AnalyzingState │ -│ ├── BranchingState │ -│ ├── EditingState │ -│ ├── ValidatingState │ -│ ├── CommittingState │ -│ ├── PrCreatingState │ -│ ├── ReviewingState │ -│ └── DocumentingState │ -│ │ -│ McpStdioClient ──► github-mcp-server.exe │ -│ (stdio, spawned as child process) │ -│ │ -│ FileCheckpointStore → .checkpoints/ │ -│ Anthropic.SDK → Claude (claude-sonnet-4-6) │ -│ Polly → retry + exponential backoff │ -└─────────────────────────────────────────────┘ -``` - -The MCP server is spawned as a **stdio child process** by the orchestrator — separate from the HTTP instance used by AI CLIs. +Point MCP configuration at `http://localhost:8765/sse`. ---- +## Architecture Summary -## Project structure +The MCP server is spawned as a stdio child process by the orchestrator, separate from +the HTTP instance used by AI CLIs. -``` +```text GithubMCP/ -├── github-mcp-server.exe # Pre-built GitHub MCP Server binary -├── start-mcp-server.ps1 # Start HTTP MCP server (for AI CLIs) -├── install-autostart.ps1 # Register Task Scheduler auto-start -├── .env.example # Environment variable template -└── src/GsdOrchestrator/ - ├── Program.cs # Entry point, DI wiring, CLI args - ├── Auth/ # GitHub PAT provider - ├── Checkpointing/ # File-based workflow checkpoints - ├── Mcp/ # MCP stdio client + tool dispatcher - └── Workflows/ - ├── GsdStateMachine.cs # Orchestrates state transitions - ├── Models/ # WorkflowContext, enums - └── States/ # One file per workflow state +|-- github-mcp-server.exe +|-- start-mcp-server.ps1 +|-- install-autostart.ps1 +|-- .env.example +`-- src/GsdOrchestrator/ + |-- Program.cs + |-- Auth/ + |-- Checkpointing/ + |-- Mcp/ + `-- Workflows/ + |-- GsdStateMachine.cs + |-- Models/ + `-- States/ ``` diff --git a/docs/portfolio-proof.md b/docs/portfolio-proof.md new file mode 100644 index 0000000..54f4f2a --- /dev/null +++ b/docs/portfolio-proof.md @@ -0,0 +1,25 @@ +# GSD Orchestrator Portfolio Proof + +This repository is a hiring-facing proof point for autonomous engineering workflow design. + +## What It Demonstrates + +- A .NET 10 state machine driving issue-to-PR automation +- MCP-mediated GitHub operations instead of scattered direct API logic +- Checkpointed workflow durability and resume behavior +- Guardrailed validation before pull request creation +- A local-first execution model that can later be bundled into a workstation or hosted control plane + +## Why It Is Credible + +- The workflow is decomposed into explicit states rather than hidden inside one prompt loop. +- GitHub operations, AI reasoning, and validation gates are separated by responsibility. +- The local AI CLI path and the orchestrator path are distinct and inspectable. +- The repo exposes the exact code paths where planning, editing, validation, and PR creation happen. + +## Fast Review Path + +1. `src/GsdOrchestrator/Workflows/GsdStateMachine.cs` +2. `src/GsdOrchestrator/Workflows/States` +3. `src/GsdOrchestrator/Mcp` +4. `install-autostart.ps1` and `start-mcp-server.ps1` diff --git a/docs/proof-points.md b/docs/proof-points.md new file mode 100644 index 0000000..96dbce6 --- /dev/null +++ b/docs/proof-points.md @@ -0,0 +1,40 @@ +# Proof Points + +This document maps the public claims in the repository README to code or tests in the repo. It is intentionally narrow: portfolio credibility is better served by traceable proof than by broad AI claims. + +## Workflow capability + +| Claim | Evidence | +| --- | --- | +| The workflow is state-machine driven | `src/GsdOrchestrator/Workflows/GsdStateMachine.cs` | +| The implemented states include triage and test generation | `src/GsdOrchestrator/Workflows/Models/WorkflowModels.cs` | +| The host registers Idle, Triaging, Analyzing, Branching, Editing, TestGenerating, Validating, Committing, PrCreating, Reviewing, and Documenting | `src/GsdOrchestrator/Program.cs` | +| Workflows can resume from checkpoints | `src/GsdOrchestrator/Workflows/GsdStateMachine.cs`, `src/GsdOrchestrator.Tests/GsdStateMachineTests.cs` | + +## Operating modes + +| Mode | Evidence | +| --- | --- | +| Issue workflow mode via `--issue ` | `src/GsdOrchestrator/Program.cs` | +| Triage-only mode via `--issue --triage` | `src/GsdOrchestrator/Program.cs`, `src/GsdOrchestrator.Tests/TriagingStateTests.cs` | +| PR review mode via `--pr ` | `src/GsdOrchestrator/Program.cs`, `src/GsdOrchestrator.Tests/ReviewingStateTests.cs` | +| Watch mode across configured repos via `--watch` | `src/GsdOrchestrator/Program.cs`, `src/GsdOrchestrator/Workflows/Models/RepoConfigLoader.cs` | + +## Enterprise-oriented control points + +| Control point | Evidence | +| --- | --- | +| Retry and circuit-breaker protection around MCP tool calls | `src/GsdOrchestrator/Program.cs` | +| Structured logging through Serilog | `src/GsdOrchestrator/Program.cs` | +| Checkpoint files persisted under repo-local state | `src/GsdOrchestrator/Checkpointing/FileCheckpointStore.cs`, `src/GsdOrchestrator.Tests/MultiRepoConfigTests.cs` | +| Validation gates before commit and PR flow | `src/GsdOrchestrator/Workflows/States/ValidatingState.cs` | +| Review submission to GitHub as part of the workflow | `src/GsdOrchestrator/Workflows/States/ReviewingState.cs`, `src/GsdOrchestrator.Tests/ReviewingStateTests.cs` | + +## Demo-ready paths + +1. Run `dotnet run -- --issue 42` from `src/GsdOrchestrator` to execute the issue workflow. +2. Run `dotnet run -- --issue 42 --triage` to demonstrate issue classification without code changes. +3. Run `dotnet run -- --pr 7` to demonstrate PR review mode. +4. Run `dotnet run -- --watch` to demonstrate polling across configured repositories. + +These commands still require valid `.env` configuration and external service credentials. The point here is that the modes are implemented in the codebase, not just described in slides. From c31493b3d7e7218e9ce51d0a00153f761bfc6ae6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kim=20Harjam=C3=A4ki?= Date: Wed, 10 Jun 2026 18:37:45 +0300 Subject: [PATCH 2/9] docs: align README with implemented workflow --- README.md | 43 +++++++++++++++++++++++++++++-------------- 1 file changed, 29 insertions(+), 14 deletions(-) diff --git a/README.md b/README.md index a92ee76..28e5e34 100644 --- a/README.md +++ b/README.md @@ -38,12 +38,14 @@ See [docs/portfolio-proof.md](docs/portfolio-proof.md) for a concise reviewer-or ## How It Works ```text -Issue -> Analyzing -> Branching -> Editing -> Validating -> Committing -> PR Creating -> Reviewing -> Documenting -> Done +Issue -> Idle -> Triaging -> Analyzing -> Branching -> Editing -> TestGenerating -> Validating -> Committing -> PrCreating -> Reviewing -> Documenting -> Done ``` -The state machine drives the entire flow. Each state uses GitHub MCP tools via stdio +Actionable issues follow the full path. Non-actionable issues and `--triage` runs +exit after `Triaging`. The separate `--pr` mode enters at `Reviewing` and exits +after submitting its structured review. Each state uses GitHub MCP tools via stdio to interact with GitHub and Claude to reason about what to do next. Checkpoints are -written to disk so a failed run can be resumed. +written to disk so an interrupted or failed run can be inspected and resumed. ## State Machine @@ -51,28 +53,41 @@ written to disk so a failed run can be resumed. stateDiagram-v2 direction LR [*] --> Idle - Idle --> Analyzing + Idle --> Triaging + Triaging --> Analyzing: actionable issue + Triaging --> Done: non-actionable or --triage Analyzing --> Branching Branching --> Editing - Editing --> Validating + Editing --> TestGenerating + TestGenerating --> Validating Validating --> Committing + Validating --> Failed: blocking gate Committing --> PrCreating PrCreating --> Reviewing - Reviewing --> Documenting - Documenting --> [*] + Reviewing --> Documenting: issue mode + [*] --> Reviewing: --pr mode + Reviewing --> Done: PR-review mode + Documenting --> Done + Done --> [*] + Failed --> [*] ``` +Any unhandled state exception also transitions the workflow to `Failed`. + ### State Responsibilities - **Idle** - Fetches repository metadata and full issue body from GitHub via MCP. +- **Triaging** - Classifies the issue, checks for duplicates, posts the triage result, and routes actionable issues to analysis or exits. - **Analyzing** - Produces an implementation plan, branch intent, file targets, and test expectations. - **Branching** - Creates or resumes the feature branch. -- **Editing** - Runs iterative edit loops for each file in scope. -- **Validating** - Applies safety checks, merge checks, diff checks, and test-intent checks. -- **Committing** - Confirms the resulting commit is present on the branch. +- **Editing** - Runs iterative edit loops and commits each changed file to the feature branch. +- **TestGenerating** - Generates or extends xUnit tests for eligible edited C# source files. +- **Validating** - Applies file-safety, merge-conflict, diff-size, test-intent, and generated-test structure checks. +- **Committing** - Confirms and records the latest commit on the feature branch. - **PrCreating** - Creates or reuses the pull request for the work branch. -- **Reviewing** - Posts summary and reviewer guidance. -- **Documenting** - Updates supporting documentation and optional auto-merge flow. +- **Reviewing** - Posts issue-mode reviewer guidance and requests reviewers, or submits a structured review in `--pr` mode. +- **Documenting** - Refreshes the MCP tool catalog and changelog on the default branch, then optionally auto-merges. +- **Done / Failed** - Terminal outcomes recorded by the state machine. ## Component Topology @@ -144,8 +159,8 @@ dotnet run -- --resume On success: ```text -? PR created: https://github.com/.../pull/N -? Docs updated: docs/github-mcp-tools.md, CHANGELOG.md +✓ PR created: https://github.com/.../pull/N +✓ Docs updated: docs/github-mcp-tools.md, CHANGELOG.md Workflow ID: ``` From 7543f89c142d1831c7ea1057ac382cc7ba0d91db Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kim=20Harjam=C3=A4ki?= Date: Wed, 10 Jun 2026 18:43:00 +0300 Subject: [PATCH 3/9] docs(quick-260610-ppo): record validated README workflow fix --- .planning/STATE.md | 8 +++++ .../260610-ppo-PLAN.md | 34 +++++++++++++++++++ .../260610-ppo-SUMMARY.md | 25 ++++++++++++++ .../260610-ppo-VERIFICATION.md | 24 +++++++++++++ 4 files changed, 91 insertions(+) create mode 100644 .planning/quick/260610-ppo-fix-pr-6-readme-workflow-state-diagram-r/260610-ppo-PLAN.md create mode 100644 .planning/quick/260610-ppo-fix-pr-6-readme-workflow-state-diagram-r/260610-ppo-SUMMARY.md create mode 100644 .planning/quick/260610-ppo-fix-pr-6-readme-workflow-state-diagram-r/260610-ppo-VERIFICATION.md diff --git a/.planning/STATE.md b/.planning/STATE.md index 0aca5b6..f6dbb1c 100644 --- a/.planning/STATE.md +++ b/.planning/STATE.md @@ -16,6 +16,8 @@ stopped_at: Milestone complete (Phase 16 was final phase) # Project State — gsd-orchestrator Feature Expansion (Milestone 3.0) +Last activity: 2026-06-10 - Completed quick task 260610-ppo: Fix PR #6 README workflow state diagram responsibilities to match actual code including Triaging and TestGenerating and render success sample cleanly + ## Current Status **Active Phase:** Phase 16 — Multi-Repo Support (planned — 2 plans ready) @@ -267,3 +269,9 @@ All 11 phases and 11 v2 requirements satisfied. Full portfolio live at: |------|-----------|------|------------| | 16-01 | Add RepoConfig record + RepoConfigLoader stub; namespace FileCheckpointStore.StatePath; 7 RED/GREEN test stubs | 1 | yes | | 16-02 | Implement RepoConfigLoader.Load(); remove IConfiguration from IdleState; multi-repo watch loop; all 30 tests GREEN | 2 | yes | + +### Quick Tasks Completed + +| # | Description | Date | Commit | Status | Directory | +|---|-------------|------|--------|--------|-----------| +| 260610-ppo | Fix PR #6 README workflow/state documentation and success sample | 2026-06-10 | c31493b | Verified | [260610-ppo-fix-pr-6-readme-workflow-state-diagram-r](./quick/260610-ppo-fix-pr-6-readme-workflow-state-diagram-r/) | diff --git a/.planning/quick/260610-ppo-fix-pr-6-readme-workflow-state-diagram-r/260610-ppo-PLAN.md b/.planning/quick/260610-ppo-fix-pr-6-readme-workflow-state-diagram-r/260610-ppo-PLAN.md new file mode 100644 index 0000000..eb8e290 --- /dev/null +++ b/.planning/quick/260610-ppo-fix-pr-6-readme-workflow-state-diagram-r/260610-ppo-PLAN.md @@ -0,0 +1,34 @@ +--- +quick_id: 260610-ppo +status: complete +mode: quick-full +description: Fix PR #6 README workflow state diagram responsibilities to match actual code including Triaging and TestGenerating and render success sample cleanly +--- + +# Quick Task 260610-ppo Plan + +## Goal + +Make the README workflow documentation accurately reflect the implemented state machine and render the success sample cleanly. + +## Must Haves + +- The documented issue workflow includes `Idle`, `Triaging`, and `TestGenerating` in their implemented order. +- The state diagram shows actionable triage continuing to `Analyzing` and non-actionable or triage-only runs exiting to `Done`. +- State responsibilities match the behavior in `src/GsdOrchestrator/Workflows/States`. +- The success sample uses render-safe text matching `Program.PrintResult`. + +## Task + +### 1. Correct README workflow documentation + +**Files:** `README.md` + +**Action:** Update the workflow summary, Mermaid state diagram, state responsibilities, and success output sample from the current source implementation. + +**Verify:** +- Compare every documented transition with `WorkflowModels.cs` and each state implementation. +- Run `dotnet test GithubMCP.slnx`. +- Run `git diff --check`. + +**Done:** README accurately documents the runtime flow, includes `Triaging` and `TestGenerating`, and contains a clean success sample. diff --git a/.planning/quick/260610-ppo-fix-pr-6-readme-workflow-state-diagram-r/260610-ppo-SUMMARY.md b/.planning/quick/260610-ppo-fix-pr-6-readme-workflow-state-diagram-r/260610-ppo-SUMMARY.md new file mode 100644 index 0000000..5d5e1c4 --- /dev/null +++ b/.planning/quick/260610-ppo-fix-pr-6-readme-workflow-state-diagram-r/260610-ppo-SUMMARY.md @@ -0,0 +1,25 @@ +--- +quick_id: 260610-ppo +status: complete +completed: 2026-06-10 +implementation_commit: c31493b +--- + +# Quick Task 260610-ppo Summary + +Updated `README.md` so its workflow summary, Mermaid state diagram, and state responsibilities match the implemented runtime. + +## Changes + +- Added `Idle`, `Triaging`, and `TestGenerating` to the documented issue workflow. +- Documented actionable, non-actionable, triage-only, and PR-review transitions. +- Aligned every state responsibility with the corresponding state implementation. +- Replaced broken success-sample question marks with the UTF-8 checkmarks emitted by `Program.PrintResult`. + +## Validation + +- `dotnet test GithubMCP.slnx --configuration Release`: 35 passed. +- README source-evidence check: passed. +- `git diff --check`: passed. + +Implementation commit: `c31493b` diff --git a/.planning/quick/260610-ppo-fix-pr-6-readme-workflow-state-diagram-r/260610-ppo-VERIFICATION.md b/.planning/quick/260610-ppo-fix-pr-6-readme-workflow-state-diagram-r/260610-ppo-VERIFICATION.md new file mode 100644 index 0000000..a749993 --- /dev/null +++ b/.planning/quick/260610-ppo-fix-pr-6-readme-workflow-state-diagram-r/260610-ppo-VERIFICATION.md @@ -0,0 +1,24 @@ +--- +quick_id: 260610-ppo +status: passed +verified: 2026-06-10 +--- + +# Quick Task 260610-ppo Verification + +## Result + +Passed. The PR #6 README blocker is resolved against the current source implementation. + +## Must-Have Evidence + +- The workflow summary and diagram include `Idle -> Triaging -> Analyzing` and `Editing -> TestGenerating -> Validating`. +- The diagram includes triage exits to `Done`, issue-mode review to `Documenting`, PR-review mode to `Done`, and validation blocking to `Failed`. +- State responsibilities were checked against all registered implementations under `src/GsdOrchestrator/Workflows/States`. +- The success sample contains the same UTF-8 checkmarks and labels emitted by `Program.PrintResult`. + +## Commands + +- `dotnet test GithubMCP.slnx --configuration Release`: passed, 35/35 tests. +- README evidence check: passed. +- `git diff --check`: passed. From 6c18a9ced29e2b0c7e4a85c6ec5954459c0fe286 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kim=20Harjam=C3=A4ki?= Date: Wed, 10 Jun 2026 19:01:27 +0300 Subject: [PATCH 4/9] fix(ci): resolve F-01 run solution tests --- .github/workflows/ci.yml | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index aaee639..16dced7 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -19,7 +19,10 @@ jobs: dotnet-version: '10.0.1xx' - name: Restore dependencies - run: dotnet restore src/GsdOrchestrator/GsdOrchestrator.csproj + run: dotnet restore GithubMCP.slnx - name: Build - run: dotnet build src/GsdOrchestrator/GsdOrchestrator.csproj --no-restore --configuration Release + run: dotnet build GithubMCP.slnx --no-restore --configuration Release + + - name: Test + run: dotnet test GithubMCP.slnx --no-build --configuration Release From 76253cb8f5f82a3f801bef2e3fcedf52a591a0e3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kim=20Harjam=C3=A4ki?= Date: Wed, 10 Jun 2026 19:02:32 +0300 Subject: [PATCH 5/9] fix(testgen): resolve F-02 reject empty LLM output --- .../TestGeneratingStateTests.cs | 28 +++++++++++++++++++ .../Workflows/States/TestGeneratingState.cs | 2 +- 2 files changed, 29 insertions(+), 1 deletion(-) diff --git a/src/GsdOrchestrator.Tests/TestGeneratingStateTests.cs b/src/GsdOrchestrator.Tests/TestGeneratingStateTests.cs index c58dc49..33aa23b 100644 --- a/src/GsdOrchestrator.Tests/TestGeneratingStateTests.cs +++ b/src/GsdOrchestrator.Tests/TestGeneratingStateTests.cs @@ -72,6 +72,22 @@ private static IChatClient BuildLlmNoToolCall() return llm; } + + private static IChatClient BuildLlmWithEmptyToolContent() + { + var llm = Substitute.For(); + var functionCall = new FunctionCallContent( + "call_empty", "write_file", + new Dictionary { ["content"] = " ", ["commitMessage"] = "test: empty" }); + var response = new ChatResponse(new ChatMessage(ChatRole.Assistant, [functionCall])) + { + FinishReason = ChatFinishReason.ToolCalls + }; + llm.GetResponseAsync( + Arg.Any>(), Arg.Any(), Arg.Any()) + .Returns(Task.FromResult(response)); + return llm; + } // Returns IMcpClient that stubs get_file_contents and create_or_update_file. // When testFileExists=true, the second get_file_contents call (test file) returns existing sha. private static IMcpClient BuildMcpClient(bool sourceFileExists = true, bool testFileExists = false) @@ -241,4 +257,16 @@ await mcp.Received(2).CallToolAsync( Arg.Any(), Arg.Any()); } + [Fact] + public async Task ExecuteAsync_WithWhitespaceToolContent_SkipsWithoutCommitting() + { + var mcp = BuildMcpClient(); + var sut = BuildSut(mcp, BuildLlmWithEmptyToolContent()); + + var result = await sut.ExecuteAsync(BuildContext(), CancellationToken.None); + + Assert.True(result.TestGeneration!.GeneratedTests[0].WasSkipped); + await mcp.DidNotReceive().CallToolAsync( + Arg.Is("create_or_update_file"), Arg.Any(), Arg.Any()); + } } diff --git a/src/GsdOrchestrator/Workflows/States/TestGeneratingState.cs b/src/GsdOrchestrator/Workflows/States/TestGeneratingState.cs index 1ef89a2..754c795 100644 --- a/src/GsdOrchestrator/Workflows/States/TestGeneratingState.cs +++ b/src/GsdOrchestrator/Workflows/States/TestGeneratingState.cs @@ -169,7 +169,7 @@ Generate comprehensive xUnit tests and call write_file with the complete test fi { if (call.Name == "write_file") { - finalContent = call.Arguments?["content"]?.ToString(); + var rawContent = call.Arguments?["content"]?.ToString();`r`n if (!string.IsNullOrWhiteSpace(rawContent))`r`n finalContent = rawContent; messages.Add(new ChatMessage(ChatRole.Tool, [new FunctionResultContent(call.CallId, "File staged for commit.")])); } From 0baa1f3e365fd0424c6dbce0abc7040c48b0a2c2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kim=20Harjam=C3=A4ki?= Date: Wed, 10 Jun 2026 19:03:07 +0300 Subject: [PATCH 6/9] fix(testgen): complete F-02 response guards --- .../Workflows/States/TestGeneratingState.cs | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/GsdOrchestrator/Workflows/States/TestGeneratingState.cs b/src/GsdOrchestrator/Workflows/States/TestGeneratingState.cs index 754c795..f4df005 100644 --- a/src/GsdOrchestrator/Workflows/States/TestGeneratingState.cs +++ b/src/GsdOrchestrator/Workflows/States/TestGeneratingState.cs @@ -160,7 +160,13 @@ Generate comprehensive xUnit tests and call write_file with the complete test fi { turns++; var response = await _llm.GetResponseAsync(messages, options, ct); - var lastMessage = response.Messages.Last(); + var lastMessage = response.Messages.LastOrDefault(); + if (lastMessage is null) + { + _logger.LogWarning("LLM returned no messages for {TestPath}, turn {Turn}", testPath, turns); + break; + } + messages.Add(lastMessage); if (response.FinishReason == ChatFinishReason.ToolCalls) @@ -169,7 +175,9 @@ Generate comprehensive xUnit tests and call write_file with the complete test fi { if (call.Name == "write_file") { - var rawContent = call.Arguments?["content"]?.ToString();`r`n if (!string.IsNullOrWhiteSpace(rawContent))`r`n finalContent = rawContent; + var rawContent = call.Arguments?["content"]?.ToString(); + if (!string.IsNullOrWhiteSpace(rawContent)) + finalContent = rawContent; messages.Add(new ChatMessage(ChatRole.Tool, [new FunctionResultContent(call.CallId, "File staged for commit.")])); } From 8f9e6cd5386e812a4c0bafc5a5ca0f7797067327 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kim=20Harjam=C3=A4ki?= Date: Wed, 10 Jun 2026 19:03:33 +0300 Subject: [PATCH 7/9] docs(audit): record F-01 through F-08 classification --- .../260610-enterprise-audit-fix/AUDIT-FIX.md | 34 +++++++++++++++++++ 1 file changed, 34 insertions(+) create mode 100644 .planning/audits/260610-enterprise-audit-fix/AUDIT-FIX.md diff --git a/.planning/audits/260610-enterprise-audit-fix/AUDIT-FIX.md b/.planning/audits/260610-enterprise-audit-fix/AUDIT-FIX.md new file mode 100644 index 0000000..2c8cf81 --- /dev/null +++ b/.planning/audits/260610-enterprise-audit-fix/AUDIT-FIX.md @@ -0,0 +1,34 @@ +# Enterprise Audit-Fix Report + +**Date:** 2026-06-10 +**Source:** `gsd-audit-fix --severity all --max 8` +**Scope:** .NET correctness, workflow durability, security, GitHub integration, observability, tests, CI, and documentation. + +## Classification + +| ID | Finding | Severity | Classification | Status | +|---|---|---|---|---| +| F-01 | CI builds only the production project and never runs tests | high | auto-fixable | fixed | +| F-02 | Test generation accepts blank tool content and crashes on empty LLM messages | high | auto-fixable | fixed after validation repair | +| F-03 | Editing state accepts blank tool content and crashes on empty LLM messages | high | auto-fixable | not attempted after pipeline stop | +| F-04 | Workflow states use null-forgiving context dereferences instead of diagnostic guards | medium | auto-fixable | not attempted after pipeline stop | +| F-05 | Checkpoint writes reuse a predictable temporary filename and can collide | medium | auto-fixable | not attempted after pipeline stop | +| F-06 | Watch mode examines only 20 issues and evicts processed issues nondeterministically | medium | auto-fixable | not attempted after pipeline stop | +| F-07 | MCP pending requests may hang when the child process exits cleanly | medium | auto-fixable | not attempted after pipeline stop | +| F-08 | Repo configuration accepts empty owner/repo values and invalid delays | low | auto-fixable | not attempted after pipeline stop | + +## Manual-Only Findings + +- Replace the committed `github-mcp-server.exe` with a reproducible, checksum-verified acquisition or release packaging strategy. +- Decide the production authentication model. The current local PAT model conflicts with the target enterprise managed-identity/OAuth posture. +- Run live end-to-end GitHub and LLM workflow UAT; mocked tests cannot prove external API behavior, prompt robustness, or reviewer permissions. + +## Fix Evidence + +- F-01: CI restores/builds the solution and runs the complete test suite. +- F-02: Blank generated test content is skipped and empty LLM response collections are handled safely; regression coverage added. +- Final local validation: `dotnet build GithubMCP.slnx --configuration Release --no-restore`, `dotnet test GithubMCP.slnx --configuration Release --no-build`, and `git diff --check`. + +## Pipeline Stop + +The first F-02 edit failed compilation because a patch transport inserted literal newline escapes. The finding was repaired immediately and the full suite returned green. In accordance with `gsd-audit-fix`, remaining findings were marked not-attempted rather than continuing after a failed validation. \ No newline at end of file From a18013939af5038db0e11ba563381ee60e0572b2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kim=20Harjam=C3=A4ki?= Date: Wed, 10 Jun 2026 19:04:20 +0300 Subject: [PATCH 8/9] Revert "fix(ci): resolve F-01 run solution tests" This reverts commit 6c18a9ced29e2b0c7e4a85c6ec5954459c0fe286. --- .github/workflows/ci.yml | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 16dced7..aaee639 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -19,10 +19,7 @@ jobs: dotnet-version: '10.0.1xx' - name: Restore dependencies - run: dotnet restore GithubMCP.slnx + run: dotnet restore src/GsdOrchestrator/GsdOrchestrator.csproj - name: Build - run: dotnet build GithubMCP.slnx --no-restore --configuration Release - - - name: Test - run: dotnet test GithubMCP.slnx --no-build --configuration Release + run: dotnet build src/GsdOrchestrator/GsdOrchestrator.csproj --no-restore --configuration Release From 9a471e21a064875a16c500657ab5b0b3e1109b6a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kim=20Harjam=C3=A4ki?= Date: Wed, 10 Jun 2026 19:04:21 +0300 Subject: [PATCH 9/9] docs(audit): record F-01 workflow scope blocker --- .planning/audits/260610-enterprise-audit-fix/AUDIT-FIX.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.planning/audits/260610-enterprise-audit-fix/AUDIT-FIX.md b/.planning/audits/260610-enterprise-audit-fix/AUDIT-FIX.md index 2c8cf81..edfb0bf 100644 --- a/.planning/audits/260610-enterprise-audit-fix/AUDIT-FIX.md +++ b/.planning/audits/260610-enterprise-audit-fix/AUDIT-FIX.md @@ -8,7 +8,7 @@ | ID | Finding | Severity | Classification | Status | |---|---|---|---|---| -| F-01 | CI builds only the production project and never runs tests | high | auto-fixable | fixed | +| F-01 | CI builds only the production project and never runs tests | high | auto-fixable | blocked: GitHub token lacks workflow scope | | F-02 | Test generation accepts blank tool content and crashes on empty LLM messages | high | auto-fixable | fixed after validation repair | | F-03 | Editing state accepts blank tool content and crashes on empty LLM messages | high | auto-fixable | not attempted after pipeline stop | | F-04 | Workflow states use null-forgiving context dereferences instead of diagnostic guards | medium | auto-fixable | not attempted after pipeline stop | @@ -25,7 +25,7 @@ ## Fix Evidence -- F-01: CI restores/builds the solution and runs the complete test suite. +- F-01: The fix was validated locally, then reverted because GitHub rejected workflow updates from the active OAuth token without `workflow` scope. - F-02: Blank generated test content is skipped and empty LLM response collections are handled safely; regression coverage added. - Final local validation: `dotnet build GithubMCP.slnx --configuration Release --no-restore`, `dotnet test GithubMCP.slnx --configuration Release --no-build`, and `git diff --check`.