diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md new file mode 100644 index 000000000..50041c6ee --- /dev/null +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -0,0 +1,23 @@ +## Summary + + + +- + +## Verification + +- [ ] `bun run typecheck`, `bun run build`, and `bun run test` pass +- [ ] + + diff --git a/AGENTS.md b/AGENTS.md index d08beeeca..2c0391128 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -49,9 +49,13 @@ Run the full suite before declaring any task complete. Do not substitute individ scans `vendor/`, adding hundreds of unrelated results and making pass/fail counts meaningless to compare across branches — always use `bun run test`. -## Commits +## Commits, pull requests, and issue tracking -Follow the `style` skill's message format: plain-English summary, no `feat:`/`fix:` prefixes, no filename in the summary. Separate refactors from feature additions. Commit with the user's local git identity. +**MUST follow `CONTRIBUTING.md`.** That file is the source of truth for commit +titles and bodies, PR titles and bodies, and Linear/GitHub linking. Do not use +Conventional Commits prefixes (`feat:`, `fix:`, `docs:`, `ci:`, …), ticket IDs +in commit subjects, or free-form PR body sections. Rewrite before push if a +message violates those rules. Commit with the operator's local git identity. ## Pushing diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 2b1dfb3d7..6bd6c2457 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,6 +1,9 @@ # Contributing to Corbits Code -Thanks for contributing. This document covers setup, workflow, and legal requirements. Coding conventions live in `AGENTS.md` — read that before writing code. +Thanks for contributing. This document is the **source of truth** for commits, +pull requests, and issue tracking. Coding conventions live in `AGENTS.md` — +read that before writing code. Agents **must** follow the rules below; do not +substitute a personal or skill-only convention when this file conflicts. ## Prerequisites @@ -24,23 +27,214 @@ git config core.hooksPath .githooks ```bash bun run typecheck bun run build -bun test ./src ./tests +bun run test ``` -These match the CI workflow in `.github/workflows/ci.yml`. Run the full suite before opening a PR. +These match the CI workflow in `.github/workflows/ci.yml`. Run the full suite +before opening a PR. Do not substitute a bare `bun test` (it also scans +`vendor/` and pollutes pass/fail counts). + +## Commits + +### Title (MUST) + +- Imperative, present tense, max **72** characters +- Starts with a verb: `Add`, `Fix`, `Remove`, `Harden`, `Document`, … +- No trailing punctuation, no abbreviations for their own sake +- No filenames or paths in the subject — the diff already lists them +- Match the voice of recent history: + +```bash +git log origin/main --format='%s' | head -20 +``` + +**Banned subject prefixes** (all of them, including habits from other projects): + +- Conventional Commits: `feat:`, `fix:`, `chore:`, `docs:`, `refactor:`, `test:`, `ci:`, `perf:`, `style:`, `build:` +- Scoped forms: `docs(changelog):`, `net:`, `frontend:` +- Ticket IDs: `CL-1234:`, `INTR-79:`, `#456:` +- Status tags: `WIP:`, `[urgent]`, `(security):` + +**Good:** + +```text +Add retry logic for failed network requests +Fix race condition in transaction verification +Document the permission queue behavior +``` + +**Bad:** + +```text +feat: add retry logic +fix(auth): race in server.ts +CL-5494: flatten model picker +Update code +``` + +### Why not `feat:` / `fix:` / `docs:` / `ci:`? + +Conventional Commits are useful when tools **generate** changelogs, SemVer bumps, +or release notes from commit types. This project does not: + +- Release notes are hand-written in `CHANGELOG.md` and deliberately strip ticket + and PR IDs from public notes. +- Reviewers and `git log` readers need a sentence that stands alone years later, + not a taxonomy debate (`chore` vs `refactor` vs `fix`). +- An imperative subject already encodes the action: `Fix race in the approval + queue` is clearer than `fix: race in the approval queue`. +- Prefixes train agents and humans to smuggle scope, ticket IDs, and file names + into the subject — noise we already reject elsewhere. + +The Git and Go projects use the same plain-English model. Familiarity with +Angular-style prefixes is not a reason to adopt them here. + +### Body (usually omit) + +Most commits need **no** body. A clear subject plus a coherent diff is enough. + +Add a body only when a future reader of `git log` could not answer *why this +change* from the subject and the diff alone. When present: + +- Blank line between subject and body +- Wrap body lines at 72 characters +- Motivation only: why this change, why now, why not the obvious alternative +- Do **not** walk the diff file-by-file +- Do **not** reference PR review threads, chat, or "the next commit" +- Do **not** put Linear or GitHub issue IDs in the subject or body — linking is + a pull-request concern (see [Issue tracking](#issue-tracking-linear-and-github)) + +Write for a stranger reading `git log` years from now with only the repo in +hand, not for the person reviewing this PR today. + +### Organization (MUST) + +- One logical unit of work per commit +- Separate refactors from feature additions +- Separate formatting/whitespace from behavioral changes +- Commit with the operator's local git identity (never invent author metadata) ## Pull requests -1. Keep changes focused — one concern per PR. See scope discipline in `AGENTS.md`. -2. Include or update tests for behavior changes. Bug fixes start with a failing test. -3. Use plain-English commit messages (no `feat:` / `fix:` prefixes). Details are in `AGENTS.md`. -4. Do not commit secrets, credentials, or generated noise. +### Scope (MUST) + +1. One concern per PR. See scope discipline in `AGENTS.md`. +2. Include or update tests for behavior changes. Bug fixes start with a failing + test that reproduces the bug — do not start by patching. +3. Do not commit secrets, credentials, or generated noise. +4. Draft title and body from the current diff, not from memory of the work: + +```bash +git diff origin/main...HEAD +git log origin/main..HEAD --format='%s' +``` + +### Title (MUST) + +Same rules as [commit titles](#title-must): imperative present-tense sentence, +no prefixes, no ticket IDs, no trailing punctuation. The title describes the +**whole branch**, not a single commit. + +### Body (MUST) + +Only these sections. Present tense — what the branch **does**, not the journey +of writing it. + +```markdown +## Summary + +- +- + +## Verification + +- `bun run typecheck`, `bun run build`, and `bun run test` pass +- + +Fixes CL-1234 +``` + +Rules: + +- `## Summary` and `## Verification` are required. Do not add `## Changes`, + `## Context`, `## Notes`, or review-fleet diaries — the diff is the change + list; review discussion belongs on the PR review, not in the description. +- Optional short **Why** paragraph is allowed only when Summary would look + arbitrary without motivation. Keep it to a few sentences, present tense, + under the Summary section (not a separate heading). +- Scan for past-tense journey verbs (`was`, `added`, `fixed`, `refactored`, + `I changed`) and rewrite to present-tense product statements. +- When the work tracks an issue, end the body with a magic-word link (see + below). When it does not, omit the link line entirely — do not invent IDs. + +GitHub auto-fills this shape from `.github/PULL_REQUEST_TEMPLATE.md`. + +## Issue tracking (Linear and GitHub) + +Link trackers at the **PR boundary**, not inside every commit. + +### When work tracks a Linear issue (MUST) + +1. **Branch name** — use the issue's Linear `gitBranchName` (Copy git branch + name / `Cmd/Ctrl+Shift+.`). Branch names that include the issue ID are + Linear's preferred auto-link path. +2. **PR body** — include a **closing** magic word and the issue ID so merge + automation can complete the issue: + + ```text + Fixes CL-1234 + ``` + + Full Linear URLs also work. Prefer the body over stuffing the ID into the + PR title so the title stays a plain-English sentence. +3. Do **not** put `CL-…` in commit subjects or bodies. + +**Closing magic words** (issue moves to Done on merge when automation is +configured): `close`, `closes`, `fix`, `fixes`, `resolve`, `resolves`, +`complete`, `completes`, `implement`, `implements` (and tense variants). + +**Non-closing** (link only; do not auto-complete): `ref`, `refs`, `related to`, +`relates to`, `part of`, `contributes to`, `toward`, `towards`. + +Use non-closing words for partial work or multi-issue branches. Only issues +this PR fully completes get a closing word. + +To deliberately **not** link an issue whose ID appears in the branch name: + +```text +skip CL-1234 +``` + +(or `ignore CL-1234`). + +### When work tracks a GitHub issue only (MUST) + +Same pattern in the PR body: + +```text +Fixes #123 +``` + +### When there is no tracker + +Omit magic words. Do not invent issue IDs. + +### After merge (SHOULD for agents running the full workflow) + +1. Confirm the PR is merged and CI is green on the merge commit. +2. Comment the PR URL and merge SHA on the Linear issue. +3. Tick only description checkboxes that `main` actually completed. +4. Mark the Linear issue Done only when every outcome is truly done — never on + "PR opened" alone. ## Contributor License Agreement -All contributions require acceptance of the Contributor License Agreement in `CLA.md`. The CLA grants ABK Labs, Inc. rights needed to distribute contributions under the project license and alternative terms. +All contributions require acceptance of the Contributor License Agreement in +`CLA.md`. The CLA grants ABK Labs, Inc. rights needed to distribute +contributions under the project license and alternative terms. -CLA Assistant enforces this on pull requests (see `.github/workflows/cla.yml`). Sign once by posting a PR comment with exactly: +CLA Assistant enforces this on pull requests (see `.github/workflows/cla.yml`). +Sign once by posting a PR comment with exactly: ```text I have read the CLA Document and I hereby sign the CLA @@ -53,7 +247,10 @@ Signatures are stored on the `cla-signatures` branch and do not touch `main`. - `docs/ARCHITECTURE.md` — reactor loop, events, directors, permissions - `docs/IMPLEMENTATION.md` — runtime, config, CLI, state - `docs/PRODUCT.md` — product goals +- `docs/TUI.md` — terminal UI behavior +- `AGENTS.md` — coding conventions agents and contributors share ## Questions -Open a GitHub issue for design discussion or bugs that are not security-sensitive. For security reports, see `SECURITY.md`. +Open a GitHub issue for design discussion or bugs that are not +security-sensitive. For security reports, see `SECURITY.md`. diff --git a/README.md b/README.md index 89f38d10f..90a181cd0 100644 --- a/README.md +++ b/README.md @@ -38,7 +38,7 @@ After pulling new changes, re-run `bun run build:bin` to refresh the binary. Before your first commit: `git config core.hooksPath .githooks` and `./bin/check-env`. -Every change must pass `bun run typecheck`, `bun run build`, and `bun test`, and behavior changes come with tests. Conventions live in `AGENTS.md` (functional TypeScript, no classes, arktype at boundaries, plain-English commit messages); the system design is documented in `docs/ARCHITECTURE.md` and `docs/IMPLEMENTATION.md`. +Every change must pass `bun run typecheck`, `bun run build`, and `bun run test`, and behavior changes come with tests. Coding conventions live in `AGENTS.md` (functional TypeScript, no classes, arktype at boundaries); commit, PR, and Linear/GitHub linking rules live in `CONTRIBUTING.md`. System design is documented in `docs/ARCHITECTURE.md` and `docs/IMPLEMENTATION.md`. ## Stack