Skip to content

fix(workhub): preserve topic identity and remote conversation continuity - #6068

Merged
likun666661 merged 5 commits into
apache:mainfrom
ARE404:fix/workhub-remote-topic-continuity
Oct 11, 2026
Merged

likun666661 merged 5 commits into
apache:mainfrom
ARE404:fix/workhub-remote-topic-continuity

Conversation

@ARE404

@ARE404 ARE404 commented Oct 11, 2026 •

Copy link
Copy Markdown
Contributor

Summary

WorkHub could answer a follow-up such as “刚才到第几讲内容了?” in the right context but omit its work identity. Even a successful CS336 association lost its heading on an immediate WeChat reply. Modern tool-call transcripts could also leave delegated results without their originating remote chat.

  • Record topic association independently of execution. Require a successful association decision before other work, and retry missing decisions at the Runtime completion boundary (at most two repairs). Explicit unrelated/overview/ambiguous decisions avoid inheriting an unrelated work. This does not force delegation or guarantee semantic classification accuracy.
  • Restore result routing from modern task-call receipts, retain delivery deduplication across restart, and prefix every associated remote reply with its work name. Successful same-turn null association decisions clear prior topic attribution in both remote replies and the Desktop projection; failed or mismatched receipts cannot clear another turn. Existing delivered messages are not resent or relabeled.
  • Compact remote choices into lettered options with separate progress/next-step lines and nxt pagination. Keep one assistant voice across acknowledgments, execution, and returned results.

Verification

  • npm run build:test, npm run typecheck, npm run lint, and npm run format:check: passed.
  • Ten affected test files, including the complete AI SDK backend suite: 338 passed, 0 failed. Coverage includes topic prerequisites, prepared capability calls, direct-answer labels, remote routing/restart/deduplication, and picker answers.
  • CI architecture repair: place topic receipt parsing in the application contracts layer and consume the feature testing entry. Renderer architecture check passed against the CI base; desktop build/typecheck, lint/format, and 18 focused tests passed.
  • Runtime Host integration fixtures now complete topic association through Desktop capability receipts before replying, including cold recovery and Code Mode. Target immutability, capability ownership, and single-successor assertions remain in place. Both original failing tests pass locally.
  • CI run 38141796913 passed on 8603b3028, including all affected workspace tests, Runtime Host tests, and desktop E2E.
  • Additional local Node 24 run of the two complete integration files: 87/88 passed; the unchanged WorkHub steering/handoff test timed out locally. The complete Runtime Host suite passes in CI. A local Node 26 full-suite run encountered multiple timeouts and was stopped.
  • Review correction (e364f8afa): the three clearing-reason regressions failed with the stale SQL heading before the fix. Afterward all 161 Desktop WorkHub tests passed, including restart/paging, delivery deduplication, failed/mismatched receipts, cross-turn/chat isolation, and SQL-to-CS336 switching. Desktop main build, all four desktop typechecks, renderer architecture, changed-file lint, repository formatting, and diff checks passed.
  • Desktop review correction (2192ba537): fold validated topic decisions in transcript order per turn, removing superseded topic links while retaining actual delegation/result links. Five defect reproductions failed before the fix; afterward all 167 Desktop WorkHub tests passed. Desktop main build, all four desktop typechecks, renderer architecture, changed-file lint, repository formatting, and diff checks passed.
  • ASF header audit, git diff --check, and node scripts/protocol-epoch-check.mjs --base upstream/main: passed; no protocol epoch change required.
  • Native development instance: the omitted-subject lecture follow-up acquired CS336 labels without delegation; an unrelated question acquired no CS336 label. Live WeChat delivery state confirmed the reported reply already had a CS336 association; its heading was suppressed by the old timing condition. Rebuilt and restarted after fixing it. A fresh external WeChat delivery after that restart was not performed.

Remote transport regression evidence (work name abbreviated in the fixture):

Input: 刚才到第几讲内容了?
Before: 刚到第 2 讲。
After:  [CS336]
        刚到第 2 讲。

The new regression failed with the unprefixed reply before the fix and passed afterward. Full-repository tests and screenshot capture were not run; verification uses native accessibility state, durable runtime receipts, and transport output assertions.

AI use

  • No generative tool made a substantive contribution
  • Generative tooling made a substantive contribution

Tool(s) and scope: OpenAI Codex implemented the changes, regression tests, and validation. The commit includes Generated-by: OpenAI Codex.

Checklist

  • Tests cover the change and fail without it
  • Lint, format, typecheck and CI pass; local test limitations are recorded above

Does this PR entail a change in behavior?

  • Yes — described under Summary above
  • No

@github-actions github-actions Bot added the effort/L Under 1000 readable lines label Oct 11, 2026
Exercise Desktop association receipts before inspection replies and recovered-turn completion, including Code Mode. Preserve target immutability and recovery capability-binding assertions.

Generated-by: OpenAI Codex

@Astro-Han Astro-Han 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.

Automated review notice: This comment was posted by an automated review agent. It is not an independent human review and does not replace one.

I reviewed 8603b3028da39595c58455f74c69668bb63f0a1f, including the production Host fixture changes. I found one P2 issue: a successful decision to remove a topic association does not clear the remote reply's previous work heading.

The new associate operation records an existing work identity without starting execution. The Host blocks other work until a successful association decision, and the Runtime retries a tool-free response at most twice when that prerequisite is missing. The remote bridge reconstructs modern action routes, preserves delivery receipts while upgrading its saved state, and prefixes associated replies with the work name. I checked these paths, the receipt parser, the renderer's linked-work projection and the wn/nxt choice behavior.

P2 — Clear a previous heading when a later association is explicitly null (apps/desktop/src/main/workhub-remote-bridge.ts:127–130). In one turn, associate("sql") can succeed and then be corrected to associate(null, reason: "unrelated"); the schema, runtime and Host gate accept both calls. The bridge only handles string targets and ignores the successful null receipt, so the final unrelated answer still gets [SQL]. overview and ambiguous reproduce the same stale attribution. Using the real schema, actTasks, Host gate and bridge with local candidate/transport fixtures, I reproduced all three cases without starting any work. An isolated control that validates the corresponding null receipt and clears the saved target removes the incorrect heading while preserving ordinary association, SQL-to-CS336 switching and restart deduplication. Please handle successful clearing decisions explicitly and add a same-turn correction regression; error or mismatched receipts must not clear another turn's association.

The fresh dependency install and normal build:test passed. The complete AI SDK backend suite passed 258 tests; all 148 Desktop WorkHub tests and all 167 renderer-architecture tests passed, as did the four Desktop typechecks, the architecture check against the PR base, formatting and diff checks. The local Host group passed 122 of 123 tests; the managed-Bash test failed because this machine reports that its Linux command sandbox is unavailable. The same unchanged test also failed at the same assertion after rebuilding the actual merge base, 16f910168bd641572061bffd5511df3537a4cdca; I did not attribute that environment failure to this PR or describe the local Host group as fully green.

The exact-head CI run 38141796913 succeeded. This PR does not change a wire-protocol file or database schema. Its local merge with main 9a32d423b is clean, keeps main's epoch 217 and passes the epoch check; it does not allocate an epoch that could collide with another pending PR. CI success does not resolve the stale-heading issue. I did not exercise a live WeChat/QQ transport or provider, independently verify semantic topic classification, run the full monorepo suite or capture the native UI.

}
if (message.type === 'tool_result') {
const source = state.actions[clientCapabilityEntityId(message.toolUseId)];
const topic = source?.associationTargetSessionId && source.associationTurnId === message.turnId

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.

P2 — Clear the previous work heading on a successful null association. In one turn, associate can first succeed for SQL and later succeed with targetSessionId: null and reason: "unrelated" (or overview/ambiguous). workHubAssociationTarget returns only string targets, so this condition ignores the clearing receipt and leaves state.turns[turnId].targetSessionId pointing to SQL. The final unrelated remote answer is consequently sent as [SQL]\n.... I reproduced this through the real schema, actTasks, Host gate and bridge, without executing work; a control that validates the matching null receipt and clears the saved target fixes all three cases without breaking ordinary association, target switching or restart deduplication. Please explicitly apply clearing decisions and cover same-turn corrections; failed or mismatched receipts must not affect another turn.

Distinguish explicit null association decisions from absent receipts. Validate the matching successful receipt before clearing the turn target, preserving failed-call and cross-turn isolation. Cover all clearing reasons, restarts, deduplication, and topic switching.

Generated-by: OpenAI Codex

@chinawch007 chinawch007 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.

Automated review notice: This review was generated and posted by OpenAI Codex (AI) at the user's request. It is not an independent human review and does not replace one.

Reviewed 8603b3028da39595c58455f74c69668bb63f0a1f, including all 21 changed files and the surrounding Runtime, Host, transcript, and Desktop paths.

P2 — Explicit topic clearing must reach both remote and Desktop projections. I independently reproduced the existing remote-heading finding. There is also a Desktop manifestation in apps/desktop/src/renderer/features/workhub/model/linked-work.ts:63–70: after a successful SQL association followed by a successful null association in the same turn, workHubLinkedWork still returns the SQL link. The conversation uses those links for headings, rails, and work filtering. The inline comment identifies this additional repair location; fixing only the remote bridge would leave Desktop attribution stale.

My reproducer used the actual workHubTasksSchema, createWorkHubRuntime().actTasks, Host topic gate, remote bridge, and workHubLinkedWork, with fixture candidates and transport. For each of unrelated, overview, and ambiguous, both receipts succeeded, no work was dispatched, the remote answer retained [SQL], and Desktop retained ["SQL"]. Restart still deduplicated the delivered reply.

Verification performed

  • Installed the locked dependencies, applied the repository's dependency patches, and ran npm run build:test: passed.
  • Complete AI SDK backend and interactive-run-composer suites: 273 passed.
  • Remote bridge, remote choices, and topic association suites: 15 passed.
  • The changed production WorkHub inspection and cold-recovery integration tests: 2 passed.
  • Three additional reproduction cases confirmed the defect above; these are defect-confirmation checks, not passing fixes.
  • git diff --check: passed. Independently checked that exact-head CI run 38141796913 succeeded.

Required conclusions

  1. Optimal for the actual problem? Separating association from execution addresses the problem, but the association lifecycle is incomplete until explicit clearing updates both projections.
  2. Production code to delete? None identified.
  3. Low-quality tests to delete or replace? None identified. Add same-turn association-to-null regressions for both consumers; retain the positive-association and restart/deduplication coverage.
  4. Deeper refactor required? No broad refactor identified. Represent a valid clearing receipt distinctly from an invalid/missing receipt, and apply association decisions in order per turn while preserving genuine delegation/result links.
  5. Ready to merge? Not yet: the reproduced P2 remains unresolved. This automated conclusion is not an approval.
  6. Residual risks / verification gaps? I did not run the full monorepo suite, exercise live WeChat/QQ or a live model, or capture the native UI. Semantic topic selection remains model-dependent. This changes user-visible attribution and remote delivery behavior, so material changes require independent human review under CONTRIBUTING.md; a maintainer makes the final merge decision.

Comment on lines +63 to +66
if (message.type === 'tool_result') {
const call = associationCalls.get(message.toolUseId);
const topic = call?.turnId === message.turnId ? readWorkHubTopicAssociation(message, call.target) : undefined;
if (topic) return [{ id: message.id, coordinationTurnId: message.turnId,

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.

AI review — OpenAI Codex.

[P2] Apply explicit topic clearing to the Desktop projection

This is the Desktop counterpart of the existing remote-heading finding. In one turn, a successful associate("sql") followed by successful associate(null, reason: "unrelated") still makes workHubLinkedWork return the SQL link: this flatMap emits the earlier association and never retracts it, while the call parser drops null targets. I reproduced the same result for overview and ambiguous using actual schema/runtime receipts. The conversation therefore keeps the wrong heading, rail, and work-filter membership even if the remote bridge is fixed. Apply validated clearing decisions to the current per-turn association, preserving genuine delegation/result links, and cover this correction sequence in the Desktop projection test.

Retract superseded topic associations on Desktop, including explicit clearing decisions, while preserving durable delegation and result links. Cover correction sequences using actual tasks schema and runtime receipts.

Generated-by: OpenAI Codex
@likun666661
likun666661 merged commit 0a8e29d into apache:main Oct 11, 2026
1 check passed
@ARE404
ARE404 deleted the fix/workhub-remote-topic-continuity branch October 11, 2026 14:37
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

effort/L Under 1000 readable lines

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants