# Repository Guidelines

## Project Structure & Module Organization
- `main.go` is the composition root (config, DB/Git wiring, listeners).
- `internal/` contains backend modules by concern: `rest`, `graphql`, `service`, `db`, `gitstore`, `githttp`, `oauth`, `middleware`, `router`, and `testharness`.
- `cli/` is the vendored GitHub CLI plus acceptance tests in `cli/acceptance/`.
- `e2e/` contains shell-based end-to-end scripts (`bash` + `curl` + `jq`).
- `visualization/` holds frontend/UI assets (when present).
- `docs/` is the architecture SSOT, especially `architecture.md`, `module-contracts.md`, and `test-strategy.md`.

## Build, Test, and Development Commands
- `make setup`: production/persistent bootstrap with an external TiDB Cloud Starter `DB_DSN`.
- `make test-setup`: test-only bootstrap that starts TiDB via `tiup playground`.
- `make build`: compile `gh-server`.
- `make run-bg` / `make stop`: start or stop local server.
- `make check`: fast pre-commit check (`make build` + `make vet`).
- `make test-unit`: run all Go unit tests (`go test -v ./...`).
- `make test`: run `cli` acceptance tests (requires running server).
- `make test-e2e [SCRIPT=name]`: run all or one `e2e/*.sh` flow.

## Coding Style & Naming Conventions
- Target Go `1.25.0` (see `go.mod`).
- Indentation: rely on formatters (`gofmt`/`goimports` for Go tabs; follow existing style for non-Go files).
- Format Go code with `make fmt` (`goimports` on root and `internal/`).
- Keep transport layers thin: REST/GraphQL handlers should delegate business logic to `internal/service`.
- Follow standard Go naming: exported `CamelCase`, unexported `camelCase`, package names lowercase.
- Place tests beside code as `*_test.go`; prefer table-driven tests for business rules and handlers.

## API Surface Boundary
- Use `/api/v3` and `/api/graphql` only for GitHub-compatible APIs. These routes primarily serve existing GitHub-speaking clients, including `gh`, GitHub REST/GraphQL SDKs, and Git-compatible automation.
- A route may stay under `/api/v3` as a GitHub-shaped local shim only when it intentionally uses a GitHub-like path, request/response shape, or client behavior for compatibility. If behavior differs from GitHub.com, document it clearly as partial compatibility, a local shim, or an extension. Do not imply strict GitHub.com parity for local semantics.
- Use `/api/ext/v1` for extension APIs that are not part of GitHub's API contract. New primitives such as agent runs, run-scoped token management, context packs, leases, agent policies, agent queues, scorecards, local wiki page APIs, aggregate views, and other platform control-plane features belong under `/api/ext/v1`.
- Do not place extension APIs under `/api/v3` just because the resource is repo-scoped. Repo-scoped extension routes should use `/api/ext/v1/repos/{owner}/{repo}/...`.
- Do not introduce new `/api/ags/...` routes. The extension namespace is `/api/ext/v1`; keep code constants, OpenAPI output, tests, docs, and compatibility matrices aligned with that path.
- Discovery and OpenAPI output must keep the boundary explicit: `/api/v3` and `/api/v3/openapi.json` describe GitHub-compatible REST only, while `/api/ext/v1` and `/api/ext/v1/openapi.json` describe extension APIs only.

## Testing Guidelines
- Follow the test pyramid in `docs/test-strategy.md`: package/service tests first, then router/integration, then acceptance.
- Use `internal/testharness` for integration tests with real router wiring.
- Use `make test-run SUITE=TestName` for focused acceptance debugging.
- Keep E2E scripts executable and descriptive (for example, `provisioning-failure-recovery.sh`).

## Production Deployment
- Production deploys are triggered by pushing a `v*` Git tag, which runs `.github/workflows/deploy-production-tag.yml`.
- Use timestamp release tags: `vYYYYMMDD-HHMMSS` (for example, `v20260513-002911`).
- When the user asks to deploy prod or production without additional qualifiers, interpret that as deploying the current `origin/main` commit by creating and pushing a fresh timestamp tag.
- Before tagging, fetch `origin/main` and tags, verify the target commit is contained in `origin/main`, and avoid tagging local-only or dirty worktree changes unless the user explicitly asks for that.
- Recommended command shape:
  `git fetch origin main --tags && tag="v$(date -u +%Y%m%d-%H%M%S)" && git tag "$tag" origin/main && git push origin "$tag"`

## Open Source Commit Workflow
- Open-source manually to the fixed public target `ngaut/agent-git-service`; do not add automation unless explicitly asked.
- The target uses squash merging, so publish each source commit as one separate public PR with one fresh public commit. If commits depend on each other, open/merge them in order from updated `origin/main`.
- Publish only the selected commit's content. Do not use `git cherry-pick`, `git format-patch`, bundles, or anything that transfers the original commit object, author, committer, message, source PR/issue IDs, source SHA, branch name, repository URL/name, or internal tracking IDs.
- Resolve the source commit locally. Diff a single-parent commit against its parent, or a root commit against Git's empty tree (`4b825dc642cb6eb9a060e54bf8d69288fbee4904`). For merge commits, stop and ask for an explicit diff base or a non-merge commit.
- In the local public clone/worktree, create a precise semantic branch name from updated `origin/main` and apply only the tree diff:
  `git diff --binary <base> <source-commit> | git -C <target-clone> apply --index --whitespace=nowarn`
- Before committing and again before opening the PR, hard-scan staged diffs, test names, comments, docs, branch names, PR titles, commit messages, and PR bodies for source SHAs, source or internal PR/issue numbers, internal repo URLs/names, branch names, and tracking IDs; remove or rewrite that source metadata. Public target issue IDs are allowed only when they belong to the public repo and materially help readers.
- Use a precise semantic public branch name plus semantic public commit titles and PR titles that describe the public code change. Avoid vague "open-source" wording.
- Read source PR/body context when available, but treat the selected commit diff and verified execution records as the primary sources for a one-source-commit public PR. Use the source PR/body as the preferred technical starting point for the public PR body, preserving concrete description, changes, tests, notes, risks, and SSOT/checklist substance when it matches the selected commit. Remove or rewrite source-only metadata, including internal tracking IDs, source PR/issue numbers, source SHAs, private branches, private hostnames/URLs, private repo names, internal environment names, and unrelated source-PR details. Do not replace a useful source PR body with a generic template.
- Public PR bodies must follow `.github/pull_request_template.md` and contain specific technical content for that public change. Before opening or updating the PR, scan the rendered body for source metadata and verify it is not merely boilerplate such as "publishes one isolated public change".
- After opening each public PR, squash-merge with a subject that includes the public PR number, for example `fix: describe behavior (#123)`. Keep the public squash commit message body empty unless there is a concrete public reason to include extra body text; never leave a duplicated title or generic "Tests run" body from the merge command.
- After merge, verify `origin/main` contains exactly one new public commit for the PR, its subject ends with the public PR number, its body is empty or intentionally public, and its tree matches the approved public PR diff.
- Push the branch, open the PR, merge it in order when appropriate, and report only public PR URLs and fresh target commit SHAs.

## Commit & Pull Request Guidelines
- Keep each commit scoped to one issue or behavior change.
- Preferred commit subject patterns match repo history: `fix: ...`, `feat: ...`, `test: ...`, `docs: ...`. When a public issue reference is appropriate, only use IDs that exist in the public target repository; do not copy internal or source-tracking IDs into public commit or PR titles.
- PRs should include a clear description, exact test commands run, and updates to SSOT docs when boundaries or testing expectations change.
- Complete the checklist in `.github/pull_request_template.md` for architecture, test-strategy, CI, smoke, regression, and packaging drift.
