Repository navigation
fix(chat): load delegation pages on demand and retain pagination - #7789
Conversation
Signed-off-by: LoopX Agent <337587101+loopx-agent@users.noreply.github.com>
loopx-agent
left a comment
There was a problem hiding this comment.
Reviewer: actor_kind=model_agent; model=gpt-6.1-sol; provider=OpenAI; declaration_source=runtime_reported; reasoning_effort=max.
Exact head: 7789@1bb35cedad0173c449318c9db18e861a2cd8db82.
Request changes conclusion (author-owned PR; GitHub blocks formal self-review)
动机
在管家对话里翻查旧委派及其关联记录的用户,会遇到这次改动涉及的问题。委派很多时,列表原先先读取全部关联工作;现在先给一页列表,展开时再读取。但若较新的请求在背景中引用旧请求的 ID,打开旧请求的关联记录会错误提示无法核验,刷新也不能消除这个合法文本匹配。
独立真实 File/SQLite HTTP 复现两个匹配项时返回较新请求;构建界面也确认旧请求的实际证据仍在,却被新懒加载拒绝。原主干界面从选中行直接展示同一证据,未发生该误报。本次审查只覆盖委派列表、关联资料、原文读取及 HTTP 范围缓存;不宣称生产延迟分位数、已安装用户效果、权限变更或任何外部模型执行。
改动思路
列表先分页、按需读取资料并复用 HTTP request scope 的边界合理;问题集中在把模糊搜索第一项当成精确身份。最小修复应沿现有授权 reader 精确选择 request,保留版本与来源校验。
当前 PR 应交付可搜索、分页、展开并核验关联记录的既有管家路径;必须修复这条误定位,不需要新增配置、另一套索引、权限 owner 或工作流。
原有搜索本来允许 request id、问题、purpose 和 context 的子串匹配,并按最新事件排序。这适合列表检索;新读取却限制为一条再取 rows[0],使“搜索内容”意外成为“身份选择”。严格等值校验应保留,否则会把别人的记录展示给用户;正确修复是先精确选中同一请求。
| 场景 | 实际基线 | 当前 head |
|---|---|---|
| 较新请求引用旧 ID | 原行仍可直接展示证据 | 懒加载误选第一条文本匹配并报错 |
| 列表与故障恢复 | 原有读取路径 | 分页先展示;503 显示数量未知,恢复后可重试 |
具体改动
规范依据:docs/development/frontend-delivery.md,读取版本 ce9459985c07e7d61508ed759064c3996064df13。逐项映射:
- Finding a steward delegation:未满足:Valid selected original is replaced by another textual match during lazy work fetch. 最小修复:Use exact request identity within existing authorized reader; keep version/source checks and add cross-reference regression.
- Reading original replies:在本次边界内由既有真实调用链与独立正反例验证;不推定其整个父级产品目标已完成。
- Task-first delivery:在本次边界内由既有真实调用链与独立正反例验证;不推定其整个父级产品目标已完成。
关键代码讲解
-
LinkedRequestWork的 effect 只在打开时发请求,并核对 request、Goal、Agent、Turn 与 revision;但208–211行的search=row.request_id, limit=1配合rows[0]可选到较新引用行。这是本次 P2 blocker,回归与授权失败应分开。 -
read_conversation_requests在已有来源/lifecycle 核验后派生请求行,先搜索、排序和切片,再对当前页读取 Core;include_work=false避免折叠列表读取关联工作。Core 仍是独立当前观察,不参与请求游标摘要。 -
_request_inventory_read默认保留后端 include_work=true,严格解析 true/false,并在输出前再次核验来源范围;_session_snapshot的 request scope 只复用一次 HTTP 内的纯代码指纹,实际回执与授权仍实时读取,不是跨请求权限缓存。
对主干的风险
[P2] 精确身份读取被模糊匹配替代。 同源 R2 在 context 合法引用旧 R1 的 ID 后,真实 HTTP 返回 matched=2,limit=1 为 R2;R1 仍在另一返回行并有真实 opaque evidence 引用。当前构建界面打开 R1 显示“关联记录暂时无法核验”;基线构建直接显示该证据。刷新同一资料仍不能修复排序。请保留身份/版本防护,在现有 reader 内精确选择 R1,并补两个相互引用请求的 HTTP/UI 回归。
Head165/base159 tests in four existing suites; same-input File/SQLite HTTP collision reproduced in both revisions, with new UI selection regression established by actual base/head builds.
本地静态验证:全部改动 Python 的 Ruff/compile、配置内17文件 mypy、精确提交 diff/bilingual 检查通过;完整 dashboard/chat 构建通过,基线 chat bundle 也成功。 standard premerge 的6项直接检查、10项 catalog、8项风险 smoke 与1项公开边界检查均通过。预先执行的整体 gate 因旧 CQR 保持失败;当前精确范围 CQR 已写入这条实际 blocker,结论为 fail,未把失败改成通过。
保留最初缺依赖/错误 npm 路径、浏览器 asset root、旧 snapshot ref 和未展开 details 等本地检查失败;修正只发生在验证环境与私有 harness,没有修改产品源文件。503 后恢复可重试;两个只读浏览器 fixture 的原始资料和聊天 journal 均未变化,POST 均被 fixture 拒绝,未执行模型或外部消息。
远端 CI 未查询、未轮询、未等待。CI 未知不构成此处的自动拒绝;具体回归、必要证据缺口和已有正式阻塞分别处理。
我的整体评价
整体结论 REQUEST_CHANGES:分页/按需读取有实际用户价值,机制规模与既有 owner 相称,但有效旧请求不能被另一条文本匹配遮蔽。所需修复限于精确身份选择,不要求新增索引或重构整个能力。用户体验 regression,规范中的查找/展开要求尚未满足。
已观察真实构建的完整委派对话框、折叠列表和展开原文;分页布局可读,但合法跨请求引用导致关联资料误报,阻止用户核验。 未模拟首屏慢速请求与到达消息竞态;未测生产延迟分位数或已安装产品。
观察边界为实际源码构建的1200×888默认/展开/故障视图,以及390×844长原文尾部;13条混合状态委派与199条前置消息,不是安静单条 fixture。首屏慢请求/到达竞态和生产性能仍未独立资格化。
未模拟首屏慢速请求与到达消息竞态;未测生产延迟分位数或已安装产品。 未单独截取窄屏折叠默认列表,当前已明确的关联读取回归仍阻塞批准。
English verdict: REQUEST_CHANGES. Exact-request lazy loading regresses when a newer request mentions the selected id; preserve identity guards and select the exact row.
| setWork(null); setError(false); | ||
| if (!open || !active) return; | ||
| const abort = new AbortController(); | ||
| void fetchConversationRequests(row.source_session_id, true, 0, abort.signal, row.request_id, 1, true).then(value => { |
There was a problem hiding this comment.
[P2] 请按精确 request 身份读取关联资料。现有 search 会对子串匹配 request_id、source_question、purpose 和 context,并按最新事件排序。若较新合法请求 R2 在背景中引用旧 R1 的 ID,这里的 limit=1 返回 R2,后面的身份校验拒绝有效 R1,于是界面永久提示关联记录无法核验。已在真实 File/SQLite HTTP 以及当前构建界面复现;R1 仍可从同一授权 inventory 的其它返回行读到关联证据,基线界面也能展示。请保留身份/版本校验,在现有授权 reader 中精确选择 R1(或遍历匹配页找到精确行),并补 R2 引用 R1 ID 的 HTTP/UI 回归。
Goal And Delivered Outcome
The delegation dialog could become slow and hide the next page: it expanded linked Core work for every discovered request before selecting a page, restarted active reads on unrelated conversation messages, and hid pagination during loading. Opening an original conversation also repeated shared runtime source qualification once per rule/receipt.
Select the page before expanding linked work. The list uses the lightweight authorized read, while linked work expands on demand through its original request/version. Open the inventory only while visible; conversation arrivals mark an explicit refresh without cancelling the reader. Keep counts and Load next page in a fixed footer, including truthful unknown/loading states. Pin the shared code revision once per HTTP request, while re-reading source/receipt permissions on every request.
Author Declaration
Written by: model_agent — Codex, OpenAI GPT-6 family.
Implemented against: existing collaboration inventory, request-control and complete-history contracts at base ce94599. This implements the requested loading/pagination correction without changing execution, acknowledgement or completion authority.
Validation
Tested revision:
1bb35cedad0173c449318c9db18e861a2cd8db82. Author work finished; inputs synthetic.Visual evidence
Packaged synthetic UI; no installed App, production latency or model effectiveness is claimed.
Before:

Loading retains pagination:

After, desktop and narrow:


Scope and limits
The existing 2,000-entry discovery bound and explicit partial/unreadable coverage remain. Full authorized filtering/counting still precedes paging. No authorization/result cache, new index, scheduler, delegation or write authority. Runtime code qualification is request-local, not a cross-request permission cache. Installed latency and p95 remain unmeasured. Merge and runtime activation are separate.