> ## Documentation Index
> Fetch the complete documentation index at: https://dev.haico.gr/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# ADR-0002: Dual development pathways

> Traditional + AI-assisted contribution pathways, gated by issue label.

# 0002. Dual development pathways: traditional + AI-assisted

## Context and problem statement

An AI coding agent can take a GitHub Issue, open a draft PR, and iterate to green CI without a human author writing a line of code. The question is not *"can we let it implement everything?"*; that bar is too low, since current code-generation models are not reliable on architecture work. The question is *"which subset of issues is the agent allowed to implement, and how do we make that boundary obvious to maintainers, contributors, and the tooling?"*.

If the boundary is implicit, two failure modes follow: the agent starts ghost-writing architecture (bad outcomes), or maintainers stop using it for the trivial work where it actually saves time (lost benefit).

This decision is about the **boundary**, which is independent of *which* agent implements. For the implementer choice itself, see *Decision outcome* below.

## Decision drivers

* The review bar must not change. Maintainer effort per PR stays the same; the savings come from cheaper *authorship*, not cheaper review.
* Pathway membership must be a single, visible signal, readable from the Issues list without opening each issue.
* The boundary must be enforceable in the human triage step, not in code. Process beats automation here.
* Architecture decisions must remain human-owned: a human must consciously authorize any change that would need an ADR. ADR existence ([ADR-0000](/docs/adr/0000-record-architecture-decisions)) is the canonical marker the plan flags for that decision.

## Considered options

1. **No AI authorship.** Humans implement everything.
2. **AI authorship on all issues.** Copilot takes any assigned issue.
3. **AI authorship gated by issue label** (`path:ai-automation`), applied by a maintainer at triage time per a fixed checklist.
4. **AI authorship gated by a CODEOWNERS file**: paths declare whether AI may modify them.

## Decision outcome

**Chosen option: gate by issue label**, applied at triage time. The label is `path:ai-automation`. Default is `path:traditional` (or the absence of any path label).

The label is the entry signal; the **plan stage then surveys the change for risk and the assignee decides**. This replaces the original hard gate (see the 2026-06 update below): the agent no longer refuses or self-routes on scope grounds, because a human consciously authorizes every implementation.

What the plan assesses and records, as plain notes, so the reviewer sees the shape of the work:

* Size and layer span (one layer typical; two or more is fine when the plan is clear).
* DB schema changes or migrations.
* New runtime dependencies.
* Public-API contract changes.
* Whether an architectural decision is involved (an ADR may be warranted).

The plan raises an explicit **⚠️ warning** only for the two genuinely higher-risk traits:

* A security-sensitive surface (auth, crypto, file uploads, deserialization).
* A destructive or irreversible database migration.

A warning is a flag for the assignee, never a refusal. The **assignee is the gate**: commenting `/approve-plan` is the explicit human authorization to implement the plan in full, warnings included; declining (closing the PR, or relabelling `path:traditional`) sends the work to a human author. The review and merge gate at the end is unchanged.

### Update (2026-06): warn-and-approve, not a hard gate

Originally (2026-05) this decision was a hard, mechanical gate: a change qualified for the AI pathway only if **all** of a checklist held (small and self-contained, no schema or migration, no new dependency, no public-API change, no security-sensitive surface, no ADR needed, quickly verifiable), and a single unchecked box forced the issue to the traditional pathway. In practice that bar excluded almost anything that persisted or exposed data, so the plan or implement stage refused most labelled issues even after a maintainer approved them, which defeated the point of approval (see PRs #72 and #74, approved then refused).

We keep the human in the loop but move the decision from a checklist to the assignee. The plan still assesses the same signals and records them, and it warns (⚠️) on the two traits where caution genuinely pays (security-sensitive surfaces, and destructive or irreversible migrations), but it no longer refuses or self-routes. `/approve-plan` is now a real authorization: once a maintainer approves, the implement stage builds the plan in full rather than stopping on triviality grounds. Architecture stays human-owned because a human reads the plan, sees the warnings, and consciously authorizes the work; the final human review and merge gate is unchanged.

### Implementer: provider-agnostic, not Copilot-specific

The pathway is implemented with **GitHub Agentic Workflows (`gh-aw`)** running a
configurable model (default: Claude Opus, set via the `AI_MODEL` repo variable)
on the repository's own `ANTHROPIC_API_KEY`, **not** the GitHub Copilot Coding
Agent. The reason is access: Copilot's coding agent is entitlement-gated to the
*initiating user*, so only maintainers holding a paid Copilot seat could dispatch
it. Running the agent inside GitHub Actions on the repo's key means **any
maintainer with write access can drive the full flow without a Copilot seat**,
and all AI cost falls on the repo (API key + Actions minutes). The trade-off is
that we own the prompt-injection hardening (mitigated by the four guardrails in
[ai-pathway.md](/docs/ai-pathway): write-access-only triggers, no secrets to
forks, least-privilege read-only agents, human-only merge). Copilot remains a
drop-in alternative implementer for anyone who has a seat. The as-built flow is
documented in [ai-pathway.md](/docs/ai-pathway).

**Update (2026-06):** the implementer is now selectable **per issue** via the pathway label, without changing this decision. `path:ai-automation-claude` runs the Claude engine on the repo's `ANTHROPIC_API_KEY`, seat-free; `path:ai-automation-codex` runs Codex/OpenAI (`OPENAI_API_KEY`), also seat-free; `path:ai-automation-copilot` (and the bare `path:ai-automation` alias) runs Copilot, which still needs a Copilot seat (`COPILOT_GITHUB_TOKEN`). The bare `path:ai-automation` label now defaults to the **Copilot** engine (changed from Claude, 2026-06). Assigning the `HAI-Coco` bot account to an issue automatically adds `path:ai-automation`, triggering the Copilot pipeline without a separate labelling step. Per-engine models are set with `AI_MODEL_CLAUDE` / `AI_MODEL_CODEX` / `AI_MODEL_COPILOT` (`AI_MODEL` still feeds Claude), and each stage can be overridden independently via the optional `AI_MODEL_<ENGINE>_<STAGE>` variables (`STAGE` in `PLAN`/`IMPLEMENT`/`ITERATE`/`REVIEW`), which take precedence over the per-engine value. See [ai-pathway.md §2.6](/docs/ai-pathway).

### Positive consequences

* The pathway membership is one click in the labels UI, visible on the issues list, the Project board, and to every reviewer.
* The two pathways converge at the same review gate. CODEOWNERS approval, branch protection, and CI are all unchanged.
* The agent never ghost-writes architecture by accident: an architectural change surfaces in the plan (warned where it touches a security-sensitive surface or a destructive migration), and a human must consciously authorize it with `/approve-plan` before any code is written.

### Negative consequences

* The maintainer is the bottleneck: every issue gets one human-applied label. We accept this; triage is already a 30-min/week activity.
* The checklist is a judgement call, not a regex. The benefit is that borderline cases get a human eye, which is the right outcome.
* We need a different *PR-side* signal for who authored the change. The agent's PRs carry the `path:ai-automation` label and are authored by the automation token's account; the issue's assignee is carried onto the PR as the PR assignee (falling back to the maintainer who applied the label when the issue is unassigned).

## Pros and cons of the options

### Option 1: No AI authorship

* **+** No risk of bad architecture.
* **−** Throws away the real benefit of trivial-work acceleration.

### Option 2: AI on all issues

* **+** Fastest path on the trivial subset.
* **−** The agent will attempt architecture. Bad outcomes.

### Option 3: Label-gated (chosen)

* **+** Visible, reversible, requires no code changes to enforce.
* **−** Relies on maintainer discipline at triage.

### Option 4: CODEOWNERS-gated

* **+** Mechanically enforceable on PRs.
* **−** Mixes ownership with authorship. CODEOWNERS is about *review*, not *authorship*. The wrong axis to overload.

## Links

* [`docs/ai-pathway.md`](/docs/ai-pathway), the as-built implementation of this pathway (provider-agnostic, `gh-aw`-based).
* [`docs/github-projects-copilot-automation.md`](/docs/github-projects-copilot-automation), the original Copilot-based design, kept as background.
* [ADR-0000](/docs/adr/0000-record-architecture-decisions), "needs an ADR?" is the bright-line test that excludes AI authorship.
