Product · Releases

Immutable snapshots instead of conditional parameters

Nona treats runtime configuration like something you can prepare, snapshot, activate, and patch deliberately — a different operational model from systems where one mutable config surface keeps branching through conditions.

What a release means in Nona

Every environment has one editable working configuration and zero or more immutable releases. Operators make changes in the working configuration, then snapshot those changes as a release. Release routes never fall back to the working configuration — a release request either resolves to an immutable snapshot or fails explicitly.

That separation is what lets you answer questions like: what exactly was live, what exactly changed, and what exact version should we go back to?

How clients read releases

There are three ways to read release config, and they answer three different questions:

  • /releases/1.2.0/parameters — that exact release, pinned. It never changes underneath you.
  • /releases/1.2.x/parameters — the highest patch published in the 1.2 line. Clients on this route float to the newest patch automatically.
  • /releases/active/parameters — whatever release the environment currently has activated. Returns 409 active_release_not_configured if nothing is active yet, rather than guessing.

That 409 instead of a silent fallback is deliberate: a client that fails to refresh stays on its last-known-good release rather than being quietly handed the editable working configuration it was never meant to read. The line selector (.x) is part of the public client API — admin and CLI release-management operations always require exact versions like 1.2.0.

the three read patterns
# Exact version — pinned, never moves
curl "https://nona.example.com/api/environments/production/releases/1.2.0/parameters" \
  -H "X-Api-Key: your-api-key"

# Floating line — always the newest patch in 1.2.x
curl "https://nona.example.com/api/environments/production/releases/1.2.x/parameters" \
  -H "X-Api-Key: your-api-key"

# Active release — whatever the environment currently has activated
curl "https://nona.example.com/api/environments/production/releases/active/parameters" \
  -H "X-Api-Key: your-api-key"
# -> 409 active_release_not_configured if nothing is activated yet

How to use releases in practice

1

Prepare changes in Parameters

Treat the Parameters page as your working area. Edit values, add new parameters, or adjust a JSON config until the next release looks right.

2

Create a version by line, not by patch

On the Releases page, click Create a version and enter a major-minor version such as 1.2. Nona normalizes that to 1.2.0 for the first release in the line.

3

Review, then create

Review the exact values that will be captured before you create the immutable snapshot — creating it stores the snapshot but does not yet activate it.

4

Activate separately, when ready

Activation is a second deliberate step. Clients reading the active-release route only switch once you explicitly activate that version.

the same flow from the CLI
# Create 1.2 — Nona normalizes the first release in a line to 1.2.0
nona releases create 1.2 --project mobile-app --environment production

# Backport a fix into an older line — targets the next free patch automatically
nona releases amend 1.1.0 \
  --project mobile-app \
  --environment production \
  --set Features:Checkout=false

Why releases beat conditional parameters for many config workflows

Conditional parameters look flexible because they let one key branch by environment, rule, or targeting clause. But flexibility isn't free — in many systems, "what value is live" becomes "it depends on which branch wins at runtime."

Releases are better when your team cares more about operational clarity than about building a mini rule engine into config: explicit snapshots, explicit activation, explicit rollback.

Question
Release model
Conditional parameter model
What clients read
An explicit immutable snapshot — exact version, floating .x line, or the active one.
A runtime branch selected by environment, rules, or condition evaluation.
Debugging
You can ask: which exact release was active, and read its exact contents back.
You often have to reconstruct which branch won and why.
Rollback
Activate an older release, or patch a line intentionally with Amend.
Change the conditions again and hope every branch still lines up.
Promotion
Create, review, activate — three separate deliberate steps.
Edit live branching rules inside the same mutable config surface.

Amend: patching an older line without a condition tree

Amend targets the next free patch in an existing release line and opens a separate, client-side-editable copy of that release's parameters — the working configuration is never touched. For example: amending 1.1.0 produces 1.1.1; if that already exists, the next amend becomes 1.1.2. You never type the patch number yourself.

The new patch is not automatically activated, and canceling an amend discards the local buffer with no effect on the working configuration or the source release.

Deleting a release

Non-active releases can be deleted from the release list — that removes the immutable snapshot without touching the editable working configuration. A release that's currently active can't be deleted directly; activate a different release or clear the active release first.

When conditional parameters are still useful

If your main problem is per-user targeting, cohorts, or runtime segmentation, a condition-heavy system may still be the right tool — this isn't a claim that branching rules are always wrong.

The point is narrower: for teams using remote config as operational infrastructure, releases are simpler to run, simpler to debug, and simpler to trust.

Try the release workflow yourself

Nona is open source and self-hosted. Stand it up, create a project, add a couple of environments, and run through the release flow once — the model becomes obvious the moment you activate a snapshot instead of editing a live conditional tree.