Autonomous Agents Agentic Workflow
QA Consolidation — Autonomous Agents Agentic Workflow
Epic-level QA close-out — the findings ledger, clusters into proposed tickets, a person's approval, then the Bugs and SD tasks filed and the epic summary posted
sidebutton install agents The quality lane's close-out, run once per quality epic after every QA task on it is done. The QA sessions never file tracker issues: each posts its findings as a block on the epic ("QA findings · KEY · session n" — defects, observations, pack and harness gaps, each numbered KEY-Fn). This job reads every block and every child's report, builds one ledger, and clusters the rows that share a root cause or a surface — the same file, read-out, endpoint or contract — into one proposed ticket each, with the priority the whole picture supports rather than the one a single session guessed.
It runs in two sessions by design. The first posts the PROPOSAL on the epic — the ledger summary, the proposed tickets with the finding ids each merges, the parked observations, the SD tasks for pack gaps, the open questions — and pauses for a person (NEEDS_APPROVAL). Once someone answers on the epic and re-runs the step, the second session files exactly what was approved: one Bug per cluster carrying every merged finding in full and related to every task it came from, one SD task per skill domain for the pack gaps, then the summary on the epic (ISSUES_FILED). A hint of auto-file collapses the two into one session for an account that trusts the job; NOT_READY says a QA child is still open and pauses until it is not.
Steps
- 1. Open a terminal
- title
- Agent: QA Consolidation
- cwd
- {{entry_path}}
terminal.open - 2. Run a terminal command
- cmd
- |
terminal.run
Workflow definition
schema_version: 1
id: agent_qa_consolidate
title: "QA Consolidation"
description: "Epic-level QA close-out — the findings ledger, clusters into proposed tickets, a person's approval, then the Bugs and SD tasks filed and the epic summary posted"
overview: |
The quality lane's close-out, run once per quality epic after every QA task on it is done. The QA
sessions never file tracker issues: each posts its findings as a block on the epic ("QA findings · KEY ·
session n" — defects, observations, pack and harness gaps, each numbered KEY-Fn). This job reads every
block and every child's report, builds one ledger, and clusters the rows that share a root cause or a
surface — the same file, read-out, endpoint or contract — into one proposed ticket each, with the priority
the whole picture supports rather than the one a single session guessed.
It runs in two sessions by design. The first posts the PROPOSAL on the epic — the ledger summary, the
proposed tickets with the finding ids each merges, the parked observations, the SD tasks for pack gaps,
the open questions — and pauses for a person (NEEDS_APPROVAL). Once someone answers on the epic and
re-runs the step, the second session files exactly what was approved: one Bug per cluster carrying every
merged finding in full and related to every task it came from, one SD task per skill domain for the pack
gaps, then the summary on the epic (ISSUES_FILED). A hint of auto-file collapses the two into one session
for an account that trusts the job; NOT_READY says a QA child is still open and pauses until it is not.
category:
level: pipeline
domain: engineering
metadata:
agent: true
role: qa
# Gate-verdict vocabulary for portal playbook steps (PLAYBOOKS.md §5) — matched from the step's
# epic comment. Pack-declared tokens match their explicit UPPER_SNAKE form only, so the prompt
# keeps each of them out of the body and allows it as the final line alone. The QA Consolidation
# seed routes ISSUES_FILED → pass (Finish) and the other three → pause: a person answers on the
# epic and re-runs the step to move from the proposal to the filing session.
verdicts: [NEEDS_APPROVAL, ISSUES_FILED, NOT_READY, BLOCKED]
params:
agentic_app:
type: string
default: "cc"
description: "Agent-app slug selecting the per-run env file ~/.agent-env.d/<slug> (AAP-C); 'cc'/subscription clears provider vars"
ticket_url:
type: string
description: "Jira epic URL — the quality epic whose QA tasks are done"
hint:
type: string
default: ""
description: "Optional extra instructions; auto-file skips the approval pause and files in one session"
entry_path:
type: string
default: "~/workspace"
description: "Working directory for the agent"
steps:
- type: terminal.open
title: "Agent: QA Consolidation"
cwd: "{{entry_path}}"
- type: terminal.run
cmd: |
source ~/.agent-env
# AAP-C (SCRUM-1506) + AAP-17 (SCRUM-1653): clear EVERY provider var an agent-app can deliver so
# none hijacks/poisons a subscription run. A stray global ANTHROPIC_MODEL / ANTHROPIC_SMALL_FAST_MODEL
# needs no CLAUDE_CODE_USE_* flag, so the old ${!CLAUDE_CODE_USE_@} glob never caught it — it survived
# into the run and 404-ed aux/small-fast calls against api.anthropic.com. This explicit list mirrors
# AGENT_APP_ENV_KEYS 1:1 (the-assistant website/src/lib/cloud/agent-app-env.ts — the single source of
# truth; a parity test in each repo guards the two from drifting). Explicit over a glob: the union has
# non-ANTHROPIC_ members (AWS_REGION, AWS_PROFILE, CLOUD_ML_REGION, CLAUDE_CODE_MAX_OUTPUT_TOKENS) and
# a ${!AWS_@} glob would over-clear unrelated creds. Then source the per-run app env by slug when it
# exists; no file => subscription/default. base/19-secrets stages ~/.agent-env.d/<slug>.
unset \
ANTHROPIC_API_KEY ANTHROPIC_BASE_URL ANTHROPIC_AUTH_TOKEN CCR_CONFIG_B64 \
CLAUDE_CODE_USE_BEDROCK AWS_REGION AWS_PROFILE ANTHROPIC_MODEL \
ANTHROPIC_SMALL_FAST_MODEL_AWS_REGION ANTHROPIC_SMALL_FAST_MODEL CLAUDE_CODE_MAX_OUTPUT_TOKENS \
CLAUDE_CODE_USE_VERTEX CLOUD_ML_REGION ANTHROPIC_VERTEX_PROJECT_ID ANTHROPIC_VERTEX_BASE_URL \
CLAUDE_CODE_USE_FOUNDRY ANTHROPIC_FOUNDRY_RESOURCE ANTHROPIC_FOUNDRY_BASE_URL \
ANTHROPIC_DEFAULT_OPUS_MODEL ANTHROPIC_DEFAULT_SONNET_MODEL ANTHROPIC_DEFAULT_HAIKU_MODEL
if [ -f "$HOME/.agent-env.d/{{agentic_app}}" ]; then
source "$HOME/.agent-env.d/{{agentic_app}}"
fi
claude --dangerously-skip-permissions "$(cat <<'SB_PROMPT'
read the epic with attachments and ALL comments - {{ticket_url}}; then every child issue of the epic that carries the label qa, with ALL its comments and the results artifacts its reports link. if the epic cannot be read, stop and report the error.
READINESS: if any child that carries the label qa is not in a done status category, post ONE comment on the epic naming the open children and what each waits on, end it with NOT_READY alone on its last line, and do nothing else.
EXECUTION RULES (read first — they override any habit):
- Do ALL of the work in THIS session, in the FOREGROUND, and finish before your turn ends. You MAY spawn subagents (the Agent / Task tool) or run parallel searches to read faster — but you MUST wait for every subagent and any background task to return and fold their results in YOURSELF before ending the turn. Never move the work (or the comment) into the background — no run_in_background, no background workflows, no trailing & — and then end the turn expecting to be resumed. Ending your turn is FINAL here: nothing wakes you to "resume", so a turn that ends while a spawned subagent or any background work is still pending is reported as a FAILED step, not a pause.
- Post the epic comment YOURSELF, in the foreground, as the LAST thing you do — after every subagent and background task has returned. Never delegate that comment to a subagent, and never end the turn "holding", "pausing", or planning to "resume/continue later".
LEDGER: every "QA findings" block on the epic becomes rows — id, task, session, severity, kind, area, symptom, repro, expected vs actual, URL, evidence, predicted-by, same-as. a child whose sessions posted no block (an older contract) is read from its report comments and results artifact instead; a Bug a session already filed is a row carrying its key. keep the whole ledger in a results artifact you publish (KEY-qa-ledger.md, KEY = the epic key) and cite it.
CLUSTER: rows that share a root cause or a surface — the same file, read-out, endpoint or contract; one figure rendered wrong on several pages; one guard missing on several doors — become ONE proposed ticket. an observation becomes a ticket only when it names a wrong behaviour; otherwise it is parked, listed with its id. pack findings become one SD task per skill domain (issue type Task, label skill-pack, the workflow agent_sd_coverage named in the description) listing the modules to add or refresh; harness findings become one SE task per recipe (label qa-fixture). priority per ticket = the highest severity in it (P0 → Highest, P1 → High, P2 → Medium, P3 → Low), and say so when the evidence contradicts a recorded severity. a security finding — script execution, an auth or tenant boundary crossed — is never merged with anything else.
PROPOSAL — when the epic carries no proposal from this job yet, or the latest proposal was answered with changes that need a fresh one, and the hint does not say auto-file: post ONE comment on the epic — the ledger summary (rows by task, by severity, by kind, with the ledger link), then the proposed tickets (title · type · priority · labels · the finding ids and tasks each merges · one line of why they are one), then the parked observations, the SD and SE tasks, and the questions a person must answer. create nothing. end with NEEDS_APPROVAL alone on the last line.
FILING — when the epic carries your proposal AND a later comment approving it (with or without changes), or the hint says auto-file: apply the changes the approval names, then create the tickets. idempotent: before each, search the project for an open issue carrying the same title or one of the same finding ids in its description, and link that instead of creating a duplicate. each Bug carries the label qa-found, its area labels, a "relates to" link to EVERY task its findings came from, and a description with every merged finding in full (id, repro, expected vs actual, URL, evidence). a Bug a session filed that a merged ticket supersedes is closed with a comment naming the ticket. then post the epic summary as ONE comment: tasks × verdict × sessions × cost where the reports state them, tickets by priority with their keys, parked observations, SD and SE tasks, what stays open. end with ISSUES_FILED alone on the last line.
BLOCKED: a missing credential, access or decision that stops either session — post one comment saying what and what would unblock it, and end with BLOCKED alone on the last line.
{{hint}}
the four routing tokens appear only as the last line of your comment, never in its body, and the upper-case word BLOCKED appears nowhere else either.
EVIDENCE: publish the ledger and the cluster map with publish_artifact and cite the links; if it is unavailable, save under ~/workspace/artifacts/ for post-run collection.
SB_PROMPT
)"