|
| 1 | +# Repository Guidelines |
| 2 | + |
| 3 | +## Project Structure & Module Organization |
| 4 | + |
| 5 | +- Core library code lives in `src/org/sqids/`. |
| 6 | +- Cross-platform API is in `clojure.cljc`; specs are colocated in owning `.cljc` namespaces (`alphabet`, `block_list`, `encoding`, `decoding`, `init`, `results`). |
| 7 | +- Platform-specific helper functions are in `platform.clj` (JVM) and `platform.cljs` (CLJS). |
| 8 | +- Sqids algorithm logic is implemented in-repo (`alphabet.cljc`, `encoding.cljc`, `decoding.cljc`, `block_list.cljc`, `init.cljc`). |
| 9 | +- Bundled data assets are in `resources/` (for example `resources/org/sqids/clojure/blocklist.json`). |
| 10 | +- Tests are under `test/org/sqids/clojure/*_test.cljc`. |
| 11 | +- Tooling scripts are in `bin/` (`setup`, `kaocha`, `repl`, `_clj-kondo`, `_cljstyle`, `update-blocklist`). |
| 12 | + |
| 13 | +## Build, Test, and Development Commands |
| 14 | + |
| 15 | +- `bin/setup`: installs local prerequisites (`brew bundle`, `npm install`) on macOS/Homebrew setups. |
| 16 | +- `bin/kaocha`: runs all Kaocha suites (JVM `clojure.test`, automatic `clojure.spec.test.check`, and CLJS) with coverage output in `target/coverage/` and JUnit XML in `target/test-results/junit.xml`. |
| 17 | +- `bin/repl clj` / `bin/repl cljs`: starts interactive REPLs. |
| 18 | +- `bin/update-blocklist`: refreshes `resources/org/sqids/clojure/blocklist.json` from `sqids-spec`. |
| 19 | +- `pre-commit run --all-files`: runs local hooks; CI mirrors this as `SKIP=kaocha-test pre-commit run --all-files` followed by `bin/kaocha`. |
| 20 | +- `clojure -T:build jar` and `clojure -T:build install`: build and install the jar locally. |
| 21 | + |
| 22 | +## Project Patterns |
| 23 | + |
| 24 | +- Treat `AGENTS.md` as a repo table of contents, not an encyclopedia: point to the system-of-record files for behavior, build, tests, lint, and generated data before adding new prose here. |
| 25 | +- Prefer checked-in repo knowledge over chat or PR context; if code, tests, and docs disagree, the repository wins and stale guidance should be fixed in the same change. |
| 26 | +- Treat `bin/kaocha` as the single test entrypoint for local runs, pre-commit, and CI; avoid re-introducing split CLJ/CLJS wrappers. |
| 27 | +- Keep `tests.edn` as the source of truth for suite and report behavior (`:unit`, `:cljs`, `:generative-fdef-checks`, cloverage, JUnit XML target). |
| 28 | +- Keep test automation in sync: when pre-commit hook IDs or test commands change, update `.github/workflows/clojure.yml` (`SKIP=...`) in the same commit. |
| 29 | +- Prefer local/system hooks and wrappers over Docker hooks (`clj-kondo`, `cljstyle`, `shfmt`, `prettier`); avoid adding Docker-based hook runners. |
| 30 | +- Move invariants into mechanical enforcement whenever possible; prefer `clj-kondo`, `cljstyle`, pre-commit, Kaocha, and CI checks over reviewer memory or PR prose. |
| 31 | +- Keep algorithm code total in internal namespaces: only public `org.sqids.clojure/{sqids,encode,decode}` should throw. |
| 32 | +- Model internal success/failure with `org.sqids.clojure.results` envelopes and staged `results/conform`, `results/bind`, `results/attempt` pipelines. |
| 33 | +- Keep tool versions pinned in project config (`deps.edn`, `.pre-commit-config.yaml`); CI may use `latest` for bootstrap tools, but lint/format/test versions should remain explicit. |
| 34 | +- Treat `resources/org/sqids/clojure/blocklist.json` as generated data; update it via `bin/update-blocklist` rather than manual edits. |
| 35 | +- Add nested `AGENTS.md` files only when a subtree has materially different rules or maintenance needs; keep them short, additive, and scoped to local deltas rather than copying the root guide. |
| 36 | +- Pair every `AGENTS.md` with a human-facing `README.md` in the same scope. `AGENTS.md` directs agent behavior; `README.md` explains layout, intent, and workflows for humans. |
| 37 | +- When adding a new subsystem, ship code, tests, lint/config enforcement, docstrings, and navigation docs together. |
| 38 | +- Keep docs aligned with tooling changes: update `README.md` and this file in the same PR when commands or test flow change. |
| 39 | +- When behavior changes, update tests, docstrings, and README examples in the same commit so the contract stays synchronized. |
| 40 | +- Preserve public API behavior for `sqids`, `encode`, and `decode`; behavior changes must include deterministic tests and release notes updates. |
| 41 | + |
| 42 | +## Coding Style & Naming Conventions |
| 43 | + |
| 44 | +- Follow `.cljstyle`: 2-space indentation and one blank padding line between top-level forms. |
| 45 | +- Run formatting before commits: `bin/_cljstyle fix`. |
| 46 | +- Lint with pre-commit (includes `clj-kondo`, `cljstyle`, `kaocha-test`, `shellcheck`, `shfmt`, `markdownlint-cli2`, `prettier`, and a clean `git-diff` check). |
| 47 | +- `clj-kondo` is intentionally strict in `.clj-kondo/config.edn`; run `bin/_clj-kondo --lint src test bin/update-blocklist build.clj deps.edn tests.edn shadow-cljs.edn` before pushing. |
| 48 | +- Every `def`, `defn`, and `defmacro` needs a high-quality docstring. Treat docstrings as living contracts: explain purpose, inputs, return shape, invariants, and failure semantics when they are not obvious from the name alone. |
| 49 | +- Keep docstring enforcement strict. If `clj-kondo` stops catching missing docstrings on new function-like forms, tighten the linter or hooks instead of weakening the rule. |
| 50 | +- Namespace/file naming follows Clojure conventions: `kebab-case` namespaces and `*_test.cljc` test files. |
| 51 | + |
| 52 | +## Testing Guidelines |
| 53 | + |
| 54 | +- Primary framework: `clojure.test` executed by Kaocha; generative spec checks run via a `:kaocha.type/spec.test.check` suite. |
| 55 | +- Coverage is enforced at 100% via `:cloverage/opts :fail-threshold`; CI artifacts include `target/coverage/lcov.info` and `target/coverage/codecov.json`. |
| 56 | +- Add tests beside related behavior in `test/org/sqids/clojure/`. |
| 57 | +- Keep tests deterministic and cover both encode/decode behavior and invalid-input paths. |
| 58 | +- Before opening a PR, run `bin/kaocha`. |
| 59 | + |
| 60 | +## Commit & Pull Request Guidelines |
| 61 | + |
| 62 | +- Match existing history: short, imperative commit subjects (for example `Fix sqids-javascript link`, `Improve caching`). |
| 63 | +- Keep commits focused; separate refactors from behavior changes when possible. |
| 64 | +- PRs should include: purpose, key changes, and verification steps/commands run. |
| 65 | +- Link relevant issues when applicable and update `CHANGELOG.md` for release-facing changes. |
0 commit comments