name: Agent Verification Workflow on: issues: types: [labeled] jobs: # When work is claimed, track the implementer track-implementer: if: github.event.label.name == 'agent:wip' runs-on: ubuntu-latest steps: - name: Record implementer run: | echo "Implementer: ${{ github.actor }}" # Could store in issue body or external system # When work is submitted for review, add to verification queue request-verification: if: github.event.label.name == 'agent:review' runs-on: ubuntu-latest steps: - name: Add to Workstation for verification uses: actions/add-to-project@v1.0.2 with: project-url: https://github.com/orgs/host-uk/projects/2 github-token: ${{ secrets.PROJECT_TOKEN }} - name: Comment verification needed uses: actions/github-script@v8 with: script: | const implementer = context.payload.sender.login; await github.rest.issues.createComment({ owner: context.repo.owner, repo: context.repo.repo, issue_number: context.issue.number, body: `## 🔍 Verification Required\n\nWork submitted by @${implementer}.\n\n**Rule:** A different agent must verify this work.\n\nTo verify:\n1. Review the implementation\n2. Run tests if applicable\n3. Add \`verified\` or \`verify-failed\` label\n\n_Self-verification is not allowed._` }); # Block self-verification check-verification: if: github.event.label.name == 'verified' || github.event.label.name == 'verify-failed' runs-on: ubuntu-latest steps: - name: Get issue details id: issue uses: actions/github-script@v8 with: script: | const issue = await github.rest.issues.get({ owner: context.repo.owner, repo: context.repo.repo, issue_number: context.issue.number }); // Check timeline for who added agent:wip const timeline = await github.rest.issues.listEventsForTimeline({ owner: context.repo.owner, repo: context.repo.repo, issue_number: context.issue.number, per_page: 100 }); const wipEvent = timeline.data.find(e => e.event === 'labeled' && e.label?.name === 'agent:wip' ); const implementer = wipEvent?.actor?.login || 'unknown'; const verifier = context.payload.sender.login; console.log(`Implementer: ${implementer}`); console.log(`Verifier: ${verifier}`); if (implementer === verifier) { core.setFailed(`Self-verification not allowed. ${verifier} cannot verify their own work.`); } return { implementer, verifier }; - name: Record verification if: success() uses: actions/github-script@v8 with: script: | const label = context.payload.label.name; const verifier = context.payload.sender.login; const status = label === 'verified' ? '✅ Verified' : '❌ Failed'; await github.rest.issues.createComment({ owner: context.repo.owner, repo: context.repo.repo, issue_number: context.issue.number, body: `## ${status}\n\nVerified by @${verifier}` }); // Remove agent:review label try { await github.rest.issues.removeLabel({ owner: context.repo.owner, repo: context.repo.repo, issue_number: context.issue.number, name: 'agent:review' }); } catch (e) { console.log('agent:review label not present'); } # If verification failed, reset for rework handle-failure: if: github.event.label.name == 'verify-failed' runs-on: ubuntu-latest needs: check-verification steps: - name: Reset for rework uses: actions/github-script@v8 with: script: | // Remove verify-failed after processing await github.rest.issues.removeLabel({ owner: context.repo.owner, repo: context.repo.repo, issue_number: context.issue.number, name: 'verify-failed' }); // Add back to ready queue await github.rest.issues.addLabels({ owner: context.repo.owner, repo: context.repo.repo, issue_number: context.issue.number, labels: ['agent:ready'] });