Skip to main content

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. This is reference material, not a runbook for one-off setup. For setup instructions, see docs/repository-foundation.md.

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; 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 and ADR-0002. 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 §2.4 and §2.6.

2. Labels: what each one means

The full taxonomy lives in docs/labels-reference.md and is applied by .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; never set them by hand. Each AI-pathway issue and PR shows its lifecycle stage (stage:planningstage: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.

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.

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.

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

ci.yml handles both: tag-driven. The end-to-end release flow, from a merged PR to production:

Cutting a dev release

  1. The dev draft release accumulates as PRs merge to develop. Review the draft at Releases → Draft (dev) for any title cleanups.
  2. From develop, push the next dev tag:
  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:
  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, 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): Add the richer views (Ready for AI, On Dev, Approved) only when you turn on the AI-automation pathway. See docs/ai-pathway.md.

7. The community standards page

GitHub maintains an Insights → Community Standards 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 and tune the issue forms based on which fields contributors skip.
  • On release: cut tags, publish drafts, open the Announcement.