Skip to content

fix(server): a link card stops asking once anyone writes past it - #32473

Open
eyeveil wants to merge 2 commits into
pingdotgg:mainfrom
eyeveil:fix/link-card-agent-messages-upstream
Open

eyeveil wants to merge 2 commits into
pingdotgg:mainfrom
eyeveil:fix/link-card-agent-messages-upstream

Conversation

@eyeveil

@eyeveil eyeveil commented Nov 7, 2026

Copy link
Copy Markdown
Contributor

Problem

When an agent calls t3_environment_link, its link card marks the thread as waiting for input. #28491 made the card stop counting once the user writes in the thread again, but it counts only messages with createdBy: "user". Threads that agents drive, through subagent notifications, coordination messages from other threads, or a thread started over MCP, may never get one. They stay on Input for good while every pending-request list is empty.

To reproduce, have an agent ask for a link and end its turn. Then start another turn with an agent-authored message, for example t3 thread send. The thread finishes but still shows Input, and t3 thread show reports pendingRequestCount: 0. In the thread where this surfaced, a card asked 53 runs earlier kept the thread on Input. A watcher keyed on that status also re-reported "asks a question" on every new run.

Change

The card now stops counting once any user-role message newer than it arrives, whoever sent it. Idle compactions still don't count. Both shell paths (threadShellFromProjection and the SQL shell row) and the auto-settle query from #29847 use the same rule. A thread that reads as done can therefore also settle. The card stays pending and answerable in the timeline. Secret cards are unchanged.

Scope and approval

This is a very small, focused fix for an obvious bug. It finishes the rule #28491 introduced for threads that no person types into, and it changes one comparison in three places that must agree. It is server-only. Web, desktop, and mobile read pendingRuntimeRequest from the shell, so they pick it up with no client changes. #26944 is related but separate. It ends a card after a matching retry links, and in this case no retry happened.

Verification

  • The existing the agent asks without waiting… case in PeerLinkRequests.test.ts now writes an agent-authored message past the card. On main it fails with expected { …(4) } to be null at the shell assertion. With the fix, it passes, and the settlement assertion after it passes too.
  • PeerLinkRequests.test.ts, ProjectionSettlement.test.ts, and ThreadSettlementService.test.ts pass 58/58.
  • On a dev server with fixture data, a thread had a waiting card and then a turn started by an agent message. Before the fix, the sidebar showed Input. After it, the sidebar shows Done.
  • Not checked: a real link flow between two machines. The test drives the real PeerLinkRequests service against a served peer.
Before After
Sidebar shows Input Sidebar shows Done

Moved from #32470, which came from an organization-owned fork that maintainers can't push to. This copy comes from a personal fork with maintainer edits allowed.

Model and harness: Claude Opus 5.5 (lead, implementation) via Claude Code in T3 Code.

@github-actions github-actions Bot added vouch:unvouched PR author is not yet trusted in the VOUCHED list. size:M 30-99 changed lines (additions + deletions). labels Nov 7, 2026
@macroscopeapp

macroscopeapp Bot commented Nov 7, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Approved at e0aa293

Macroscope's review found this PR approvable — Link cards stop keeping a thread on Input after a newer agent-authored user-role message, matching the existing behavior for human messages. Cards remain answerable, and existing settlement safeguards are unchanged.

You can add or adjust custom eligibility rules. Learn more.

@coderabbitai

coderabbitai Bot commented Nov 7, 2026

Copy link
Copy Markdown
Contributor

Explain Change →

No actionable comments were generated in the recent review.

Walkthrough

Link-request waiting checks now use the latest non-idle-compaction user-role message, regardless of its author. The shell and settlement-candidate query use this rule. Secret-request waiting behavior is unchanged.

Changes: Link-request waiting state

Layer / File(s) Summary
Update link-request waiting checks
apps/server/src/orchestration-v2/ProjectionStore.ts, apps/server/src/peer/PeerLinkRequests.test.ts
The projection shell and settlement-candidate query use the latest qualifying user-role message when checking whether a link card still asks for input. The test covers a subsequent agent-authored message and leaves the card answerable.

Estimated code review effort: 2 (Simple) | ~10 minutes

Change: Bug fix

Possibly related issues

  • pingdotgg/t3code#28384: The change updates when a link-request card counts as waiting after a thread message, but it does not close or resolve the card.

Suggested reviewers: georgenijo

Merge Risk: Minimal · up to e0aa2

Later user-role activity clears the link card’s Input status. No actionable merge-blocking risk was identified.

Pre-merge checks: Passed 4

Check name Status Explanation
Title check Passed The title clearly describes the link card waiting-state fix.
Description check Passed The description covers the problem, change, scope, and verification. It also identifies the unchecked real link flow and provides before-and-after images.
Linked Issues check Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check Passed Check skipped because no linked issues were found for this pull request.
Finishing Touches

Generate unit tests (beta)

  • Create a new PR
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Tip

🎯 Customize your risk assessments

Guide how CodeRabbit assesses merge risk and security architecture risk. Highlight sensitive changes and explain your security boundaries using Merge Risk Instructions and Security Risk Instructions in your review settings. Security architecture risk assessments require the Advanced plan or above.

✅ Automatic approvals, with your rules

Let CodeRabbit approve pull requests once required threads are resolved, pre-merge checks pass, and your risk limits are met. Enable Automatic approvals in review settings, with overrides for teams or file paths.

Recent review info

Run configuration

Commits

Reviewing files that changed from the base of the PR and between e455200 and e0aa293.

Files selected for processing: 2

  • apps/server/src/orchestration-v2/ProjectionStore.ts
  • apps/server/src/peer/PeerLinkRequests.test.ts

Included review availability: This review used your included allowance. Your plan provides up to 10 included reviews per hour; 8 remain after this review.

@Wladefant Wladefant left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Refs Wladefant/superboard#1477 #1773 #1778 #1798 #1899 #2233; #32473 — bounded separate nonauthor status/reconciliation review, 7 Nov 2026 UTC

Verdict: APPROVED for the source correction at exact e0aa293590aaf565a41d33a645b351921431daf1 (OPEN, unmerged, original author eyeveil). Reviewing GitHub principal Wladefant differs from source author; review is separate under the current #1899 same-family allowance. This does not authorize upstream merge, installed runtime, changed operator session, fleet watcher cutover, or physical peer-link acceptance.

Concrete source contract: Previously, a pending link card remained in the shell's Input state when a later user-role message was agent-authored (createdBy=agent, e.g. t3 thread send), despite zero pending requests; a fleet watcher could repeatedly report a question. The two-file patch consistently uses the latest non-idle-compaction user-role message regardless of creator in (a) projection shell, (b) SQL shell pending-link query and (c) settlement-candidate filtering. Secret-card and actual pending-runtime-request ownership are unchanged. The existing real PeerLinkRequests fixture now advances via an agent-created user-role message and verifies the shell card no longer blocks and settlement becomes eligible. No additional P1/P2 was demonstrated in the bounded source patch. A later unrelated agent-authored user-role message may intentionally count as “moved past”; this is the explicit semantics of the proposed change, not proof that the actual link request was fulfilled.

Actual exact-head workflow: normally triggered CI #42376250124 COMPLETE/SUCCESS. Original server shard job logs checked out synthetic merge 972e01d explicitly containing the exact candidate merged into e455200077ce60806a01c8f28435b58860dcfc74. Original changed PeerLinkRequests.test.ts ran 19/19 PASS (Test Server 2 job #128414316965); ProjectionSettlement.test.ts 5/5 PASS (Test Server 3 #128414316991); ThreadSettlementService.test.ts 34/34 PASS (Test Server 6 #128414316805), 58/58 across the three selected suites. Lint, 8 server shards, Test, Build/Typecheck and aggregate Check succeeded; Agent Context Budget #42376250031 succeeded. Test Web, Rust, Release Smoke and Mobile Native Static Analysis SKIPPED. No live two-machine peer flow or installed T3 watcher measured. Commit-workflow lookup is PR-event first-page limited; this is not a claimed complete all-event run inventory.

Next custody: original eyeveil/T3 maintainers handle protected source merge, then original Superboard #1773 fleet-watch owner checks selected pinned revision and t3 thread show/thread-shell status under authorized pilot fixture. Do not automatically restart operators, replay uncertain work or replace a working route to adopt this change. This approval is source-level only; #1773/#1778 fleet integration and human browser control remain open.

This branch has not been deployed

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

Labels

size:M 30-99 changed lines (additions + deletions). vouch:unvouched PR author is not yet trusted in the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants