Skip to content

persona-mention: the job-level if: conditions are barely tested — an accidental narrowing of the comment job's recursion guard would pass CI #1288

Closed

Description

@don-petry

Problem

.github/workflows/persona-mention-reusable.yml has two job-level if: expressions that decide whether a run ever reaches a step holding the org token: jobs.route.if (comments) and jobs.route-pull-request.if (pull requests). Each duplicates, in workflow-expression syntax, a shell pre-filter that is unit-tested (pm_should_route, pm_pr_should_route). The expressions themselves are almost untested, so the two copies can drift without a red check.

PR #1287 (#1286) added one structural test for the PR job. Measured on its head 3f9088ea by editing the workflow and re-running tests/persona_mention.bats:

Edit to the workflow Tests failing
route-pull-request.if: startsWith(pull_request.body…) → contains(…) 1 (caught)
route-pull-request.if: marker line removed 1 (caught)
route.if: !contains(comment.body, '<!-- persona:') → !startsWith(…) 0 (not caught)

The third is the one that matters most. The comment job's marker check is the recursion guard added after the #860 runaway (pm_is_agent_comment deliberately matches the marker anywhere in a comment). Narrowing it by accident would let a persona's own comment re-trigger routing, and nothing in CI would notice. The existing test also greps the whole file, so a matching string in a YAML comment could satisfy it.

Acceptance criteria

  1. The structural tests parse the workflow (python3 + PyYAML, already required by pm_manifest_query) and assert on jobs["route"]["if"] and jobs["route-pull-request"]["if"] specifically, not on the file's text.
  2. route.if is pinned: it contains !contains(github.event.comment.body, '<!-- persona:'), the @petry-projects/ handle check, both bot-login exclusions, and the trust-floor list.
  3. route-pull-request.if is pinned: !startsWith(github.event.pull_request.body, '<!-- persona:'), no contains(github.event.pull_request.body, the same-repo head check, the bot-login exclusions on both pull_request.user.login and github.actor, and the trust-floor list.
  4. The bot logins hardcoded in both if: expressions equal the set pm_is_bot_actor rejects (one test that fails if either side gains or loses a login).
  5. Each assertion is shown to bite: the PR description lists, per assertion, the one-line workflow edit that makes it fail.

Budget guard

Tests only — tests/persona_mention.bats and, if needed, a small helper under tests/. No change to the workflow or to scripts/lib/persona-mention.sh. If AC 4 needs a library change to expose the bot list, stop and file that separately.

Activity

  1. don-petry commented on Oct 10, 2026

    @don-petry
    ContributorAuthor

    Dev-Lead Implementation Plan

    Issue: #1288 — persona-mention: the job-level if: conditions are barely tested

    Scope

    Tests only: parse persona-mention-reusable.yml with python3 + PyYAML and pin jobs.route.if and jobs.route-pull-request.if clause by clause, plus a bot-login parity test against pm_bot_logins / pm_is_bot_actor.

    Implementation Checklist

    • tests/persona_mention.bats: inline helper (python3 + yaml) that loads the workflow and emits a job's if: split into && clauses (whitespace-normalised) — no file-text grep, so YAML comments can't satisfy an assertion
    • No change to the reusable workflow or scripts/lib/persona-mention.sh

    Tests to Write

    Test Command

    bats tests/persona_mention.bats

  2. don-petry commented on Oct 10, 2026

    @don-petry
    ContributorAuthor

    Dev-Lead: Progress (in progress — not yet durable)

    Provisional. Nothing is pushed yet; the automation posts the authoritative
    completion record (with PR number + head SHA) after the push. Treat the notes
    below as intent, not delivered results.

    Plan Execution (intended)

    • Added a # --- workflow job-level if: pre-filters (#1288) section to tests/persona_mention.bats: python3 + PyYAML loads the workflow, takes jobs[<job>]["if"], splits it on && into whitespace-normalised clauses, and the tests assert on whole clauses. Text in YAML comments can't satisfy them, and a negated copy of a clause doesn't match either.
    • Workflow and scripts/lib/persona-mention.sh are unchanged.

    Per-assertion bite list (each one-line edit to persona-mention-reusable.yml was applied locally; the named test went red; the edit was reverted)

    Test Edit that makes it fail
    route.if is a pure && conjunction append || true to route.if
    route.if keeps the comment recursion guard (#860) !contains(github.event.comment.body, '<!-- persona:') → !startsWith(…); or delete that line; or move it into a YAML comment
    route.if requires an @petry-projects/ handle contains(…'@petry-projects/') → !contains(…)
    route.if excludes both bot logins delete the != 'donpetry-bot' line (or the github-actions[bot] one)
    route.if enforces the trust floor add "CONTRIBUTOR" to the fromJSON list
    route-pull-request.if is a pure && conjunction append || true
    route-pull-request.if marker axis matches pm_pr_should_route delete the marker line; on today's main, !contains → !startsWith; with #1287 applied, !startsWith → !contains; or move it into a YAML comment
    route-pull-request.if only runs for same-repo pull_request events delete the head.repo.full_name == github.repository line (or the event_name line)
    route-pull-request.if excludes bot logins on author AND github.actor delete pull_request.user.login != 'donpetry-bot', or github.actor != 'github-actions[bot]'
    route-pull-request.if enforces the trust floor add "CONTRIBUTOR" to the list
    bot logins … equal the set pm_is_bot_actor rejects drop a login from either job; add != 'other-bot'; add github.triggering_actor != 'donpetry-bot'

    Notes

  3. don-petry commented on Oct 10, 2026

    @don-petry
    ContributorAuthor

    Dev-Lead: Implementation Complete — PR #1289

    The implementation for issue #1288 is durable: commits are pushed and a pull request is open. This record is backed by verifiable artifacts you can confirm in one click.

    Review happens on the PR. Acceptance criteria and test results are evidenced by the PR's diff and CI checks — not asserted here. If a later stage fails, this claim is retracted in place.

  4. added a commit that references this issue on Oct 11, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    dev-leadFor dev-lead agent pickupenhancementFeature requests

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions