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:
- Audit any pending breaking changes — group them.
- Bump
0.X.Yto1.0.0-rc.1. - Run a deliberate one-week customer pilot on the RC.
- Tag
1.0.0, write a substantial release note, mark the API stable. - From there: SemVer proper. MAJOR for breaking, MINOR for features, PATCH for fixes.