Agentic systems / Pattern 14 / Build the working path

Build an offline version bundle and canary decision gate

Hash release inputs, assign stable cohorts, and test hold, approval, promotion, and rollback decisions.

By Sandeep Belgavi · 23 October 2026 · Architecture and design patterns

Run the gate as a deterministic exercise

Download pattern_14.py and test_pattern_14.py. Use Python 3.11 or later. On macOS run python3 -B pattern_14.py and python3 -B -m unittest -v test_pattern_14.py. On Windows use py -3 -B pattern_14.py and py -3 -B -m unittest -v test_pattern_14.py. No model, deployment API, or cloud credentials are involved.

The example first holds a small sample, then promotes a candidate with approval, then rolls back after an authorization violation. The final active_code is c1. This is a state change inside a Python object, not an actual rollout. The JSON makes the decision sequence observable without pretending that infrastructure was deployed.

Architecture and request sequence

Component diagram for Build an offline version bundle and canary decision gate
Original reference architecture by Sandeep Belgavi. Arrows show the responsibilities and transitions described below.
Read the architecture as text
  • Bundle digest: Hash supplied version identifiers
  • cohort method: Stable hash of tenant and incident
  • assess method: Counts, hard violations and quality gate
  • Active bundle state: Local promotion or rollback only
  • Bundle digest → cohort method: Validated input
  • cohort method → assess method: Bounded processing
  • assess method → Active bundle state: Recorded result
Request sequence for Build an offline version bundle and canary decision gate
Illustrative sequence for this design; failure and recovery variants are explained in the article.
Read the sequence as text
  1. Caller → Boundary: Submit version bundle
  2. Boundary → Store: Validate compatibility
  3. Store → Boundary: Supply cohort observations
  4. Caller → Boundary: Bind approval
  5. Boundary → Store: Set local active bundle

Build a complete identity before comparing versions

Bundle is an immutable dataclass containing code, prompt, model, tools, and schema identifiers. Its digest method rejects empty or non-string values, serializes the fields in sorted order, and computes a hash. The prompt-change test confirms that a changed prompt produces a different identity even when the code identifier stays the same.

These identifiers are supplied by the caller. A production artifact registry must resolve them to immutable content and verify provenance separately. The example does not read a container image, fetch a model revision, or check a signature. That limitation is useful: it isolates the release-manifest contract from the infrastructure adapters. Add adapters only after deciding how their evidence will be represented and validated.

Reject a state mismatch before starting the canary

ReleaseGate validates both bundles and rejects different schema identifiers. It also validates that the canary percentage is between zero and one hundred. The active bundle starts as baseline. This construction step prevents the exercise from casually promising rollback across an unreviewed schema change. It does not prove that two identically named schemas are actually compatible.

For a real migration, replace the simple equality rule with reviewed compatibility metadata and tests that exercise old and new readers and writers. Keep a conservative failure mode when that evidence is missing. Do not permit the model to declare the migration compatible because it generated both versions. The release controller needs evidence from the relevant storage and application tests.

Inspect stable cohort selection

The cohort method serializes tenant and incident as a JSON pair, hashes it, and maps the result to one hundred buckets. A bucket below the configured percentage selects candidate; otherwise it selects baseline. JSON encoding avoids ambiguous concatenations such as two different identifier pairs producing the same unseparated string. Empty identifiers are rejected.

Tests confirm repeatability and the zero-percent and hundred-percent boundaries. They do not assert that a small incident population divides perfectly into the requested percentage. Hash bucketing provides an assignment rule, not a guarantee of representative traffic. A real release service also needs to pin the chosen version for the lifetime required by the incident contract and preserve that assignment through restarts.

Read the assessment order carefully

The assess method validates nonnegative integer counts and rejects failure counts larger than observations. Any authorization violation rolls back immediately. Otherwise insufficient cohort observations produce hold. A candidate failure rate above the illustrative tolerance rolls back. A passing rate without explicit approval produces await_approval; with approval it promotes the candidate.

This order prevents a good average from overriding a security invariant. The tests first promote a candidate and then inject a violation to verify that active returns to baseline. The approved flag is an input seam for a release authority, not an authentication mechanism. A deployed controller must derive it from a verified approval record and bind that approval to the exact candidate and evidence.

Connect deployment and telemetry as separate adapters

A proposed integration reads signed release metadata, obtains cohort observations from a validated metrics query, and calls the gate. A deployment adapter then applies an authorized decision and records whether the infrastructure action succeeded. The gate's desired state and the platform's observed state must remain distinguishable. A failed rollback request cannot be reported as a completed rollback merely because the local decision returned that word.

Kubernetes Deployment documentation describes workload revisions, but the adapter still needs application-specific state and external-effect handling. The eight local tests cover identity, compatibility, observation sufficiency, quality rollback, approval, hard violations, invalid counts, and cohort boundaries. They do not establish a production deployment or model-quality benchmark. Keep those claims for actual integration evidence.

Record the gate inputs alongside its output. A later reviewer should be able to replay the exact decision without querying a metrics system whose historical results might have changed through retention or revised filters.