From dacecfbbb72c923c3645262de92fe2dc1f02b109 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=B0=8F=E6=A9=98?= Date: Fri, 22 May 2026 05:21:19 +0000 Subject: [PATCH] feat: create .workflows/solve-issue.yaml MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit TDD-driven issue resolution workflow with 5 roles: - planner: analyzes issue, outputs TDD test spec (stored in CAS) - developer: implements code following TDD - reviewer: code standards compliance check (not functionality) - tester: functional correctness verification - committer: commits and creates PR Graph handles bounce-backs: reviewer→developer, tester→developer, tester→planner (fix_spec), committer→developer (hook_failed). Refs #370 --- .workflows/solve-issue.yaml | 187 ++++++++++++++++++++++++++++++++++++ 1 file changed, 187 insertions(+) create mode 100644 .workflows/solve-issue.yaml diff --git a/.workflows/solve-issue.yaml b/.workflows/solve-issue.yaml new file mode 100644 index 0000000..0b5ff20 --- /dev/null +++ b/.workflows/solve-issue.yaml @@ -0,0 +1,187 @@ +name: "solve-issue" +description: "TDD-driven issue resolution for small, focused changes" +roles: + planner: + description: "Analyzes issue and outputs a TDD test spec" + goal: "You are a planning agent. You analyze Gitea issues and produce a TDD test specification that downstream roles will implement and verify." + capabilities: + - issue-analysis + - planning + procedure: | + On first run (no previous steps): + 1. Read the issue and all comments from Gitea using `tea issues --repo ` + 2. Read CLAUDE.md (or equivalent project conventions file) to understand coding standards + 3. Assess whether the issue has enough information to produce a test spec + 4. If insufficient info: comment on the issue via `tea issues comment "..."` (skip if you already commented), then output status=insufficient_info and terminate + 5. If sufficient: produce a detailed TDD test spec in markdown covering all scenarios + + On subsequent runs (bounced back by tester with fix_spec): + 1. Read the tester's output from the previous step to understand what's wrong with the spec + 2. Revise the test spec accordingly + + After producing the test spec: + 1. Store it via `uwf cas put ""` and capture the returned hash + 2. Put the hash in meta.plan + output: "Output a brief summary of the test spec. The full spec is stored in CAS — put its hash in meta.plan." + meta: + type: object + properties: + status: + type: string + enum: [ready, insufficient_info] + plan: + type: string + required: [status] + developer: + description: "TDD implementation per test spec" + goal: "You are a developer agent. You implement code changes following TDD — write tests first, then implementation." + capabilities: + - cursor-agent + procedure: | + 1. Read the test spec from CAS: `uwf cas get ` (find the hash from the latest planner step's meta.plan) + 2. If bounced back from reviewer or tester: read the previous role's output to understand what needs fixing + 3. Write tests first based on the spec + 4. Implement the code to make tests pass + 5. Ensure `npm run build` passes with no errors + 6. Run `npm test` to verify all tests pass + output: "List all files changed and provide a summary of the implementation." + meta: + type: object + properties: + status: + type: string + enum: [done, failed] + required: [status] + reviewer: + description: "Code standards compliance check" + goal: "You are a code reviewer. You verify code standards compliance — NOT functionality (that's the tester's job)." + capabilities: + - code-review + - static-analysis + procedure: | + Hard checks (must all pass): + 1. `npm run build` — no build errors + 2. `npx biome check` — no lint violations + 3. TypeScript strict mode — no type errors + + Soft checks (review against CLAUDE.md conventions): + - Functional-first: `function` + `type`, not `class` + `interface` + - No optional properties (`?:`) — use `T | null` + - Naming conventions (kebab-case files, PascalCase types, camelCase functions) + - Module boundary discipline (folder exports via index.ts) + - No `console.log` (use structured logger) + - No dynamic imports in production code + + Only review standards compliance. Do NOT test functionality. + If rejecting, you MUST explain the specific reason in your output. + output: "Approve or reject with detailed comments explaining your decision." + meta: + type: object + properties: + approved: + type: boolean + required: [approved] + tester: + description: "Functional correctness verification" + goal: "You are a tester agent. You verify that the implementation correctly satisfies every scenario in the test spec." + capabilities: + - testing + procedure: | + 1. Run `npm test` for automated test verification + 2. Read the test spec from CAS: `uwf cas get ` (find the hash from the latest planner step's meta.plan) + 3. Verify each scenario in the spec is covered and passing + 4. Determine outcome: + - passed: all scenarios verified, tests pass + - fix_code: tests fail or implementation doesn't match spec → send back to developer + - fix_spec: the spec itself is wrong or incomplete → send back to planner + output: "Report test results and verification status for each scenario in the spec." + meta: + type: object + properties: + status: + type: string + enum: [passed, fix_code, fix_spec] + required: [status] + committer: + description: "Commits and creates PR" + goal: "You are a committer agent. You create a clean commit and push a PR linking the original issue." + capabilities: [] + procedure: | + 1. Stage all changes: `git add -A` + 2. Commit with a descriptive message referencing the issue: `git commit -m "type: description\n\nFixes #N"` + 3. Push the branch: `git push -u origin ` + - If push hook fails: capture the error log in your output, mark hook_failed + 4. On push success: create a PR via `tea pr create --title "..." --description "..."` + - PR description must link the issue with `Fixes #N` + output: "Report whether commit and PR creation succeeded. Include the PR URL on success or error log on failure." + meta: + type: object + properties: + success: + type: boolean + required: [success] +conditions: + insufficientInfo: + description: "Planner determined there's not enough info to proceed" + expression: "steps[-1].output.status = 'insufficient_info'" + ready: + description: "Planner produced a test spec" + expression: "steps[-1].output.status = 'ready'" + devDone: + description: "Developer finished implementation" + expression: "steps[-1].output.status = 'done'" + devFailed: + description: "Developer failed to implement" + expression: "steps[-1].output.status = 'failed'" + notApproved: + description: "Reviewer rejected the implementation" + expression: "steps[-1].output.approved = false" + approved: + description: "Reviewer approved the implementation" + expression: "steps[-1].output.approved = true" + fixCode: + description: "Tester found code issues" + expression: "steps[-1].output.status = 'fix_code'" + fixSpec: + description: "Tester found spec issues" + expression: "steps[-1].output.status = 'fix_spec'" + passed: + description: "Tester verified all scenarios pass" + expression: "steps[-1].output.status = 'passed'" + hookFailed: + description: "Push hook failed" + expression: "steps[-1].output.success = false" + pushSuccess: + description: "Commit and PR created successfully" + expression: "steps[-1].output.success = true" +graph: + $START: + - role: "planner" + condition: null + planner: + - role: "$END" + condition: "insufficientInfo" + - role: "developer" + condition: "ready" + developer: + - role: "$END" + condition: "devFailed" + - role: "reviewer" + condition: "devDone" + reviewer: + - role: "developer" + condition: "notApproved" + - role: "tester" + condition: "approved" + tester: + - role: "developer" + condition: "fixCode" + - role: "planner" + condition: "fixSpec" + - role: "committer" + condition: "passed" + committer: + - role: "developer" + condition: "hookFailed" + - role: "$END" + condition: "pushSuccess"