You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
PRD: Looper Network — Coordinator admission and review assignment with exact Node targeting
Problem
Looper needs to coordinate autonomous work across both single-machine and multi-node deployments without changing the authority that Worker and Reviewer already trust: current GitHub state.
The product goals are:
After an Issue is published, Looper can decide whether it should be worked and, if yes, add looper:worker-ready.
After a Pull Request is created, Looper can decide who should review it and request that reviewer.
Both behaviours work in local-only mode and Network mode.
In Network mode, multiple Nodes may share the same GitHub identity, so assignee/review-request is not enough to identify the exact Node that should act.
Decision
Model this as Network-aware Coordinator control-plane work, not as a separate product-level Router role.
Coordinator owns:
Issue admission / dispatch: decide whether an Issue should be implemented, then apply the GitHub state that lets Worker claim it.
PR review assignment: decide whether a PR should receive Looper review, then request an eligible reviewer.
Network exact targeting: in Routed mode only, add/repair exactly one looper:target:<node_name> label so a specific Node can claim the work.
loopernet remains infrastructure only: membership, health, lease, webhook ingress, event fanout, state, and audit. It never mutates GitHub.
Modes
Local-only mode
Default mode. Existing single-machine behaviour is preserved.
No loopernet is required.
No Network membership is required.
looper:target:* labels are ignored.
Coordinator may admit Issues by adding looper:worker-ready and assigning the configured GitHub identity.
Coordinator may assign PR review by requesting the configured GitHub reviewer identity.
Worker and Reviewer claim using current GitHub state only.
Routed Network mode
Per-project opt-in via network.mode = routed.
One loopernet hosts one Network.
A Node joins exactly one Network at a time.
node_name must be Network-unique, label-safe, lower-case, and case-insensitive unique.
Duplicate github_user_id values are allowed.
Exactly one current lease-holder Coordinator Node performs Network control-plane GitHub mutations.
The lease-holder Node mutates GitHub using its local gh authentication; loopernet never mutates GitHub.
The lease must be revalidated before every GitHub side-effect. Stale fencing tokens fail closed, e.g. 412.
Authority model
Issue admission authority
The authority to add looper:worker-ready is:
Coordinator's current admission/dispatch decision, or
an existing human/external GitHub label.
Worker claim authority remains current GitHub state:
Issue is open.
Issue has looper:worker-ready.
Issue assignees include the local GitHub identity.
In Routed mode only: Issue has exactly one syntactic looper:target:* label total, and that single label names the local Node.
PR review assignment authority
The authority to request review is:
Coordinator's current PR review-assignment decision, or
an existing human/external GitHub review request.
Reviewer claim authority remains current GitHub state:
PR is open.
Existing Reviewer filters pass.
GitHub currently has a review request for the local GitHub identity.
In Routed mode only: PR has exactly one syntactic looper:target:* label total, and that single label names the local Node.
Exact Node target authority
In Routed mode, exact Node authority is current GitHub label state:
exactly one looper:target:<node_name> label exists on the item;
the label names the local Node.
Zero, multiple, unknown, orphaned, stale, or non-matching target labels make the item unclaimable until reconciliation repairs it.
Identity strategy
Each Node uploads numeric github_user_id when available. Worker and Reviewer routed predicates compare numeric IDs first. Login fallback is allowed only when numeric ID is unavailable, and fallback usage must be surfaced in status/audit output. Duplicate github_user_id values are allowed and are disambiguated solely by looper:target:<node_name>.
Event ingress and wakeup model
In Routed mode, repository webhooks are centralized on loopernet; individual Nodes do not need their own GitHub webhook tunnel for Worker/Reviewer/Coordinator label and PR events.
loopernet receives GitHub webhook deliveries, records/fans out events over the Node event stream, and never performs GitHub mutations. Nodes use the stream as a wakeup signal, then re-read GitHub authority with local credentials before admission, assignment, discovery, claim, or process. Low-frequency polling remains a fallback for missed webhooks, SSE disconnects, restarts, and drift recovery; it is not the primary routed event path.
Mutation ordering
Coordinator must avoid exposing a claimable half-mutated item.
Issue admission in Routed mode:
Revalidate lease.
Apply/repair coarse GitHub authority: assignee and looper:worker-ready.
Revalidate lease.
Add/repair looper:target:<node_name> last.
PR review assignment in Routed mode:
Revalidate lease.
Apply/repair coarse GitHub authority: review request to selected GitHub identity.
Revalidate lease.
Add/repair looper:target:<node_name> last.
Worker/Reviewer must still re-read GitHub immediately before processing a claimed item.
PR review assignment policy
v1 should stay deliberately simple:
Candidate Nodes come from Network membership and project eligibility.
Candidate reviewer identity must be able to receive review requests for the repo.
Existing Reviewer filters and self-review rules must be considered before selecting a target.
If no eligible Node exists, Coordinator records/statuses no-eligible-node and does not add a target label.
The selection algorithm should be deterministic and explainable; capacity/health may be used if already available, but speculative balancing is out of scope.
Reconciliation
The lease-holder Coordinator Node performs reconciliation using local gh authentication. loopernet does not mutate GitHub.
Reconciliation may repair:
missing target label for already-admitted/assigned work;
stale target labels for non-member Nodes;
multiple target labels;
target labels whose coarse GitHub authority was removed by a human;
interrupted mutation sequences.
Current GitHub state remains authority. Audit records are observability only and must not be used to override human changes by themselves.
Non-goals for v1
Hosted/multi-tenant loopernet.
loopernet directly calling GitHub.
Hiding exact target state only in loopernet; target authority is the current GitHub label.
Role×Node trigger-label matrices such as looper:worker-ready:red.
A separate product-level Router role.
Network-aware Planner/Fixer execution beyond the Coordinator admission/assignment control plane described here.
Complex queue balancing, quotas, or global scheduling.
PRD: Looper Network — Coordinator admission and review assignment with exact Node targeting
Problem
Looper needs to coordinate autonomous work across both single-machine and multi-node deployments without changing the authority that Worker and Reviewer already trust: current GitHub state.
The product goals are:
looper:worker-ready.Decision
Model this as Network-aware Coordinator control-plane work, not as a separate product-level Router role.
Coordinator owns:
looper:target:<node_name>label so a specific Node can claim the work.loopernetremains infrastructure only: membership, health, lease, webhook ingress, event fanout, state, and audit. It never mutates GitHub.Modes
Local-only mode
Default mode. Existing single-machine behaviour is preserved.
loopernetis required.looper:target:*labels are ignored.looper:worker-readyand assigning the configured GitHub identity.Routed Network mode
Per-project opt-in via
network.mode = routed.loopernethosts one Network.node_namemust be Network-unique, label-safe, lower-case, and case-insensitive unique.github_user_idvalues are allowed.ghauthentication;loopernetnever mutates GitHub.Authority model
Issue admission authority
The authority to add
looper:worker-readyis:Worker claim authority remains current GitHub state:
looper:worker-ready.looper:target:*label total, and that single label names the local Node.PR review assignment authority
The authority to request review is:
Reviewer claim authority remains current GitHub state:
looper:target:*label total, and that single label names the local Node.Exact Node target authority
In Routed mode, exact Node authority is current GitHub label state:
looper:target:<node_name>label exists on the item;Zero, multiple, unknown, orphaned, stale, or non-matching target labels make the item unclaimable until reconciliation repairs it.
Identity strategy
Each Node uploads numeric
github_user_idwhen available. Worker and Reviewer routed predicates compare numeric IDs first. Login fallback is allowed only when numeric ID is unavailable, and fallback usage must be surfaced in status/audit output. Duplicategithub_user_idvalues are allowed and are disambiguated solely bylooper:target:<node_name>.Event ingress and wakeup model
In Routed mode, repository webhooks are centralized on
loopernet; individual Nodes do not need their own GitHub webhook tunnel for Worker/Reviewer/Coordinator label and PR events.loopernetreceives GitHub webhook deliveries, records/fans out events over the Node event stream, and never performs GitHub mutations. Nodes use the stream as a wakeup signal, then re-read GitHub authority with local credentials before admission, assignment, discovery, claim, or process. Low-frequency polling remains a fallback for missed webhooks, SSE disconnects, restarts, and drift recovery; it is not the primary routed event path.Mutation ordering
Coordinator must avoid exposing a claimable half-mutated item.
Issue admission in Routed mode:
looper:worker-ready.looper:target:<node_name>last.PR review assignment in Routed mode:
looper:target:<node_name>last.Worker/Reviewer must still re-read GitHub immediately before processing a claimed item.
PR review assignment policy
v1 should stay deliberately simple:
no-eligible-nodeand does not add a target label.Reconciliation
The lease-holder Coordinator Node performs reconciliation using local
ghauthentication.loopernetdoes not mutate GitHub.Reconciliation may repair:
Current GitHub state remains authority. Audit records are observability only and must not be used to override human changes by themselves.
Non-goals for v1
loopernet.loopernetdirectly calling GitHub.loopernet; target authority is the current GitHub label.looper:worker-ready:red.Implementation sub-issues
Recommended order:
Acceptance criteria
looper:target:*.loopernetmembership and a valid lease for Coordinator control-plane GitHub mutations.looper:worker-readyfor admitted Issues in both local-only and Routed modes.loopernetnever mutates GitHub.loopernet; per-Node webhook tunnels are not required in Routed mode.