Files
baya-monorepo/docs/rules/shared/git-and-gates.md
T
2026-08-02 18:58:46 +03:30

5.0 KiB

Git and the quality gates

What must pass before work is done, and what the repo refuses to let you commit.

Last verified: 2026-08-02 against commit 51e86a1.


1. The gates

Each project is built, linted, and tested on its own. There is no root-level build, package, or solution, so there is no single command that gates the repo. Run the gate for the side you edited.

Client — cd client

Command What it runs
npm run check The gate. typelintlint:copy, in that order
npm run type tsc --noEmit (strict on)
npm run lint eslint . (flat config)
npm run lint:copy node scripts/check-copy.mjs — greps fa.json for banned Persian orthography variants
npm run test:ci jest --cialso required when you touched a component with a co-located *.test.tsx

npm run check must be green. en.json and fa.json must be in sync.

lint:copy is part of check, not a separate step you can forget. It is what stops a copy regression — a hamza-less «تایید», a space in the brand name — from needing to be re-discovered by a human. The rules it enforces are in client/i18n.md.

Server — cd server

Command What it runs
dotnet build Baya.sln Zero new warnings. Unused usings, locals, parameters, private fields or members count as failures — delete them, don't suppress them
dotnet test Baya.sln All tests pass, including the ones your change adds

A reachable SQL Server is required to run the API (not to build or unit-test it).

Both

Read your own diff as if you were reviewing the PR: would a senior engineer approve it without comment? A change that passes the mechanical gate and fails that question is not done.


2. What "done" means

A change is done when all of these hold:

  • The full scope is implemented. No // TODO: implement later, no stub that returns fake data. Anything not real is behind a DI-registered seam and recorded (see code-quality.md).
  • It follows the rules for that project — the relevant CLAUDE.md plus the one reference file for the area you touched.
  • No dead code. Comments explain why, not what.
  • The project's own gate above is green.
  • If the structure changed, the matching architecture section is updated in the same change (see documentation.md §3).
  • If a business rule was discovered or decided, product/ reflects it — recorded, not invented.
  • If a new reusable pattern or seam landed, the reference file for that area names it, so the next change reuses it instead of reinventing it.

A change that doesn't pass its own gate is not done, regardless of how complete the code looks.


3. No pre-commit secret scan (for now)

There is no git hook enforcing anything in this repo — .githooks/ was removed in phase 7 as an MVP-stage call: this is a pre-launch demo project and the mechanical backstop wasn't worth the overhead yet. The underlying rule is unchanged — never commit a real secret — it's just unenforced by tooling. Root CLAUDE.md §6 already documents the repo's actual trade: config lives in committed files, including live credentials, until real users exist (see DEPLOY.md "Going to Production" for the rotation step that unblocks that). Revisit adding a hook — or a CI scanner (gitleaks, trufflehog) — if that trade changes before this one does.


4. Branches and commits

main is the default branch and the base for PRs.

  • Commit or push only when asked. If you are on main and about to commit, branch first.
  • One coherent change per commit. The repo's history reads as a sequence of completed units of work (ui phase 11, remove user-secrets approach & prepare a pilot deploy) — keep that.
  • Never skip hooks (--no-verify) or bypass signing unless explicitly asked. If a hook fails, fix the underlying issue.
  • Prefer a new commit over amending an existing one.
  • Before a destructive git operation (reset --hard, push --force, checkout --), consider whether a safer route reaches the same place.

5. Known pre-existing warnings

These are expected and must not be "fixed" unless a task says so — a change that touches them is scope creep, and one that silences them is worse.

Warning Project Note
NU1510 on Microsoft.Extensions.Logging.Debug Baya.Web.Api Redundant transitive reference, harmless
NETSDK1057 (preview SDK) all server projects The .NET 10 SDK is preview on this machine

On the client, import/no-cycle is disabled in eslint.config.mjs (its TypeScript resolver has an interface mismatch with this toolchain), and ESLint is pinned to 9 — ESLint 10 crashes against this Next 16 toolchain with scopeManager.addGlobals is not a function. See client/testing.md.