You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
同伴会话的消息收成一条可执行规则。origin=user 但正文以 Another Claude session sent a message: 开头、随后是 <teammate-message teammate_id="…"> 的,是别的 CC 会话发进这条泳道的消息(多 agent 协作时的空闲通知与审查汇报),不是真人,也不是子代理泳道里的 [派生指令],而它照样占一个轮号。实测样本:9287e1ca 会话 46 条 [用户] 行里 28 条属于这类。此前这条判据散在多处,观察者按 [用户] 读会把子代理汇报当成用户的新要求,凭空造出目标变化。
变更
A→G 图把 G 和 T 的层级画出来(issue 260912_AG图G与T视觉层级)。用户反馈「界面挺好看,但 G 和 T 一眼看上去不能区分」。此前 G 段头是一条顶线加 11px 小标签,T 段头是一条左线加 11px 小标签,两者只差边框方向和 10px 缩进,而下属的 T 卡片是全场最重的元素——层级是反的。现在每个 G 段有自己的底衬(主色淡雾 + 描边 + 顶线),把属于它的 T 全圈进去,「谁属于谁」直接可见;G 的编号做成实心徽标,标题提到 15px;T 的编号改成描边 chip、标题回到常规字重。颜色全部由 --ag-key / --brand-ink 经 color-mix 派生,不新增主题 token。底衬不能用负 z-index:.ag-canvas 自己有背景且不构成层叠上下文,负层级会退到更外层被画布背景整个盖住(实测完全不可见),改为插在连线 svg 之前靠 DOM 顺序压底;段高取决于本段 T 排完后的位置,先渲染再回填。
两处浏览器探针断言修正。observe_goal_browser.cjs 里「页面正文逐字包含 current.understanding」改为去掉空白后比对:分条渲染加的只是空白,不改一个字,这样反而更贴合它要守的「页面不篡改观察者写的内容」。另一处 [data-om-action="goal-anchor"] 在 strict 模式下命中两个元素——首个 G 段没有显式目标变化可指时,段头自 260909 起就与 A 卡片共用这个 action,与本次改动无关,只是这个手动探针本机从没跑起来过(缺 playwright)所以一直没暴露;改为 .ag-anchor [data-om-action="goal-anchor"]。
English
Added
Recordings that arrive today now announce themselves while you are looking at an older date (issue 260912). If the user switched to a past date before starting a recording, today's captures were dropped wholesale by flushSSE: checkDayRollover() only switches when the user was already on today (the 260801 rule: never take away a date the user chose deliberately), and today's chip would not even appear, because dates_available is refreshed only by fetchCaptures. The only way out was to remember to switch by hand. Now the batch is counted before it is dropped: today joins the date bar, a pending count is kept (deduplicated by id), that chip shows a badge and highlights, and one click switches over and clears it. The no-stealing-focus rule stays, and neither the list nor total is polluted — that is where the 260712 phantom "load more" came from. No polling and no request was added: captures already arrive over SSE, so the data was in hand and the cost is zero.
Fixed
The ×N count swatch on the timeline failed contrast in all three appearances (issue 260912). Lane colour #A66B13 has luminance 0.186, right in the middle: white text scores 4.44 and black 4.18, so neither text colour clears 4.5, while fgOnHex() only ever picks one of the two and the result stays below the bar. The new inkBg() keeps the hue and darkens step by step until white text passes, and the swatch uses it. Lanes are recognised by hue, so darkening costs nothing, and the lane palette itself — shared with the wires and the legend — is untouched; fgOnHex lost its last caller and was removed. The same treatment applies to the sub-agent badge on turn cards. This one surfaced only by running contrast_probe.js per view; looking at the page was not enough.
Documentation
The observer prompt gains criteria and a worked example for goal (issue 260912). The top-level instruction in AI_USAGE.md defined only refinement (refine) and turn (turn); goal had a single sentence — "the overall goal itself changed" — buried in the contract below with no example at all, and the same passage warned in one direction only ("do not record starting another piece of work as a changed goal"). Why: on another machine, an observer running A→G on 0.4.34 met a user who had not stated the real purpose and whose requests jumped repeatedly — trim the CHANGELOG → change the workspace rules → delete test material → merge sections → delete packaging docs → reorganise issues → prepare for the prototype phase. The observer compressed all of it into one overall goal and recorded goal only at the end; after the user pushed back it took two rebuild_goal_flow passes to get it right, ending at three goal entries. Changes: all three kinds of change now sit side by side in the top instruction with definitions, trigger signals and a worked example; the criteria became a two-way table (what is not a goal / what really is one); the letter "G" is reserved for the overall goal, with the task level always called T; recording a goal now requires one line in the trigger saying why it is a goal and not a turn — the two have identical structural conditions, and being unable to write that line usually means it is a turn; a new ninth rule makes "the overall goal has not formed yet" a recordable state instead of forcing a guess between two failing criteria; and mode gains a one-line test. API契约.md follows the same wording.
Messages from a teammate session became one executable rule. A line with origin=user whose body starts with Another Claude session sent a message: followed by <teammate-message teammate_id="…"> comes from another CC session on the same lane — idle notices and review reports during multi-agent work. It is not the human, nor the [派生指令] of a sub-agent lane, and it still occupies a turn number. Measured sample: 28 of the 46 [用户] lines in session 9287e1ca. The criterion used to be scattered, so an observer reading [用户] at face value would take a sub-agent's report for a new user request and invent a goal change.
Changed
The A→G diagram now draws the difference between G and T (issue 260912). User feedback: "the interface looks good, but G and T cannot be told apart at a glance." A G heading was a top rule plus an 11px label; a T heading was a left rule plus an 11px label — they differed by which side the border sat on and 10px of indent, while the T cards below them were the heaviest elements on screen. The hierarchy was upside down. Each G section now sits in its own band (tinted wash, hairline, top rule) enclosing its T sections, so membership is visible instead of read; the G number became a solid badge and its title moved up to 15px, while the T number became an outlined chip with a regular-weight title. Every colour derives from --ag-key / --brand-ink through color-mix, so no theme token was added. The band cannot use a negative z-index: .ag-canvas has its own background and is not a stacking context, so a negative layer falls outside it and the canvas background covers it completely (verified: invisible). It is inserted before the wire svg instead and sits underneath by DOM order; its height depends on where the section ends, so it is filled in after rendering.
The A→G diagram switched to a two-pass layout; cards no longer overlap. Positions came from fixed cadence constants while real heights depend on content: a G heading measures 67px against the 64px the cadence reserved, so every section overlapped the T heading below it by 2px, and a T heading of 25px was given 46px — leaving gaps of 12 / -2 / 21 / 30 / 48. Raising the constants does not fix it; one wrapped heading and the overlap is back (the 260909 report "partly covered" was the same root cause). The generated top is now only a first-paint approximation: after rendering, layoutGoalFlow() re-places everything by measured height and the wires are drawn against the new positions. Card height moved from a hard 112px to min-height and the clamp from 2 lines to 3 — a fixed height cut long goals in half, and position derived from that same constant, so the two belong together. Measured at 1600px and 1180px, including expanded tasks and an open inline detail: zero overlaps.
The "current understanding and situation" block was re-set. User feedback on the expanded block: the type looks odd and bunches to one side, the small headings are smaller than the body text they introduce, the body is one solid mass, and ① ② run together. The spoken headline was capped at max-width:46em and took up half of a wide screen; the headings were 13px against 14px body text; and observers tend to write the points as one paragraph with the numbers buried mid-sentence. The headline now has no width cap, is 18px with a colour rule at its left, the headings are 15px with a dot, each column sits in its own card, and body leading opened to 2.0. At render time a newline goes in before ①–⑳, the text is split into paragraphs and numbered lines get a hanging indent — display only; the stored current.understanding is unchanged.
Two browser-probe assertions were corrected. In observe_goal_browser.cjs, "the page contains current.understanding verbatim" now compares with whitespace removed: the itemised rendering adds only whitespace and changes no character, which expresses what the assertion guards — the page does not alter what the observer wrote — more precisely. The other, [data-om-action="goal-anchor"], matched two elements under strict mode: when the first G section has no explicit goal change to point at, its heading has shared that action with the A card since 260909. Unrelated to this release; it simply never surfaced because this manual probe had never run here (no playwright installed). It now targets .ag-anchor [data-om-action="goal-anchor"].
同僚セッションからのメッセージを一つの実行可能な規則に集約。origin=user でありながら本文が Another Claude session sent a message: で始まり <teammate-message teammate_id="…"> が続く行は、同じレーンに届いた別の CC セッションのメッセージ(マルチエージェント作業中の待機通知やレビュー報告)です。人間でもサブエージェントレーンの [派生指令] でもなく、それでもターン番号を一つ占めます。実測:セッション 9287e1ca の [用户] 46 行のうち 28 行。判断材料が各所に散っていたため、[用户] をそのまま読むとサブエージェントの報告を利用者の新しい要求と取り違え、ありもしない目標変化を作ってしまいます。
変更
A→G 図で G と T の階層が見えるようになりました(issue 260912)。利用者の指摘:「画面はきれいだが、G と T が一目で区別できない」。従来 G の見出しは上罫線+11px の小ラベル、T の見出しは左罫線+11px の小ラベルで、違いは罫線の向きと 10px の字下げだけ。一方その下の T カードは画面で最も重い要素でした。階層が逆だったのです。今は各 G 区画が自分の帯(淡い色地+細枠+上罫)を持ち、属する T をすべて囲みます。G の番号は塗りのバッジ、見出しは 15px に。T の番号は輪郭チップ、見出しは通常の字面に戻しました。色はすべて --ag-key / --brand-ink から color-mix で導出し、テーマトークンは増やしていません。帯に負の z-index は使えません:.ag-canvas は自前の背景を持ちながら重ね合わせコンテキストを作らないため、負の層は外側に落ちてキャンバス背景に完全に隠れます(実測で不可視)。線の svg の前に挿入し、DOM 順で下に敷いています。高さは区画を並べ終えて初めて決まるので、描画後に埋めます。