Skip to content

Latest commit

 

History

History
131 lines (93 loc) · 6.18 KB

File metadata and controls

131 lines (93 loc) · 6.18 KB

Contributing

Thanks for taking a look. This template's harness is the product, so the contribution flow is opinionated — every change goes through the same gates as a feature.

Branching

main  ◄── release PR ◄── develop ◄── feat/123-short-name
                                  ◄── fix/124-bug-name
                                  ◄── chore/125-config-change
  • main is the release line. Protected: 21 required status checks, code-owner approval, no force pushes. (One additional non-required check, Draft next release from release-drafter, runs informationally on PRs to main and shows up in the rollup but is not gated.)
  • develop is the integration branch. Same 21 gates, less strict (PRs don't need rebases).
  • Feature branches are short-lived and named <type>/<issue-number>-<kebab-title>. Open one issue per branch so the project board stays usable.

Commit messages

Seven prefixes (enforced in three places — [tool.commitizen] in pyproject.toml, pr-title.yml, check_commit_types.py):

Prefix When
feat: New capability
fix: Bug fix
docs: Documentation only
test: Tests / eval harness
refactor: Internal change with no behaviour delta
chore: Tooling, deps, infra
release: develop → main release PRs only

The subject is lowercase after the colon. Title Case prose (Add the thing) is rejected; all-caps initialisms (CI failure, SDK upgrade) are fine.

Pull requests

  1. Open the issue first. Use a feature/bug template; fill every section.
  2. Branch off develop with the matching name.
  3. If your team uses Beads, mirror or claim the linked issue in the local Beads queue after the issue exists. Beads track local ready/blocked execution only; GitHub Issues remain canonical for scope, discussion, PR linkage, and closure.
  4. Land one logical change per PR. Stack PRs if the work is naturally split.
  5. The PR template asks five things — answer each (None is valid where applicable):
    • What & why (1–3 lines)
    • Test plan (checkbox list; CI covers most of it)
    • Invariants affected — cite numbered rules from docs/INVARIANTS.md
    • New deps / actions / external surface (anchor for supply-chain review)
    • Screenshots (UI changes only)
  6. Wait for green CI + a code-owner review before merging.

Solo-owner merge policy

Transitional — only while this repo has a single code owner. Standard practice is a code-owner review on every PR. The flow below exists because GitHub forbids self-approval, so a single-owner repo cannot satisfy the "1 code-owner review" gate any other way. The exemption is removed the moment a second collaborator with merge rights joins.

This repo currently runs with a single code owner (* @constk in CODEOWNERS). While in this state, the intended merge command is:

gh pr merge <N> --admin --squash --delete-branch

…for feat: / fix: / chore: PRs, and --admin --merge (preserves history) for release: PRs. The enforce_admins: false line in .github/branch-protection/{develop,main}.json is the documented escape hatch — admin merge here is the documented single-owner workaround, not bypass of the gates (every required status check still has to pass).

When the exemption ends. As soon as a second collaborator with merge rights is onboarded:

  1. Drop the --admin flag from the merge command and adopt standard PR review.
  2. Remove this entire subsection.
  3. Update CODEOWNERS to add the new collaborator.
  4. Flip enforce_admins to true in the branch-protection JSON for both branches. Leaving it false would keep the admin-bypass door open even after the single-owner workaround is no longer needed — defeats the point of removing the workaround.

All four changes land in a single PR.

Line endings (Windows clones)

This repo enforces LF line endings via .gitattributes (* text=auto eol=lf) and the pre-commit hygiene hook. If you cloned on Windows with core.autocrlf=true, the first checkout after pulling the .gitattributes change can leave the working tree out of sync with the index. Renormalise once:

git add --renormalize .
git commit -m "chore: renormalise line endings"

After that, day-to-day work is unaffected.

Line endings (Windows clones)

This repo enforces LF line endings via .gitattributes (* text=auto eol=lf) and the pre-commit hygiene hook. If you cloned on Windows with core.autocrlf=true, the first checkout after pulling the .gitattributes change can leave the working tree out of sync with the index. Renormalise once:

git add --renormalize .
git commit -m "chore: renormalise line endings"

After that, day-to-day work is unaffected.

Local pre-push gate

just check                     # ruff + mypy + import-linter + pytest
cd frontend && npm run lint && npm run format:check && npm run check && npm run test && npm run build
uv run pre-commit run --all-files

A green pre-push run is a high-confidence predictor of a green CI run. The just check gate is intentionally a subset of CI — fast feedback over coverage.

Adding a check

When the harness grows a new gate:

  1. Add the workflow job in .github/workflows/.
  2. If it's a required gate, add the job's display name to the contexts arrays in .github/branch-protection/{develop,main}.json.
  3. If it's NOT required (scheduled / dispatch-only / push-to-main-only), add the workflow filename to EXEMPT_WORKFLOWS in .github/scripts/check_required_contexts.py.
  4. Update docs/HARNESS.md and docs/SECURITY.md (if security-relevant).
  5. Land in one PR — the meta-gate Branch-protection contexts sync will fail if you skip step 2 or 3.

Code of conduct

Be kind. Disagree on substance, not on people. If review feedback gets sharp, take it offline and come back when both sides are ready.

Reporting security issues

If you find a vulnerability that affects users of the template, do not open a public issue. Email the maintainer (see commit history for contact). Include:

  • Repro steps
  • Affected version / commit SHA
  • Severity assessment (informational / low / medium / high / critical)
  • Suggested fix if you have one

We'll acknowledge within 72 hours.