Skip to content

fix(meetings): strip the chat marker from the translation source (#6763) - #6927

Merged
iamwhatever merged 1 commit into
mainfrom
fix/meetings-chat-prefix-translation-6763
Aug 30, 2026
Merged

fix(meetings): strip the chat marker from the translation source (#6763)#6927
iamwhatever merged 1 commit into
mainfrom
fix/meetings-chat-prefix-translation-6763

Conversation

@chenmingwei23

@chenmingwei23 chenmingwei23 commented Aug 30, 2026

Copy link
Copy Markdown
Contributor

What is the problem?

In the Meetings app, typed/chat lines are dispatched with the internal [chat] marker prepended (handle_dispatch_text builds line = f"{k.CHAT_PREFIX} {transcript_text}" for typed input) so the meeting agents can tell typed input from speech. MeetingSession.broadcast passed that same prefixed line to TranslationQueue.enqueue, so the literal [chat] marker was persisted as the translation source and interpolated into the translation prompt. Flagged as a real, observable advisory by the Opus review of #5739.

Why this issue matters to the user

The TranslationSidebar's source column shows the raw internal marker in front of every typed line, and the marker is spent as translation-prompt tokens -- the model can echo it into the translated line. Separately, the code contradicted its own documentation: the in-code comment and docs/system-specs/modules/meetings.md both said translation happens from the dictionary-corrected text, but the code enqueued the raw line.

What changed

One call site, MeetingSession.broadcast (the app's only translations.enqueue caller): the translation source now strips a leading, whitespace-bounded CHAT_PREFIX from the RAW line first, then runs the same dictionary-correct/clamp/noise pipeline the agents get (_prepare_line). Stripping before the clamp means a max-length typed message is capped on its payload rather than losing its final characters to the marker (found by the GPT review lane on the first head).

  • The strip is anchored: only a bare marker or [chat] ... counts as agent context. A mid-line occurrence (quoted speech) and marker-like speech ([chat]room availability...) reach translation verbatim.
  • The agent-broadcast line and the stored transcript are byte-identical to before -- the marker still reaches the agents, whose prompts rely on it.
  • Correcting the clean payload also makes the code match the pre-existing comment and module-spec claim that translation happens from the corrected text. One consequence, now documented in the spec: typed filler ("ok") falls under the same noise gate as spoken filler and is dropped from the translation panel only (agents and transcript still get it).
  • Spec updated in the same commit (docs/system-specs/modules/meetings.md, Live translation section).

Tests

  • test_broadcast_strips_chat_prefix_from_the_translation_source: a [chat]-prefixed dispatch produces a clean translation source while the note-taker queue keeps the prefixed line. Mutation-verified: red on base behavior, green with the fix.
  • test_broadcast_strips_only_the_anchored_marker: mid-line marker survives, glued marker-like speech survives, a bare marker strips to empty (dropped by the queue's blank filter, no empty translation row).
  • test_broadcast_translates_the_dictionary_corrected_speech_line: a speech line's translation source is the corrected text. Also red on base (base enqueued the raw line).
  • test_a_max_length_typed_line_keeps_its_full_payload_in_translation: a MAX_TRANSCRIPT_CHARS typed payload survives intact -- red on the strip-after-clamp variant.
  • Local gates: isort/flake8/mypy clean on touched files; black diff-gate green; meetings suites 338 passed; full backend pytest 7490 passed with 5 failures in test_artifact_source.py proven env-owned (identical failures on clean base ba65da1e8 -- host home-dir layout).
  • Pre-push review fleet: two model-pinned reviewers, both NO BLOCKING; all four Low advisories dispositioned (anchored match + negative tests folded in; truncation-at-ceiling accepted as now-consistent-with-agents; dictionary-can-mangle-the-marker is pre-existing on base for the agent line and kept out of scope).

Any other suggestions on the work

Pre-existing, out of scope here: a domain-dictionary term with alias "chat" can rewrite the marker itself (e.g. [chat] -> [Chat]) before the strip runs -- on base the same rewrite already corrupts the marker on the agent line, which is the larger half of that problem. Tracked locally for its own issue; the fix belongs at _prepare_line (correct only the payload).

Closes #6763

@github-actions

github-actions Bot commented Aug 30, 2026

Copy link
Copy Markdown
Contributor

Design Review (Fable 5) — ✅ PASS

Design-level review of 9ca42c758095237780550060f9d24279116bd9ae — updated in place on each push. A BLOCK verdict blocks PR readiness; PASS/CONCERNS are advisory.

Design-Verdict: PASS

One anchored strip at the single enqueue seam, agent/transcript bytes untouched, spec updated in-commit — real harm, minimal and proportionate fix.

[DESIGN-REVIEWED] 9ca42c7

@github-actions

github-actions Bot commented Aug 30, 2026

Copy link
Copy Markdown
Contributor

Opus 4.8 Review — ✅ no blocking findings

Reviewed 9ca42c758095237780550060f9d24279116bd9ae — this comment is updated in place on each push.

Review details

No findings.

[OPUS-REVIEWED] 9ca42c7

Verdict parsed from the review's SHA-scoped output markers for commit 9ca42c758095237780550060f9d24279116bd9ae.

False positive or not applicable? A repository writer can comment:
/ai-review override fable 9ca42c758095237780550060f9d24279116bd9ae: <one-sentence reason>

@github-actions

github-actions Bot commented Aug 30, 2026

Copy link
Copy Markdown
Contributor

GPT 5.6 Review — ✅ no blocking findings

GPT 5.6 completed its review of 9ca42c758095237780550060f9d24279116bd9ae and found no blocking issues.

This comment is updated in place on each push.

Review details

No findings.
[GPT-REVIEWED] 9ca42c7

False positive or not applicable? A repository writer can comment:
/ai-review override gpt 9ca42c758095237780550060f9d24279116bd9ae: <one-sentence reason>

@github-actions github-actions Bot added readiness: action required A blocking check or review needs attention and removed readiness: checking Automated validation is still running labels Aug 30, 2026
@github-actions

github-actions Bot commented Aug 30, 2026

Copy link
Copy Markdown
Contributor

First Principles Review (Fable 5) — ✅ PASS

Premise-level review of 9ca42c758095237780550060f9d24279116bd9ae — why this exists and whether the shipped surface is the smallest honest version. Updated in place on each push. A BLOCK verdict blocks PR readiness; PASS/CONCERNS are advisory.

All claims verified. The change is fully declared, the single translations.enqueue caller is real (count: 1), no existing strip mechanism exists elsewhere (frontend and backend greps: prepend sites only), and the deferred root cause is named in the description itself. One useful depth note: _record_line already carries is_chat out-of-band (agents.py:313, stored as TRANSCRIPT_SOURCE_TYPED), so the marker-parsing heuristic exists only because chat-ness is erased into the string between the route and broadcast — the author defers exactly this, correctly, since fixing it changes agent-visible bytes they deliberately froze.

First-Principles-Verdict: PASS

A reported defect fixed at its mechanism, in the one call site that has it, with the residual cause named and deferred rather than hidden.

What this change ships

Intent: typed meeting-chat lines stop showing the internal [chat] marker in the translation panel and its prompt — a FIX.

  1. Translation source column no longer shows [chat] before typed lines — justified (defect fix(meetings): chat prefix leaks into translation source and prompt for typed lines #6763, flagged in review of feat(meetings): translate the transcript line by line #5739).
  2. Speech now translates from dictionary-corrected text, as the pre-existing comment and spec already claimed — justified (documented invariant).
  3. Typed filler ("ok") no longer reaches the translation panel — declared consequence, spec updated same commit.
  4. A bare [chat] line yields no empty translation row — justified edge of item 1 (queue blank filter, translate.py:184).
  5. Spec section updated in the same commit — mandated by AGENTS.md.

Watch

The strip is a parse-back heuristic only because chat-ness is flattened into the string at _record_line (routes/agents.py:337) — yet that same function already carries is_chat out-of-band for the transcript (TRANSCRIPT_SOURCE_TYPED, line 327), and broadcast has exactly one caller (grep \.broadcast\(: agents.py:395) which holds the boolean. The description defers this cause ("the fix belongs at _prepare_line"); when the tracked follow-up runs, threading is_chat through the one call site is smaller than it looks and retires the heuristic, the dictionary-mangles-the-marker sibling, and the agent-line clamp charge together.

[FIRST-PRINCIPLES-REVIEWED] 9ca42c7

Typed/chat lines are broadcast with the internal [chat] marker prepended so
the meeting agents can tell typed input from speech. The same prefixed line
flowed into TranslationQueue.enqueue, so the literal marker was spent as
translation-prompt tokens and surfaced in the TranslationSidebar's source
column. The stored transcript was never affected.

MeetingSession.broadcast now derives the translation source from the raw
line with a leading, whitespace-bounded CHAT_PREFIX stripped BEFORE
dictionary correction and the transcript-length cap run, so a max-length
typed message is capped on its payload rather than losing its tail to the
marker's characters. This also makes the code match what its own comment
and the module spec already documented (translation from the corrected
text). The agent-broadcast line and the stored transcript are
byte-identical to before. One consequence: typed filler ("ok") now falls
under the same noise gate as spoken filler and is dropped from the
translation panel only.

Closes #6763
@chenmingwei23
chenmingwei23 force-pushed the fix/meetings-chat-prefix-translation-6763 branch from 23ea2a1 to 9ca42c7 Compare August 30, 2026 05:25
@github-actions github-actions Bot added readiness: checking Automated validation is still running and removed readiness: action required A blocking check or review needs attention labels Aug 30, 2026
@chenmingwei23

Copy link
Copy Markdown
Contributor Author

Disposition of the GPT 5.6 blocking finding on 23ea2a1 (max-length typed lines lose their final seven characters in translation): FIXED in 9ca42c7, using the finding's own remedy -- the marker is now stripped from the raw line before dictionary correction and the transcript-length cap, so the cap is charged against the payload. New regression test test_a_max_length_typed_line_keeps_its_full_payload_in_translation is red on the strip-after-clamp variant and green on this head. All review lanes re-run on the new head.

@github-actions github-actions Bot added readiness: action required A blocking check or review needs attention readiness: checking Automated validation is still running readiness: passed Eligible automated validation passed for the current revision and removed readiness: checking Automated validation is still running readiness: action required A blocking check or review needs attention labels Aug 30, 2026
@chenmingwei23

Copy link
Copy Markdown
Contributor Author

Disposition of the First Principles Watch note (thread is_chat out-of-band through broadcast's single caller instead of the parse-back heuristic): accepted-and-deferred into the same tracked follow-up as the dictionary-mangles-the-marker class -- the FP observation that one is_chat parameter retires the heuristic, the dictionary sibling, and the agent-line clamp charge together is recorded with it. Kept out of this PR because it changes agent-visible bytes this PR deliberately freezes.

Review-ready summary for head 9ca42c7: all CI checks green (flaky test_cli_logging shard rerun green, zero overlap with this diff), CodeQL success, PR Readiness success, and all five review lanes clean on this head (GPT + Opus no blocking, Design PASS, First Principles PASS, UX pass). One fix round: GPT's blocking max-length-tail-loss finding on the first head was fixed with its own remedy (strip before correct/clamp) plus a mutation-verified ceiling test. Merge is the maintainer's call.

@bolichen97 bolichen97 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Tier 1 auto-approve: fix (3 files). Criteria: no conflict, no requested changes, security path denylist clean, design-doc gate clean, SAST annotations clean, security checklist all-NO, AI reviewers green. Category: strips the [chat] agent-context marker from the translation source before enqueue so it is not translated or surfaced in the panel source column (clear root cause). Spec files changed as a ride-along (a minority of the diff on both file count and changed lines), not reviewed as a design decision: docs/system-specs/modules/meetings.md.

@iamwhatever
iamwhatever merged commit dbc8a6e into main Aug 30, 2026
113 of 117 checks passed

@iamwhatever iamwhatever left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Tier 1 auto-approve: fix (3 files). Criteria: no conflict, no requested changes, security path denylist clean, design-doc gate clean, SAST annotations clean, security checklist all-NO, AI reviewers green. Category: single root cause -- the CHAT_PREFIX marker is agent context rather than speech, so enqueueing the raw line sent it to translation and surfaced the literal marker in the source column; the fix strips the marker from the raw line before correction and the length cap. Spec files changed as a ride-along (a minority of the diff on both file count and changed lines), not reviewed as a design decision: docs/system-specs/modules/meetings.md.

@iamwhatever
iamwhatever deleted the fix/meetings-chat-prefix-translation-6763 branch August 30, 2026 07:07
@github-actions github-actions Bot removed the readiness: passed Eligible automated validation passed for the current revision label Aug 30, 2026

@bolichen97 bolichen97 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Tier 1 auto-approve: fix (3 files). Criteria: no conflict, no requested changes, security path denylist clean, design-doc gate clean, SAST annotations clean, security checklist all-NO, AI reviewers green. Category: clear root cause -- MeetingSession.broadcast passed the [chat]-prefixed line to TranslationQueue.enqueue, persisting the internal marker into translations; the fix strips it at the enqueue boundary. Spec files changed as a ride-along (a minority of the diff on both file count and changed lines), not reviewed as a design decision: docs/system-specs/modules/meetings.md. [Note: the auto-merge arm is denied by this cron agent's permission posture; merge deferred to a human maintainer.]

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.

fix(meetings): chat prefix leaks into translation source and prompt for typed lines

3 participants