Triaged delivery bridge

scripts/triaged_delivery.py takes triaged GitHub issues (vibey-gh:triaged) into Vibey one at a time: it dispatches a project for the issue, drives the normal worker, and publishes the finished project as a pull request. scripts/triage_queue.py is its durable ordering and lease authority, the triaged_ticket table (migration 0020). This page is how to run the bridge unattended, and what it will and will not do while nobody is watching.

What one pass does

  1. Reap and reconcile (with a ticket store). Expired ticket leases go back to ready. The open triaged issues are upserted; a claimable ticket whose issue was closed, or lost the triaged label, is retired to blocked (its reason is in the ticket's evidence file). A listing that reached its limit retires nothing: an issue past the limit is unknown, not closed.
  2. Resume before selecting. For each dispatched project, in priority order:
  3. DONE: publish it (idempotently: an existing pull request is reused) and mark the ticket completed. The slot is free.
  4. abandoned: the ticket is blocked. The slot is free. A project that will not finish -- built on the wrong spec, superseded -- holds the slot until a person abandons it: vibey abandon PROJECT_ID --reason "..." (--dry-run first to see what it stops).
  5. waiting on a person (an open human gate, or a design waiting for vibey design accept): record it and stop. Nothing new is selected: one active project at a time.
  6. otherwise: drive it again, bounded by --max-steps, and stop.
  7. Only with nothing in flight, claim the next issue (a ticket lease plus an idempotent dispatch comment), check whose words and whose labels it carries (below), create its project with vibey new, and drive it.

Who may put an issue in the queue

The hourly triage sweep labels every open issue vibey-gh:triaged, a stranger's included, and ranks it partly from its own wording. So the label says nothing about trust, and before it dispatches anything the bridge asks the forge who is behind the issue. It reuses the storm's trust seam (docs/plans/qwenstorm-3.0.0/tools/storm_trust.py, ADR-0053, sub-doctrine 12.j) through scripts/intake_trust.py, rather than keeping a second list:

  • The grant is read from reviewed history: .vibey-gh.toml and .github/CODEOWNERS as origin/<integration branch> records them, never the working tree, through vibey-gh's own parser. A local edit cannot widen it.
  • The text: one GraphQL query returns the issue's title, body, author, every body edit and every title rename. Every one of those accounts must be in [unattended_approval] authors (@codeowners expanded). The text judged is the text dispatched: the ticket's listing copy is never used.
  • The labels: the same answer lists who last applied vibey-gh:triaged and each vibey-gh:priority-* label the issue carries (priority-bumped included). Each must be a curator: an author above, or [merge_train] trusted_authors or owner -- which is where the sweep's own account (github-actions[bot]) is declared. Bot spellings (app/x, x[bot], x) are matched with vibey-gh's normalise_actor.

What happens:

Finding Outcome
Every account is trusted Dispatched. ticket-<issue>.json records outcome: admitted, the author, accounts, curators and the grant it was judged against.
A stranger opened, edited, renamed or labelled it; an account the forge cannot name (a deleted "ghost"); a history longer than one page Held: never dispatched, ticket blocked, outcome: held_untrusted with the reason, and one comment on the issue (<!-- vibey-delivery-held issue:N -->) asking a maintainer. Without a ticket store, that comment is what makes the next pass skip it. The next issue is taken on the next pass.
The grant or the forge could not be read Not a verdict about anyone: a failed dispatch, handed back and retried, blocked after MAX_DISPATCH_FAILURES. Nobody is told an unproven thing.

A hold is sticky: the history that refused the issue does not change. To go ahead, a maintainer reviews the request and re-files it under their own account, or names the account in a reviewed change to .vibey-gh.toml.

An admitted issue still reaches the ledger only as quoted data. vibey new --intake receives a provenance line the bridge writes (issue, author, grant), then the issue framed by PromptShield (src/vibey/domain/prompt_shield.py): control characters stripped, a random per-dispatch nonce on the <github_issue_…> tags, any `