Repository navigation
lanes: make the automation lanes reusable by any repository #7656
Description
No related issue: a new owner goal, recorded 2026-10-16. Refs #7555.
Goal (owner)
Every repository in the organization, and any public consumer, can opt into the same automation lanes this repository runs: issue to PR, unblocking items when a blocker closes, the PR pipeline, and merge. The lanes should be generic and configurable, with no copy per repository.
What exists today
melodic-software/ci-workflows(public) already ships reusable workflows for intake triage, the review lanes (pr-review,pr-review-security), checks, Dependabot auto-merge and the standards sync.- The lanes still local to this repository are
work-resolve-issue,work-unblock,pr-merge,pr-unblock/pr-refineandpr-run-activity-*. Their actions live under.github/actions/and.github/scripts/. They are already config-driven throughdocs/conventions/pr-pipeline.yaml. - Portability blockers:
- The lanes token broker (azure-iac) pins repository ids and exact caller workflow paths, and it requires the caller file to be byte-equal to the copy on
main. - Lane admission reads this repository's
.github/standards/trusted-actors/trusted-actors.json. - Some scripts assume this repository's layout.
- The lanes token broker (azure-iac) pins repository ids and exact caller workflow paths, and it requires the caller file to be byte-equal to the copy on
Outcome
A design, then slices, that move the lane workflows and actions into ci-workflows as reusable workflows driven by each consumer's own convention config. The broker must accept a consumer's caller without a broker code change for each repository, and a consumer must be able to adopt one lane at a time.
Not now
The owner asked that this not derail the current epic. Design starts after Phase 9 (verifier-gated merge) settles the merge lane's shape. Automation Lanes owns the lanes and the broker.
Activity
github-actions commentedon Oct 16, 2026
Proposed work class: work-class: structural
Basis: automated intake triage; the lanes App applied this class.
Size: Medium
Complexity: Medium
Uncertainty: Knowable
Flags: none
Blocked by: none
Understood: the goal is a design, then per-lane slices, that move the lanes into ci-workflows as reusable workflows that each consumer configures. The owner's decision settles the trust-model question.
That decision settles the open questions. The start condition also holds, since ADR 0082 is accepted.
Automated triage, applied by the lanes App.
kyle-sexton commentedon Oct 24, 2026
Released for re-triage under the owner's 2026-10-24 rule: an issue stops for a person only for an intent or vision question, a security call, a host or attended run, or spend outside prepaid credit. The hold label came off and intake triage runs again now; it re-applies a hold, with a numbered question, when one of those applies.
To hold this issue again, add
needs-human(orstatus: needs-decision) and say why in a comment.melodic-automation-lanes commentedon Oct 24, 2026
Not admitted to the issue lane: no trusted-human acceptance criteria: a listed human must put the confirmed
- [ ]criteria in the body or post them as their own comment, or, on an issue a listed human filed, intake's newest refinement comment must hold them unedited; Size large: the split into sub-issues at intake is pending (owner Q93). Admission takes the issue once each of those is met, when intake triages it again (.github/actions/resolve-config/admission-rules.json).1 remaining item
melodic-automation-lanes commentedon Oct 24, 2026
The latest triage verdict holds nothing: the issue is at
status: ready.melodic-automation-lanes commentedon Oct 24, 2026
Refinement. A read-only run explored this repository, searched its issues and pull requests, and read the allowed docs to draft what follows. On an issue a listed human filed, it counts as the issue's spec once posted, while unedited; it is still model text, so check it.
Intended outcome: A design document, then sliced issues, moving the lane workflows and actions into ci-workflows as reusable workflows driven by each consumer's convention config, with a broker that accepts consumer callers without per-repository changes.
Dependencies
Related work
Open questions
RECOMMENDED: No: hold the issue until Phase 9 closes, then start the design. Basis: issue body, Not now section
RECOMMENDED: Yes: the design and a list of filed slice issues is the deliverable, because the work is too large for one change. Basis: issue body, Outcome section; intake triage says Large/High
RECOMMENDED: Trust callers that reference a pinned ci-workflows reusable workflow, with repository membership taken from the organization rather than a pinned id list. This is a security decision for the owner. Basis: judgment
RECOMMENDED: From the consumer's own convention config, with a ci-workflows default. Basis: judgment
RECOMMENDED: Start with work-resolve-issue and work-unblock, then pr-unblock/pr-refine and pr-run-activity, and move pr-merge last, after Phase 9. Basis: judgment
Sources read
Automated refinement by the lanes App. Answer with a comment whose first line is
**Decision recorded.**.kyle-sexton commentedon Oct 26, 2026
Owner question (security), not a decision. This record goes to the owner; it does not open with a decision marker so intake does not read it as one.
Owner question (security): The body's outcome requires that "The broker must accept a consumer's caller without a broker code change for each repository". Today the lanes token broker trusts exactly one configuration source and an allowlist of repositories, so meeting the outcome widens who can obtain a lanes App token. Which trust model should the broker take for a consumer repository?
Evidence (azure-iac
origin/mainatd6ff945, read 2026-10-26):if (!settings.allowedRepositoryIds.includes(claims.repository_id))(src/lanes-token-broker/src/claims.mjs:170-171), set fromBROKER_ALLOWED_REPOSITORY_IDS(BrokerConstants.cs:85).claims.mjs:8-38:pr-run-activity-write.yml,work-resolve-issue.yml,pr-merge.ymland others) and binds the caller to the copy on main (src/lanes-token-broker/src/authorize.mjs:302,checkBinding).authorize.mjs:6-8) and readstrusted-actors.jsonfrom that main (authorize.mjs:117).Options:
BROKER_ALLOWED_REPOSITORY_IDS(a setting, not code), and the broker reads that consumer's own main for its grants and trusted actors. Each consumer is still admitted by a person; the new trust is in the consumer's own main branch.melodic-softwarerepository whose caller references a pinned ci-workflows reusable workflow is accepted with no per-repository step (intake's refinement suggestion, lanes: make the automation lanes reusable by any repository #7656 (comment), item 3).Recommendation: option 1 for organization repositories and option 3 for public consumers outside the organization. Basis: judgment; it keeps a person's step per repository and never mints this App's token for a repository outside the organization. The evidence that would settle it is a threat review of the broker reading grants from a consumer's main.
Context, not decided here: the body's start condition was "after Phase 9 (verifier-gated merge) settles the merge lane's shape", and ADR 0082 "Drop the C4 rung and merge on the verifier verdict" is
accepted, dated 2026-10-22 (docs/adr/0082-drop-the-c4-rung-and-merge-on-the-verifier-verdict.md:3-4).kyle-sexton commentedon Oct 26, 2026
Decision recorded. The owner answered in the Refinement session (2026-10-26). He rejected one GitHub App per repository ("One app per repo sound like a terrible maintenance burden to me") and accepted the recommendation that followed:
Decided: one lanes App, installed across the organization, and one admission row per repository.
BROKER_ALLOWED_REPOSITORY_IDS, azure-iacsrc/lanes-token-broker/src/claims.mjs:170-171), plus its grant set in a central grant file in this repository. Adopting a lane needs no broker code change and no copy of the lanes: the consumer calls the reusable workflows.authorize.mjs:6-8), never from the consumer's, so a consumer cannot grant itself more than its row says. A repository with no row gets no token.GITHUB_TOKEN.The start condition holds: design starts after Phase 9, and ADR 0082 (verifier-gated merge) is accepted, dated 2026-10-22 (
docs/adr/0082-drop-the-c4-rung-and-merge-on-the-verifier-verdict.md:3-4).Acceptance criteria:
melodic-software/ci-workflowsas reusable workflows driven by each consumer's convention config, each lane adoptable on its own.GITHUB_TOKEN, and the broker never mints this App's token for them.trusted-actors.json.melodic-automation-lanes commentedon Oct 26, 2026
The work-resolve-issue lane stopped on its funding (
funding: no credit or a disabled key), not on this issue. It keepsagent-ready; once the lane is funded again, a person removes and addsagent-readyto restart it.Run: https://github.com/melodic-software/claude-code-plugins/actions/runs/40354698247
kyle-sexton commentedon Oct 26, 2026
Design for criterion 1: decisions taken on the evidence. The design is ADR 0085
(
docs/adr/0085-run-org-lanes-from-ci-workflows-under-one-lanes-app-with-central-grants.md, in thepull request that delivers criterion 1). The open questions the draft raised were decided as
recommended, under the owner's standing rule to decide on facts and loosen no security boundary:
repository's main, plus optional additions in its grant row. ADR 0049 Decision 1 already
requires one central list every lane reads.
central grant file. ci-workflows does not join the trust root.
BROKER_ALLOWED_REPOSITORY_IDSconstant, the central grant row, and the github-iac
LanesBrokerClientRepositoriesentry. Thethird exists because the broker denies a repository with no kill-switch variable
(azure-iac
kill-switch.mjs:51-54), and that variable comes from the github-iac entry(
OrgCiRouting.cs:91-98). A missing row denies; it never widens. The allowlist row is a codeconstant (azure-iac
BrokerConstants.cs:79), so each admission is still an azure-iac pullrequest and an owner-run deploy. Consumers do not join
trust-root: today it adds no effective rule over the organizationbaseruleset(github-iac
OrgRulesets.cs:79-105against:152-187).UNIVERSAL_REFUSEclass inpatch-rules, so no lane patch can change them. Every lane modelactivity is
effect: read, so lanes change files only through scripted patches.Corrected premise. The decision says the broker "keeps reading grants from this repository's
main (
authorize.mjs:6-8)". Those lines cover the resolve-config code only. The broker reads grantdata and trusted actors from the caller's own main (azure-iac
authorize.mjs:260-268,298, the latter throughreadTipFiles), andclaims.mjs:232-235requires the caller's own workflow. Central reading is anew one-time broker change, sliced as the azure-iac prerequisite, with a matching amendment to
github-iac ADR 0015 Decisions 2 and 5.
Slices to file under this issue: three prerequisites (the central grant file, the broker change,
the shared reusables and resolve-config move), then one per lane: work-unblock, intake-triage,
work-resolve-issue, pr-refine, pr-unblock, pr-merge.