Contributing to nest-base
May 20, 2026 · View on GitHub
Thanks for considering a contribution. This file is the minimum you need to know before opening a PR.
For deeper context:
docs/architecture.md— how the system is put together (modules, permission model, output pipeline, security layers).docs/code-guidelines.md— conventions a quick scan won't teach you (naming, validation, error codes, planner / runner split, HTML escaping, …).CLAUDE.md— the agent-facing "where do I find X" index.
TL;DR
- One slice per PR, Conventional Commit title, six gates green.
- Story test or e2e spec for every behaviour change — red first, green after.
src/core/is template-owned (synced to every consumer). New project-specific code goes insrc/modules/. Generic utilities that benefit every consumer can be PR'd tosrc/core/— but the review bar is higher there.
Before you start
- Read
.claude/QUICKSTART.md— the 60-second onboarding card. It tells you where everything lives and what conventions are non-negotiable. - For architectural context, read
docs/architecture.md. For conventions,docs/code-guidelines.md. The eight-phase initialisation log lives indocs/initialisation-history.mdfor historical reference. - For a feature flag: read
.claude/skills/adding-feature-flag.md. - For a new Hub/admin page: read
.claude/skills/extending-hub.md. - For a new resource module: read
.claude/skills/adding-feature-module.mdand copysrc/modules/example/as the reference.
Setup
git clone git@github.com:lenneTech/nest-base.git
cd nest-base
bun install
bun run setup # .env + docker + schema + migrate + seed
bun run dev # Hub at / (sign in) → /hub
The TDD cycle
Every behaviour change follows red → green → refactor:
- Write the failing test first in
tests/stories/<feature>.story.test.ts(pure planners) ortests/<feature>.e2e-spec.ts(HTTP layer). - Confirm it's red:
bun run test:e2e tests/stories/<your-test>.story.test.ts - Commit:
test(<scope>): add red tests for <slice> - Implement the minimum code to make the test pass.
- Refactor without changing behaviour. Tests stay green.
- Run all six gates:
bun run lint && \ bun run format && \ bun run test:types && \ bun run test:unit && \ bun run test:e2e && \ bun run test:coverage && \ bun run build - Commit:
feat(<scope>): <slice>(orfix(<scope>):, etc.)
Coverage thresholds: src/core/ ≥ 80% lines, src/modules/ ≥ 75% lines (enforced
by vitest.config.ts via src/core/testing/coverage-gate.ts).
Failing the gate forces more tests, not more exclusions.
Conventional Commits
| Type | When |
|---|---|
feat(<scope>): | New behaviour, new feature flag, new page |
fix(<scope>): | Bug fix |
test(<scope>): | Adding a test (red commit before the impl) |
docs(<scope>): | Docs only |
refactor(<scope>): | No behaviour change |
chore(<scope>): | Dependency bumps, tooling, repo hygiene |
ci(<scope>): | CI / build pipeline |
perf(<scope>): | Measurable performance improvement |
Scope examples: auth, webhooks, hub, features,
<resource-name> for module changes.
What happens after you open a PR
- CI runs the same six gates (lint, format, types, unit, e2e,
coverage, build) on the PR branch — same matrix that runs on
main. The aggregator jobci-successflips green only when every required gate passed. - A maintainer (
@lenneTechperCODEOWNERS) gets requested as a reviewer. - We review for: fits-the-spec, test-first, conventions, and "would a future agent reading this commit understand it".
For repository owners — recommended branch protection
Set this once on main so PRs can't bypass the gates:
- Require a pull request before merging ✓
- Require approvals: 1
- Dismiss stale approvals on new commits ✓
- Require review from Code Owners ✓
- Require status checks to pass before merging ✓
- Required check:
ci-success— the aggregator job in.github/workflows/ci.yml. Flips green only when lint / format / test-types / test-unit / test-e2e / test-coverage / build all passed. One switch covers the whole gate matrix. - Require branches to be up to date before merging ✓
- Required check:
- Require conversation resolution before merging ✓
- Do not allow bypassing the above settings ✓ (even for admins)
AI-driven contributions
This project is optimised for AI-assisted development with Claude Code. If you're using an AI agent:
- Spawn
feature-toggle-implementerfor feature flags - Spawn
module-scaffolderfor new resources - Use
/add-feature,/add-module,/add-pageslash commands - Read the matching skill in
.claude/skills/before letting the agent loose
The agent will follow the same TDD discipline + six gates. If it doesn't, that's a bug in the skill — open an issue.
What does NOT belong here
- Project-specific business logic — keep that in your fork's
src/modules/. The template is a template. - Optional dependencies that drag CI weight — every package added
affects every consumer's
bun installtime. - Copy-pasted code from other repos — re-implement in the project's conventions or PR upstream-of-here.
Code of conduct
By participating, you agree to follow our Code of Conduct. Be kind. We're all here to ship better code.
Security
Found a vulnerability? Don't file a public issue. See
SECURITY.md for the private disclosure path.
Questions
For free-form questions, use GitHub Discussions. For specific bug reports or feature requests, use the issue templates.