Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
67 changes: 62 additions & 5 deletions standards/canary-rings.json
Original file line number Diff line number Diff line change
Expand Up @@ -857,13 +857,70 @@
}
}
}
}
},
"unmanaged": {
},
"pr-auto-review": {
"host": "petry-projects/.github",
"reusable": ".github/workflows/pr-auto-review-reusable.yml",
"reason": "Frozen-major @v2 review-dispatcher infra \u2014 not a canary-promoted agent."
"run_workflow": "PR Auto-Review \u2014 Ready Check",
"rings": [
{
"channel": "next",
"order": 0,
"members": [
"petry-projects/.github-private"
]
},
{
"channel": "ring0",
"order": 1,
"members": [
"petry-projects/.github"
]
},
{
"channel": "ring1",
"order": 2,
"members": [
"petry-projects/TalkTerm",
"petry-projects/bmad-bgreat-suite"
]
},
{
"channel": "stable",
"order": 3,
"members": [
"*"
]
}
],
"gate": {
"_standard": "petry-projects/.github#548 \u2014 graduated dwell/sample gate over a per-candidate cumulative window. These are registry-configurable per-transition knobs; the values below are the #548 defaults.",
"baseline_window_days": 14,
"baseline_spike_cap_multiple": 3,
"benign_failure_classes": [],
"control": {
"allow_pre_existing": false
},
"_benign_note": "benign_failure_classes (#1025 P2): per-reusable allowlist matched against a failed run's workflow name (`workflow` ERE) + failed-step signature (`step` ERE, matched via `gh run view`). Matches are excluded from cum_fail \u2014 but ONLY when the candidate's reusable is byte-identical to the prior channel (differs=0), so the allowlist can never mask a candidate-introduced regression. `control.allow_pre_existing`, or `promote --allow-pre-existing`, advances a BLOCKED+PRE_EXISTING frontier (never REGRESSION).",
"transitions": {
"next->ring0": {
"dwell_hours": 4,
"sample_fraction_permille": 250,
"sample_clamp_min": 3,
"sample_clamp_max": 15,
"waive_sample_if_no_caller": true
},
"ring0->ring1": {
"dwell_hours": 8,
"waive_sample": true
},
"ring1->stable": {
"dwell_hours": 12,
"sample_min": 1
}
}
}
}
}
},
"unmanaged": {}
}
12 changes: 12 additions & 0 deletions tests/canary_rollout.bats
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,18 @@ setup() {
}

# ── canary-rings.json SoT shape (rings + gate knobs) ──────────────────────────
@test "canary-rings.json: pr-auto-review onboarded to canary; unmanaged block emptied" {
run jq -e '.agents["pr-auto-review"].host == "petry-projects/.github"' "$RINGS"
[ "$status" -eq 0 ]
run jq -e '.agents["pr-auto-review"].run_workflow == "PR Auto-Review — Ready Check"' "$RINGS"
[ "$status" -eq 0 ]
run bash -c "jq -r '.agents[\"pr-auto-review\"].rings | sort_by(.order) | map(.channel) | join(\",\")' '$RINGS'"

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

low

Avoid spawning an unnecessary subshell with bash -c in BATS tests. You can invoke jq directly within the run wrapper, which is cleaner, avoids complex quote escaping, and is more efficient. This aligns with the general practice of avoiding bash -c subshells in BATS tests.

  run jq -r '.agents["pr-auto-review"].rings | sort_by(.order) | map(.channel) | join(",")' "$RINGS"
References
  1. In BATS tests, avoid spawning a subshell with bash -c when the command can be invoked directly within the run wrapper.

[ "$output" = "next,ring0,ring1,stable" ]
# every reusable is now a managed agent — the unmanaged block holds nothing
run jq -e '(.unmanaged // {}) | length == 0' "$RINGS"
[ "$status" -eq 0 ]
}

@test "canary-rings.json: add-to-project onboarded to full ring model (#651)" {
run jq -e '.agents["add-to-project"].host == "petry-projects/.github"' "$RINGS"
[ "$status" -eq 0 ]
Expand Down
Loading