Cookbook 11 · Govern
Release Signoff Factory
Aggregate cross-cookbook evidence into a defensible go / no-go decision.
GovernCore30–50 min
What you build. A durable release candidate with server-computed weighted criteria, blockers, accountable waivers, rollback target, immutable go/no-go signoff, and Allure-compatible report evidence.
Surfaces: Releases Evaluations Review Queues Observability
What you learn
- Collect evidence from Evaluations + Review Queues
- Re-run critical slices and capture fresh run ids
- Generate durable Allure-compatible evidence
- Inspect the server-computed release score and blockers
- Record an immutable decision with blockers + waivers
Implementation flow
flowchart TD
E1[Eval run ids 07/08/10] --> SC[Release candidate]
E2[Review queues complete] --> SC
E3[Allure report loads] --> SC
E4[Re-run critical slices] --> SC
SC --> D{"blockers = 0 and score >= 0.90?"}
D -->|yes| GO[go]
D -->|no| NG[no_go + blockers]Step-by-step UI only
Each step shows the exact navigation path, the fields to fill, the button to click, and a snapshot of the CALIBER screen you'll be on.
- This scenario is an operator process, not a built workflow — there is no release-scoring engine. Start by opening the fill-in manifest run-id-manifest.json. You will paste real evidence (run ids, review states, Allure status) into it across the next steps, then score by hand. Leave a field empty until you have verified it — any empty required field counts as MISSING and forces no_go.Fill in
release_tag your candidate tag, e.g. r2026.06.0prepared_by your name / role You'll see: The manifest is open with one block per upstream scenario (SCN-07, SCN-08, SCN-09, SCN-10) and anallureblock, all empty and ready to fill.Screen snapshotcaliber · (outside the app) Run-id manifest - Collect the scorecard run id for each required scenario. Open Evaluations (under Evaluate) and find each upstream scenario's scorecard run in the table. Copy its run id into the matching
eval_run_idfield in the manifest. Then open each run and confirm by hand that its pass rate clears that scenario's bar — thepass ≥ …chip on the run detail is a per-row threshold, not a run-level verdict. CALIBER does not compute a single run-level pass/fail gate (the Evaluations table has no gate column), so the go/no-go judgment on each scorecard is yours.Fill inscenarios[SCN-07].eval_run_id the SCN-07 support-triage scorecard run id scenarios[SCN-08].eval_run_id the SCN-08 incident-response scorecard run id scenarios[SCN-09].eval_run_id the SCN-09 workflow-debugger scorecard run id scenarios[SCN-10].eval_run_id the SCN-10 judge-certification scorecard run id You'll see: Each scenario row in the manifest now carries a realeval_run_id; you have clicked into each run and judged by hand that its pass rate clears that scenario's bar.Screen snapshotcaliber · Evaluate › Evaluations - Confirm review coverage. Open Review Queues (under Observe) and check that each required queue from the upstream scenarios (e.g. SCN-10's
faithfulness-certification) is fully answered with no unresolved items. Setreview_queue_completeto true only for queues that are completely answered.Fill inscenarios[*].review_queue_complete true only where every item in that scenario's required queue is answered You'll see: Each scenario'sreview_queue_completereflects the real queue state; any queue with open items stays false.Screen snapshotcaliber · Observe › Review Queues Compose › Workflows › (workflow detail)creates · Fresh critical-slice run ids run-id-manifest.json ↓Re-run the high-risk slices to prove they still pass. From Workflows (under Compose) open each workflow and click Run Pipeline (labelled Queue Run when queued execution is enabled) to re-execute the critical subsets — the SCN-07 approval branch (its human_approval gate pauses the run; clear it with Approve then Resume in the run's approval panel), the SCN-08 rollback path, and the SCN-09 retry/resume recovery. Record each fresh run id in the manifest'sapproval_branch_run_idfield for that scenario.Fill inscenarios[SCN-07].approval_branch_run_id fresh run id from re-running the approval branch scenarios[SCN-08].approval_branch_run_id fresh run id from re-running the rollback path scenarios[SCN-09].approval_branch_run_id fresh run id from re-running the retry/resume recovery You'll see: Each critical slice has a fresh, successful run id recorded; you can open each in the workflow's run history and its trace in Observability.Screen snapshotcaliber · Compose › Workflows › (workflow detail)(terminal) make allure-reportcreates · Regenerated Allure report (static HTML)Allure is generated externally — the app only serves it. Before opening the report, regenerate it from the suite root by runningmake allure-report(this combines the vitest, playwright, and pytest Allure results). This is the one out-of-band command in the whole recipe.You'll see: The command finishes and writes a fresh static Allure report that the backend can serve.Screen snapshotcaliber · (terminal) make allure-reportRead / inspect this surface — no form to fill.Platform › Settings › Allure Reportcreates · In-app Allure report URL + load confirmed run-id-manifest.json ↓Open and verify the report in-app. Click Settings (under Platform at the bottom of the sidebar), then the Allure Report tab. Confirm the Allure report URL points at the served report (default is the backend-served/observability/allure-report/), click Open Allure report, and confirm it loads. Record the URL and setloaded: truein the manifest'sallureblock.Fill inAllure report URL /observability/allure-report/ (or your served URL) manifest allure.report_url the same URL manifest allure.loaded true (only after it visibly loads) Click Open Allure reportYou'll see: The Allure report renders in-app. The manifest'sallureblock now has a URL andloaded: true.Screen snapshotcaliber · Platform › Settings › Allure ReportOpen Allure report(optional) Observe › Review Queues › + New Queuecreates · (optional) Blocker-triage queue + answers blocker-questions.json ↓(Optional) If issues surfaced and you need to triage which are true blockers, create a triage queue. Click + New Queue and add the questions from blocker-questions.json (use the + Add question button for each; map thetypevalues bool → pass_fail and str → text/categorical). Enqueue the candidate trace ids in the Add traces to review field and answer them — answers write back onto each trace.Fill inName release-blocker-triage Description Triage candidate release blockers: confirm whether each is a true release blocker, who owns it, and (if waived) when the waiver expires. Questions is_release_blocker (pass_fail), owning_scenario (text), severity (text), waiver_granted (pass_fail), waiver_expiry (text), waiver_owner (text) — paste from blocker-questions.json Click Create queueYou'll see: Arelease-blocker-triagequeue exists; answered items record, per blocker, whether it blocks the release, its owner, and any waiver.Screen snapshotcaliber · (optional) Observe › Review Queues › + New QueueCreate queue(optional) Library › Prompts › New promptcreates · (optional) Prompt release-risk-summarizer release-risk-summarizer.md ↓(Optional) To auto-draft the decision rationale from your evidence, register the summarizer prompt. Open Prompts (under Library), click New prompt, and paste the template body (everything below the YAML frontmatter) from release-risk-summarizer.md. It only narrates evidence you supply and is hard-wired to force no_go on missing evidence or open blockers — it never invents passing evidence.Fill inName release-risk-summarizer Template paste the template body from release-risk-summarizer.md (variables: scenario_run_ids,review_summary,allure_status,blocker_list)Commit message v1 release-risk summarizer (evidence-in, decision-out, no invention) You'll see: Arelease-risk-summarizerprompt is registered; feed it your filled manifest to draft the rationale (it returns JSON only).Screen snapshotcaliber · (optional) Library › Prompts › New prompt(outside the app) Release rubriccreates · Hand-computed release score + blocker count release-rubric.json ↓Score the release by hand using release-rubric.json. For each of the four dimensions, read the evidence in your filled manifest, mark a status (pass/partial/fail), convert it to a factor (1.0 / 0.5 / 0.0), multiply by the weight, and sum. Then count open blockers. The weights are fixed: component_readiness 0.30, workflow_readiness 0.30, review_coverage 0.20, evidence_visibility 0.20.Fill incomponent_readiness (0.30) pass if all SCN-07/08/09/10 eval_run_id present AND each scorecard passes workflow_readiness (0.30) pass if every critical-slice re-run has a fresh run id AND completed successfully review_coverage (0.20) pass if all required review_queue_complete == true evidence_visibility (0.20) pass if allure.loaded == true AND allure.report_url set AND every gate state maps to a recorded run id / review answer / Allure result overall_release_score sum(weight × factor) blocker_count number of still-open blockers You'll see: A weightedoverall_release_scoreand ablocker_count. As the worked example in the rubric shows, a score of exactly 0.90 with one open blocker is still a no_go.Screen snapshotcaliber · (outside the app) Release rubric- Publish the go/no-go decision. Copy decision-record.template.md and replace every
<FILL: …>placeholder: the run-id list, the Allure URL + load confirmation, the per-dimension scores, the blocker list (each mapped to its owning scenario), the waiver log, and the final decision + rationale. Publish go only if all three gates hold:overall_release_score ≥ 0.90ANDblocker_count = 0AND Allure visible. Otherwise no_go, naming each failing gate and the owning scenario per blocker.Fill inDecision go | no_go Gate check overall_release_score ≥ 0.90? · blocker_count == 0? · Allure visible? Rationale cite evidence by id/name; for no_go, name the failing gate(s) and each blocker's owning scenario You'll see: A complete, audit-ready decision record where every gate state traces back to a concrete run id, review answer, or Allure result.Screen snapshotcaliber · (outside the app) Decision record
Assets (copy-paste)
The exact files this cookbook uses — copy each into the matching field. Source: docs-site/cookbooks/11-release-readiness-factory/assets/.
{
"_comment": "Fill-in template. The operator pastes REAL evidence here before scoring — there is no engine that fills this. Leave a field empty until you have verified the evidence; the release-risk-summarizer (and the rubric) treat any empty required field as MISSING and force no_go. eval_run_id = the Evaluations scorecard run id (Evaluate -> Evaluations). review_queue_complete = true only when every required Review Queue is fully answered (Observe -> Review Queues). approval_branch_run_id = the fresh run id from re-running that scenario's high-risk pipeline slice (SCN-07 approval branch, SCN-08 rollback path, SCN-09 retry/resume recovery); it is REQUIRED only for SCN-07/08/09. SCN-10 is NOT required to carry approval_branch_run_id — its critical slice is human-review-queue completion, not a pipeline re-run, so SCN-10 readiness gates on eval_run_id + review_queue_complete only.",
"release_tag": "",
"prepared_by": "",
"prepared_at": "",
"scenarios": [
{
"scenario": "SCN-07",
"name": "support-triage-resolution-loop",
"critical_slice": "approval branch (human_approval gate -> approve -> resume)",
"required": ["eval_run_id", "review_queue_complete", "approval_branch_run_id"],
"eval_run_id": "",
"review_queue_complete": false,
"approval_branch_run_id": "",
"notes": ""
},
{
"scenario": "SCN-08",
"name": "incident-response-commander",
"critical_slice": "rollback path (re-run to confirm it still passes)",
"required": ["eval_run_id", "review_queue_complete", "approval_branch_run_id"],
"eval_run_id": "",
"review_queue_complete": false,
"approval_branch_run_id": "",
"notes": ""
},
{
"scenario": "SCN-09",
"name": "workflow-debugger-self-healing-lab",
"critical_slice": "retry/resume recovery path",
"required": ["eval_run_id", "review_queue_complete", "approval_branch_run_id"],
"eval_run_id": "",
"review_queue_complete": false,
"approval_branch_run_id": "",
"notes": ""
},
{
"scenario": "SCN-10",
"name": "judge-certification-human-review-lab",
"critical_slice": "judge certification + human-review queue completion",
"required": ["eval_run_id", "review_queue_complete"],
"eval_run_id": "",
"review_queue_complete": false,
"approval_branch_run_id": "",
"notes": ""
}
],
"allure": {
"_comment": "Generated EXTERNALLY via `make allure-report`, then served in-app at Settings -> Allure Report (GET /observability/allure-report). Set loaded:true only after you have confirmed the report opens in-app; the tab reads the stored URL caliber.allure.reportUrl.",
"report_url": "",
"loaded": false,
"regenerated_at": ""
}
}
{
"_comment": "Optional Review Queue question schema for blocker triage. Create a queue via POST /review-queues with these questions, enqueue the candidate trace ids (.../items), and answer them; answers write back onto the trace as MLflow assessments. type is the feedback value type (bool|int|float|str), matching the platform's review-queue question shape. Use this to decide which surfaced issues are real release blockers and to record waivers.",
"queue_name": "release-blocker-triage",
"description": "Triage candidate release blockers: confirm whether each is a true release blocker, who owns it, and (if waived) when the waiver expires.",
"questions": [
{
"key": "is_release_blocker",
"type": "bool",
"prompt": "Is this a release blocker (must be fixed or waived before go)?"
},
{
"key": "owning_scenario",
"type": "str",
"prompt": "Which upstream scenario owns this blocker? (e.g. SCN-07, SCN-08, SCN-09, SCN-10)"
},
{
"key": "severity",
"type": "str",
"prompt": "Severity: one of [critical, high, medium, low]."
},
{
"key": "waiver_granted",
"type": "bool",
"prompt": "Is a waiver granted for this release? (false means it must be fixed, not waived)"
},
{
"key": "waiver_expiry",
"type": "str",
"prompt": "If waived, the waiver expiry date (YYYY-MM-DD). Leave empty if no waiver."
},
{
"key": "waiver_owner",
"type": "str",
"prompt": "If waived, the accountable owner for the waiver. Leave empty if no waiver."
}
]
}
---
name: release-risk-summarizer
model_hint: any capable instruct model; this only narrates supplied evidence (no tools, no retrieval)
variables: [scenario_run_ids, review_summary, allure_status, blocker_list]
commit_message: "v1 release-risk summarizer (evidence-in, decision-out, no invention)"
---
You are a release-readiness summarizer for a software release control lane. You
DO NOT score releases on your own authority and you DO NOT gather evidence. You
are given evidence that an operator already collected, and you turn it into a
single structured decision. You return JSON ONLY — no prose, no markdown, no code
fences.
You are given:
- Scenario run ids (the evidence the operator collected per upstream scenario):
{{ scenario_run_ids }}
- Review summary (review-queue completion + any blocker-triage answers):
{{ review_summary }}
- Allure status (whether the in-app Allure report was regenerated and loaded):
{{ allure_status }}
- Blocker list (open blockers, each with its owning scenario):
{{ blocker_list }}
Output exactly this shape:
{
"release_score": number between 0 and 1,
"blocker_count": integer >= 0,
"decision": one of ["go", "no_go"],
"rationale": short string (<= 600 chars) citing the evidence by id/name,
"missing_evidence": array of strings (empty if nothing is missing)
}
Hard rules — follow these exactly, in this order:
1. Use ONLY the evidence supplied above. NEVER invent, assume, or "fill in"
passing evidence. If a required field is empty, null, or absent, treat that
evidence as MISSING — do not guess that it passed.
2. Compute "blocker_count" as the number of entries in {{ blocker_list }} that
are still open (not waived/closed). Count it; do not estimate it.
3. Force "decision":"no_go" if ANY of the following is true:
- any required evidence is missing (list every missing item in
"missing_evidence"),
- blocker_count > 0,
- Allure was not regenerated or did not load (allure_status is not a clear
"loaded/visible" signal).
When you force no_go, the rationale MUST name the specific failing condition.
4. Only return "decision":"go" when ALL of these hold simultaneously:
"missing_evidence" is empty, blocker_count == 0, Allure is loaded, and
release_score >= 0.90.
5. "release_score" must be consistent with the evidence: if any dimension lacks
its evidence, the score cannot be >= 0.90. Do not output a score that
contradicts "missing_evidence" or "blocker_count".
6. Never approve a release to be helpful, to resolve ambiguity, or because the
evidence is "probably fine". When in doubt, return no_go and say why.
Return only the JSON record.
{
"_comment": "Operator scoring config for the SCN-11 release rubric. There is NO engine that evaluates this — the operator scores each dimension BY HAND from the evidence in dataset/run-id-manifest.json, computes the weighted sum, counts blockers, and applies the gates. Weights mirror verification.yaml.",
"version": "1",
"scoring": {
"_comment": "Per dimension, mark a status and convert to a score factor, then multiply by the weight. overall_release_score = sum(weight * factor).",
"status_to_factor": { "pass": 1.0, "partial": 0.5, "fail": 0.0 }
},
"dimensions": [
{
"key": "component_readiness",
"weight": 0.30,
"satisfied_by": "Component-level evidence is green and recorded: prompt/tool/skill scorecards from the upstream scenarios pass. Concretely, every SCN-07/08/09/10 eval_run_id is filled and its scorecard passes its own gate.",
"evidence_source": "dataset/run-id-manifest.json -> scenarios[].eval_run_id (Evaluate -> Evaluations scorecards)",
"pass_if": "all required eval_run_id present AND each scorecard passes",
"partial_if": "some scorecards pass, others missing or below their gate",
"fail_if": "any required eval_run_id missing OR any scorecard fails"
},
{
"key": "workflow_readiness",
"weight": 0.30,
"satisfied_by": "The high-risk workflow slices were re-run and still pass: SCN-07 approval branch, SCN-08 rollback path, SCN-09 retry/resume recovery, with fresh run ids. Scoped to SCN-07/08/09 only — SCN-10's critical slice is human-review-queue completion (scored under review_coverage), not a pipeline re-run, so it carries no approval_branch_run_id.",
"evidence_source": "dataset/run-id-manifest.json -> scenarios[SCN-07/08/09].approval_branch_run_id (Workflow run monitor + Observability traces)",
"pass_if": "every SCN-07/08/09 critical-slice re-run has a fresh run id AND completed successfully",
"partial_if": "some SCN-07/08/09 critical slices re-run green, others not yet re-run",
"fail_if": "any SCN-07/08/09 critical slice missing a fresh run id OR a re-run failed"
},
{
"key": "review_coverage",
"weight": 0.20,
"satisfied_by": "Every required Review Queue from the upstream scenarios is fully answered (no unresolved items), and blocker-triage answers are recorded where used.",
"evidence_source": "dataset/run-id-manifest.json -> scenarios[].review_queue_complete (Observe -> Review Queues); optional review/blocker-questions.json answers",
"pass_if": "all required review_queue_complete == true",
"partial_if": "some queues complete, others still have unresolved items",
"fail_if": "any required review queue not complete"
},
{
"key": "evidence_visibility",
"weight": 0.20,
"satisfied_by": "The in-app Allure report was regenerated (make allure-report) and LOADS at Settings -> Allure Report, and the run-id manifest is complete enough to trace every gate state back to a concrete run id / review answer / Allure result.",
"evidence_source": "dataset/run-id-manifest.json -> allure {report_url, loaded}; GET /observability/allure-report",
"pass_if": "allure.loaded == true AND allure.report_url set AND every gate state maps to a recorded run id / review answer / Allure result",
"partial_if": "Allure loads but some evidence links are missing",
"fail_if": "Allure not regenerated or does not load (allure.loaded != true)"
}
],
"gates": {
"_comment": "All three must hold for a go. Mirrors verification.yaml quality_gates.",
"overall_release_score_min": 0.90,
"blocker_count_must_equal": 0,
"allure_visibility_required": true
},
"decision_rule": "decision = go ONLY IF overall_release_score >= overall_release_score_min AND blocker_count == 0 AND allure_visible == true; otherwise no_go. Missing required evidence is a fail for its dimension (and typically forces blocker review), so a missing-evidence release cannot reach 0.90.",
"worked_example": {
"_comment": "Illustrative only — shows the arithmetic and how one open blocker forces no_go even when the weighted score clears the threshold.",
"scenario": "Release candidate r2026.06.0",
"dimension_status": {
"component_readiness": "pass",
"workflow_readiness": "pass",
"review_coverage": "partial",
"evidence_visibility": "pass"
},
"calculation": [
"component_readiness: 0.30 * 1.0 = 0.30",
"workflow_readiness: 0.30 * 1.0 = 0.30",
"review_coverage: 0.20 * 0.5 = 0.10",
"evidence_visibility: 0.20 * 1.0 = 0.20"
],
"overall_release_score": 0.90,
"allure_visible": true,
"blockers": [
{
"id": "BLK-1",
"summary": "SCN-07 approval-branch re-run surfaced one unresolved review item: an over-refund case was approved without the eligibility check.",
"owning_scenario": "SCN-07",
"status": "open"
}
],
"blocker_count": 1,
"decision": "no_go",
"rationale": "Weighted score is exactly 0.90 and Allure is visible, but blocker_count == 1 (BLK-1, owned by SCN-07). The blocker_count_must_equal:0 gate fails, so the release is no_go regardless of the score. Resolve BLK-1 in SCN-07 (or log a waiver with an explicit expiry + owner), re-run the SCN-07 approval branch, then re-score."
}
}
# Release decision preparation template
This is an optional drafting aid. Record the authoritative candidate, waiver,
report-job, and final signoff in **Operate → Releases**.
- Candidate name / artifact / version:
- Required score:
- Planned action:
- Rollback target:
- Evidence references:
- Blocking criteria:
- Waivers with reason / expiry / approver:
- Decision: `go` / `no_go`
- Rationale:
- Report-job id:
- Candidate snapshot SHA-256:
Before `go`, confirm the server reports `ready`, no unwaived blocker remains,
and both the planned action and rollback target are populated.
Evaluation & quality gates
| Quality gate | Target |
|---|---|
| Overall release score | ≥ 0.90 |
| Blocker count | = 0 |
| Allure visible | report loads in-app |
Developer notes & gotchas
- The server recomputes score and blockers from the stored criteria; the browser's aggregate is never trusted.
- The report job is durable Allure-compatible JSON; CI still owns the separate rendered HTML test report.
- Map every blocker back to its owning cookbook and reopen that gate.