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

# Maintainers handbook

> Triage, label discipline, review, and the release flow for maintainers.

# Maintainer's handbook

This handbook is for HAI-Co² maintainers: the people with write access to the repository who triage issues, review PRs, cut releases, and make the judgement calls that keep the project moving. If you are an external contributor, the document you want is [community-guide.md](/docs/community-guide).

This is reference material, not a runbook for one-off setup. For setup instructions, see [`docs/repository-foundation.md`](/docs/repository-foundation).

***

## 1. The triage loop

### Cadence

The metric contributors notice is: **every issue triaged within 7 days of being opened.**

### The Triage view

Open the *Triage* view on the [community Project board](https://github.com/petrosrapto/HAICO/projects); it filters to `Status = Backlog AND label = needs-triage`. Walk the queue top-to-bottom.

### For each issue

1. **Read it.** If it's a duplicate or wontfix → label and close with a kind message.
2. **Under-specified?** Add `needs-info`, ask the question, await reply. Set a calendar reminder to follow up if the reporter goes silent for 14 days.
3. **Otherwise, apply labels:**
   * Exactly one `type:*` (`type:bug`, `type:enhancement`, …).
   * Exactly one `area:*`.
   * One `priority:*` and one `effort:*`.
   * **Pathway decision** (see §2 below).
   * `good first issue` if a newcomer can finish it in under 2 hours without reading internal docs.
4. **Add to a milestone** if the issue is on the near-term roadmap.
5. **Remove `needs-triage`.**

### Pathway decision

The pathway decision is the most consequential triage call. See the [pathway guidance](/docs/repository-foundation#2-what-trivial-means--when-to-use-the-ai-pathway) and [ADR-0002](/docs/adr/0002-dual-development-pathways). The label is the entry signal, not a hard gate: once you apply `path:ai-automation`, Coco plans the issue, warns in the plan about any higher-risk traits, and you authorize the work by commenting `/approve-plan` on the PR.

Route an issue to the AI pathway when it is well-scoped and you are comfortable reviewing Coco's diff. The plan surfaces these so you can weigh them before approving:

* Size and layer span.
* DB schema changes or migrations.
* New runtime dependencies.
* Public-API contract changes.
* Whether an architectural decision is involved (an ADR may be warranted).

Coco raises a ⚠️ warning in the plan only for a security-sensitive surface (auth, crypto, uploads, deserialization) or a destructive or irreversible migration. A warning is informational: approve with `/approve-plan` to implement, or relabel `path:traditional` to send it to a human. Prefer traditional when the design is the hard part, or when you would not want an agent authoring the change even with a warning.

**Pick the engine with the label.** Apply exactly one pathway label: `path:ai-automation` (or `path:ai-automation-copilot`) runs **Copilot** (default; requires a Copilot seat); `path:ai-automation-claude` runs **Claude** (seat-free); `path:ai-automation-codex` runs **Codex / OpenAI** (seat-free). The chosen engine drives the whole PR through. See [ai-pathway.md](/docs/ai-pathway) §2.4 and §2.6.

***

## 2. Labels: what each one means

The full taxonomy lives in [`docs/labels-reference.md`](/docs/labels-reference) and is applied by [`.github/scripts/init-labels.sh`](https://github.com/petrosrapto/HAICO/blob/main/.github/scripts/init-labels.sh). The short version for triage:

* **Every issue gets exactly one `type:` label.**
* **Every issue gets exactly one `area:` label.** (Labeler workflow auto-applies the area on PRs from changed paths.)
* **`needs-triage` must be removed once triage is done.** This is the signal to the rest of the world that the issue is actionable.
* **`good first issue` is sacred.** Reserve it for issues a newcomer can finish in under 2 hours without reading internal docs. Putting it on harder issues kills trust faster than anything else.
* **`path:ai-automation` (or an engine-specific `path:ai-automation-{claude,codex,copilot}`) is added explicitly by you, or automatically when you assign `HAI-Coco` to the issue.** Default is traditional (absence of any `path:*` label means traditional). The bare label is the Copilot alias (default engine; requires a seat).
* **`stage:*` labels are managed automatically** by [`coco-stage-labels.yml`](https://github.com/petrosrapto/HAICO/blob/main/.github/workflows/coco-stage-labels.yml); never set them by hand. Each AI-pathway issue and PR shows its lifecycle stage (`stage:planning` … `stage:awaiting-merge`) in the Issues and Pull-requests lists, so you can see where everything is at a glance; warm colors mean it is your turn to act. See the state diagram in [ai-pathway.md](/docs/ai-pathway).

***

## 3. Reviewing PRs

### The same bar for both pathways

A PR's review effort does not depend on its author. Coco is bounded by **human approval** (`/approve-plan`), not by a triviality gate: the review bar stays constant regardless of who authored the change; see [ADR-0002](/docs/adr/0002-dual-development-pathways).

### What to check

* **Target branch is `develop`.** PRs to `main` are release promotions only.
* **PR title is Conventional Commits.** Reject anything else, since the title becomes the squash-commit message and the Release Drafter category.
* **`Closes #...` in the body.** Without this, the issue does not auto-close.
* **CI is green.** Lint, tests, build.
* **CODEOWNERS approval.** You are usually the CODEOWNER; review accordingly.
* **No secrets committed.** Push protection catches the obvious ones; you catch the rest.
* **ADR for architectural changes.** If the diff changes how modules compose, how data flows, or which framework owns what, ask for an ADR in the same PR. See [`docs/adr/README.md`](/docs/adr/index).

### Responding to Coco

On `path:ai-automation` PRs, the reviewer iterates with Coco using the `/coco` slash command (gh-aw has no `@mention` trigger):

```
/coco the dev container fails health-check at /api/health.
The cause looks like a missing env var. Please add a default to settings.py
and a test that covers the missing-env path.
```

Coco picks up the command, treats the entire PR thread + AGENTS.md as context, and pushes new commits to the PR branch (which re-runs CI).
These iteration pushes do not trigger a review; when you are satisfied, mark the PR **Ready for review** to run Coco's automated review once (or comment `/review` for an extra pass on demand).

If a Coco PR repeatedly misses the mark, the change may be a poor fit for an agent: re-label it `path:traditional` and assign a human implementer (or do it yourself).

### Merging

* **Squash merge.** Always. The PR title becomes the commit; the body appears below.
* The branch auto-deletes.
* The linked issue auto-closes on merge into `develop`.

***

## 4. Releases

### Two channels, one CI workflow

| Tag pattern  | Built from | Deploys to      | Release Drafter config                                                                                                |
| ------------ | ---------- | --------------- | --------------------------------------------------------------------------------------------------------------------- |
| `dev-vX.Y.Z` | `develop`  | Dev environment | [`.github/release-drafter-dev.yml`](https://github.com/petrosrapto/HAICO/blob/main/.github/release-drafter-dev.yml)   |
| `vX.Y.Z`     | `main`     | Production      | [`.github/release-drafter-prod.yml`](https://github.com/petrosrapto/HAICO/blob/main/.github/release-drafter-prod.yml) |

[`ci.yml`](https://github.com/petrosrapto/HAICO/blob/main/.github/workflows/ci.yml) handles both: tag-driven.

The end-to-end release flow, from a merged PR to production:

```mermaid theme={null}
flowchart TD
    A["PRs squash-merged to develop"] --> B["dev draft release accumulates"]
    B --> C["Push dev-vX.Y.Z tag from develop"]
    C --> D["ci.yml builds :dev images, runs dev deploy"]
    D --> E{"Validated on dev?"}
    E -->|"no"| A
    E -->|"yes"| F["Fast-forward develop to main (git merge --ff-only)"]
    F --> G["Push main, then push vX.Y.Z tag"]
    G --> H["ci.yml builds :latest images, runs prod deploy"]
    H --> I["Publish prod draft, open Announcement discussion"]
```

### Cutting a dev release

1. The dev draft release accumulates as PRs merge to `develop`. Review the
   draft at [Releases → Draft (dev)](https://github.com/petrosrapto/HAICO/releases)
   for any title cleanups.

2. From `develop`, push the next dev tag:

   ```bash theme={null}
   git checkout develop
   git pull
   git tag dev-v0.3.1
   git push origin dev-v0.3.1
   ```

3. Publish the draft release (its `tag-template` matches your pushed tag).

4. `ci.yml` builds and pushes the `:dev` + `:X.Y.Z` images and runs the dev
   deploy job.

### Cutting a production release

1. The prod draft release accumulates as `develop` is fast-forwarded into
   `main`. Review it.

2. Promote `develop → main`:

   ```bash theme={null}
   git checkout main
   git merge --ff-only develop       # locally; or via a PR develop → main
   git push origin main
   git tag v1.0.0
   git push origin v1.0.0
   ```

3. Publish the prod draft release.

4. `ci.yml` builds and pushes the `:latest` + `:X.Y.Z` images and runs the
   prod deploy job.

5. **Open a 📣 Announcement discussion** linking the release page,
   highlighting notable PRs/Issues. The Announcement is the highest-leverage
   outreach mechanism short of social posts.

### Why two Drafters

Release Drafter only watches one branch. Two configs and two workflows let us have running notes for both channels without one polluting the other. Keep both configs in sync, especially the `autolabeler` rules.

***

## 5. ADRs: the bright line

If a change *needs* an [Architecture Decision Record](/docs/adr/index), the issue is `path:traditional` by construction. Coco does not propose architecture.

Write an ADR when:

* The decision shapes the structure of more than one module or service.
* The decision picks one of several reasonable approaches, and a future contributor would reasonably ask *"why this?"*.
* The decision constrains future work (framework, database, wire format, topology).
* The decision touches the dual-pathway model, the release workflow, or any governance question.

Don't ADR cosmetic choices, reversible-in-a-day decisions, or things the code adequately documents.

To override an existing ADR: open a new one, link forward, and change the old ADR's `status:` to `superseded by NNNN-...`. **Do not edit the old decision**, since that is the historical record.

***

## 6. Reading the Project board

The community Project board has at minimum these views (defined in [`docs/repository-foundation.md` §6.10](/docs/repository-foundation)):

| View                  | Filter                                                   | Audience                        |
| --------------------- | -------------------------------------------------------- | ------------------------------- |
| **Roadmap** (default) | `Status in (Backlog, In Progress)`, grouped by milestone | Visitors, contributors browsing |
| **Triage**            | `Status = Backlog AND label = needs-triage`              | Maintainers, weekly triage      |
| **Good first issues** | `label = "good first issue" AND Status = Backlog`        | First-time contributors         |
| **In progress**       | `Status = In Progress`                                   | Maintainers, daily glance       |

Add the richer views (`Ready for AI`, `On Dev`, `Approved`) only when you turn on the AI-automation pathway. See [`docs/ai-pathway.md`](/docs/ai-pathway).

***

## 7. The community standards page

GitHub maintains an [Insights → Community Standards](https://github.com/petrosrapto/HAICO/community) page listing the files it considers community-essential. Keep every box green:

* Description.
* README.
* Code of Conduct.
* Contributing.
* License.
* Security policy.
* Issue templates.
* PR template.

Visitors look at this page once the repo is public; an unticked box is a signal that the project is not yet serious. The page is publicly visible.

***

## 8. Recurring chores

The CI-runs-it-for-you ones:

* **Dependabot**: opens grouped PRs weekly for `pip`, `npm`, `docker`, and `github-actions`. Treat them as ordinary PRs; squash-merge after green CI.
* **Release Drafter (dev/prod)**: runs on every merge; keep an eye on the draft, fix titles before publishing.
* **Labeler**: runs on every PR open; auto-applies `area:*`.
* **Stale bot**: Monday 06:00 UTC weekly; conservative (180-day idle, 21-day warning). Watch the first run after enabling and confirm nothing important was swept.
* **CodeQL + Autofix**: runs on PRs; surface findings in Security tab.

The human-driven ones:

* Weekly triage (§1).
* Monthly: glance at the Discussions tab for unanswered Q\&A.
* Quarterly: re-read [`docs/repository-foundation.md`](/docs/repository-foundation) and tune the issue forms based on which fields contributors skip.
* On release: cut tags, publish drafts, open the Announcement.

***

## 9. Sources and related docs

* [`docs/repository-foundation.md`](/docs/repository-foundation): the long-form setup guide; rationale for every convention here.
* [`docs/community-guide.md`](/docs/community-guide): the contributor-facing view of the same conventions.
* [`docs/labels-reference.md`](/docs/labels-reference): full taxonomy.
* [`docs/adr/README.md`](/docs/adr/index): how ADRs work.
* [`docs/going-public.md`](https://github.com/petrosrapto/HAICO/blob/main/docs/going-public.md): public-launch checklist.
* [`docs/ai-pathway.md`](/docs/ai-pathway): the as-built AI-pathway automation (Coco, gh-aw). [`docs/github-projects-copilot-automation.md`](/docs/github-projects-copilot-automation) is the original Copilot-based design, kept as background.
* [`MAINTAINERS.md`](https://github.com/petrosrapto/HAICO/blob/main/MAINTAINERS.md): who maintains what and how to add a maintainer.
