diff --git a/apps/decodex/src/orchestrator/operator_dashboard.html b/apps/decodex/src/orchestrator/operator_dashboard.html
index 6f3c3b9f..3169f1c7 100644
--- a/apps/decodex/src/orchestrator/operator_dashboard.html
+++ b/apps/decodex/src/orchestrator/operator_dashboard.html
@@ -7490,12 +7490,21 @@
Run History
const historyRuns = sessionHistoryRuns(snapshot);
const postReviewLanes = snapshot?.post_review_lanes ?? [];
const postReviewIssueKeys = new Set(postReviewLanes.flatMap(issueIdentityKeys));
- const activeRunByIssue = new Map(activeRuns.map((run) => [run.issue_id, run]));
+ const activeRunByIssue = new Map();
+ for (const run of activeRuns) {
+ for (const key of issueIdentityKeys(run)) {
+ if (!activeRunByIssue.has(key)) {
+ activeRunByIssue.set(key, run);
+ }
+ }
+ }
const queuedCandidates = [...(snapshot?.queued_candidates ?? [])]
.map((candidate) => {
- const activeRun = activeRunByIssue.get(candidate.issue_id);
+ const activeRun = issueIdentityKeys(candidate)
+ .map((key) => activeRunByIssue.get(key))
+ .find(Boolean);
- if (activeRun && candidate.classification === "claimed") {
+ if (activeRun) {
return {
...candidate,
display_classification: "owned_active",
@@ -7509,7 +7518,6 @@ Run History
const queueBacklogCandidates = queuedCandidates.filter(
(candidate) =>
candidate.display_classification !== "owned_active" &&
- candidate.classification !== "claimed" &&
candidate.classification !== "closed" &&
!issueMatchesKeySet(candidate, postReviewIssueKeys),
);
diff --git a/apps/decodex/src/orchestrator/tests/operator/status/dashboard.rs b/apps/decodex/src/orchestrator/tests/operator/status/dashboard.rs
index de943011..295e0c8e 100644
--- a/apps/decodex/src/orchestrator/tests/operator/status/dashboard.rs
+++ b/apps/decodex/src/orchestrator/tests/operator/status/dashboard.rs
@@ -1319,7 +1319,6 @@ fn operator_dashboard_flow_counts_distinguish_intake_attention() {
assert!(response.contains("intakeAttentionCount"));
assert!(response.contains("queuedBlockedWithoutAttention"));
assert!(response.contains("attention.thread_status && attention.thread_status !== \"systemError\""));
- assert!(response.contains("candidate.classification !== \"claimed\""));
assert!(response.contains("queueBacklogCandidates.filter(queuedCandidateNeedsAttention).length"));
assert!(response.contains(
"${pluralize(derived.postReviewLanes.length, \"PR\")} ยท ${pluralize(derived.reviewBlockerCount, \"needs attention\", \"need attention\")}"
@@ -1335,6 +1334,18 @@ fn operator_dashboard_flow_counts_distinguish_intake_attention() {
assert!(!response.contains("const repairCount = attentionItems.length;"));
}
+#[test]
+fn operator_dashboard_does_not_hide_claimed_queue_without_local_lane() {
+ let response = dashboard_response();
+
+ assert!(response.contains("const activeRunByIssue = new Map();"));
+ assert!(response.contains("for (const key of issueIdentityKeys(run))"));
+ assert!(response.contains("const activeRun = issueIdentityKeys(candidate)"));
+ assert!(response.contains("if (activeRun) {"));
+ assert!(!response.contains("activeRun && candidate.classification === \"claimed\""));
+ assert!(!response.contains("candidate.classification !== \"claimed\" &&"));
+}
+
#[test]
fn operator_dashboard_prioritizes_needs_attention_reason_over_retry_count() {
let response = dashboard_response();