Services Hire Developers Pricing Case Studies Blog Resources Free Tools Process Methodology About Book Free Consultation →
Public engineering excerpt

Engineering standards — public excerpt

This is a redacted version of the engineering handbook every RG INSYS engineer follows. It covers how we branch, review, test, ship, and document. If your team has its own standards, we adopt yours instead — this is the floor, not the ceiling.

Branching strategy

We use trunk-based development on every project. There is one long-lived branch — main — and it is always deployable. Feature branches are short-lived (typically less than 48 hours of life) and exist only to gather review feedback before being squash-merged back into main. We do not maintain parallel develop, release, or environment branches because they consistently produce drift, merge pain, and "works on my branch" bugs.

Branch names are namespaced: feat/<ticket-id>-short-slug, fix/<ticket-id>-short-slug, chore/<short-slug>. Commit messages follow Conventional Commits: feat:, fix:, chore:, refactor:, test:, docs:, perf:. The squash-merged commit on main becomes the single authoritative entry for the change, which keeps the history readable and changelog-friendly.

We work behind feature flags for anything user-visible that is not yet ready to ship. This lets us merge daily without releasing daily. Flags are checked into a single config file with a TTL comment so they don't quietly accumulate.

Pull request review

Every pull request requires at least one senior reviewer approval before it can merge. For changes touching authentication, payments, schema, or anything labelled security, two senior reviewers are required. Self-merging is disabled on every repo we own or maintain.

The first comment on every PR is auto-posted by our Claude Code reviewer agent, which generates a diff summary: what changed, which files, the risk level it assesses, and any obvious smells (missing tests, hardcoded values, broad any types, suspicious dependency bumps). It is a starting point for the human reviewer, not a replacement.

A PR cannot merge until:

  • All CI checks are green (lint, typecheck, tests, security scans, build).
  • A senior human reviewer has explicitly approved.
  • A changeset entry exists for any user-facing or API-facing change.
  • The PR description includes a How to test section that another engineer could follow without context.

We aim for PRs under 400 lines of diff. Larger changes are split or moved behind a feature flag so they can be merged incrementally.

Test coverage gates

Coverage is enforced in CI, not as a vibe. The default gate is ≥80% line coverage on new and changed code, configurable per project based on risk:

  • 90%+ for billing, payments, auth, anything touching money or credentials.
  • 80% default for product features, APIs, business logic.
  • 70% for early-stage prototypes and throwaway internal tooling, raised before production launch.

The gate is enforced via the test runner itself, e.g. vitest --coverage --coverage.thresholds.lines=80 or the equivalent Jest, Pytest, or Go test configuration. Coverage reports (Cobertura or LCOV) are uploaded as PR artifacts and a summary table is posted as a PR comment so the reviewer can see what dropped or improved before approving.

Coverage is necessary but not sufficient. We pair it with mutation testing on critical paths (Stryker for JS/TS) at least once per release to catch tests that pass without actually asserting anything meaningful.

CI/CD pipeline structure

Every repo runs the same pipeline shape, varied only by language and target. Stages run in order; a failing stage stops the pipeline.

Stage What runs Trigger Blocks merge?
1. LintESLint, Prettier, Stylelint, ruff/black, gofmtEvery pushYes
2. Typechecktsc --noEmit, mypy, go vetEvery pushYes
3. Unit testsVitest / Jest / Pytest / go testEvery pushYes
4. Integration testsAPI tests against ephemeral DB, contract testsEvery pushYes
5. Security scansSemgrep (SAST), Snyk (dependencies), Trivy (containers), gitleaks (secrets)Every pushYes
6. BuildProduction build, Docker image, artefact uploadEvery pushYes
7. Deploy previewEphemeral preview environment per PROn PR open / updateNo (informational)
8. Deploy stagingStaging environment, smoke testsOn merge to mainNo (post-merge)
9. Manual approvalProduction deploy gateTriggered by release managerYes (for prod)
10. Deploy productionRolling deploy, health checks, auto-rollbackOn approval

For VoIP and FreeSWITCH work we add a stage 4b that boots a containerised SIP test rig and runs SIPp scenarios against the build before it can be promoted. For data-heavy work we add a stage 4c that runs migration apply-and-rollback against a snapshot of staging data.

AI prompt patterns we use

We are AI-native, but we are not "vibe coding". Every engineer uses a small library of prompt patterns with Claude Code and Cursor that emphasise tight context, explicit file references, and test-first thinking. A few representative examples (redacted from real projects):

🧪

Mirror an existing pattern, test-first

Read @services/jobs.ts. Add `archiveJob` mirroring the soft-delete pattern used by `deleteJob`. Write vitest tests first with table-driven cases for: missing job, already archived, archived by non-owner, success. Then implement.

🔎

Bounded refactor with guard rails

Read @routes/auth.ts and @middleware/rbac.ts. Extract role-check logic into a single `requireRole(role)` middleware. Do not change behaviour. Add tests asserting old call sites return identical responses for: admin, user, anon. No edits outside these two files.

📐

Schema migration with reversibility

Read @prisma/schema.prisma. Add `Invoice.voidedAt` (nullable timestamp). Generate the migration AND its `down` reversal. Update @services/invoices.ts to filter voided invoices from the default list query. Tests must cover: list excludes voided, explicit `?includeVoided=true` includes them.

🩺

Bug reproduction before fix

Read @services/billing.ts. Bug: pro-rated refund double-counts taxes when subscription changed mid-cycle. First, write a failing vitest test that reproduces the bug at the exact boundary. Show me the failing test output. Only then fix.

What these prompts have in common: every one names the exact files to read (@path/to/file.ts), states the desired behaviour, requires tests, and constrains scope. Open-ended prompts ("build a payments module") produce slop; bounded prompts produce reviewable diffs.

We never paste customer data, secrets, or production logs into an AI tool. Prompts run against redacted fixtures. Every AI-touched file ends up in front of a human reviewer before it can merge.

Code review checklist

Every reviewer mentally walks this list before approving. It is also posted as a PR template comment so the author can self-check first.

  • Tests cover happy path + at least 2 edge cases. Empty input, max boundary, error path, concurrent call, whichever apply.
  • No secrets, keys, or tokens committed. Verified by gitleaks in CI; reviewer also greps for suspicious strings.
  • Error handling is explicit. No silent catches, no catch (e) {}. Errors surface with enough context to debug from logs alone.
  • Types are narrow. No drive-by any or as unknown as T. Public function signatures are precise.
  • Public APIs documented. JSDoc / docstrings on anything callable from outside the file.
  • No leftover console.log, print, or debug breakpoints. Logging goes through the project logger with appropriate levels.
  • Dependency additions justified. A new package needs a one-line reason in the PR description and a check that it is actively maintained.
  • Schema migrations are reversible. Every up has a working down; both have been run in CI.
  • Risky changes are feature-flagged. Anything user-visible and load-bearing ships dark and is rolled out gradually.
  • Accessibility on UI changes. Keyboard reachable, visible focus, labels associated, axe-core check passing.
  • Performance budget respected. No N+1 queries, no unbounded loops, no synchronous I/O in hot paths.

Definition of Done

A ticket is not "done" because the code compiles. We use a single, non-negotiable Definition of Done across all client projects. A change ships to production only when:

  1. Code has been reviewed and explicitly approved by a senior engineer (and a second reviewer for security-sensitive changes).
  2. All unit and integration tests pass in CI, on the merged commit, not just the PR branch.
  3. Coverage thresholds for the project are met or exceeded on changed code.
  4. Security scans (SAST, dependency, container, secrets) are clean. Any waivers are documented and time-boxed.
  5. Documentation is updated: README, API docs, runbooks, and any architecture diagrams that the change affects.
  6. The change has been deployed to staging and smoke-tested. For user-facing UI, an exploratory pass is done by someone who did not write the code.
  7. For UI changes, an automated axe-core accessibility check has run on the new screens and is passing at WCAG 2.2 AA.
  8. Product manager (or the equivalent client stakeholder) has signed off on user-facing behaviour matching the ticket's acceptance criteria.
  9. A changelog entry exists for anything externally observable. A rollback plan exists for anything risky.

If any of the above is missing, the ticket goes back. There is no "we'll add the tests later" — later does not happen, and the next engineer pays for it.

What this looks like in numbers

📈

~80% line coverage

Default floor on new and changed code. Higher for billing, auth, and payments.

⏱️

<48h branch life

Feature branches are short. Trunk-based development keeps the team integrated, not stranded.

🛡️

0 known criticals

No PR merges with a critical Semgrep, Snyk, or Trivy finding open against the changed code.

📝

1 changeset per PR

Every user-visible change has a changeset entry. Release notes write themselves.

Free consultation, no commitment

Want this rigour on your codebase?

Tell us about your project. We will share the full handbook section relevant to your stack and propose how we would apply it to your team.

Chat with us on WhatsApp