Thanks for looking at the code. This document is the shortcut so you don't have to reverse-engineer conventions from the git log. Keep it open in a tab while you work.
| Tool | Version | Why |
|---|---|---|
| Node.js | 22.x or newer | Native test runner, stable crypto.hkdfSync, modern Buffer API. |
| Yarn | 4.x (Corepack) | The repo pins packageManager in package.json. Run corepack enable once. |
| Git | any recent | Standard. |
Windows works via WSL. Native Windows shells may hit path-separator quirks in test globs — the CI does not cover them.
git clone https://github.com/ExorTek/auth.git
cd auth
corepack enable # once per machine
yarn install
yarn build # topological build of every publishable package
yarn test # runs node:test across every workspaceIf you're only touching one package, you can skip the root build:
cd packages/crypto
node --test 'tests/**/*.test.js'One prefix per branch, matching the intent of the change. Reviewers can filter their inbox by prefix.
| Prefix | Use for | Example |
|---|---|---|
feat/ |
New user-visible functionality. | feat/otp-backup-codes |
fix/ |
Bug fixes. | fix/base32-empty-input |
refactor/ |
Internal cleanup, no behaviour change. | refactor/centralize-encoding-check |
perf/ |
Performance work with no behaviour change. | perf/base58-decode-loop |
docs/ |
README, CONTRIBUTING, JSDoc, ARCHITECTURE. | docs/crypto-readme |
test/ |
Test-only additions or reshuffles. | test/seal-clock-skew |
chore/ |
Repo housekeeping — CI, deps, config. | chore/upgrade-prettier |
release/ |
Cutting a version (Changesets). | release/v1.1.0 |
Keep branch names lower-kebab-case. Avoid trailing issue numbers; commits and PR descriptions carry those.
We follow Conventional Commits. One concern per commit. Present tense.
<type>(<scope>): <summary>
<body — what and why, wrapped at ~72 cols>
- type —
feat·fix·refactor·perf·docs·test·chore·build·ci - scope — the package or subsystem, most-specific first:
crypto/hash,crypto/cipher,crypto/internal,security/csrf,security/middleware,otp,password/algorithms,session/stores,session/middleware,web, or omit for repo-wide work.
Good examples pulled from the log:
feat(crypto/cipher): add seal / unseal for timed authenticated tokens
refactor(crypto/internal): centralize encoding validation & buffer coercion
chore: repo housekeeping — LICENSE, editorconfig, gitattributes
Avoid wip, fixes stuff, or squashing four unrelated changes into one commit. Split them.
- Open (or pick up) an issue. New surface area — flag it first so we can check it fits the dependency graph in
ARCHITECTURE.mdbefore you build it. - Branch off
master. Use the prefix above. - Write code + tests + JSDoc. Every public function needs JSDoc. Tests go next to the code
(
packages/<pkg>/tests/**). - Add a changeset (
yarn changeset) — one per user-facing change. Refactor-only PRs don't need one. - Run the local gate before pushing:
yarn format yarn lint yarn typecheck yarn test yarn build - Push, open a PR. Fill in the description with what changed and why. Draft PRs are welcome for early feedback.
- Address review. Prefer new commits over force-pushes during discussion; squash on merge is decided at merge time.
Every package uses Node's native test runner — no Jest, no Mocha, no Vitest. Tests colocate under
packages/<name>/tests/**/*.test.js.
import { describe, it } from 'node:test';
import assert from 'node:assert/strict';
import { fingerprint } from '../../src/index.js';
describe('fingerprint', () => {
it('is stable across key order', () => {
assert.equal(fingerprint({ a: 1, b: 2 }), fingerprint({ b: 2, a: 1 }));
});
});Coverage is available via yarn test:coverage. There is no coverage floor policy yet — cover the happy path plus one
negative case per branch.
- ESLint (flat config) —
prefer-const,no-var,eqeqeq: always,curly: all,no-unused-vars(allow_-prefixed),no-console: warn. - Prettier — semicolons on; single quotes; 120-col; ES5 trailing commas; arrows drop parens on single args
(
arrowParens: 'avoid'); LF line endings. The.prettierrcis the source of truth. - JSDoc is required on every public function.
.d.tsis emitted from JSDoc duringyarn build. - Errors — throw
CryptoError(or the equivalent per-package error class) with a stablecode. Never string-match error messages downstream. - No
console.*in shipped code.no-console: warncatches most of it.
The dependency layering in ARCHITECTURE.md is not optional. Do not import upward from a
lower-layer package. If you find yourself needing something in @exortek/crypto from @exortek/jwt, open an issue —
that's the sign the primitive belongs one layer down.
The umbrella @exortek/auth package re-exports everything and is the only place cross-package composition happens.
Releases are driven by Changesets:
- Author a changeset while your feature branch is open:
Pick the packages you touched, pick a bump level (patch / minor / major), describe the change from the user's perspective.
yarn changeset
- Merge the PR. The changeset stays as a file under
.changeset/. - A maintainer runs
yarn version— this consumes the changesets, bumpspackage.jsonversions, and writesCHANGELOG.mdper package. yarn releasepublishes to npm and pushes tags.
Do not bump versions by hand. Do not publish from a feature branch.
Please do not file a public GitHub issue for a security bug. Email memet@memet.dev or
open a private security advisory on the repo. We'll acknowledge within a few days and coordinate disclosure.
For anything that doesn't fit an issue template, start a Discussion.
Thanks for helping.