Skip to main content

HAICO Repository Foundation: Community-First Setup with Dual Development Pathways

This document is the prerequisite for the AI-automation guide (github-projects-copilot-automation.md). It describes the foundation a serious community-facing repository needs before any AI automation is layered on top. Two ideas drive the design:
  1. Two development pathways coexist. A traditional pathway (human author, human review, human merge) is the default and the one that handles meaningful work (logic changes, refactors, architecture, anything that touches a decision). An AI-assisted pathway is opt-in per issue and only used for trivial changes (cosmetic fixes, single-layer bugs, mechanical refactors, doc updates). The AI pathway is an accelerator on top of the traditional pathway, not a replacement for it.
  2. The repository is community-first. It targets external contributors and visibility (stars, citations, references). The structure mirrors what mature open-source projects use (Apache and CNCF projects) so that arriving contributors recognise the conventions without reading a manual.
The other two guides (going-public.md and the two automation guides) layer on top of this one. This guide should be read before flipping the repo public or wiring AI workflows.

1. Two pathways, one repository

The two pathways converge at the same review gate and use the same branch-protection rules. The only thing that changes is who writes the code. A reviewer should not be able to tell from the PR template whether the author was a human or the AI agent, because the standards are identical.

2. What “trivial” means: when to use the AI pathway

The AI pathway is opt-in per issue, applied by a maintainer at triage time. The default is traditional. The label is the entry signal: once an issue is path:ai-automation, Coco plans it, warns about any higher-risk traits in the plan, and a human authorizes the work with /approve-plan (see ADR-0002). It is no longer a hard checklist gate: a single “risky” trait does not disqualify the issue, it just gets surfaced for the assignee to weigh. Route an issue to the AI pathway when it is well-scoped and you would be comfortable reviewing Coco’s diff. The plan stage assesses and records these traits so you see the shape of the work before approving:
  • Size and layer span (one layer is typical; spanning frontend and backend is fine when the work is mechanical and well-scoped).
  • Database schema changes or migrations.
  • New runtime dependencies (new package.json or pyproject.toml entries).
  • Public-API contract changes (new endpoints, changed response shapes).
  • Whether an architectural decision is involved (an ADR may be warranted).
Coco raises an explicit ⚠️ warning in the plan only for the two genuinely higher-risk traits: a security-sensitive surface (auth, crypto, file uploads, deserialization), or a destructive or irreversible database migration. A warning is a flag for you, not a refusal: you approve with /approve-plan to have Coco implement it in full, or you re-route to a human by relabelling path:traditional.

Typical AI-pathway changes

  • Cosmetic fixes: CSS spacing, copy text, accessibility labels, error messages.
  • Localized bugs: a state bug in one React component, a None check missing in one Python helper.
  • Test additions for existing endpoints (happy-path + obvious edge case).
  • Documentation updates that don’t require subject-matter judgment.
  • Dependency version bumps with no breaking changes (Dependabot already handles these; noted here so contributors know not to file an issue).

When to prefer the traditional pathway

Larger work (new endpoints, DB schema changes and migrations, cross-cutting changes) is now allowed on the AI pathway when you approve the plan; Coco warns on security-sensitive surfaces and destructive or irreversible migrations so you can decide. Still prefer the traditional pathway when:
  • The design is the hard part, not the typing.
  • The change needs an ADR (Architecture Decision Record); the ADR itself stays human-authored.
  • It is the most security-critical code (core auth or crypto) and you would not want an agent authoring it even with a warning.
  • It needs performance benchmarking and judgment.
The maintainer labels the issue accordingly during triage; see §7.

3. Gap analysis: what’s here, what’s missing

3.1 What HAICO has today

With these in place, the repository now meets the community-first bar this guide describes. The remaining gaps below are mostly GitHub UI settings to confirm and a few optional files not yet added.

3.2 What remains

Most of the foundation files are now in place (§3.1). What remains falls into three groups. GitHub UI settings (no repo file, confirm in repository settings): Satisfied a different way (no dedicated file by design): Optional files not yet added: “Essential” items are blockers for public launch / community readiness. “Optional” items are nice once the community is active enough to feel the pain they solve.

3.3 The CODEOWNERS file needs work

The current file is one line:
That is fine for a solo maintainer, but it means every path requires the maintainer’s approval: CODEOWNERS picks reviewers for every PR (including the agent’s), and external contributors will not have anyone else to ping. Even with one maintainer, paths are mapped to areas (and later to people as maintainers are onboarded):
It looks redundant today, but it documents the intent, and the moment a second maintainer is added for any area, only a single line changes.

4. What belongs in .github/

GitHub surfaces a specific set of metadata files at the moments contributors act: opening an issue, opening a PR, reading the front page. The discipline that keeps a community-facing repository legible is to spend effort on the files contributors actually see and treat the rest as housekeeping. A modest, well-chosen .github/ beats an exhaustive one.

4.1 The files that matter

4.2 Issue templates worth having

Beyond the standard bug report and feature request, a separate refactor-proposal template earns its place: refactoring discussion has a different shape than a bug or a feature, and giving it its own form keeps that conversation structured. Release-tracking templates (one for bugfix releases, one for feature releases) are a useful optional addition once release cadence picks up. The principle that drives the whole directory: a repository can hold a lot of files in .github/, but the ones that matter are the ones contributors see. Effort goes into the issue-chooser config, the PR template, Discussions, the README, and the Project board. The rest is housekeeping.

4.3 Discussions

The Discussions tab anchors the parts of community that are not issues: questions, ideas, show-and-tell. Keep at least one pinned discussion at the top to orient new visitors. HAICO’s category set is defined in §6.9.

5. The dual-pathway lifecycle in detail

Here is what each pathway looks like from issue to deploy, side by side. Both end at the same place; only the implementer differs.

5.1 Traditional pathway

  1. Issue filed via the Bug report or Feature request form (§6.6).
  2. Triage by a maintainer (§7): apply labels (type:*, area:*, priority:*), set path:traditional (or no path label, since traditional is the default), add to the Project board.
  3. Claim: a contributor comments “I’d like to take this” and the maintainer assigns the issue. (For internal contributors, self-assignment is fine.)
  4. Fork + branch per CONTRIBUTING.md’s naming rules.
  5. PR opened against develop with the PR template filled in.
  6. CI runs: lint, test, build, branch-name validation.
  7. Reviews:
    • CODEOWNERS approval (mandatory).
    • Coco’s automated AI review (comment-only, on path:ai-automation PRs), which catches obvious issues.
    • Optional: human peer-review from another contributor.
  8. Merge by maintainer (squash). Branch auto-deleted.
  9. Deploy: maintainer pushes dev-vX.Y.Z tag; existing CI deploys to dev.

5.2 AI-assisted pathway

The as-built pathway is documented in ai-pathway.md, a provider-agnostic agent run by gh-aw on the repo’s own API key, so no maintainer needs a Copilot seat. The summary:
  1. Issue filed: same forms as above.
  2. Triage: maintainer adds path:ai-automation; Coco opens a draft PRdevelop and posts its plan as the first comment.
  3. Approve the plan: maintainer comments /approve-plan on the PR; Coco implements into that same PR.
  4. CI: same CI as the traditional pathway runs on the implementation push and on each later push.
  5. Promote: /promote dev comment pushes the dev tag; CI deploys to dev and the assignee is pinged to test.
  6. Iterate: /coco X makes Coco push more commits; CI re-runs, and no review fires on these pushes.
  7. Review: the assignee marks the PR Ready for review, which runs Coco’s automated review once (comment-only, never an approval; it leads with a 🟢/🟡/🔴 decision).
  8. Merge: same human gate: only a maintainer can merge, and the reviewer is pinged on approval.

5.3 What is identical between pathways

  • Branch-naming convention.
  • Target branch (develop).
  • CI checks (must all pass).
  • CODEOWNERS approval requirement.
  • Branch protection rules (signed commits, required reviews, etc.).
  • Merge strategy (squash, branch deletion).
  • Deploy mechanism (tags drive the existing CI).

5.4 What is different

The AI pathway is not “cheaper review”. It is “cheaper authorship”. The lifecycle above only works if the links between artefacts are machine-readable. GitHub provides several mechanisms; adopt them consistently so the audit trail is automatic. Quick answer to a common question, “does the issue number go in the PR title?” No. Use Closes #123 in the PR body (not the title). The body keyword creates the “Linked PR” relationship and auto-closes the issue on merge. PR titles stay descriptive (Conventional Commits style); the issue↔PR link is a body concern.

Closing keywords (PR body → Issue)

In the PR body, use one of: Rules of thumb:
  • Multi-issue PR: each issue needs its own keyword (e.g. Closes #123, closes #124).
  • Cross-repo: Closes owner/repo#123.
  • Auto-close only fires when the PR merges into the default branch. HAICO’s default is develop (set in going-public.md), so the develop-merge closes the issue. The later promotion to main does not re-trigger.
  • Closing keywords are also recognised inside commit messages, but PR-body is the canonical place: keep the single source of truth in the PR.
The PR template (§6.6) is updated to prompt for this.

PR title convention: Conventional Commits

Use <type>(<scope>): <description>:
  • feat(backend): add OAuth callback endpoint
  • fix(frontend): correct submit-button alignment on mobile
  • refactor(agents): extract retrieval factory
  • docs: expand contributing guide with linking rules
  • chore(deps): bump fastapi to 0.115
Allowed type values track the branch-name types in CONTRIBUTING.md: feat, fix, hotfix, refactor, docs, test, chore, experiment. Why this convention:
  • The PR title becomes the squash-commit message after merge → readable git log.
  • Release Drafter (§11) groups release notes by type:.
  • It is the most widely-adopted convention in open source: zero friction for arriving contributors.
Do not put #123 in the title. GitHub auto-appends (#PR_NUMBER) (the PR number, not the issue number) on squash-merge, and that is enough to backtrack from git log to the PR, and the PR’s body contains the issue link. Putting both numbers in the title makes commit messages noisy.

Branch name convention

Already enforced by .github/workflows/branch-name.yml and .githooks/pre-push. Optionally include the issue number after the type for clarity:
Branch names are ephemeral (they vanish on squash-merge), so this is purely for the contributor’s own readability. Coco’s PRs get a gh-aw-generated branch name automatically; both styles coexist fine.

Discussion → Issue promotion

The recommended flow for non-trivial features:
  1. Someone files a 💡 Idea discussion describing the use case.
  2. Community + maintainers discuss; consensus emerges (or doesn’t).
  3. If consensus: a maintainer uses Discussion → ⋯ menu → “Convert to issue”. The original Discussion remains, with a link to the new Issue.
  4. Triage applies labels and (if appropriate) path:ai-automation.
For bugs, skip Discussions: file Issues directly. For usage questions, the answer never becomes an Issue: it stays in 🙏 Q&A and a maintainer marks an answer accepted. That keeps the Issues tab a clean inventory of work, not help requests.

The “Development” sidebar

The right sidebar of every Issue has a Development section. Use it when:
  • A PR exists but does not include closing keywords (e.g. partial fix).
  • A branch needs to be associated with an Issue before a PR exists.
  • The PR targets a non-default branch (e.g. a release branch) and the auto-close link is still wanted.
Create a branch can be invoked directly from the Issue sidebar to spin up a properly-named, pre-linked branch in one step. (Handy for traditional-pathway work; the AI pathway instead starts automatically from the path:ai-automation label.)

Task lists and sub-issues for epics

For work too large for one PR, the parent Issue lists child Issues:
GitHub renders these as live checkboxes; the parent shows 1 of 3 completed. As each child PR merges with Closes #234, the parent’s progress updates in real time. GitHub’s newer sub-issues feature (2024+) makes the parent/child relationship first-class: visible as a panel in the Issue UI and navigable in the Project board. It applies when the epic needs more structure than a checklist or when the hierarchy should appear in Project views.

Announcing releases (PR ↔ Discussion)

PRs don’t auto-post to Discussions; this is the one manual link in the chain. For each vX.Y.Z release:
  1. Tag and publish the GitHub Release (notes can be auto-drafted by Release Drafter, see §11).
  2. Open a 📣 Announcement discussion summarising the release, linking the release page, and referencing notable PRs (#N) and resolved Issues (#M).
Announcement discussions are subscribable and surface in the Discussions tab, so they reach users who don’t watch the Releases tab. For HAICO, this is the single highest-leverage outreach mechanism short of social posts.

Cheat-sheet


6. Step-by-step setup

These are done in order. After §6 the repo is community-ready; it can then be flipped public per going-public.md and the automation guides layered on top.

6.1: Decide your tier targets

The gap analysis (§3.2) is walked down to decide which Optional items apply; defaults are sensible. Tiers ship in this order: Essential → Recommended → Optional → Automation. Earlier tiers are not skipped.

6.2: Add the missing root files

These live at the repo root:

CODE_OF_CONDUCT.md

Uses the Contributor Covenant v2.1 verbatim. GitHub recognises it and surfaces it on the Insights → Community Standards page. The enforcement contact is the project security address (petrosrapto@gmail.com, the same one used in SECURITY.md).

NOTICE

Required for Apache 2.0 redistribution. The skeleton:
It is updated yearly. Long license texts are not put inline; that’s what LICENSE is for.

GOVERNANCE.md

A short document that answers: Who decides what gets merged? For a single-maintainer project today, the honest version reads:
Even at one maintainer, having this file says “this project takes contributors seriously”.

MAINTAINERS.md

SUPPORT.md

A two-sentence file that GitHub auto-links from the issue chooser. The <owner> placeholder resolves to the GitHub org/user that hosts the repo:

.all-contributorsrc

Config for the all-contributors bot. The bot listens for @all-contributors add @<user> for <contribution-type> comments on issues and PRs, updates this file, and regenerates a visual contributor table in README.md. Contribution types cover code as well as non-code work (ideas, bug, design, review, talk, tutorial, etc.), which is the main reason to prefer it over a hand-maintained AUTHORS file. The skeleton:

.github/FUNDING.yml (optional)

Deferred until sponsors are actually wanted. When added:

Expand .github/dependabot.yml

Beyond GitHub Actions, the config covers the language and container ecosystems:
The groups: blocks collapse minor/patch bumps into one PR per ecosystem per week, which cuts review noise dramatically.

Expand .github/CODEOWNERS

See §3.3. Area-scoped rules are added so the file describes intent even when every owner is currently the same person.

6.3: Changelog strategy

HAICO uses Release Drafter and keeps no manual CHANGELOG.md (consistent with §3.1/§3.2 and automations.md §5). Two channel-specific configs (.github/release-drafter-dev.yml and .github/release-drafter-prod.yml) plus their workflows draft running release notes for the dev and prod channels. Each merged PR auto-categorises (based on labels) into the running draft for its channel; a maintainer reviews and publishes on tag. The discarded alternative was a manual CHANGELOG.md in Keep a Changelog format, updated by hand on each vX.Y.Z release. That is a fit only when releases are infrequent and curated, and it is superseded here by the two Release Drafter channels.

6.5: Add Architecture Decision Records (ADRs)

The docs/adr/ directory holds a docs/adr/0000-record-architecture-decisions.md (“Meta: architecture decisions are recorded in this directory”). It uses the MADR template: short, structured. Why this matters for the dual-pathway design: an ADR is the artefact that marks an architectural decision. A change that needs an ADR is flagged in Coco’s plan and the ADR itself stays human-authored; the agent implements only after a human approves the plan with /approve-plan (see ADR-0002). It is seeded with one or two real decisions that can be written today:
  • docs/adr/0001-two-branch-model.md (rationale for develop + main)
  • docs/adr/0002-dual-development-pathways.md (rationale for this guide)
  • docs/adr/0003-langgraph-for-agent-core.md (or whichever choice is most load-bearing in backend/).

6.6: Convert templates to YAML issue forms

The issue templates are YAML forms rather than Markdown. Forms give structured fields (text, dropdown, checkboxes) that are easier for humans to fill and easier for AI to parse. .github/ISSUE_TEMPLATE/bug_report.yml:
.github/ISSUE_TEMPLATE/feature_request.yml:
A third template covers refactor proposals, a real third category, distinct from bugs and features: .github/ISSUE_TEMPLATE/refactor.yml:
And the config file, which is the single most undervalued file in the issue-template directory: .github/ISSUE_TEMPLATE/config.yml:
Disabling blank issues prevents the “just opened a blank issue with one line” problem.

Refining the pull request template

The .github/pull_request_template.md prompts for a closing keyword (see §5.5), makes the issue link explicit, adds a Conventional-Commits title reminder, and adds an ADR check for architectural changes:
For multi-template repos (rare at this scale), a .github/PULL_REQUEST_TEMPLATE/ directory can hold several files (feature.md, hotfix.md, …) and contributors choose by appending ?template=feature.md to the new-PR URL. HAICO doesn’t need this yet.

6.7: Define the labels taxonomy

Labels are the connective tissue of the whole system: triage uses them, the Project board filters on them, the labeler workflow (§11) assigns them automatically, and the AI pathway dispatches on them. Standardise once. They are created in one go with the gh CLI:
That script calls gh label create --force ... for each row. Once created, the labels survive forever; this is a one-time operation. A few rules so the taxonomy stays meaningful:
  • Every issue gets exactly one type: label during triage.
  • Every issue gets exactly one area: label during triage.
  • needs-triage is removed once the issue is triaged.
  • good first issue is reserved for issues a newcomer can finish in <2 hours without reading internal docs. Putting it on harder issues kills trust.
  • path:ai-automation is added explicitly by a maintainer. Default is traditional; the absence of path:traditional means traditional. The engine is chosen by which pathway label is applied: the bare path:ai-automation (= Claude) and -claude / -codex are seat-free; -copilot needs a Copilot seat. Apply exactly one.

6.8: Polish the README and repository card

The README is the single biggest determinant of star conversion, and warrants real time. Recommended structure (cherry-picking from the current one):
  1. Hero: project name + tagline (one sentence describing what it does, not what it is).
  2. Badges: build status, license, latest release, stars. Keep it to ~5; more looks performative.
  3. Demo: a 30-second GIF or a screenshot strip. The single highest-ROI addition available.
  4. Why HAI-Co²?: one paragraph for the audience (researchers? AI/UX teams? educators?).
  5. Quickstart: 3–5 commands that get to a running demo.
  6. Architecture: link to docs/architecture.md and the paper.
  7. Contributing: link to CONTRIBUTING.md and docs/repository-foundation.md.
  8. Community: link to Discussions; mention Code of Conduct.
  9. License.
Then in Settings → General:
  • Description: one sentence (use the README’s tagline).
  • Website: link to the paper or to a project page.
  • Topics: 5–10 lowercase keywords (e.g. hai-co, langgraph, fastapi, nextjs, human-ai-collaboration, agent-framework, research).
  • A 1280×640 PNG social preview. This is the image that appears on Twitter/Mastodon/HN previews and it dramatically affects clicks.

6.9: Configure GitHub Discussions

Enable Discussions: Settings → General → Features → Discussions → ✓. Configure categories (Discussions tab → ⚙️ → Categories). Recommended set (the common defaults plus two HAICO-specific ones): One welcome discussion is pinned in General explaining the dual-pathway model and where to file what; it is linked from the README too. (Optional) .github/DISCUSSION_TEMPLATE/q-a.yml and similar files give discussion authors structured prompts. Same syntax as issue forms.

6.10: Create the community Project board

Either a user-owned Project (owned by an individual) or an org-owned Project (owned by the GitHub org; required for multiple maintainers with equal access). For HAICO solo today, user-owned is fine; the project moves to org-owned once there are co-maintainers. Fields and views are defined in detail in github-projects-copilot-automation.md §5.1. For the foundation guide (this one), the minimum is:
  • Status field with Backlog, In Progress, Done.
  • A public roadmap view filtered to Status in (Backlog, In Progress), grouped by milestone or iteration. This view is the default so visitors land on the roadmap, not the table.
  • A Good first issues view filtered to label = "good first issue" AND Status = Backlog, linked from the README: it is the single most effective onboarding link for newcomers.
The richer status set (Ready for AI, On Dev, …) from the automation guide is added later, when the AI pathway is wired.

6.11: Configure Insights → Community Standards

The repo’s Insights → Community Standards page is a checklist of the files GitHub considers community-essential:
  • Description
  • README
  • Code of conduct
  • Contributing
  • License
  • Security policy
  • Issue templates
  • Pull request template
After §6.2–§6.6 every box should be green. The repo is not flipped public until they are. The page is publicly visible once the repo is public and visitors do look at it.

6.12: Branch protection and review policy

Handled in going-public.md. The relevant rules are the same regardless of which pathway authored a PR; they stay strict and are not relaxed for AI PRs. The one thing to add before the public flip: CODEOWNERS review is required on develop and main. The default branch protection rule doesn’t require it.

6.13: A triage workflow (the human one)

Triage cadence is a maintainer’s choice; weekly is sustainable for a one-maintainer project. With 30 minutes blocked on the calendar, the Triage view of the Project board (filter Status = Backlog AND label = needs-triage) is opened and the queue is walked: For each issue:
  1. Read it. If it’s a duplicate or wontfix → label and close with a kind message.
  2. If under-specified → add needs-info, ask the question, await reply.
  3. Otherwise:
    • Set type:* (one).
    • Set area:* (one).
    • Set priority:* (one).
    • Set effort:* (one).
    • Decide pathway. If §2’s checklist is fully ticked → path:ai-automation (adding the label starts Coco). Otherwise → no path label (defaults to traditional).
    • If newcomer-friendly → good first issue.
    • Remove needs-triage.
    • Add to a milestone if the issue is on the near-term roadmap.
The target is all issues triaged within 7 days of being opened. That is the metric contributors notice.

7. Connection to the automation guides

Once §6 is done and the repo is in the green:
  1. Flip the repo to public per going-public.md.
  2. Wait one or two weeks. Watch how real contributors arrive (or don’t). Improve the README and the issue forms based on what trips people up.
  3. Then layer the AI pathway, following ai-pathway.md.
The automation guides assume this foundation is in place. They reuse the same labels, the same Project, the same review process; they just plug the AI agent (Coco) into the implementer slot when the pathway label says so.

8. What not to do

  • Don’t auto-close stale issues without a long timeout and a maintainer prompt. Aggressive stale bots are the single most-cited reason contributors leave projects. If one is adopted, it uses 180-day inactivity, two warnings, and a needs-info exemption.
  • Don’t accept AI-authored PRs to the traditional pathway. The pathway label is a contract: a path:traditional issue is implemented by a human. This keeps authorship aligned with the pathway the maintainer chose.
  • Don’t lower the review bar for AI PRs. The agent is bounded by human approval (/approve-plan), not a triviality gate, so the reviewer’s effort stays the same regardless of who authored the change.
  • Don’t make the AI pathway the default. It is opt-in. The triaging maintainer chooses.

9. Optional: stale bot, Release Drafter, labeler

These three are common open-source quality-of-life automations. They are not part of the AI-pathway automation; they’re foundation polish. All three are now configured in this repository; this section keeps the wiring rationale, while automations.md gives the lifecycle-oriented functional overview of every live automation.

9.1 Labeler (auto-label PRs by changed paths)

actions/labeler. Workflow:
Config:

9.2 Release Drafter

release-drafter/release-drafter generates the next release’s notes from merged PRs, grouping by label. Two channel-specific configs (.github/release-drafter-dev.yml and .github/release-drafter-prod.yml) plus their workflows drive the dev and prod channels. This is HAICO’s changelog strategy (§6.3); there is no manual CHANGELOG.md.

9.3 Stale bot

actions/stale. Recommended config:
Applied only after Phase 2: a stale bot should not bite before a maintenance rhythm is in place.

10. Sources