The path is part of the release
The script creates three HTTP servers on 127.0.0.1 with system-assigned ports: blue, green and router. These are actual listeners and requests, executed by threads within one Python process. The router selects a target and forwards the request to another listener. Initially every request goes to blue. green already responds ready when accessed directly, but the pilot request through the router still identifies blue. In an APS project, this difference prevents reporting availability merely because installation ended. Identify the path a dependent consumer will use, including batch processing, and observe version and outcome through that path. The lab runs no enterprise load balancer, DNS, TLS, Kubernetes or authentication.
Explicit cohort and relevant population
When candidate becomes true, the router chooses green only for cohort=pilot; control remains on blue. The field is an explicit exercise input, not an authenticated customer identity. It does not represent ten percent of traffic, random selection or an affinity guarantee in a real product. Observation should state who entered the sample and which behavior was exercised. A group consisting only of internal users may not cover older external-client contracts. Increasing duration without changing that profile does not automatically introduce absent paths. For a fictional release, relate populations to the risk mechanism and define missing observations before expansion. These local requests establish no universal canary size.
Successful status and incorrect outcome
On the ordinary path, the candidate returns 100. On the critical path, blue returns 100 and green returns 108 although both use HTTP 200. The defect is deliberate and the exercise requires 100; this is not a financial formula. The ready endpoint remains true because it does not validate that operation. Status and component availability are therefore insufficient to approve the release. Connect criteria to outcomes recognizable to the consumer and retain the identity of the version producing them. When a mandatory criterion fails, hold expansion and decide mitigation, recovery or correction under applicable authority. An approaching deadline does not change the expected result or turn observation into acceptance.
What the trace supports
The router trace records target, method, path, kind and value after receiving each response. At this stage ordinary and critical observations exist, but none for export. The export rate is shown as unknown with a zero denominator, not zero-percent failures. The record is also not a production sample and measures neither capacity nor latency percentiles. Later, a request admitted first is held and appears after another in the trace: this is observed completion order, not an admission log. During release investigation, establish each field’s timing and meaning before reconstructing the sequence. Retain telemetry gaps instead of filling them with favorable conclusions.
python3 content/labs/release-routing/run.py --output /tmp/dr-release-routing.json
# Inspect installedCandidateIsNotExposure and httpSuccessMissesSemanticFailure.
# Three temporary loopback listeners only; not a production proxy.green is ready, but pilot stays on blue until the rule changes; critical then returns HTTP 200 with 108 instead of 100.
Common pitfalls
Direct access as availability, a cohort as a random percentage, HTTP 200 as correct outcome or absent requests as success.
Related topics: Go/no-go criteria · In-flight requests and recovery
A release needs evidence for relevant paths and populations; component readiness does not establish functional acceptance.
Reference: Canarying Releases · Release management practices 2026-09; scoped GitLab GitHub CodeDeploy and EF Core documentation