Skip to content

fix(orchestration): scope idle mail nag to the bound Run - #13564

Open
bbingz wants to merge 1 commit into
stablyai:mainfrom
bbingz:fix/13563-orchestration-nag-run-scope
Open

fix(orchestration): scope idle mail nag to the bound Run#13564
bbingz wants to merge 1 commit into
stablyai:mainfrom
bbingz:fix/13563-orchestration-nag-run-scope

Conversation

@bbingz

@bbingz bbingz commented Aug 10, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Idle push-on-idle mail pointers counted all undelivered messages for a terminal handle, so a pane bound to one Run could show a large N while check --peek for that Run was 0 (Bug: orchestration nag counts outside the session's bound Run #13563).
  • When the leaf has a current bound Run, only count terminal-handle rows with that run_id (Run mailboxes were already scoped via run:<id>).

Test plan

  • scopes the idle mail pointer count to the pane bound Run only
  • Manual multi-Run: bound Run peek=0 → no inflated nag for other Runs' terminal-addressed mail

Fixes #13563

Push-on-idle counted every undelivered row for the terminal handle, so a
multi-Run coordinator saw other Runs' mail in \"You have N orchestration
messages\". Filter terminal-handle nags to the pane's current bound Run.

Fixes stablyai#13563.
@coderabbitai

coderabbitai Bot commented Aug 10, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

Unread-message filtering now scopes non-Run mailboxes to the terminal pane’s bound Run. Reserved message types and messages with live waiters remain excluded. Test message construction accepts an optional runId, and coverage verifies that terminal pending-message counts exclude messages from other Runs.

🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (2 warnings)

Check name Status Explanation Resolution
Description check ⚠️ Warning The description explains the bug and test but omits required Screenshots, Testing, AI Review Report, Security Audit, and Notes sections. Add all required template sections, state No visual change where applicable, record validation results, and include AI cross-platform and security audit summaries.
Linked Issues check ⚠️ Warning The fix scopes terminal-handle counts to the bound Run, but the linked issue also requires unbound-session behavior and broader multi-Run regression coverage. Define and test behavior for sessions without a bound Run, and add coverage for messages in both the bound and another Run.
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly identifies the main change: scoping the orchestration idle-mail nag to the bound Run.
Out of Scope Changes check ✅ Passed The runtime change and regression test are directly related to correcting bound-Run orchestration nag counts.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

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.

Actionable comments posted: 2


ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: a005ab91-bb09-42d8-9400-e11349eb8597

📥 Commits

Reviewing files that changed from the base of the PR and between fb3a3c5 and 510cccf.

📒 Files selected for processing (2)
  • src/main/runtime/orca-runtime.test.ts
  • src/main/runtime/orca-runtime.ts

Comment on lines +34300 to +34343
it('scopes the idle mail pointer count to the pane bound Run only', async () => {
const runtime = new OrcaRuntimeService(store)
const db = new InMemoryOrchestrationMessages()
const write = vi.fn().mockReturnValue(true)
setInMemoryOrchestrationMessages(runtime, db)
runtime.setPtyController({
write,
kill: vi.fn(),
getForegroundProcess: async () => null
})
syncSinglePty(runtime)

const [terminal] = (await runtime.listTerminals()).terminals
db.setRun({
id: 'run_bound',
coordinator_handle: terminal.handle,
coordinator_pane_key: 'tab-1:pane:1'
})
runtime.onPtyData('pty-1', '\x1b]0;Codex done\x07', 101)
db.insertMessage({
from: 'sender',
to: terminal.handle,
subject: 'other run',
runId: 'run_other'
})
db.insertMessage({
from: 'sender',
to: terminal.handle,
subject: 'bound run',
runId: 'run_bound'
})

runtime.deliverPendingMessagesForHandle(terminal.handle)

expect(write).toHaveBeenCalledWith(
'pty-1',
expect.stringContaining('You have 1 orchestration message')
)
expect(write).not.toHaveBeenCalledWith(
'pty-1',
expect.stringContaining('You have 2 orchestration messages')
)
db.close()
})

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.

🗄️ Data Integrity & Integration | 🟡 Minor | ⚡ Quick win

Add regression cases for empty and unbound Runs.

This test covers one bound-Run message and one message from another Run. It does not verify that an empty bound Run produces zero messages or no nag. It also does not define or test behavior when the pane has no bound Run. Add focused cases for both conditions and assert the intended contract.

Comment on lines +31958 to +31979
// Why: a pane with a bound Run must only nag for that Run's mail. Counting every
// undelivered row for the terminal handle included other coordinators' Runs (#13563).
const boundRun = this._orchestrationDb.getCurrentRunForPane?.(`${leaf.tabId}:${leaf.leafId}`)
const unread = this._orchestrationDb
.getUndeliveredUnreadMessages(mailboxHandle)
.filter(
(message) =>
!options.reservedTypes?.has(message.type) &&
!messageTypeHasLiveWaiter(waiters, message.type)
)
.filter((message) => {
if (options.reservedTypes?.has(message.type)) {
return false
}
if (messageTypeHasLiveWaiter(waiters, message.type)) {
return false
}
if (
boundRun &&
!mailboxHandle.startsWith('run:') &&
message.run_id &&
message.run_id !== boundRun.id
) {
return false
}
return true
})

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.

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "Files matching orca-runtime:"
fd -i 'orca-runtime' . | sed 's#^\./##'

echo
echo "Git status concise:"
git status --short

echo
echo "Locate deliverPendingMessages and getCurrentRunForPane:"
rg -n "deliverPendingMessages|getCurrentRunForPane|getUndeliveredUnreadMessages|run_id|reservedTypes|Run" src/main/runtime/orca-runtime.ts | head -n 200

echo
echo "Segment around target lines:"
sed -n '31920,32010p' src/main/runtime/orca-runtime.ts | cat -n

echo
echo "Segment around getCurrentRunForPane definitions/usages in repository:"
rg -n "getCurrentRunForPane|getUndeliveredUnreadMessages|deliverPendingMessages" src -S

Repository: stablyai/orca

Length of output: 12688


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "Git status concise:"
git status --short

echo
echo "Locate target symbols:"
rg -n "deliverPendingMessages|getCurrentRunForPane|getUndeliveredUnreadMessages|run_id|reservedTypes|getCurrentRunForPane" src/main/runtime/orca-runtime.ts src/main/runtime/orca-runtime.test.ts src -S --glob '!src/main/runtime/orca-runtime.ts' | head -n 300

echo
echo "Segment around target lines in src/main/runtime/orca-runtime.ts:"
sed -n '31930,32000p' src/main/runtime/orca-runtime.ts | cat -n -v

echo
echo "Segment around getCurrentRunForPane definition if present:"
rg -n "getCurrentRunForPane|getUndeliveredUnreadMessages" src/main/runtime/orca-runtime.ts; sed -n '31600,31900p' src/main/runtime/orca-runtime.ts | cat -n -v

echo
echo "Behavioral probe: simulate filter from snippet with representative inputs"
python3 - <<'PY'
def filter_messages(messages, bound_run_id, mailbox):
    def messageTypeHasLiveWaiter(waiters, msg_type):
        # Placeholder: no live waiters in this probe.
        return False
    waiters = set()
    return [
        m for m in messages
        if (
            False if False else  # options.reservedTypes placeholder
            not messageTypeHasLiveWaiter(waiters, m["type"])
        ) and not (
            bound_run_id and
            not mailbox.startswith("run:") and
            m.get("run_id") and
            m["run_id"] != bound_run_id
        )
    ]

messages = [
    {"type": "mail", "run_id": "run-a"},
    {"type": "mail", "run_id": "run-b"},
    {"type": "mail"},
]
print("bound_run_id=run-a mailbox terminal:", filter_messages(messages, "run-a", "terminal:pane"))
print("bound_run_id=None mailbox terminal:", filter_messages(messages, None, "terminal:pane"))
print("bound_run_id=run-a mailbox run:", filter_messages(messages, "run-a", "run:mailbox"))
PY

Repository: stablyai/orca

Length of output: 50371


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "target deliverPendingMessages implementation:"
sed -n '31919,32025p' src/main/runtime/orca-runtime.ts | cat -n -v

echo
echo "orchestration-db getCurrentRunForPane/usages in src/main:"
rg -n "getCurrentRunForPane|getUndeliveredUnreadMessages|deliverPendingMessagesForHandle|deliverPendingMessagesForLeaf" src/main --glob '*.ts' --glob '!src/main/runtime/orca-runtime.ts'
echo
sed -n '30820,30895p' src/main/runtime/orca-runtime.ts | cat -n -v

echo
echo "test helpers around messages/runs:"
sed -n '1028,1135p' src/main/runtime/orca-runtime.test.ts | cat -n -v

echo
echo "focused tests around no-bound-run / run scoping in orchestration tests:"
sed -n '34268,34355p' src/main/runtime/orca-runtime.test.ts | cat -n -v -s || true
sed -n '39970,40135p' src/main/runtime/orca-runtime.test.ts | cat -n -v -s @@ -40580,40635p src/main/runtime/orca-runtime.test.ts | cat -n -v -s

Repository: stablyai/orca

Length of output: 28925


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "orchestration-current-run-for-pane tests:"
sed -n '34350,34400p' src/main/runtime/orca-runtime.test.ts | cat -n -v

echo
echo "run delivery getCurrentRunForPane tests:"
sed -n '235,285p' src/main/runtime/orchestration/orchestration-run-delivery-db.test.ts | cat -n -v

echo
echo "no-bound terminal deliverPendingMessages tests:"
python3 - <<'PY'
from pathlib import Path
p = Path("src/main/runtime/orca-runtime.test.ts")
text = p.read_text()
for i, line in enumerate(text.splitlines(), start=1):
    if "deliverPendingMessagesForHandle" in line and i > 34330 and i < 34375:
        print(f"\nNear context around line {i}:")
        for j in range(max(1,i-25), min(len(text.splitlines()), i+30)+1):
            print(f"{j:6}: {text.splitlines()[j-1]}")
PY

echo
echo "behavioral simulation of filter predicate:"
python3 - <<'PY'
messages = [
    {"type": "status", "run_id": "run-other"},
    {"type": "status"},
]
bound_run = None
mailbox_handle = "terminal:pane"
filtered = []
for message in messages:
    excluded = False
    if bound_run and not mailbox_handle.startswith("run:") and message.get("run_id") and message["run_id"] != bound_run["id"]:
        excluded = True
    if not excluded:
        filtered.append(message)
print("bound_run:", bound_run)
print("input_count:", len(messages), "filtered_count:", len(filtered), "count:", len(filtered))
print("filtered_ids:", [m.get("run_id") for m in filtered])
PY

Repository: stablyai/orca

Length of output: 6288


🏁 Script executed:

#!/bin/bash
set -euo pipefail

python3 - <<'PY'
from pathlib import Path
text = Path("src/main/runtime/orchestration/db.ts").read_text()
lines = text.splitlines()
for name, start in [("getCurrentRunForPane", 2440), ("getCurrentRunForPane", 2452), ("getUndeliveredUnreadMessages", 3490), ("getUndeliveredUnreadMessages", 3506)]:
    print(f"\n{name} at line {start}\n")
    for i in range(start, min(len(lines), start+120)+1):
        print(f"{i:6}: {lines[i-1]}")
PY

Repository: stablyai/orca

Length of output: 21620


Scope Run-tagged mail when no bound Run is available.

getCurrentRunForPane can return undefined for a pane, while getUndeliveredUnreadMessages still returns all undelivered rows for that handle. In that case, the filter does not exclude messages with another Run's run_id, so an unbound terminal can nag or wait for mail that belongs to a different Run. Skip those rows when boundRun is undefined too, unless the delivery contract explicitly supports DB-wide counting for unbound sessions.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Bug: orchestration nag counts outside the session's bound Run

1 participant