Skip to content

lanes: make the automation lanes reusable by any repository #7656

Description

@kyle-sexton

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-refine and pr-run-activity-*. Their actions live under .github/actions/ and .github/scripts/. They are already config-driven through docs/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.

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

  1. added
    needs-triageNot yet classified. Floor until a type and one priority tier are set.
    on Oct 16, 2026
  2. github-actions commented on Oct 16, 2026

    @github-actions
    Contributor

    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.

    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:

    go w/ recommendations

    Decided: one lanes App, installed across the organization, and one admission row per repository.

    • A consumer repository in the organization is admitted by adding its id to the broker's existing allowlist (BROKER_ALLOWED_REPOSITORY_IDS, azure-iac src/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.
    • The broker keeps reading grants from this repository's main (azure-iac 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.
    • Public consumers outside the organization do not get this App's token. They run the reusable lanes with their own App or the built-in GITHUB_TOKEN.

    (Decision comment: #7656 (comment))

    That decision settles the open questions. The start condition also holds, since ADR 0082 is accepted.

    Automated triage, applied by the lanes App.

  3. added
    needs-humanHuman-in-the-loop required; autonomous sessions must not resolve items carrying this.
    and removed
    needs-triageNot yet classified. Floor until a type and one priority tier are set.
    on Oct 16, 2026
  4. removed
    needs-humanHuman-in-the-loop required; autonomous sessions must not resolve items carrying this.
    on Oct 24, 2026
  5. kyle-sexton commented on Oct 24, 2026

    @kyle-sexton
    MemberAuthor

    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 (or status: needs-decision) and say why in a comment.

  6. added
    needs-triageNot yet classified. Floor until a type and one priority tier are set.
    priority: mediumReal value, no hard deadline; normal backlog flow.
    and removed
    needs-triageNot yet classified. Floor until a type and one priority tier are set.
    on Oct 24, 2026
  7. changed the issue type fromtoon Oct 24, 2026
  8. added
    status: readyTriaged, unblocked, and fully specified; eligible to pick up.
    work-class: structuralRefactors, migrations, contract changes; cross-cutting and hard to reverse.
    status: needs-decisionAwaiting a human or maintainer judgment call.
    on Oct 24, 2026
  9. melodic-automation-lanes commented on Oct 24, 2026

    @melodic-automation-lanes
    Contributor

    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).

  10. 1 remaining item

  11. melodic-automation-lanes commented on Oct 24, 2026

    @melodic-automation-lanes
    Contributor

    The latest triage verdict holds nothing: the issue is at status: ready.

  12. melodic-automation-lanes commented on Oct 24, 2026

    @melodic-automation-lanes
    Contributor

    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

    • Phase 9 (verifier-gated merge) must settle the merge lane's shape before design starts, per the issue body
    • The azure-iac lanes token broker change lives outside this repository and needs its own issue

    Related work

    Open questions

    1. Is Phase 9 (verifier-gated merge) settled enough to begin design, since the issue says design starts only after it?
      RECOMMENDED: No: hold the issue until Phase 9 closes, then start the design. Basis: issue body, Not now section
    2. Should this issue deliver only the design document and the slice issues, leaving all implementation to the slices?
      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
    3. How should the broker trust a consumer caller without per-repository changes, given it now pins repository ids and requires the caller file to be byte-equal to main?
      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
    4. Where should lane admission read trusted actors for a consumer, instead of this repository's .github/standards/trusted-actors/trusted-actors.json?
      RECOMMENDED: From the consumer's own convention config, with a ci-workflows default. Basis: judgment
    5. In which order should lanes move to ci-workflows?
      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

    • /home/runner/work/_temp/refine-data/context.json: issue 7656 body, triage and the 2026-10-24 release comment
    • .base/.github/workflows/: pr-merge.yml, pr-refine.yml, pr-unblock.yml, work-resolve-issue.yml and work-unblock.yml exist locally, so they are still to be moved

    Automated refinement by the lanes App. Answer with a comment whose first line is **Decision recorded.**.

  13. kyle-sexton commented on Oct 26, 2026

    @kyle-sexton
    MemberAuthor

    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/main at d6ff945, read 2026-10-26):

    • The broker denies any repository not on its allowlist: if (!settings.allowedRepositoryIds.includes(claims.repository_id)) (src/lanes-token-broker/src/claims.mjs:170-171), set from BROKER_ALLOWED_REPOSITORY_IDS (BrokerConstants.cs:85).
    • It accepts only fixed caller workflow names (claims.mjs:8-38: pr-run-activity-write.yml, work-resolve-issue.yml, pr-merge.yml and others) and binds the caller to the copy on main (src/lanes-token-broker/src/authorize.mjs:302, checkBinding).
    • It resolves every grant from "the tip of claude-code-plugins' main whatever the caller" (authorize.mjs:6-8) and reads trusted-actors.json from that main (authorize.mjs:117).

    Options:

    1. Per-repository admission by setting: the operator adds each consumer's repository id to 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.
    2. Organization-wide: any melodic-software repository 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).
    3. No shared broker for consumers: the broker keeps serving this repository only, and a consumer, including any public consumer the body names, runs the reusable lanes with its own App and token source.

    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).

  14. kyle-sexton commented on Oct 26, 2026

    @kyle-sexton
    MemberAuthor

    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:

    go w/ recommendations

    Decided: one lanes App, installed across the organization, and one admission row per repository.

    • A consumer repository in the organization is admitted by adding its id to the broker's existing allowlist (BROKER_ALLOWED_REPOSITORY_IDS, azure-iac src/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.
    • The broker keeps reading grants from this repository's main (azure-iac 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.
    • Public consumers outside the organization do not get this App's token. They run the reusable lanes with their own App or the built-in 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:

    • A design doc records the lanes' move to melodic-software/ci-workflows as reusable workflows driven by each consumer's convention config, each lane adoptable on its own.
    • The design keeps one lanes App, admits an organization repository by one allowlist row plus one central grant entry, and keeps grants read from this repository's main.
    • The design states that public consumers outside the organization supply their own App or GITHUB_TOKEN, and the broker never mints this App's token for them.
    • The design names where each consumer's trusted actors are set, in place of this repository's trusted-actors.json.
    • Slices are filed under this issue, one per lane, each with its own criteria.
  15. added
    status: confirmedA maintainer confirmed the item is real and in scope; ready to be worked.
    and removed
    status: needs-decisionAwaiting a human or maintainer judgment call.
    on Oct 26, 2026
  16. added
    needs-triageNot yet classified. Floor until a type and one priority tier are set.
    and removed
    status: confirmedA maintainer confirmed the item is real and in scope; ready to be worked.
    needs-triageNot yet classified. Floor until a type and one priority tier are set.
    on Oct 26, 2026
  17. added
    status: readyTriaged, unblocked, and fully specified; eligible to pick up.
    agent-readyFully specified and briefed; eligible for autonomous pickup from the frontier.
    and removed on Oct 26, 2026
  18. melodic-automation-lanes commented on Oct 26, 2026

    @melodic-automation-lanes
    Contributor

    The work-resolve-issue lane stopped on its funding (funding: no credit or a disabled key), not on this issue. It keeps agent-ready; once the lane is funded again, a person removes and adds agent-ready to restart it.

    Run: https://github.com/melodic-software/claude-code-plugins/actions/runs/40354698247

  19. kyle-sexton commented on Oct 26, 2026

    @kyle-sexton
    MemberAuthor

    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 the
    pull 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:

    1. Trusted actors (criterion 4): every consumer is judged against the central list on this
      repository's main, plus optional additions in its grant row. ADR 0049 Decision 1 already
      requires one central list every lane reads.
    2. Reusable binding: the broker accepts a ci-workflows reusable only at a commit listed in the
      central grant file. ci-workflows does not join the trust root.
    3. Admission: three fail-closed rows, not two: the azure-iac BROKER_ALLOWED_REPOSITORY_IDS
      constant, the central grant row, and the github-iac LanesBrokerClientRepositories entry. The
      third 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 code
      constant (azure-iac BrokerConstants.cs:79), so each admission is still an azure-iac pull
      request and an owner-run deploy. Consumers do not join
      trust-root: today it adds no effective rule over the organization base ruleset
      (github-iac OrgRulesets.cs:79-105 against :152-187).
    4. Protecting the central files: the grant file and the trusted-actor list join a new
      UNIVERSAL_REFUSE class in patch-rules, so no lane patch can change them. Every lane model
      activity 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 grant
    data and trusted actors from the caller's own main (azure-iac authorize.mjs:260-268,298, the latter through
    readTipFiles), and claims.mjs:232-235 requires the caller's own workflow. Central reading is a
    new 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.

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

    agent-readyFully specified and briefed; eligible for autonomous pickup from the frontier.priority: mediumReal value, no hard deadline; normal backlog flow.status: readyTriaged, unblocked, and fully specified; eligible to pick up.work-class: structuralRefactors, migrations, contract changes; cross-cutting and hard to reverse.

    Fields

    No fields configured for Feature.

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions