Skip to main content
Settings
Search
Appearance
Theme Mode
About
Jekyll v3.10.0
Environment Production
Last Build
2026-05-22 22:41 UTC
Current Environment Production
Build Time May 22, 22:41
Jekyll v3.10.0
Build env (JEKYLL_ENV) production
Quick Links
Page Location
Page Info
Layout default
Collection quests
Path _quests/1010/agentic-success-criteria-and-signals.md
URL /quests/gh-600/agentic-success-criteria-and-signals/
Date 2026-05-17
Theme Skin
SVG Backgrounds
Layer Opacity
0.6
0.04
0.08

The Oracle's Rubric: Defining Agent Success Criteria and Signals

By IT-Journey Team

Define what 'done' looks like for agent-executed tasks — craft measurable acceptance criteria, configure GitHub signals that indicate success, and wire them into automated task completion detection.

Estimated reading time: 5 minutes

The Oracle of the Chamber does not speak in poetry — she speaks in rubrics. Each rubric is a list of verifiable truths that must all be true before a task is complete. No rubric, no completion. She has seen too many agents return claiming victory when the ramparts were still un-built.

🗺️ Quest Network Position

graph LR
    Q10[✅ Q10: Tool Planes] --> Q11[🎯 Q11: Oracle's Rubric]
    Q11 --> Q12[🔜 Q12: Necromancer's Inquest]
    style Q11 fill:#4CAF50,stroke:#2E7D32,stroke-width:4px,color:#fff

🎯 Quest Objectives

  • Define an acceptance criteria schema — machine-verifiable completion conditions embedded in issues
  • Map GitHub signals to success — identify which Actions outcomes, PR states, and labels indicate task completion
  • Implement auto-detection — workflow that checks all success signals and marks a task complete
  • Test a passing and failing scenario — verify the detector correctly identifies both
  • Document signal coverage — confirm every acceptance criterion has a corresponding GitHub signal

⚔️ The Quest Begins

Chapter 1 — The Acceptance Criteria Schema

Success criteria must be machine-verifiable. Vague criteria like “it works” cannot be automatically checked.

Exercise 11.1: Add a structured acceptance criteria block to your issue template.

<!-- .github/ISSUE_TEMPLATE/agent-task.md -->
---
name: Agent Task
about: Task for GitHub Copilot coding agent
labels: ['copilot', 'agent-task']
---

## Task Description
<!-- What should the agent do? Be specific. -->

## Acceptance Criteria
<!-- Each item must be verifiable by the agent or an automated check. -->
- [ ] **Files changed**: <!-- List exact files that should be modified -->
- [ ] **Tests pass**: All tests in `test/` pass without modification
- [ ] **No regressions**: Existing test suite still passes
- [ ] **PR opens**: A draft PR is created referencing this issue
- [ ] **Code review ready**: PR is marked ready for review (not draft) when complete
- [ ] **Documentation updated**: `docs/` updated if API or behaviour changed

## Out of Scope
<!-- Explicitly state what the agent should NOT do. -->
- Do not modify files outside the listed scope
- Do not merge the PR — only open it

Chapter 2 — Mapping GitHub Signals to Success

Every acceptance criterion needs a corresponding GitHub signal:

Acceptance Criterion GitHub Signal How to Check
Tests pass Actions check test = success Branch protection check
PR opened pull_request event with opened action Actions trigger
PR references issue PR body contains Closes #N String match in PR body
No extra files modified git diff --name-only matches expected list Script comparison
Lint passes Actions check lint = success Branch protection check
Draft removed PR draft = false GitHub API

Chapter 3 — Implementing the Success Signal Detector

Exercise 11.2: Create a workflow that checks all success signals.

# .github/workflows/check-task-completion.yml
name: Check Agent Task Completion

on:
  pull_request:
    types: [opened, edited, ready_for_review, synchronize]
  workflow_run:
    workflows: ["Run Tests"]
    types: [completed]

jobs:
  check-completion:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Check all success signals
        id: check_signals
        uses: actions/github-script@v7
        with:
          script: |
            // Resolve the PR for both 'pull_request' and 'workflow_run' triggers.
            // workflow_run fires after a workflow completes; payload.pull_request is
            // null, but workflow_run.pull_requests carries the associated PR(s).
            let pr = context.payload.pull_request;
            if (!pr && context.payload.workflow_run) {
              pr = context.payload.workflow_run.pull_requests?.[0];
            }
            if (!pr) {
              console.log('No PR associated with this event — skipping');
              return;
            }
            
            const signals = [];
            let allPassed = true;
            
            // Signal 1: PR body references an issue
            const closesPattern = /closes\s+#\d+/i;
            const refersPattern = /issue\s+#\d+/i;
            const hasRef = closesPattern.test(pr.body || '') || refersPattern.test(pr.body || '');
            signals.push({ name: 'Issue reference in PR body', passed: hasRef });
            if (!hasRef) allPassed = false;
            
            // Signal 2: PR is not a draft
            const notDraft = !pr.draft;
            signals.push({ name: 'PR is ready for review (not draft)', passed: notDraft });
            if (!notDraft) allPassed = false;
            
            // Signal 3: Check required status checks
            const { data: checks } = await github.rest.checks.listForRef({
              owner: context.repo.owner,
              repo: context.repo.repo,
              ref: pr.head.sha,
            });
            
            const testCheck = checks.check_runs.find(c => c.name === 'test');
            const testPassed = testCheck?.conclusion === 'success';
            signals.push({ name: 'Test suite passes', passed: testPassed ?? false });
            if (!testPassed) allPassed = false;
            
            // Report results
            const statusLines = signals.map(s => 
              `${s.passed ? '✅' : '❌'} ${s.name}`
            ).join('\n');
            
            const comment = allPassed
              ? `## 🎉 Task Complete\n\nAll success signals verified:\n${statusLines}`
              : `## ⏳ Task In Progress\n\nSuccess signal status:\n${statusLines}\n\n_Checks will re-run automatically as the task progresses._`;
            
            // Add or update completion comment
            const comments = await github.rest.issues.listComments({
              owner: context.repo.owner,
              repo: context.repo.repo,
              issue_number: pr.number,
            });
            
            const existing = comments.data.find(c => 
              c.body.includes('Task Complete') || c.body.includes('Task In Progress')
            );
            
            if (existing) {
              await github.rest.issues.updateComment({
                owner: context.repo.owner,
                repo: context.repo.repo,
                comment_id: existing.id,
                body: comment,
              });
            } else {
              await github.rest.issues.createComment({
                owner: context.repo.owner,
                repo: context.repo.repo,
                issue_number: pr.number,
                body: comment,
              });
            }
            
            core.setOutput('all_passed', allPassed);

✅ Quest Validation

python3 scripts/validate_quest.py --quest q11
# ✅ Issue template: agent-task.md with acceptance criteria block present
# ✅ Signal detector: check-task-completion.yml present
# ✅ Signal table: documented in quest and in docs/agent-eval/
# 🏆 Quest Q11 complete!

🏆 Quest Rewards

Reward Details
🔮 Oracle’s Scribe Badge Earned on completion
📋 Success Signal Configuration Skill unlocked
100 XP Added to Level 1010 total
Unlocks Q12: The Necromancer’s Inquest