Skip to content

Give the QA voice's findings labels, so the loop can see them - #258

Merged
zendev-acceptor[bot] merged 1 commit into
masterfrom
policy/qa-intake
Sep 7, 2026
Merged

zendev-acceptor[bot] merged 1 commit into
masterfrom
policy/qa-intake

Conversation

@drevendev

@drevendev drevendev commented Sep 7, 2026 •

Copy link
Copy Markdown
Owner

Closes #261

Goal

Let SLOPSTER's findings reach the loop. The QA account has read access only — enough
to open an Issue, not to label one — and an Issue with no labels is invisible to every
work-selection item in the AUTHOR runbook.

Depends on #257 (verdict ownership). Merging this first would put a second QA voice
into a queue that still reads any account's review as a verdict.

Scope — every changed path

  • scripts/qa_intake.py — new. Reads Type: / Area: / Priority: declaration
    lines, applies only labels that already exist, plus qa and status:needs-triage.
    Acts only on Issues authored by vars.ZENDEV_QA_LOGIN.
  • scripts/tests/test_qa_intake.py — new. 15 tests.
  • .github/workflows/qa-intake.yml — new. issues: [opened, reopened], gated on the
    QA login, MACHINE identity, no model.

Non-goals

Does not grant status:ready — promotion to work is a judgement the AUTHOR makes at
triage. Does not create labels. Does not comment. Does not touch Issues from any other
account, including the researcher's and the operator's.

Acceptance criteria

  • A well-formed finding gets its three axes plus qa and status:needs-triage.
  • An unknown axis value is dropped; the finding still arrives labelled qa.
  • status:ready is never applied, however the body is written.
  • No second status:* label is added when one already stands (An open Issue can carry two status:* labels, and nothing removes the stale one #214).
  • An Issue from any other account is untouched.
  • A labelling failure warns; the job stays green.

Verification

python -m unittest discover -s scripts/tests   →  Ran 355 tests … OK

Live check after merge: open one Issue from the QA account by hand and confirm the
labels appear within a minute; open one from drevendev and confirm it is untouched.

Needs from the operator before this can work

  1. zendev-machine app → Issues: Read and write, and accept the new permission on
    the trade_simulation installation. Contents and Pull requests are not enough.
  2. Repository variable ZENDEV_QA_LOGIN = the QA account's login. Unset, the job
    never runs.
  3. The qa label. The script skips it if absent, so this is not blocking.

🤖 Generated with Claude Code

SLOPSTER acts as an account with read access only, which is enough to open an Issue
and deliberately not enough to label one: an account that could label could mark its
own finding status:ready and put work into the AUTHOR's queue with nobody reading it.

But every work-selection item in the AUTHOR runbook is expressed over labels, so an
unlabelled Issue is not low priority — it is unreachable. Without this job the QA
voice talks to nobody.

qa_intake reads the three declaration lines the QA manifest requires and applies only
labels the repository already has, plus `qa` and `status:needs-triage`. Never
status:ready: promotion to work stays a judgement made by the AUTHOR at triage.

Two refusals worth naming. An unknown value is dropped rather than created — the
label set is the repository's vocabulary and several guards key on it, so losing an
axis costs one triage while inventing a label costs the meaning of every axis. And
`status:needs-triage` is added only when no status:* label stands, because an open
Issue carrying two of them is #214, which happened twice in one day.

A labelling failure warns rather than fails the job: an unlabelled finding is a triage
cost, a red workflow on every QA Issue is a broken control plane.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

@zendev-acceptor zendev-acceptor Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ACCEPT

Head revision: 8708c0c

Evidence:

  1. Every required check is measured green at the head revision:

    • build-and-test: SUCCESS
    • typescript: SUCCESS
    • policy-guard: SUCCESS
    • mergeability: SUCCESS (CLEAN)
  2. Every acceptance criterion is met:

    • Well-formed findings receive three axes + qa + status:needs-triage ✓
    • Unknown axis values are dropped, finding still arrives ✓
    • status:ready is never applied ✓
    • No duplicate status:* labels added ✓
    • Issues from other accounts untouched ✓
    • Labelling failures warn but keep job green ✓
  3. Diff is confined to declared scope:

    • .github/workflows/qa-intake.yml
    • scripts/qa_intake.py
    • scripts/tests/test_qa_intake.py
  4. No invariants or tests weakened:

    • Python test suite: 355/355 pass
    • TypeScript test suite: 351/351 pass
    • 15 new tests added for qa_intake logic
    • All verification commands pass: npm typecheck, npm test, npm build
  5. No secrets, credentials, or personal data present

  6. Handoff record is complete with Issue linked, all sections present, and operator requirements documented

  7. Dependency #257 (verdict ownership) is already merged

  8. Policy change does not widen automated authority—adds control-plane QA labeling automation, not agent permissions

@zendev-acceptor
zendev-acceptor Bot merged commit b2b5d42 into master Sep 7, 2026
6 checks passed
@zendev-acceptor
zendev-acceptor Bot deleted the policy/qa-intake branch September 7, 2026 19:33
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Findings from a read-only QA account arrive unlabelled, so no work-selection item can reach them

1 participant