Last updated: 2026-10-06
How work is done in this repository. Operational rules for agents are in ../AGENTS.md; this document is the human-readable version with the reasons and the commands.
- Flow:
feature/*,fix/*orchore/*intodev, thendevintostg, thenstgintomain. Promotions use merge commits,stgintomainis merged only by the owner, and nothing is pushed to the protected branches. - Start every task from an up-to-date
dev, one branch and one pull request per task. - Pull requests into
devmerge automatically (auto-merge-dev.yml) once the required checks pass. Merged branches are deleted bydelete-merged-branches.yml, every 12 hours or on demand with itsdry_runinput; it skips protected branches, branches with an open pull request and branches whose tip moved past the merged head. Onlyfeature/*,fix/*andchore/*branches get auto-merge. - The pull request base is validated (
validate-pr-base.yml). - A promotion head can be a branch whose tree is identical to the base side when a direct head would be reported as behind; it is checked with
git diff --quiet.
- Conventional Commits,
type(scope): message, scope required. Scopes:api,ui,db,auth,ci,deploy,docs,config,tests,security,deps,core,seo,a11y(commitlint.config.cjs). - Plain ASCII punctuation: no em dashes, en dashes or decorative icons in text, buttons and links.
- Hooks:
pre-commitrunslint-staged(ESLint and Prettier on staged files);commit-msgruns commitlint, then~/.claude/git-hooks/commit-msgwhen that executable exists on the machine. In CI,commit-lint.ymlchecks commit messages on every push.
- Astro pages stay static; client behavior is vanilla TypeScript in
src/scripts/or in a component script. TypeScript uses Astro'sstrictpreset. - Use the
@/alias for imports fromsrc/. - Components follow atomic design (
atoms,molecules,organisms) and the contracts in../COMPONENTS.md. Visual rules and tokens are in../DESIGN.md. - Write component class names as complete literals so Tailwind keeps them;
npm run css:checkfails when a class is purged. - Resolve every localized route through
src/i18n/utils.ts; never hard-code a path. - Content follows
brand.mdandcommercial.md: no claim without evidence. - Both languages change together (see
i18n.md).
Proportional to the change; for code, all of these:
npm run format:check
npm run lint
npm run check
npm run build
npm run csp:check
npm run css:check
npm run security-txt:check
npm testnpm run lhci and npm run links run in CI after a build. Do not report a check as passed unless it completed successfully.
ci.yml runs on pushes and pull requests to dev, stg and main. It has four jobs: quality (audit, security.txt expiry, format, lint, type check, build, CSP and CSS checks), tests (Playwright against a production preview on port 4329), lighthouse and links. Pull requests also run the title check, the base check and Gitleaks; Gitleaks and commit lint also run on every push. codeql.yml (CodeQL for TypeScript, JavaScript and workflows) runs on the same branches and weekly. .github/dependabot.yml opens weekly chore(deps) pull requests to dev (npm minor and patch grouped, GitHub Actions including majors); Dependabot branches are not auto-merged. npm major versions are ignored and migrated by hand in their own pull request. When an update changes how Prettier formats files, run npm run format in the same pull request. Do not merge or promote while a required check is failing, pending, cancelled, skipped or unavailable.
Each topic has one source of truth (../AGENTS.md has the table). A change updates the document it affects and its "Last updated" line, plus the CHANGELOG.md entry under [Unreleased]; the README changes only when its overview, commands, structure or document index stops being accurate.
Versions follow SemVer and are published with the manual Release workflow; see RELEASING.md.