You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@maka.apache.org by "likun666661 (via GitHub)" <gi...@apache.org> on 2026/09/27 04:03:07 UTC

[PR] docs: review Grok-assisted merged contributions [maka]

likun666661 opened a new pull request, #5747:
URL: https://github.com/apache/maka/pull/5747

   ## Summary
   
   Inventory the 25 merged PRs with Grok-assistance evidence from 2026-08-14 onward, cross-checking mainline commit trailers and PR disclosures. This draft is an engineering/provenance review, not a legal classification or completed replacement.
   
   ## Verification
   
   - `git diff --cached --check` passed before commit.
   - `node scripts/asf-license-headers.mjs check` passed.
   - No product tests run: documentation-only inventory.
   
   ## Review focus
   
   The original commits and their contributor disclosures remain intact. Rewording commit metadata, reformatting, or a no-op reimplementation cannot resolve a provenance concern. Any code replacement and legal disposition require project review.
   
   ## Remaining work
   
   - [ ] Inspect all 25 PRs against current `main` and record dispositions.
   - [ ] Identify current behavior and regression tests for material changes.
   - [ ] Agree on appropriate remediation with the project and ASF legal discussion.
   - [ ] Implement and verify approved replacements in reviewable slices.
   
   ## AI use
   
   - [ ] No generative tool made a substantive contribution
   - [x] Generative tooling made a substantive contribution
   
   Tool(s) and scope: OpenAI Codex prepared the inventory and this PR description.
   
   ## Checklist
   
   - [ ] Tests cover the change and fail without it — documentation-only inventory
   - [ ] Lint, format, typecheck and the affected suites pass locally — no product code changed
   
   Does this PR entail a change in behavior?
   
   - [ ] Yes — described under Summary above
   - [x] No


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@maka.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@maka.apache.org
For additional commands, e-mail: commits-help@maka.apache.org


Re: [PR] audit: rewrite retained Grok-assisted contribution cores [maka]

Posted by "likun666661 (via GitHub)" <gi...@apache.org>.
likun666661 commented on code in PR #5747:
URL: https://github.com/apache/maka/pull/5747#discussion_r4115069175


##########
apps/desktop/src/renderer/features/workbar/tools/side-chat/use-quote-companion.ts:
##########
@@ -1615,9 +1615,12 @@ export function useQuoteCompanion(input: UseQuoteCompanionInput): UseQuoteCompan
     [dropOptimisticUserMessage, messageQueue.entries, runQueueEntryAction, sideChat],
   );
   const reorderQueuedEntries = useCallback(
-    (entryIds: readonly string[]) =>
-      runQueueEntryAction((id) => sideChat.reorderQueueEntries(id, entryIds)),
-    [runQueueEntryAction, sideChat],
+    (entryIds: readonly string[]) => runQueueEntryAction((id) => {
+      const revision = messageQueue.queueRevision;

Review Comment:
   Fixed in `77d6987e5`. Both Side Chat and WorkHub callbacks now accept and forward the drag-start revision, and the unreachable “queue not ready” branch is removed. The relevant Desktop build/test run passes 28 tests.



##########
packages/storage/src/project-catalog.ts:
##########
@@ -859,12 +859,11 @@ export interface ResolvedProjectLocation {
 
 export async function resolveProjectLocation(input: {
   path: string;
+  intent?: 'selected';

Review Comment:
   Restored both rationale comments in `77d6987e5`: file paths are rejected before Git discovery so callers receive a classifiable invalid-path error, and chooser selections remain exact while historical cwd resolution may walk up to a worktree. The project-catalog suite passes 24 tests.



##########
apps/desktop/src/renderer/features/session-navigation/model/session-rail-layout-store.ts:
##########
@@ -53,10 +52,11 @@ export interface SessionRailLayoutState {
  * instance for it to be an instance of.
  */
 export function createSessionRailLayoutStore() {
+  const storedViewMode = safeLocalStorageGet(VIEW_MODE_KEY);

Review Comment:
   Consolidated in `77d6987e5`. All three rail persistence keys plus their read/write helpers now live in `session-list-layout.ts`; the store delegates to those helpers. Desktop typecheck, renderer build, and the Session Navigation boundary suite pass.



##########
packages/eval/harbor/eval_framework.py:
##########
@@ -15,26 +15,37 @@
 # specific language governing permissions and limitations
 # under the License.
 
-"""Authoritative Eval harness framework selection.
-
-`run_trial.py` validates the argv framework and installs it here before Harbor,
-Pier, or the shared relay can import. The relay must not read the environment.
-"""
+"""Framework selection inherited by imports in the current trial context."""
 
 from __future__ import annotations
 
+from contextlib import contextmanager
+from contextvars import ContextVar
+from typing import Iterator
+
 _FRAMEWORKS = frozenset({"harbor", "pier"})
-_framework: str | None = None
+_framework: ContextVar[str | None] = ContextVar("eval_framework", default=None)
 
 
 def install(framework: str) -> None:
     if framework not in _FRAMEWORKS:
         raise RuntimeError("framework must be harbor or pier")
-    global _framework
-    _framework = framework
+    _framework.set(framework)
+
+
+@contextmanager
+def selected_framework(framework: str) -> Iterator[None]:

Review Comment:
   Agreed. `77d6987e5` replaces the `ContextVar`/scope abstraction with one process-local `install()`. `run_trial()` installs the argv-selected framework once before importing framework modules, and the tests now cover install/replace semantics rather than an isolation guarantee the module cache cannot provide. The focused Python 3.12 suite passes 58 tests (2 skipped).



##########
packages/runtime/src/provider-error-classification.ts:
##########
@@ -21,8 +21,14 @@ import { RetryError } from 'ai';
 import { MODEL_FAILURE_MESSAGE_MAX_BYTES } from '@maka/core/model-failure';
 import { truncateUtf8 } from '@maka/core/diagnostic-log';
 import { isAuthenticationErrorText } from '@maka/core/redaction';
-import type { ProviderRetryReason } from '@maka/core/events';
 import type { ModelFailure, ModelFailureKind } from './model-protocol.js';
+import {
+  providerRetryReason,
+  responseHeadersFromError,
+  retryAfterMs,
+} from './provider-retry-policy.js';
+
+export { providerRetryReason } from './provider-retry-policy.js';

Review Comment:
   Fixed in `77d6987e5`. `ai-sdk-turn.ts` imports `providerRetryReason` directly from `provider-retry-policy.js`, and the compatibility re-export is gone. The focused retry/classification suites pass 57 tests.



##########
packages/ui/src/composer-message-queue.tsx:
##########
@@ -98,21 +101,26 @@ export const ComposerMessageQueue = memo(function ComposerMessageQueue(
   }
 
   function dropOn(targetEntryId: string) {
-    const fromId = dragEntryId.current;
-    dragEntryId.current = null;
-    if (!fromId || fromId === targetEntryId || !props.onReorderEntries) return;
+    const sourceDrag = dragSource.current;
+    dragSource.current = null;
+    if (
+      !sourceDrag
+      || sourceDrag.entryId === targetEntryId
+      || !props.onReorderEntries
+      || props.queueRevision !== sourceDrag.queueRevision

Review Comment:
   Fixed in `77d6987e5`. The UI no longer compares against the latest client projection on drop; it forwards the drag-start revision and lets the Host return `operation_conflict` through the existing error path. The updated UI regression test asserts that captured revision is submitted (8 focused UI tests pass).



##########
apps/desktop/src/renderer/app-shell.tsx:
##########
@@ -1788,16 +1790,15 @@ function AppShellContent({
     activeEventSeedRef.current = next;
     markDisplayPending(sessionId);
     setActiveEventSeed(next);
-  };
-  const completeObservationSeed = (sessionId: string) => {
-    const current = activeEventSeedRef.current;
-    if (current.sessionId !== sessionId) return;
-    flushDisplayEvents(sessionId);
-    markDisplayReady(sessionId);
-    const next = liveContent.completeLiveContentSeed(current, sessionId);
-    activeEventSeedRef.current = next;
-    setActiveEventSeed(next);
-    void retireCancelledTransientMessages(sessionId);
+    return () => {
+      if (activeEventSeedRef.current !== next) return;

Review Comment:
   This path was superseded by the broader app-shell rewrite in `0bb7392a4`: `completeLiveContentSeed` and its generation argument no longer exist at the current head, so the duplicate guard is gone rather than retained in either form.



##########
packages/runtime-host/src/protocol/index.ts:
##########
@@ -103,7 +103,11 @@ export const RUNTIME_HOST_REGISTRATION_SCHEMA_VERSION = 1 as const;
 export const RUNTIME_HOST_PROTOCOL_VERSION = 0 as const;
 // Increment when the same protocol version no longer guarantees safe Client-Host
 // interoperability. Mismatches are rejected before domain commands are admitted.
-export const RUNTIME_HOST_COMPATIBILITY_EPOCH = 192 as const;
+export const RUNTIME_HOST_COMPATIBILITY_EPOCH = 194 as const;

Review Comment:
   Fixed in `77d6987e5`: the compatibility epoch is now bumped once, to 193, solely for required `expectedQueueRevision`. Empty reorder remains a valid no-op; duplicate/invalid identities are still rejected. The focused protocol suites pass 89 tests.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@maka.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@maka.apache.org
For additional commands, e-mail: commits-help@maka.apache.org


Re: [PR] audit: review Grok-assisted contributions and replace two slices [maka]

Posted by "Astro-Han (via GitHub)" <gi...@apache.org>.
Astro-Han commented on PR #5747:
URL: https://github.com/apache/maka/pull/5747#issuecomment-5852690158

   Thanks for putting this together. I re-ran the inventory and it holds: scanning `origin/main` for `Generated-by: .*Grok` from 2026-08-14 on yields exactly the 24 trailer-bearing PRs, #5223 is the only disclosure-only case, and every present-path count reproduces at `bfb315acc`.
   
   Two suggestions and two small nits.
   
   ### 1. Measure line survival instead of path presence
   
   Path presence can't tell whether any Grok-produced line is still in the tree. `git blame` on current `main` can, at least at squash-commit granularity. Results at `d89ccce01`:
   
   | PR | Added lines | Surviving on `main` |
   |---:|---:|---:|
   | #3008 | 180 | 166 |
   | #2967 | 678 | 651 |
   | #3048 | 462 | 287 |
   | #3063 | 0 | 0 |
   | #3066 | 201 | 129 |
   | #3070 | 177 | 137 |
   | #3078 | 114 | 89 |
   | #3082 | 116 | 66 |
   | #3099 | 129 | 86 |
   | #3101 | 54 | 42 |
   | #3102 | 39 | 4 |
   | #3104 | 20 | 17 |
   | #3106 | 279 | 139 |
   | #3111 | 59 | 57 |
   | #3115 | 429 | 407 |
   | #3117 | 282 | 252 |
   | #3118 | 0 | 0 |
   | #3119 | 2 | 1 |
   | #3123 | 48 | 0 |
   | #3069 | 200 | 0 |
   | #3459 | 288 | 150 |
   | #3364 | 118 | 111 |
   | #3544 | 1713 | 1090 |
   | #4345 | 22 | 22 |
   | #5223 | 43 | 32 |
   
   - Nothing survives from four PRs. #3063 and #3118 only deleted code. #3123's only file, `apps/desktop/e2e/prompt-rail.spec.ts`, was deleted in #4741, and #3069's two tests were deleted in #4877 and #5531. None of them has a successor, so these four can be recorded as "no surviving output" instead of "find successor".
   - Almost nothing survives from #3119 (1 line), #3102 (4) and #3104 (17).
   - The remaining ~3.9k lines are concentrated in #3544 (1090), #2967 (651), #3115 (407), #3048 (287) and #3117 (252), and a large share of them are tests.
   - Caveats: counts are per squash commit, so the mixed PRs (#3048, #3364, #3459, #3544, #4345) still need to be split by original commit. Blame ran without `-C`, so code copied into other files is not traced.
   
   To reproduce for one PR:
   
   ```sh
   c=$(git rev-parse <squash-sha>)
   for f in $(git diff-tree --no-commit-id --name-only -r "$c"); do
     git cat-file -e origin/main:"$f" 2>/dev/null &&
       printf '%s %s\n' "$(git blame -w -M --line-porcelain origin/main -- "$f" | grep -c "^$c ")" "$f"
   done
   ```
   
   ### 2. Where the disposition goes (for discussion)
   
   The document stops at "project and ASF legal discussion". A few points seem worth settling explicitly:
   
   - **Who decides.** The [ASF Generative Tooling Guidance](https://www.apache.org/legal/generative-tooling.html) points to `legal-private@apache.org` for this kind of question. The concrete question would be whether the AUP's ban on using output to develop competing products or services counts, under item 1 of that guidance, as a restriction on the use of output that is inconsistent with the Open Source Definition. Should we send it there, or open a LEGAL JIRA?
   - **Release impact.** The 0.2.0-incubating RC2 tag (`54542021a`) contains all 25 PRs, and the IPMC vote is open on general@. If legal finds the output acceptable, RC2 is unaffected. If not, `main` needs remediation first, and only then would an RC3 help, because an RC3 cut from today's `main` contains the same code. I think we should mention this on the vote thread now rather than let the IPMC find it later.
   - **Where the inventory lives.** Once merged into `docs/`, it becomes a permanent file with unchecked process items. Would a tracking issue (or the LEGAL ticket) be a better home until there is a disposition, with only the outcome recorded in the repository if needed?
   - **Cross-link #5746**, which pauses new Grok-generated contributions. That PR covers future contributions and this one covers past ones.
   
   ### Nits
   
   - The header baseline is `bfb315acc`, but the revert probe used `d89ccce01`. A single baseline would be easier to check.
   - "Closed, unmerged PRs … are tracked separately": please link where.
   
   <details>
   <summary>中文版</summary>
   
   感谢整理。我复核了一遍,结论成立:在 `origin/main` 上扫 2026-08-14 起的 `Generated-by: .*Grok`,正好是这 24 个带 trailer 的 PR;只在 PR 描述里披露的只有 #5223;现存路径数在 `bfb315acc` 上全部能复现。
   
   两条建议,外加两处小问题。
   
   ### 1. 用行级存活代替路径存在
   
   路径还在,说明不了 Grok 生成的行是否还在。在当前 `main` 上跑 `git blame` 可以回答这个问题,至少能做到 squash commit 粒度。`d89ccce01` 上的结果见上方英文部分的表格。
   
   - 有四个 PR 已经没有任何存活行。#3063 和 #3118 本身只删代码;#3123 唯一改动的 `apps/desktop/e2e/prompt-rail.spec.ts` 已在 #4741 删除;#3069 的两个测试已在 #4877 和 #5531 删除。它们都没有后继文件,可以直接记为"无存活产出",不用再"找后继"。
   - #3119(1 行)、#3102(4 行)、#3104(17 行)几乎没有存活。
   - 其余约 3.9k 行集中在 #3544(1090)、#2967(651)、#3115(407)、#3048(287)、#3117(252),其中很大一部分是测试。
   - 注意:统计按 squash commit 计,混合 PR(#3048、#3364、#3459、#3544、#4345)还要按原始 commit 拆分;blame 没有开 `-C`,复制到其他文件的代码没有追踪。
   
   复现命令见上方英文部分。
   
   ### 2. 处置由谁决定(提出讨论)
   
   文档停在"项目与 ASF legal 讨论"。以下几点值得明确:
   
   - **由谁决定。** [ASF 生成式工具指南](https://www.apache.org/legal/generative-tooling.html) 指向 `legal-private@apache.org` 处理这类问题。具体要问的是:AUP 禁止用产出开发竞争性产品或服务,按该指南第 1 条,是否构成与开源定义不一致的产出使用限制。我们是发到那里,还是开 LEGAL JIRA?
   - **对发布的影响。** 0.2.0-incubating RC2 的 tag(`54542021a`)包含全部 25 个 PR,IPMC 投票正在 general@ 进行。如果 legal 认为产出可以接受,RC2 不受影响;如果不行,要先在 `main` 上处理,之后切 RC3 才有意义,因为从今天的 `main` 切出的 RC3 仍然包含同样的代码。我认为应该现在就在投票线程里说明,而不是等 IPMC 自己发现。
   - **清单放在哪里。** 合进 `docs/` 后,它会变成一份带着未勾选流程项的永久文件。在有处置结论之前,放在 tracking issue(或 LEGAL 工单)里是否更合适,需要的话仓库里只记录最终结论?
   - **关联 #5746**:那个 PR 暂停新的 Grok 生成贡献,管以后;这个 PR 管以前。
   
   ### 小问题
   
   - 文档开头的基线是 `bfb315acc`,revert 测试用的却是 `d89ccce01`,统一成一个基线更方便核对。
   - "已关闭未合并的 PR 另行跟踪":请给出链接。
   
   </details>
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@maka.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@maka.apache.org
For additional commands, e-mail: commits-help@maka.apache.org


Re: [PR] audit: rewrite retained Grok-assisted contribution cores [maka]

Posted by "likun666661 (via GitHub)" <gi...@apache.org>.
likun666661 commented on PR #5747:
URL: https://github.com/apache/maka/pull/5747#issuecomment-5854547622

   You are right. I reproduced the direction of this result, and it exposes a mismatch between the stated goal and what this branch currently does.
   
   The branch has extracted several decision boundaries, added failure-injection/regression coverage, and fixed issues found during the audit, but those changes do not by themselves constitute replacement of the surviving squash-attributed implementations. In particular, introducing a new policy helper while retaining most of the original implementation underneath it cannot be counted as a rewrite. The unchanged counts for #3117 and #3106 also contradict the current “superseded” disposition and need to be re-examined. Green CI only establishes behavioral compatibility; it does not close this provenance-remediation goal.
   
   I am reopening the rewrite checklist and will correct the PR description/document so they no longer claim technical completion. The next pass will use the latest base and work per surviving production-code slice: separate mixed-commit/test/later-author contributions, replace the actual retained implementation in dependency order, remove the old path rather than wrap it, and rerun the behavioral, ablation, build, and Electron coverage. I will report before/after blame counts per PR together with explicit exceptions where squash-level blame cannot distinguish independently authored or later-modified lines.
   
   Thanks for checking the acceptance criterion directly. The current branch should be treated as preparatory hardening and audit infrastructure, not the completed rewrite.


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@maka.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@maka.apache.org
For additional commands, e-mail: commits-help@maka.apache.org


Re: [PR] audit: rewrite retained Grok-assisted contribution cores [maka]

Posted by "likun666661 (via GitHub)" <gi...@apache.org>.
likun666661 commented on PR #5747:
URL: https://github.com/apache/maka/pull/5747#issuecomment-5854440347

   Final CI is green on the latest pushed head (`6d0fc9e8b`): audit, macOS and Windows Runtime Host owner checks, Linux and Windows packaging, and the full test job all passed. The PR is ready for project and ASF legal review.


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@maka.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@maka.apache.org
For additional commands, e-mail: commits-help@maka.apache.org


Re: [PR] audit: rewrite retained Grok-assisted contribution cores [maka]

Posted by "Astro-Han (via GitHub)" <gi...@apache.org>.
Astro-Han commented on PR #5747:
URL: https://github.com/apache/maka/pull/5747#issuecomment-5854535675

   Hi @likun666661, thanks for pushing this so far in a single day. The inventory and the dispositions are much more complete now.
   
   One thing I noticed when I re-ran the blame check on the latest head (`6d0fc9e8b`): most of the Grok-attributed lines are still there. Across the 25 squash commits, the surviving count goes from 3,935 at `027d6afba` to about 3,770 at the PR head, so roughly 4% have been replaced. The largest ones barely moved:
   
   | PR | Before (`027d6afba`) | PR head |
   |---:|---:|---:|
   | #3544 | 1090 | 1061 |
   | #2967 | 651 | 641 |
   | #3115 | 407 | 414 |
   | #3048 | 287 | 270 |
   | #3117 | 252 | 252 |
   | #3106 | 139 | 139 |
   
   Only #5223 (32 → 5) and #3082 (66 → 23) dropped substantially.
   
   Judging by the commits, the agent seems to have gone after bugs it found along the way (CONNECT host classification, the queue reorder revision, `Retry-After` parsing, and so on) and layered those fixes onto the existing code instead of rewriting the Grok-authored parts. The document says as much in several places ("scoped fix, not a replacement"). So the main goal, rewriting the surviving Grok code, still looks open.
   
   To reproduce, run the same blame loop as before with `origin/main` replaced by the PR head.
   
   <details>
   <summary>中文版</summary>
   
   @likun666661 感谢,一天之内推进到这个程度,清单和处置结论现在完整多了。
   
   我在最新 head(`6d0fc9e8b`)上重跑了 blame,发现 Grok 相关的行大部分还在:25 个 squash commit 的存活行数,从 `027d6afba` 的 3,935 行降到 PR head 的约 3,770 行,只替换了大约 4%。几个最大的 PR 基本没动(数字见上方英文部分的表格),只有 #5223(32 → 5)和 #3082(66 → 23)明显减少。
   
   从 commit 来看,agent 好像是一路修它顺手发现的 bug(CONNECT host 分类、queue reorder 的 revision、`Retry-After` 解析等),把修复叠加在原有代码上,而不是重写 Grok 写的那部分。文档里也好几处写了 "scoped fix, not a replacement"。所以最主要的目标,也就是重写还存活的 Grok 代码,看起来还没完成。
   
   复现方法:沿用之前的 blame 循环,把 `origin/main` 换成 PR head 即可。
   
   </details>
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@maka.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@maka.apache.org
For additional commands, e-mail: commits-help@maka.apache.org


Re: [PR] audit: rewrite retained Grok-assisted contribution cores [maka]

Posted by "likun666661 (via GitHub)" <gi...@apache.org>.
likun666661 commented on PR #5747:
URL: https://github.com/apache/maka/pull/5747#issuecomment-5855282333

   Thanks for the detailed review. All eight inline notes are addressed in `77d6987e5`, each thread now has a focused response and is resolved. I also re-ran squash-line survival at the current branch head and updated both the review document and PR description in `c76bb68ca`: the count is now 2,015 versus 3,935 at the base (the earlier 3,770 figure was stale). The document keeps the distinction between this engineering replacement evidence and the outstanding project/ASF legal disposition, including the RC2 and #5746 cross-links.


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@maka.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@maka.apache.org
For additional commands, e-mail: commits-help@maka.apache.org


Re: [PR] audit: rewrite retained Grok-assisted contribution cores [maka]

Posted by "Astro-Han (via GitHub)" <gi...@apache.org>.
Astro-Han commented on code in PR #5747:
URL: https://github.com/apache/maka/pull/5747#discussion_r4114809294


##########
packages/runtime/src/provider-error-classification.ts:
##########
@@ -21,8 +21,14 @@ import { RetryError } from 'ai';
 import { MODEL_FAILURE_MESSAGE_MAX_BYTES } from '@maka/core/model-failure';
 import { truncateUtf8 } from '@maka/core/diagnostic-log';
 import { isAuthenticationErrorText } from '@maka/core/redaction';
-import type { ProviderRetryReason } from '@maka/core/events';
 import type { ModelFailure, ModelFailureKind } from './model-protocol.js';
+import {
+  providerRetryReason,
+  responseHeadersFromError,
+  retryAfterMs,
+} from './provider-retry-policy.js';
+
+export { providerRetryReason } from './provider-retry-policy.js';

Review Comment:
   `ai-sdk-turn.ts` is the only importer that goes through this re-export, and the moved helpers have no other consumer besides this file. Either importing `providerRetryReason` from `provider-retry-policy.js` directly or keeping the helpers here would avoid the compatibility re-export.
   
   <details>
   <summary>中文</summary>
   
   `ai-sdk-turn.ts` 是唯一经由这个转导出引用的地方,被移走的几个 helper 除了本文件也没有别的使用者。要么让 `ai-sdk-turn.ts` 直接从 `provider-retry-policy.js` 引入 `providerRetryReason`,要么把这几个 helper 留在本文件,都能省掉这个兼容转导出。
   
   </details>



##########
apps/desktop/src/renderer/features/session-navigation/model/session-rail-layout-store.ts:
##########
@@ -53,10 +52,11 @@ export interface SessionRailLayoutState {
  * instance for it to be an instance of.
  */
 export function createSessionRailLayoutStore() {
+  const storedViewMode = safeLocalStorageGet(VIEW_MODE_KEY);

Review Comment:
   Nit: collapsed state and width are still read through the `session-list-layout` helpers, while view mode is now read and written inline here. So the three rail layout keys are persisted in two places. Either spot works, but keeping them together would be easier to follow.
   
   <details>
   <summary>中文</summary>
   
   小问题:折叠状态和宽度仍然通过 `session-list-layout` 的 helper 读取,视图模式却改成在这里直接读写。这样侧边栏的三个布局设置分散在两处持久化。放在哪边都行,但放在一起更容易看懂。
   
   </details>



##########
apps/desktop/src/renderer/features/workbar/tools/side-chat/use-quote-companion.ts:
##########
@@ -1615,9 +1615,12 @@ export function useQuoteCompanion(input: UseQuoteCompanionInput): UseQuoteCompan
     [dropOptimisticUserMessage, messageQueue.entries, runQueueEntryAction, sideChat],
   );
   const reorderQueuedEntries = useCallback(
-    (entryIds: readonly string[]) =>
-      runQueueEntryAction((id) => sideChat.reorderQueueEntries(id, entryIds)),
-    [runQueueEntryAction, sideChat],
+    (entryIds: readonly string[]) => runQueueEntryAction((id) => {
+      const revision = messageQueue.queueRevision;

Review Comment:
   `ComposerMessageQueue` already passes the drag-start revision as the second argument, but this callback (and the WorkHub controller's) ignores it and reads its own state instead. The `not ready` throw can't fire either, since the component disables dragging while the revision is unknown. Taking the passed revision would match `app-shell.tsx` and remove the dead branch.
   
   <details>
   <summary>中文</summary>
   
   `ComposerMessageQueue` 已经把拖拽开始时的 revision 作为第二个参数传进来,但这个回调(以及 WorkHub controller 里的那个)忽略了它,改读自己的状态。`not ready` 那个 throw 也不会触发,因为 revision 未知时组件已经禁止拖拽。直接用传入的 revision 就能和 `app-shell.tsx` 保持一致,也能去掉这个死分支。
   
   </details>



##########
packages/runtime-host/src/protocol/index.ts:
##########
@@ -103,7 +103,11 @@ export const RUNTIME_HOST_REGISTRATION_SCHEMA_VERSION = 1 as const;
 export const RUNTIME_HOST_PROTOCOL_VERSION = 0 as const;
 // Increment when the same protocol version no longer guarantees safe Client-Host
 // interoperability. Mismatches are rejected before domain commands are admitted.
-export const RUNTIME_HOST_COMPATIBILITY_EPOCH = 192 as const;
+export const RUNTIME_HOST_COMPATIBILITY_EPOCH = 194 as const;

Review Comment:
   Small one: this PR bumps the epoch twice. 193 only exists to reject an empty reorder, which the Host previously handled as a harmless no-op. Maybe drop the empty-reorder rejection and keep a single bump for the required `expectedQueueRevision`?
   
   <details>
   <summary>中文</summary>
   
   小问题:这个 PR 把 epoch 升了两次。193 只是为了拒绝空的 reorder,而 Host 之前把它当作无害的空操作处理。可以考虑去掉对空 reorder 的拒绝,只为必填的 `expectedQueueRevision` 升一次。
   
   </details>



##########
packages/eval/harbor/eval_framework.py:
##########
@@ -15,26 +15,37 @@
 # specific language governing permissions and limitations
 # under the License.
 
-"""Authoritative Eval harness framework selection.
-
-`run_trial.py` validates the argv framework and installs it here before Harbor,
-Pier, or the shared relay can import. The relay must not read the environment.
-"""
+"""Framework selection inherited by imports in the current trial context."""
 
 from __future__ import annotations
 
+from contextlib import contextmanager
+from contextvars import ContextVar
+from typing import Iterator
+
 _FRAMEWORKS = frozenset({"harbor", "pier"})
-_framework: str | None = None
+_framework: ContextVar[str | None] = ContextVar("eval_framework", default=None)
 
 
 def install(framework: str) -> None:
     if framework not in _FRAMEWORKS:
         raise RuntimeError("framework must be harbor or pier")
-    global _framework
-    _framework = framework
+    _framework.set(framework)
+
+
+@contextmanager
+def selected_framework(framework: str) -> Iterator[None]:

Review Comment:
   I don't think the ContextVar can isolate frameworks in practice: `relay_agent.py` runs `framework = selected()` and picks `BaseAgent` at import time, and that module is cached per process, so a second trial in the same process would still get the first trial's base class. The new concurrency test calls `selected()` directly and never goes through that import. In production each trial is its own `run_trial.py` process with the framework taken from argv, so the shared-global case doesn't seem reachable. Also, `main()` and `run_trial()` now both enter `selected_framework`. Keeping the original module-level `install()` might be simpler.
   
   <details>
   <summary>中文</summary>
   
   我觉得 ContextVar 实际上隔离不了框架:`relay_agent.py` 在 import 时执行 `framework = selected()` 并选定 `BaseAgent`,而模块缓存是整个进程共享的,同一进程里第二个 trial 拿到的仍是第一个 trial 的基类。新的并发测试直接调用 `selected()`,没有经过这个 import。生产环境里每个 trial 都是独立的 `run_trial.py` 进程,框架从 argv 读取,所以共享全局变量的情况看起来触发不到。另外 `main()` 和 `run_trial()` 现在都进入了 `selected_framework`。保留原来的模块级 `install()` 可能更简单。
   
   </details>



##########
packages/storage/src/project-catalog.ts:
##########
@@ -859,12 +859,11 @@ export interface ResolvedProjectLocation {
 
 export async function resolveProjectLocation(input: {
   path: string;
+  intent?: 'selected';

Review Comment:
   The two comments that explained this were removed: why a regular file must be rejected before Git discovery (`git -C <file>` fails with a numeric code the Host coordinator doesn't treat as an invalid path), and why a chooser selection must not walk up to the enclosing worktree while a historical cwd does. Without them, `intent?: 'selected'` looks like something a later cleanup could drop. Could we keep a short version of both?
   
   <details>
   <summary>中文</summary>
   
   原来解释这里的两段注释被删掉了:为什么要在 Git 探测之前拒绝普通文件(`git -C <file>` 会以数字错误码失败,Host coordinator 不会把它当作无效路径),以及为什么目录选择器选中的路径不能像历史 cwd 那样向上找到所在 worktree。没有这两段,`intent?: 'selected'` 看起来像是以后清理时可以删掉的东西。能否把两段各保留一个简短版本?
   
   </details>



##########
packages/ui/src/composer-message-queue.tsx:
##########
@@ -98,21 +101,26 @@ export const ComposerMessageQueue = memo(function ComposerMessageQueue(
   }
 
   function dropOn(targetEntryId: string) {
-    const fromId = dragEntryId.current;
-    dragEntryId.current = null;
-    if (!fromId || fromId === targetEntryId || !props.onReorderEntries) return;
+    const sourceDrag = dragSource.current;
+    dragSource.current = null;
+    if (
+      !sourceDrag
+      || sourceDrag.entryId === targetEntryId
+      || !props.onReorderEntries
+      || props.queueRevision !== sourceDrag.queueRevision

Review Comment:
   The queue revision is session-wide: `#mutated` bumps it from about 16 places in the Host coordinator. With this check, any unrelated queue or session change between drag start and drop makes the drop return silently, so the user drags an entry and nothing happens, with no message. It also skips the caller's error path (`runEntryAction` notes that the app shell surfaces failures).
   
   Could we drop this client-side comparison and just send `sourceDrag.queueRevision`? The Host already rejects a stale revision with `operation_conflict`, and that failure then reaches the user through the existing error handling.
   
   <details>
   <summary>中文</summary>
   
   queue revision 是整个 session 共用的,Host coordinator 里 `#mutated` 大约有 16 处会让它加一。有了这个检查,拖拽开始到放下之间只要有任何无关的队列或 session 变更,放下就会静默 return:用户拖了一下,什么都没发生,也没有提示。它还绕过了调用方的报错路径(`runEntryAction` 的注释写明失败由 app shell 负责提示)。
   
   能否去掉这里的客户端比对,直接把 `sourceDrag.queueRevision` 发给 Host?Host 已经会用 `operation_conflict` 拒绝过期的 revision,这个失败会经由现有的错误处理提示给用户。
   
   </details>



##########
apps/desktop/src/renderer/app-shell.tsx:
##########
@@ -1788,16 +1790,15 @@ function AppShellContent({
     activeEventSeedRef.current = next;
     markDisplayPending(sessionId);
     setActiveEventSeed(next);
-  };
-  const completeObservationSeed = (sessionId: string) => {
-    const current = activeEventSeedRef.current;
-    if (current.sessionId !== sessionId) return;
-    flushDisplayEvents(sessionId);
-    markDisplayReady(sessionId);
-    const next = liveContent.completeLiveContentSeed(current, sessionId);
-    activeEventSeedRef.current = next;
-    setActiveEventSeed(next);
-    void retireCancelledTransientMessages(sessionId);
+    return () => {
+      if (activeEventSeedRef.current !== next) return;

Review Comment:
   Nit: this identity check already guarantees `next` is current, so the new `generation` argument to `completeLiveContentSeed` is a second guard for the same thing. On the production path, observation callbacks are filtered by `attempt` and phases arrive in order, so either guard alone is enough.
   
   <details>
   <summary>中文</summary>
   
   小问题:这里的身份比对已经保证 `next` 就是当前的 seed,`completeLiveContentSeed` 新增的 `generation` 参数是在重复保护同一件事。生产路径上,observation 回调已经按 `attempt` 过滤,phase 也按顺序到达,留一层保护就够了。
   
   </details>



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@maka.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@maka.apache.org
For additional commands, e-mail: commits-help@maka.apache.org


Re: [PR] audit: rewrite retained Grok-assisted contribution cores [maka]

Posted by "likun666661 (via GitHub)" <gi...@apache.org>.
likun666661 merged PR #5747:
URL: https://github.com/apache/maka/pull/5747


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@maka.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@maka.apache.org
For additional commands, e-mail: commits-help@maka.apache.org


Re: [PR] audit: rewrite retained Grok-assisted contribution cores [maka]

Posted by "likun666661 (via GitHub)" <gi...@apache.org>.
likun666661 commented on PR #5747:
URL: https://github.com/apache/maka/pull/5747#issuecomment-5854468614

   Merged the latest `origin/main` baseline `d2f19f400` (`#5663`, retry transport interruptions after HTTP 2xx). This directly overlaps the #3115 provider-classification area, so I reran the combined AI SDK/backend, provider-classification, and extracted pure retry-policy suites: 307 tests pass. The full Desktop dependency build also passes, and the reproduced line-survival total remains 3,935 with every per-PR count unchanged.


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@maka.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@maka.apache.org
For additional commands, e-mail: commits-help@maka.apache.org


Re: [PR] audit: rewrite retained Grok-assisted contribution cores [maka]

Posted by "Astro-Han (via GitHub)" <gi...@apache.org>.
Astro-Han commented on code in PR #5747:
URL: https://github.com/apache/maka/pull/5747#discussion_r4116074296


##########
apps/desktop/src/renderer/app-shell.tsx:
##########
@@ -2291,19 +2293,20 @@ function AppShellContent({
                         enabled={(activeSessionForView.orchestrationMode ?? 'default') === 'graph'}
                         locale={uiLocale}
                         onOpenSession={openSessionInChat}
+                        backend={window.maka.graphs}

Review Comment:
   This prop is redundant — `AgentGraphPanel` already falls back to `window.maka.graphs` internally (`agent-graph-panel.tsx`). Reading the bridge here also adds a new `window.maka.graphs` bridgePath debt entry for `app-shell.tsx`, which `validateMonotonicDebt` rejects in `--base` mode, so this line is part of why regenerating the ledger is not enough. Deleting it removes both the redundancy and one of the new debt items.
   
   <details><summary>中文版</summary>
   这个 prop 是冗余的——`AgentGraphPanel` 内部已经 `props.backend ?? window.maka.graphs` 兜底。而且在这里读 bridge 会给 `app-shell.tsx` 记一条新的 `window.maka.graphs` bridgePath 债务,`--base` 模式下 monotonic-debt 校验不允许新增——所以光重新生成账本也过不了。删掉这行同时消掉冗余和一条新债。</details>



##########
apps/desktop/e2e/streaming-remount.spec.ts:
##########
@@ -167,187 +240,185 @@ test('a successor owns working status and remounting leaves accumulated output s
   await expect(liveBubble).toHaveCount(1);
   await expect(liveBubble).toContainText(accumulatedOutput);
 
-  expect((await liveBubble.textContent())?.split(accumulatedOutput)).toHaveLength(2);
+  expect(
+    (await liveBubble.textContent())?.split(accumulatedOutput),
+  ).toHaveLength(2);
   expect(
     await liveBubble.evaluate(
       (element) =>
         element
           .getAnimations({ subtree: true })
-          .filter((animation) => animation.playState !== 'finished').length,
+          .filter((animation) => animation.playState !== "finished").length,
     ),
   ).toBe(0);
 
   await liveBubble.evaluate((element) => {
     const observed = { texts: [] as string[] };
-    (window as typeof window & { __makaStreamingRemountObserved?: typeof observed })
-      .__makaStreamingRemountObserved = observed;
+    (
+      window as typeof window & {
+        __makaStreamingRemountObserved?: typeof observed;
+      }
+    ).__makaStreamingRemountObserved = observed;
     new MutationObserver(() => {
-      observed.texts.push(element.textContent ?? '');
-    }).observe(element, { childList: true, characterData: true, subtree: true });
+      observed.texts.push(element.textContent ?? "");
+    }).observe(element, {
+      childList: true,
+      characterData: true,
+      subtree: true,
+    });
   });
 
-  const steering = 'trigger rewrite after returning to this conversation';
-  await steerActiveTurn(composer, steering);
-  const finalText = 'prefix <redacted> NEW streamed after the remount';
+  const steering = "trigger rewrite after returning to this conversation";
+  await submitSteeringDraft(composer, steering);
+  const finalText = "prefix <redacted> NEW streamed after the remount";
   await expect(liveBubble).toContainText(finalText);
 
-  const observed = await page.evaluate(() => (
-    window as typeof window & {
-      __makaStreamingRemountObserved?: {
-        texts: string[];
-      };
-    }
-  ).__makaStreamingRemountObserved);
-  expect(observed?.texts.some((text) => text.includes('<redacted>') && !text.includes(finalText)))
-    .toBe(true);
+  const observed = await page.evaluate(
+    () =>
+      (
+        window as typeof window & {
+          __makaStreamingRemountObserved?: {
+            texts: string[];
+          };
+        }
+      ).__makaStreamingRemountObserved,
+  );
+  expect(
+    observed?.texts.some(
+      (text) => text.includes("<redacted>") && !text.includes(finalText),
+    ),
+  ).toBe(true);
 });
 
-test('returning to a live conversation settles output accumulated while away', async ({
+test("returning to a live conversation settles output accumulated while away", async ({
   window: page,
 }) => {
-  await page.emulateMedia({ reducedMotion: 'no-preference' });
-  expect(await page.evaluate(() => matchMedia('(prefers-reduced-motion: reduce)').matches)).toBe(false);
+  await page.emulateMedia({ reducedMotion: "no-preference" });
+  expect(
+    await page.evaluate(
+      () => matchMedia("(prefers-reduced-motion: reduce)").matches,
+    ),
+  ).toBe(false);
   const composer = page.locator(COMPOSER_INPUT);
   await composer.fill(FAKE_HOLD_OPEN_PROMPT);
   await awaitSendReady(page);
-  await composer.press('Enter');
+  await composer.press("Enter");
 
-  const accumulatedOutput = 'Fake backend waiting for the test to stop the Turn.';
-  const liveBubble = page.locator('.maka-bubble-streaming');
-  await expect(liveBubble).toContainText(accumulatedOutput, { timeout: 20_000 });
+  const accumulatedOutput =
+    "Fake backend waiting for the test to stop the Turn.";
+  const liveBubble = page.locator(".maka-bubble-streaming");
+  await expect(liveBubble).toContainText(accumulatedOutput, {
+    timeout: 20_000,
+  });
 
-  const sidebar = page.getByRole('navigation', { name: '任务列表' });
-  await page.getByRole('button', { name: '展开侧边栏' }).click();
-  await expect(page.locator('[data-agents-page]')).toHaveAttribute(
-    'data-sidebar-state',
-    'expanded',
+  const sidebar = page.getByRole("navigation", { name: "任务列表" });
+  await page.getByRole("button", { name: "展开侧边栏" }).click();
+  await expect(page.locator("[data-agents-page]")).toHaveAttribute(
+    "data-sidebar-state",
+    "expanded",
   );
-  const originalSessionId = await sidebar.locator('[data-session-id]').first()
-    .getAttribute('data-session-id');
+  const originalSessionId = await sidebar
+    .locator("[data-session-id]")
+    .first()
+    .getAttribute("data-session-id");
   expect(originalSessionId).toBeTruthy();
-  await composer.fill('draft before switching conversations');
-  await sidebar.getByRole('button', { name: '新任务', exact: true }).click();
-  await expect(composer).toHaveText('');
-  await composer.fill('temporary second conversation');
+  await composer.fill("draft before switching conversations");
+  await sidebar.getByRole("button", { name: "新任务", exact: true }).click();
+  await expect(composer).toHaveText("");
+  await composer.fill("temporary second conversation");
   await awaitSendReady(page);
-  await composer.press('Enter');
-  await expect(page.getByRole('log')).toContainText(
-    'Fake backend received: temporary second conversation',
+  await composer.press("Enter");
+  await expect(page.getByRole("log")).toContainText(
+    "Fake backend received: temporary second conversation",
     { timeout: 20_000 },
   );
-  await expect(page.locator('.maka-assistant-answer [data-action="copy"]')).toHaveCount(1, {
+  await expect(
+    page.locator('.maka-assistant-answer [data-action="copy"]'),
+  ).toHaveCount(1, {
     timeout: 20_000,
   });
-  const backgroundSteering = 'background output accumulated while away';
+  const backgroundSteering = "background output accumulated while away";
   await page.evaluate(
-    ({ sessionId, steering }) => new Promise<void>((resolve, reject) => {
-      const timeout = window.setTimeout(() => {
-        unsubscribe();
-        reject(new Error('Timed out waiting for background stream output'));
-      }, 10_000);
-      const unsubscribe = window.maka.sessions.subscribeEvents(sessionId, (event) => {
-        if (event.type !== 'text_delta' || !event.text.includes(steering)) return;
-        window.clearTimeout(timeout);
-        unsubscribe();
-        resolve();
-      });
-      // Runtime Host decides what this Message becomes; the test only needs it
-      // to reach the running Turn, so anything short of an accepted admission
-      // fails closed rather than waiting out the timeout.
-      void window.maka.sessions
-        .submitMessage(sessionId, 'current_turn', {
-          messageId: crypto.randomUUID(),
-          text: steering,
-        })
-        .then((result) => {
-          if (result.ok) return;
-          window.clearTimeout(timeout);
+    ({ sessionId, steering }) =>
+      new Promise<void>((resolve, reject) => {
+        const timeout = window.setTimeout(() => {
           unsubscribe();
-          reject(new Error(`Runtime Host refused the steering Message: ${result.reason}`));
-        })
-        .catch((error) => {
-          window.clearTimeout(timeout);
-          unsubscribe();
-          reject(error);
-        });
-    }),
+          reject(new Error("Timed out waiting for background stream output"));
+        }, 10_000);
+        const unsubscribe = window.maka.sessions.subscribeEvents(
+          sessionId,
+          (event) => {
+            if (event.type !== "text_delta" || !event.text.includes(steering))
+              return;
+            window.clearTimeout(timeout);
+            unsubscribe();
+            resolve();
+          },
+        );
+        // Runtime Host decides what this Message becomes; the test only needs it
+        // to reach the running Turn, so anything short of an accepted admission
+        // fails closed rather than waiting out the timeout.
+        void window.maka.sessions
+          .submitMessage(sessionId, "current_turn", {
+            messageId: crypto.randomUUID(),
+            text: steering,
+          })
+          .then((result) => {
+            if (result.ok) return;
+            window.clearTimeout(timeout);
+            unsubscribe();
+            reject(
+              new Error(
+                `Runtime Host refused the steering Message: ${result.reason}`,
+              ),
+            );
+          })
+          .catch((error) => {
+            window.clearTimeout(timeout);
+            unsubscribe();
+            reject(error);
+          });
+      }),
     { sessionId: originalSessionId!, steering: backgroundSteering },
   );
   await page.evaluate(() => {
-    // Painted frames only. A MutationObserver on `document.body` fires on every
-    // shell mutation during the remount, including React commit intermediates
-    // that never paint. Those samples made this assertion machine-load
-    // dependent (#3061): the same restore passed in isolation and failed when
-    // the rest of the file had already warmed the compositor.
-    const observed = {
-      texts: [] as string[],
-      maxActiveAnimations: 0,
-      stop() {},
-    };
-    let stopped = false;
-    const sample = () => {
-      if (stopped) return;
-      // The steer ends the waiting message; its acknowledgement streams in the last bubble.
-      const bubbles = [...document.querySelectorAll<HTMLElement>('.maka-bubble-streaming')];
-      const bubble = bubbles.at(-1);
-      if (bubble) {
-        const text = bubble.textContent ?? '';
-        if (observed.texts.at(-1) !== text) observed.texts.push(text);
-        observed.maxActiveAnimations = Math.max(
-          observed.maxActiveAnimations,
-          ...bubbles.map((element) => element
-            .getAnimations({ subtree: true })
-            .filter((animation) => animation.playState !== 'finished').length),
-        );
-      }
-      window.requestAnimationFrame(sample);
-    };
-    observed.stop = () => {
-      stopped = true;
-    };
-    (
-      window as typeof window & {
-        __makaBackgroundRestoreObserved?: typeof observed;
-      }
-    ).__makaBackgroundRestoreObserved = observed;
-    window.requestAnimationFrame(sample);
+    // Sample the paint clock, not React's intermediate mutation commits.
+    installStreamingPaintObserver();

Review Comment:
   `page.evaluate` serializes this function's source and runs it in the page — `installStreamingPaintObserver` is a Node-side import and does not exist in page scope, so this throws `ReferenceError` and the test fails when reached. `await page.evaluate(installStreamingPaintObserver)` works because the function body is self-contained — same shape as the `stopStreamingPaintObserver` call below.
   
   <details><summary>中文版</summary>
   `page.evaluate` 把这个函数的源码序列化到页面里执行,`installStreamingPaintObserver` 是 Node 侧 import,页面作用域里没有 → `ReferenceError`,测试必挂。改成 `await page.evaluate(installStreamingPaintObserver)` 即可(函数体自包含),和下面 `stopStreamingPaintObserver` 的写法一致。</details>



##########
packages/runtime-host/src/server/message-queue-state.ts:
##########
@@ -0,0 +1,130 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import { exactQueueReorder } from '@maka/core/message-queue-order';
+
+interface QueueEntryIdentity {
+  readonly entryId: string;
+  readonly messageId: string;
+}
+
+interface QueueCollections<Entry extends QueueEntryIdentity> {
+  steering: Entry[];
+  followup: Entry[];
+  readonly inFlight: ReadonlyMap<string, Entry>;
+}
+
+export type QueueRevisionCheck =
+  | { readonly kind: 'current'; readonly revision: number }
+  | { readonly kind: 'stale'; readonly expected: number; readonly actual: number };
+
+/** The Host owns this fence; clients may only propose a mutation against the revision they read. */
+export function checkQueueRevision(actual: number, expected: number): QueueRevisionCheck {
+  return actual === expected
+    ? { kind: 'current', revision: actual }
+    : { kind: 'stale', expected, actual };
+}
+
+export interface QueuedEntryLocation<Entry extends QueueEntryIdentity> {
+  readonly lane: 'steering' | 'followup';
+  readonly index: number;
+  readonly entry: Entry;
+}
+
+export type QueuedEntrySelection<Entry extends QueueEntryIdentity> =
+  | { readonly kind: 'found'; readonly location: QueuedEntryLocation<Entry> }
+  | { readonly kind: 'in_flight' }
+  | { readonly kind: 'wrong_lane'; readonly lane: QueuedEntryLocation<Entry>['lane'] }
+  | { readonly kind: 'missing' };
+
+export function locateQueuedEntry<Entry extends QueueEntryIdentity>(
+  state: QueueCollections<Entry>,
+  entryId: string,
+): QueuedEntryLocation<Entry> | undefined {
+  for (const lane of ['steering', 'followup'] as const) {
+    const index = state[lane].findIndex((entry) => entry.entryId === entryId);
+    const entry = index < 0 ? undefined : state[lane][index];
+    if (entry) return { lane, index, entry };
+  }
+  return undefined;
+}
+
+export function hasInFlightEntry<Entry extends QueueEntryIdentity>(
+  state: QueueCollections<Entry>,
+  entryId: string,
+): boolean {
+  return [...state.inFlight.values()].some((entry) => entry.entryId === entryId);
+}
+
+export function selectQueuedEntry<Entry extends QueueEntryIdentity>(
+  state: QueueCollections<Entry>,
+  entryId: string,
+  requiredLane?: QueuedEntryLocation<Entry>['lane'],
+): QueuedEntrySelection<Entry> {
+  const location = locateQueuedEntry(state, entryId);
+  if (location && (!requiredLane || location.lane === requiredLane)) {
+    return { kind: 'found', location };
+  }
+  if (location) return { kind: 'wrong_lane', lane: location.lane };
+  return hasInFlightEntry(state, entryId) ? { kind: 'in_flight' } : { kind: 'missing' };
+}
+
+export function removeQueuedEntry<Entry extends QueueEntryIdentity>(
+  state: QueueCollections<Entry>,
+  location: QueuedEntryLocation<Entry>,
+): Entry {
+  const [removed] = state[location.lane].splice(location.index, 1);

Review Comment:
   The splice runs before the identity check, so under the nack race (an in-flight entry `unshift`ed back into the lane while `retract` awaits `cancelMessageAdmissions`) this can remove the wrong entry and only then detect it — durable cancel already committed, wrong entry orphaned, target still queued. Checking `state[location.lane][location.index]` before splicing, or re-locating after the await like the update path does, would make the guard real. Note this race exists in the base too — the new version just fails loudly instead of silently removing the wrong entry, so it is not worse, but the assert as written cannot prevent the wrong removal.
   
   <details><summary>中文版</summary>
   splice 先于断言执行:nack 竞态下(`retract` await 期间 in-flight 条目被 `unshift` 回 lane 导致下标漂移)会先删错条目再发现——durable cancel 已提交、错删的条目成孤儿。改成先比对 `state[location.lane][location.index]` 再 splice,或像 update 路径那样 await 后重新 locate。这个竞态 base 就有,新版只是从静默删错变成响亮失败,不算变差,但现状断言挡不住错删。</details>



##########
packages/eval/harbor/egress_filter.py:
##########
@@ -150,49 +161,47 @@ def configure(updated: object) -> None:
 
 
 def request(flow: object) -> None:
-    apply_http_policy(flow, flow.request.pretty_url)
+    enforce_url_policy(flow, flow.request.pretty_url)
 
 
 def response(flow: object) -> None:
-    response = getattr(flow, "response", None)
-    if getattr(response, "status_code", None) != 101:
+    reply = getattr(flow, "response", None)
+    if getattr(reply, "status_code", None) != 101:
         return
     # mitmproxy 12.2.3 sets flow.websocket before HttpResponseHook only when
     # the 101 is a real WebSocket upgrade (Upgrade + version 13 + option on).
     # A websocket Upgrade header alone still falls through to CloseConnection
     # under rawtcp=false and must be audited.
     if getattr(flow, "websocket", None) is not None:
         return
-    record_raw_tunnel(flow)
+    reject_raw_transport(flow, close=False)
 
 
 def http_connect(flow: object) -> None:
+    request = getattr(flow, "request", None)
     try:
-        raw_url = connect_target_url(flow)
-    except Exception:
-        raw_url = ""
-    apply_http_policy(flow, raw_url)
+        target = parse_connect_target(
+            getattr(request, "host", None),
+            getattr(request, "port", None),
+        ).url
+    except (TypeError, ValueError):

Review Comment:
   Narrowing `except Exception` to `(TypeError, ValueError)` means an unexpected exception escapes the hook — the tunnel still dies (fail-closed) but no `policy_error` audit record is written, where the old version kept one. Nothing currently throws anything else, so this is a hardening gap rather than a live bug; keeping `except Exception` preserves the audit guarantee.
   
   <details><summary>中文版</summary>
   `except Exception` 收窄成 `(TypeError, ValueError)` 后,意外异常会逃出 hook——隧道仍被掐断(fail-closed)但不产生 `policy_error` 审计记录,旧版会留。当前输入集下不可达,属加固缺口;保留 `except Exception` 能保住审计保证。</details>



##########
packages/runtime/src/provider-retry-policy.ts:
##########
@@ -0,0 +1,91 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import type { ProviderRetryReason } from '@maka/core/events';
+import type { ModelFailureKind } from './model-protocol.js';
+
+const MAX_TIMER_DELAY_MS = 2_147_483_647;
+
+const RETRY_REASON: Record<ModelFailureKind, ProviderRetryReason | null> = {
+  abort: null,
+  auth: null,
+  context_overflow: null,
+  network: 'network',
+  provider_billing: null,
+  provider_capacity: 'provider_capacity',
+  provider_unavailable: 'provider_unavailable',
+  rate_limit: 'rate_limit',
+  request_rejected: null,
+  stream_truncated: 'stream_truncated',
+  timeout: 'timeout',
+  unknown: null,
+};
+
+export interface ProviderRetryDecision {
+  readonly reason: ProviderRetryReason | null;
+  readonly retryAfterMs?: number;
+}
+
+/** One pure policy decision consumed by both Runtime retrying and Host projection. */

Review Comment:
   This says the decision is "consumed by both Runtime retrying and Host projection", but nothing under `packages/runtime-host` imports this module (and it is not in the package exports) — the Host consumes the `reason` that arrives on the wire. Something like "consumed by Runtime retrying; the decision travels to the Host inside `provider_retry` events" would not mislead the next reader.
   
   <details><summary>中文版</summary>
   注释说这个决策被 Runtime 重试和 Host 投影共同消费,但 `packages/runtime-host` 没有任何地方 import 它(也不在 package exports 里)——Host 消费的是 wire 上已分类的 `reason`。改成 "consumed by Runtime retrying; the decision travels to the Host inside `provider_retry` events" 更准确。</details>



##########
packages/runtime-host/src/server/message-coordinator.ts:
##########
@@ -2000,60 +1894,62 @@ export class HostMessageCoordinator implements RuntimeMessageAuthority {
     queued.entry.submittedContentDigest = messageContentDigest(content);
     queued.entry.skillInvocation = prepared.skillInvocation;
     this.#mutated(state);
-    const result = { queueRevision: state.revision };
-    this.#rememberCompletedOperation(
-      'update_entry',
-      input.sessionId,
-      input.updateId,
-      input,
-      result,
-    );
-    return success(result);
+    return this.#completeQueueEntryMutation('update_entry', state, input.updateId, input);
   }
 
   async #reorderQueuedEntriesAdmitted(
     input: QueueEntriesReorderInput,
   ): Promise<MessageOutcome<QueueMutationResult>> {
-    const header = await this.#root.readSessionHeader(input.sessionId);
-    if (this.#failStopped) {
-      return failure('host_draining', 'Runtime Host message authority has failed');
-    }
-    if (!header) return failure('not_found', 'Session does not exist');
-    if (header.isArchived) return failure('session_archived', 'Session is archived');
-    const state = this.#state(input.sessionId);
-    if (state.transition) {
-      return failure('operation_conflict', 'Message queue is draining into the next Turn');
-    }
-    const steering = state.steering.some((entry) => entry.entryId === input.entryIds[0]);
-    const current = steering ? state.steering : state.followup;
-    if (input.entryIds.length !== current.length) {
+    const admitted = await this.#openQueueMutation(input.sessionId);
+    if (!admitted.ok) return admitted;
+    const state = admitted.result;
+    if (checkQueueRevision(state.revision, input.expectedQueueRevision).kind === 'stale') {
       return failure('operation_conflict', 'Message queue changed since the reorder was issued');
     }
-    const byId = new Map(current.map((entry) => [entry.entryId, entry]));
-    const reordered: LiveEntry[] = [];
-    for (const entryId of input.entryIds) {
-      const entry = byId.get(entryId);
-      if (!entry) {
-        return failure('operation_conflict', 'Message queue changed since the reorder was issued');
-      }
-      byId.delete(entryId);
-      reordered.push(entry);
+    const reorder = planQueueReorder(state, input.entryIds);
+    if (!reorder) {
+      return failure('operation_conflict', 'Message queue changed since the reorder was issued');
     }
-    if (reordered.some((entry, index) => current[index] !== entry)) {
+    if (reorder.changed) {
       await this.#admissions.reorderMessageAdmissions(
         input.sessionId,
-        reordered.map((entry) => entry.messageId),
-        steering ? 'steering' : 'followup',
+        reorder.entries.map((entry) => entry.messageId),
+        reorder.lane,
       );
-      if (steering) state.steering = reordered;
-      else state.followup = reordered;
+      commitQueueReorder(state, reorder.lane, reorder.entries);
       this.#mutated(state);
     }
-    const result = { queueRevision: state.revision };
-    this.#rememberCompletedOperation('reorder', input.sessionId, input.reorderId, input, result);
+    return this.#completeQueueEntryMutation('reorder', state, input.reorderId, input);
+  }
+
+  #completeQueueEntryMutation(
+    kind: Extract<QueuedMutationKind, 'retract_entry' | 'promote' | 'update_entry' | 'reorder'>,
+    state: SessionState,
+    operationId: string,
+    input: object,
+  ): MessageOutcome<QueueMutationResult> {
+    const result: QueueMutationResult = { queueRevision: state.revision };
+    this.#rememberCompletedOperation(kind, state.sessionId, operationId, input, result);
     return success(result);
   }
 
+  async #openQueueMutation(
+    sessionId: string,
+    allowTransition = false,
+  ): Promise<MessageOutcome<SessionState>> {
+    const header = await this.#root.readSessionHeader(sessionId);
+    if (this.#failStopped) {
+      return failure('host_draining', 'Runtime Host message authority has failed');
+    }
+    if (!header) return failure('not_found', 'Session does not exist');
+    if (header.isArchived) return failure('session_archived', 'Session is archived');
+    const state = this.#state(sessionId);
+    if (!allowTransition && state.transition) {

Review Comment:
   Ordering change vs base: `promote` previously hit the `session_busy` phase check before the transition check; now a residual `state.transition` short-circuits to `operation_conflict` first. Only observable if a failed terminal transition leaves `transition` set, but if the `session_busy` retry semantics were intentional for clients, keeping the phase check ahead of the transition check for `promote` preserves the old error code.
   
   <details><summary>中文版</summary>
   与 base 的顺序差:`promote` 以前先过 `session_busy` 的 phase 检查再到 transition 检查;现在残留的 `state.transition` 会先短路成 `operation_conflict`。只在 terminal transition 失败留下残留态时可见,但如果 `session_busy` 对 client 的可重试语义是有意的,把 phase 检查放回前面能保住旧错误码。</details>



##########
packages/eval/harbor/eval_framework.py:
##########
@@ -15,26 +15,49 @@
 # specific language governing permissions and limitations
 # under the License.
 
-"""Authoritative Eval harness framework selection.
-
-`run_trial.py` validates the argv framework and installs it here before Harbor,
-Pier, or the shared relay can import. The relay must not read the environment.
-"""
+"""Process-local framework authority shared by the trial runner and relay."""
 
 from __future__ import annotations
 
-_FRAMEWORKS = frozenset({"harbor", "pier"})
-_framework: str | None = None
+from typing import NamedTuple
+
+
+class FrameworkSpec(NamedTuple):
+    name: str
+    distribution: str
+    agent_module: str
 
 
-def install(framework: str) -> None:
-    if framework not in _FRAMEWORKS:
+_FRAMEWORKS = {
+    "harbor": FrameworkSpec("harbor", "harbor", "harbor.agents.base"),
+    "pier": FrameworkSpec("pier", "datacurve-pier", "pier.agents.base"),
+}
+_active: FrameworkSpec | None = None
+
+
+def framework_spec(name: str) -> FrameworkSpec:
+    try:
+        return _FRAMEWORKS[name]
+    except KeyError:
         raise RuntimeError("framework must be harbor or pier")
-    global _framework
-    _framework = framework
 
 
-def selected() -> str:
-    if _framework not in _FRAMEWORKS:
+def install(name: str) -> None:
+    """Select the framework before importing its process-wide relay module."""
+
+    global _active

Review Comment:
   `install()` silently replaces a prior selection, but relay modules bind their base class at import — a second `install()` in the same process would diverge `current_framework()` from the already-bound `BaseAgent`. Unreachable today (one process per trial) — a guard that raises when a different spec is already installed, or once `relay_agent` is in `sys.modules`, would make the invariant explicit instead of relying on call order.
   
   <details><summary>中文版</summary>
   `install()` 允许静默替换已安装的选项,但 relay 模块在 import 时就绑定了 base class——同进程第二次 install 会让 `current_framework()` 和已绑定的 `BaseAgent` 发散。生产每 trial 一个进程所以不可达;加一个守卫(已装不同 spec 或 `relay_agent` 已在 `sys.modules` 时 raise)可以把不变量写死,而不是靠调用顺序。</details>



##########
packages/ui/src/composer-message-queue-controller.ts:
##########
@@ -0,0 +1,163 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import { useRef, useState } from "react";
+import type { MessageQueueEntryProjection } from "@maka/core/events";
+import { moveQueueEntryId } from "@maka/core/message-queue-order";
+import type { TransientUserMessageProjection } from "./chat-view.js";
+import { useMountedRef } from "./use-mounted-ref.js";
+
+export type ComposerQueueEntry = Omit<MessageQueueEntryProjection, "state"> & {
+  state: MessageQueueEntryProjection["state"] | "local";
+  localMessage?: TransientUserMessageProjection;
+};
+
+export interface ComposerQueueActions {
+  queueRevision?: number;
+  onUpdateEntry?(entryId: string, expectedQueueRevision: number, text: string): void | Promise<void>;
+  onReorderEntries?(entryIds: readonly string[], expectedQueueRevision: number): void | Promise<void>;
+}
+
+export function useComposerMessageQueueController(
+  entries: readonly ComposerQueueEntry[],
+  actions: ComposerQueueActions,
+) {
+  const [pendingEntryId, setPendingEntryId] = useState<string | null>(null);
+  const [editing, setEditing] = useState<{
+    entryId: string;
+    queueRevision: number;
+    text: string;
+  } | null>(null);
+  const pending = useRef<string | null>(null);
+  const drag = useRef<{ entryId: string; queueRevision: number } | null>(null);
+  const mountedRef = useMountedRef();
+
+  const groups = (["current_turn", "next_turn"] as const)
+    .map((placement) => ({
+      placement,
+      entries: entries.filter((entry) => entry.placement === placement),
+    }))
+    .filter((group) => group.entries.length > 0);
+
+  async function runAction(
+    entryId: string,
+    action: (() => void | Promise<void>) | undefined,
+  ): Promise<boolean> {
+    if (!action || pending.current) return false;
+    pending.current = entryId;
+    setPendingEntryId(entryId);
+    try {
+      await action();
+      return true;
+    } catch {
+      return false;
+    } finally {
+      if (pending.current === entryId) pending.current = null;
+      if (mountedRef.current) setPendingEntryId(null);
+    }
+  }
+
+  function beginEdit(entry: ComposerQueueEntry): void {
+    if (pendingEntryId || !actions.onUpdateEntry || actions.queueRevision === undefined) return;
+    setEditing({
+      entryId: entry.entryId,
+      queueRevision: actions.queueRevision,
+      text: entry.content.displayText ?? entry.content.text,
+    });
+  }
+
+  function cancelEdit(): void {
+    setEditing(null);
+  }
+
+  async function commitEdit(): Promise<void> {
+    if (!editing) return;
+    const text = editing.text.trim();
+    if (!text) return;
+    const updated = await runAction(editing.entryId, () =>
+      actions.onUpdateEntry?.(editing.entryId, editing.queueRevision, text),

Review Comment:
   If the Host rejects this update with `operation_conflict` (queue changed while the user was editing), `editing` stays open but keeps the stale captured `queueRevision` — every subsequent save fails the same way, and the only escape is `cancelEdit`, which discards the typed text. Consider closing the editor on conflict (the list re-renders from the Host projection anyway) or refreshing `editing.queueRevision` before the next save.
   
   <details><summary>中文版</summary>
   如果 Host 因队列已变化拒绝这次 update(`operation_conflict`),编辑器保持打开但仍拿着捕获时的过期 `queueRevision`——之后每次保存都会同样失败,唯一出路是取消并重输。建议在冲突时直接关掉编辑器(列表反正按 Host 投影重渲染),或下次保存前用当前 `actions.queueRevision` 刷新。</details>



##########
packages/storage/src/project-catalog.ts:
##########
@@ -859,12 +872,13 @@ export interface ResolvedProjectLocation {
 
 export async function resolveProjectLocation(input: {
   path: string;
+  intent?: 'selected';
 }): Promise<ResolvedProjectLocation> {
   const canonicalPath = normalize(await realpath(resolve(input.path)));
-  // Regular files are not valid projects. Without this check, a file inside a
-  // Git worktree reaches `git -C <file> rev-parse ...`, whose numeric failure
-  // is not treated as an invalid path by the Host coordinator and drains it.
-  if (!(await stat(canonicalPath)).isDirectory()) {
+  const location = await stat(canonicalPath);
+  // Reject files before Git discovery: `git -C <file>` reports a generic
+  // process failure that callers cannot classify as an invalid project path.

Review Comment:
   Good to see the rationale comments back. Two consequence details from the base version are worth keeping as well: the file rejection exists because `git -C <file>`'s generic failure was "not treated as an invalid path by the Host coordinator and drains it", and the selected-path check exists because selecting `repo/child` "would silently become `repo`". Without the consequences spelled out, a future reader may again conclude the checks are removable.
   
   <details><summary>中文版</summary>
   注释恢复了好。建议把 base 里的后果细节也留住:文件路径要拒是因为 `git -C <file>` 的通用失败"不会被 Host coordinator 判为无效路径、会把它拖垮";selected 检查存在是因为选了 `repo/child` 会"静默变成 `repo`"打开父项目。不写清后果,下一个维护者可能又把这些检查当冗余删掉。</details>



##########
apps/desktop/src/main/runtime-host-queue-mutation-ipc.ts:
##########
@@ -0,0 +1,139 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import type { ReconnectableReadIpcMain } from "./ipc-reconnect-policy.js";
+import type { DesktopRuntimeHostClient } from "./runtime-host-client.js";
+
+export type RuntimeHostQueueMutationClient = Pick<
+  DesktopRuntimeHostClient,
+  | "promoteQueueEntry"
+  | "reorderQueueEntries"
+  | "retractQueueEntry"
+  | "updateQueueEntry"
+>;
+
+export function registerRuntimeHostQueueMutationIpc(
+  ipcMain: ReconnectableReadIpcMain,
+  client: RuntimeHostQueueMutationClient,
+  newId: () => string,
+): void {
+  for (const mutation of queueMutationRegistrations(client)) {
+    ipcMain.handle(mutation.channel, async (_event, ...args: unknown[]) => {
+      await mutation.invoke(args, newId);
+    });
+  }
+}
+
+type QueueMutationRegistration = {
+  readonly channel:
+    | "sessions:promoteQueueEntry"
+    | "sessions:reorderQueueEntries"
+    | "sessions:retractQueueEntry"
+    | "sessions:updateQueueEntry";
+  readonly invoke: (args: readonly unknown[], newId: () => string) => Promise<void>;
+};
+
+function queueMutationRegistrations(
+  client: RuntimeHostQueueMutationClient,
+): readonly QueueMutationRegistration[] {
+  return [
+    {
+      channel: "sessions:retractQueueEntry",
+      invoke: async ([sessionId, entryId], newId) => {
+        await client.retractQueueEntry({
+          sessionId: requiredId(sessionId, "Session"),
+          entryId: queueEntryId(entryId),
+          retractId: newId(),
+        });
+      },
+    },
+    {
+      channel: "sessions:promoteQueueEntry",
+      invoke: async ([sessionId, entryId], newId) => {
+        await client.promoteQueueEntry({
+          sessionId: requiredId(sessionId, "Session"),
+          entryId: queueEntryId(entryId),
+          promoteId: newId(),
+        });
+      },
+    },
+    {
+      channel: "sessions:updateQueueEntry",
+      invoke: async ([sessionId, entryId, expectedQueueRevision, text], newId) => {
+        await client.updateQueueEntry({
+          sessionId: requiredId(sessionId, "Session"),
+          entryId: requiredId(entryId, "Queue entry"),
+          updateId: newId(),
+          expectedQueueRevision: queueRevision(expectedQueueRevision),
+          text: queuedMessageText(text),
+        });
+      },
+    },
+    {
+      channel: "sessions:reorderQueueEntries",
+      invoke: async ([sessionId, entryIds, expectedQueueRevision], newId) => {
+        await client.reorderQueueEntries({
+          sessionId: requiredId(sessionId, "Session"),
+          reorderId: newId(),
+          expectedQueueRevision: queueRevision(expectedQueueRevision),
+          entryIds: queueEntryOrder(entryIds),
+        });
+      },
+    },
+  ];
+}
+
+function queueEntryId(value: unknown): string {

Review Comment:
   `queueEntryId` accepts any string including empty or overlong, while `requiredId` below enforces non-empty and ≤256 — and the update path in this same file already uses the stricter shape for its ids. Aligning them costs nothing and keeps IPC validation uniform.
   
   <details><summary>中文版</summary>
   `queueEntryId` 只查 `typeof === 'string'`(空串/超长都放行),而同文件 `requiredId` 要求非空且 ≤256,update 路径已经在用严格版。对齐它们不花成本,IPC 校验也保持一致。</details>



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@maka.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@maka.apache.org
For additional commands, e-mail: commits-help@maka.apache.org


Re: [PR] audit: rewrite retained Grok-assisted contribution cores [maka]

Posted by "likun666661 (via GitHub)" <gi...@apache.org>.
likun666661 commented on PR #5747:
URL: https://github.com/apache/maka/pull/5747#issuecomment-5854269093

   Addressed the review suggestions in the latest push.
   
   - Added a reproducible per-PR squash-line survival table at current `main` (`027d6afba`). The total remains 3,935 surviving attributed lines; the document records the mixed-commit and no-`-C` caveats and does not treat blame as a remediation metric.
   - Recorded #3063, #3118, #3123, and #3069 as having no surviving added output; the other 21 now have explicit current-tree dispositions.
   - Unified the document baseline and marked the earlier `d89ccce01` revert probe as historical evidence.
   - Replaced the unlinked “tracked separately” claim for closed/unmerged PRs with an explicit out-of-inventory statement.
   - Added the ASF legal decision paths, the RC2 impact analysis, and a cross-link to #5746 (future contributions versus #5747's historical review).
   - Advanced the branch through current `origin/main`, reran the affected builds/tests/inventory gates, and raised the Runtime Host compatibility epoch for the mandatory queue-reorder revision fence.
   
   All engineering review/disposition items are now complete. The remaining gates are the new CI run and the project/ASF legal decision.


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@maka.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@maka.apache.org
For additional commands, e-mail: commits-help@maka.apache.org