Skip to content

Release strategy

Versioning

Format: 0.MINOR.PATCH (semver-shaped, but locked under 1.0 until the first paying customer is happy in production).

Why stay on 0.x: A 1.0.0 tag tells customers "this API is stable, breaking changes need a major bump". We are pre-product-market- fit and intentionally reserve the right to break shapes mid-iteration. Once a paying customer is in production for 60+ days without rollback, we'll cut 1.0.0.

Bumping rules

  • MINOR (0.X.0) — anything that ships new functionality a user could ask for in a sales call. Examples: a new connector, the Annex IV PDF endpoint, a new compliance dashboard, a domain migration, the observability stack. Plans landing → minor bumps.
  • PATCH (0.X.Y) — bug fixes, docs, refactors that don't change external surface, follow-up cleanup, dep bumps, security patches. Hotfix batches → patch bumps.

The MINOR number can grow large before we hit 1.0 — that's fine and expected. We will likely cross 0.10, 0.20, etc. without any ceremony around the digit transition.

When to tag

  • MINOR when a Plan or sales-relevant feature is *complete + tests
  • docs* land. Tag immediately after the merge commit.
  • PATCH at end of any working day where ≥1 commit shipped that isn't already covered by a MINOR you're about to tag. Don't let patches stack — tagging is free.
  • Don't pre-tag features that aren't actually live in prod.

Tag format

Annotated tag (git tag -a), never lightweight. Tag message follows:

v0.X.Y — <one-line headline>

<2-5 bullet points of the most important changes since the previous tag>

Plans included: <list of Plan IDs that landed in this window>
Commits included: <git log range>

Example:

v0.2.0 — detection breadth + production hardening + customer-ready docs

- 5 GitHub detection signals (Copilot/SBOM/code/workflow/DNS) + 3 passive collectors (Azure/AWS/GCP)
- Plan 28 stack: system detail page, connector health, bulk HITL, trend chart, Annex IV PDF
- Observability baseline: Sentry, request-id middleware, security headers, IP rate limit, DR runbook, SLOs
- 2-eyes impersonation approval + audit log filtering with cursor pagination
- Domain migration to secruna.com (CloudFront 301, Container Apps custom-domain bind, Entra redirect URIs)
- 376-line codebase complexity audit identifying Phase 1-3 refactor sequence

Plans: 16b, 16c, 17b, 17c, 20a, 22d, 24c, 25, 25b, 27 (deferred), 28a, 28b, 28c, 28d, 28f
Commits: v0.1.0..fdb536e (108 commits)

Branching + merging

We are pre-team. Direct push to main is the default for solo work where the change is small + tests pass + the founder is the reviewer. This will not scale past the second engineer; at that point we'll flip to PR-required-on-main.

The current pattern is acceptable when: - The change is <500 LOC of code. - Pre-commit hooks pass (ruff + mypy + secret detection). - Unit tests pass locally. - Push triggers CI deploy + smoke tests.

For larger features (e.g. Plan 30 vendor risk assessment, Plan 31 AI risk library, Phase 2 BaseDataPlaneClient), open a PR, get an LLM code review (via /ultrareview or another agent), then self-merge.

CHANGELOG

Maintain CHANGELOG.md at the repo root following Keep-a-Changelog shape, but entries are written at tag time not commit time — nobody has bandwidth to write changelog lines per commit.

Entries are grouped by:

  • Added — new features visible to users.
  • Changed — behavioural changes to existing features.
  • Fixed — bug fixes.
  • Infra/Docs — operational hygiene that doesn't change app behaviour but matters for ops/audit.
  • Refactored — internal cleanup with no external effect.
  • Deprecated / Removed — anything users should stop relying on.

GitHub releases

For every MINOR tag, create a gh release create with the same notes copied from the tag annotation. PATCH tags don't need GitHub releases unless they include a security fix worth surfacing.

This builds up a public-ish release log on the repo that buyers can review during procurement diligence.

Post-1.0 plan

When the first paying customer is in production for 60+ days without rollback:

  1. Audit any pending breaking changes — group them.
  2. Bump 0.X.Y to 1.0.0-rc.1.
  3. Run a deliberate one-week customer pilot on the RC.
  4. Tag 1.0.0, write a substantial release note, mark the API stable.
  5. From there: SemVer proper. MAJOR for breaking, MINOR for features, PATCH for fixes.