fix(run-hardening): park the workforce on a session-limit + PR-review verdict colour (#249)

* fix(orchestrator): park the provider on a Claude session-limit 429, not crash-loop

When the org Claude usage ("5-hour") session limit is hit, an agent container
exits non-zero with a 0-token 429 rejection. The provider-unavailable break only
recognized 5xx overload signatures (529/500/503), so a session-limit crash fell
through to the normal crash-retry path — the orchestrator respawned the agent
straight back into the limit, fleet-wide, until the window reset.

Add a sibling detector _provider_rate_limit_park_target that matches the
session-limit markers ("hit your session limit", "five_hour") in the dead
container's output and parks the provider with kind="rate_limited" (a longer
probe cadence), checked before the overload path in _handle_stopped_container.
Reuses the existing park-and-probe machinery, so the background probe loop
revives the parked tasks when the quota resets — no churn. Gated by the same
overload_break_enabled flag.

Also backfills the CHANGELOG Fixed entry for the orchestrator self-call auth fix
(merged in #248 without one).

* fix(panel): PR Reviewer Notes card colour reflects the verdict

The card was hardcoded teal/green regardless of the review verdict, so a Failed
review sat inside a green card and read as passing at a glance. Derive the card
background from the verdict (red on failed, green on approved/passed, amber on
changes-requested, neutral teal before a verdict) — mirroring the QA Notes card.

---------

Co-authored-by: Renn F <rennf93@users.noreply.github.com>
This commit is contained in:
Renzo F
2026-06-24 03:20:14 +02:00
committed by GitHub
co-authored by Renn F
parent 889f3689e7
commit 40d685bd9f
4 changed files with 180 additions and 1 deletions
@@ -61,6 +61,30 @@ function prReviewBadge(task: Task): React.ReactNode {
return <Badge className={`ml-2 ${v.cls} text-white`}>{v.label}</Badge>;
}
// The card background mirrors the PR reviewer's verdict, so a FAILED review reads
// as red — not the neutral teal that made a failure look green/passing at a glance.
function prReviewCardBg(task: Task): string {
const verdict = (
task.notes_structured as
| { pr_review?: { verdict?: string } }
| null
| undefined
)?.pr_review?.verdict;
const map: Record<string, string> = {
approved:
"bg-green-50 dark:bg-green-950 border border-green-200 dark:border-green-800",
passed:
"bg-green-50 dark:bg-green-950 border border-green-200 dark:border-green-800",
changes_requested:
"bg-amber-50 dark:bg-amber-950 border border-amber-200 dark:border-amber-800",
failed: "bg-red-50 dark:bg-red-950 border border-red-200 dark:border-red-800",
};
return (
(verdict ? map[verdict] : undefined) ??
"bg-teal-50 dark:bg-teal-950 border border-teal-200 dark:border-teal-800"
);
}
interface NoteCardProps {
task: Task;
field: NoteField;
@@ -332,7 +356,7 @@ export function TabNotes({ task }: TabNotesProps) {
title="PR Reviewer Notes"
icon={<GitPullRequest className="h-5 w-5" />}
badge={prReviewBadge(task)}
bgClass="bg-teal-50 dark:bg-teal-950 border border-teal-200 dark:border-teal-800"
bgClass={prReviewCardBg(task)}
/>
{/* Auditor Notes */}