Forge Coding Intake & the Autonomy Ladder
Label an issue, get a merge request. A webhook fast-path plus a reconciler safety-net turn GitHub and GitLab issues into durable coding jobs, and a per-repo policy ladder decides how much of the pipeline runs without a human.
1 · Scope
- One generic core feature set — no instance-specific logic; every knob is per-instance configuration, so any business drops Neutron in and gets the same workflow.
- Two deliverables: forge issue intake (both forges, both entry paths) and the approval policy ladder replacing today's two hardcoded human gates.
- Out of scope: the agent-facing coding connector (chat/schedule tools) — phase 2. Auto-merge — never; a human or CI merges.
2 · Trigger protocol
A neutron:ready label on an issue in a repo the instance already knows
(workspace resources). Only collaborators with triage access can label, so the label itself
is the authorization — no separate assignment convention. Issue text enters as
untrusted_external and is delimited in the coding prompt.
flowchart LR R[neutron:ready] -- intake --> RU[neutron:running] RU -- publish --> RV[neutron:review
PR/MR link comment] RU -- terminal failure --> F[neutron:failed
safe summary comment]
Label names are per-instance settings with these defaults. Re-labeling after a failure with a changed issue body is a new revision and a new job; unchanged, it is a no-op.
3 · Intake service
One idempotent intakeWorkItem(repo, issueRef) shared by both entry paths —
nothing is built twice.
flowchart TB WH[forge webhook
issues + label events
signature verified] --> IS RC[reconciler sweep
every 5 min via WorkItemProvider.list] --> IS IS[intake service
idempotent] --> SN[snapshot · content-addressed
trustClass untrusted_external] SN --> J[coding job
per-repo runtime/model defaults] J --> C[controller pipeline
plan → change → verify → review → publish] C --> PR[open PR / MR
lifecycle labels + comment]
- Webhook path extends the existing channels layer (signature checks, repo allowlists already there) with issue/label events. Latency: seconds.
- Reconciler path lists labeled issues through the already-written
WorkItemProviderseams. Catches missed deliveries; a new business that configures no webhook still gets the whole feature. - Dedupe on an idempotency key over (repo, issue revision hash, base SHA) — the same receipt pattern the controller uses everywhere, so webhook redelivery and overlapping sweeps cannot double-fire.
4 · Bot identity
Intake and publication run on a dedicated machine account per instance (Settings → Connections; GitLab group tokens are already bot users, GitHub gets a machine user). Proven necessary in acceptance: a PR authored by the owner's personal token cannot receive the owner's external review — GitHub refuses self-approval, and the gated pipeline stalls.
5 · Autonomy ladder
The workflow already accepts planApprovalRequired and
publicationApprovalRequired; nothing configurable reaches them today. The
ladder wires them to a policy resolved per repo, falling back per workspace.
| Level | Plan gate | Publication gate | External review |
|---|---|---|---|
| supervised | human | human | required |
| trusted | auto | human | required |
| autonomous | auto | auto | required |
| full | auto | auto | self-approved |
supervisedis the default and exactly today's behavior.- A job parked at any gate raises an inbox/bell card (reusing the schedules notification path) instead of waiting silently.
- Per-repo read-only grants keep their existing hard-deny override regardless of level.
6 · First consumer: assay
- Create the GitHub machine user; add its token as a connection.
- Assay is already a workspace resource on the instance; create the four labels.
- Enable the GitHub channel webhook for the repo.
- Set assay's policy to
supervised; label one real issue; watch the PR arrive. - Ratchet to
trustedonce a handful of jobs look good.
7 · Acceptance
- Label → open PR (GitHub) and label → open MR (GitLab), lifecycle labels correct.
- Webhook-down recovery: reconciler picks the issue up within one sweep.
- Dedupe under webhook redelivery and overlapping sweeps: exactly one job.
- Unauthorized label events (forks, non-collaborators) rejected.
- Ladder behavior verified per level; read-only repos always denied.
- These runs double as the outstanding dual-forge acceptance evidence for v0.4.