feat(control-plane): promote the personal Agent workspace RFC - #3269
feat(control-plane): promote the personal Agent workspace RFC#3269maxliux5 wants to merge 105 commits into
Conversation
* feat(dash): live session dash panel focused on human-readable fleet progress Adds `loopx dash`: a loopback single-page control panel that tracks agent session task progress and result statistics in real time, organized the way an operator reads it — sessions (agent runtimes) on top, the goals each session owns underneath, and per goal the status badge, todo progress bar, waiting reason, latest run, and next action. - `loopx dash` serves at http://127.0.0.1:8767/ with in-place auto-refresh (default 10s) by polling the `/panel` fragment; `--goal-id` narrows the fleet view to one goal. - `loopx dash generate` keeps the one-shot static HTML snapshot, with the public/private boundary scan enforced before success. - Projection `session_dash_projection_v1` folds the status contract (attention queue, run-history goals, todo index, agent-management sessions, usage summary) into a compact fleet snapshot; internal control machinery (decision frames, work-lane contracts, quota slot math, truth contracts, source warnings, lease bookkeeping) is intentionally not rendered. - Routes: GET /, GET /panel, GET /status.json, GET /healthz. Loopback-only; no write routes, read-only markers, escaped output + boundary scan. - Docs: design doc, dashboard README run guide, README surface row. - Validation: examples/session-dash-panel-smoke.py (fleet fixture, read-only markers, refresh script, fragment shape, boundary negative controls, XSS escape, focus filter). Squashed from the PR #2897 branch history. * fix(dash): enforce boundary scan before every dash output path Apply the public/private boundary gate consistently so private material cannot leave through any dash output surface. - dash generate: run the scan before payload assembly or --out file creation; on failure omit html/html_path/projection from the payload and write no file (previously the file was written and the raw html leaked into the JSON payload before the scan error was returned). - dash server: serve /panel and /status.json through the same boundary check as /; withhold with 500 when the scan fails so private values cannot be served via the auto-refresh fragment or the status JSON. - smoke: add negative coverage that injects PRIVATE_TRAP_MARKERS into next_action/session text and asserts generated output is withheld, no --out file is written, and the server endpoints return 500. * ci(python-tests): diff CLI output against the PR base branch The agent-facing CLI output differential defaulted to origin/main, so a PR whose base branch is not main (e.g. frontend-control-plane-im-prototype-rfc) failed whenever main moved a shared baseline such as the heartbeat-prompt portfolio. Point LOOPX_CLI_OUTPUT_BASE_REF at the pull request base branch, falling back to origin/main for main pushes.
A goal can appear in run_history with no latest run and no recommended_action on its attention item (live registries do this). The projection called .get() on the missing run when composing next_action, raising 'NoneType' object has no attribute 'get' and making the live panel 500 on /, /panel, and /status.json. Guard the fallback branch the same way latest_run_at/latest_classification already do, and add a regression smoke for the empty-latest-run goal shape. Follow-up to #2897 which merged before this fix landed.
fix(dash): guard missing latest run in goal projection
…ct-resolution chore: sync main into frontend control plane prototype
Extend the merged single-page session dash panel (PR #2897/#2997) with an explicit Todo column on each goal table (sessions and unassigned): open agent / open user / done counts, rendered from the existing open_agent_todos/open_user_todos/done_todos projection fields. Pure presentation-layer enhancement; no new capability, read-only surface and boundary scan unchanged. Smoke: session-dash-panel-smoke asserts the Todo column, todo-count badges and agent/user/done classes; all related smokes pass.
feat(dash): show per-goal todo breakdown column
…ne-chat-session feat(chat): add recoverable Goal Agent control plane
…ct-resolution-2 chore: sync latest main into frontend control plane prototype
The panel displayed 'Waiting on: codex' for goals whose latest run is classified as codex-ready, which reads as a product reference (Codex CLI) even when the lane is actionable by any agent host (Codex, Pi, etc.). Map the codex waiting classification to the host-neutral 'agent' word at the projection layer; both words classify identically in the status-bucket logic, so no bucket behavior changes. Smoke: session-dash-panel-smoke asserts a codex-classified fixture goal projects waiting_on == 'agent'; verified live against the loopx registry.
feat(dash): surface waiting lane host-neutral as agent
…ession-startup-fixes
…ome-tiers Personal workspace: manager home, Lark connections, and session records
# Conflicts: # pyproject.toml
huangruiteng
left a comment
There was a problem hiding this comment.
Request changes conclusion (author-owned PR; GitHub review-state fallback)
精确评审头(Exact Head): 3269@19842750bf2a334eaa8dc2340d63b431e8c26d22
Base: main | 类型: personal Agent workspace RFC promotion(133 files, +33462/-289)
作者: huangruiteng(owner,多贡献者合入)
详细中文评审
动机
把个人 Agent workspace / 前端控制面 RFC 提升到 main:Manager workspace、Goal-scoped Chat/Tasks/Files、typed-action Preview/Apply 安全边界、Session 真相投影、Lark 连接与多主题支持。PR 自述门禁:“Merge only after required CI is green and an independent review confirms the safety and projection changes.”
改动思路
多源能力合入:前端 apps/presentation/dashboard(37 文件)+ 控制面投影/配额/运行历史(loopx/presentation/projections/session_dash.py、loopx/control_plane/quota/usage_collector.py、run_history.py)+ Lark goal-topic 连接 + dashboard CLI(loopx/cli_commands/dash.py)。安全核心是 apps/presentation/dashboard/src/features/personal-workspace/personal-workspace-router.ts 的受限路由契约与 loopx/presentation/public_safety.py 的 Preview/Apply 边界。
具体改动
133 个文件、+33k/-289,主体是前端与展示面;控制面侧新增/修改约 15 个 Python 文件(quota usage collector、session projections、public safety、status collection、Lark goal-topic runtime、cli output budget/differential)。API diff 超过 20k 行上限,无法在单次 bounded slice 内逐行审完,需分片复核。
关键内容讲解
- 路由安全契约:free text 进入受限路由结果(projection / typed_action / agent_chat / clarify),显式动作优先,typed action 仍需 canonical Preview + state fingerprint + 确认 + receipt;低置信/歧义走 clarification。
- CLI 输出预算:PR 同时修改了
cli_output_budget.py/cli_output_differential.py,但 base/head 差分仍超预算(见下 P1-2)。 - Session 真相:状态/进度/输出/运行历史统一来自权威投影(session_dash projections),前端不自行解释。
对主干的风险
阻断项(P1,两个)
- DCO sign-off 缺失:Sign-off check FAIL,共 20 个 commit 缺少
Signed-off-bytrailer(含 head19842750)。需为这些 commit 补git commit --amend -s后 force-push。 - CI pytest 红:
examples/control_plane/cli-output-base-head-differential-smoke.py失败——agent-facing CLI base/head 差分:chars +712(allowance 137)、utf8_bytes +712、lines +25(allowance 4)。要么收敛 agent-facing CLI 输出增长,要么给出逐项证据并更新差分 allowance(不能只改测试阈值)。
非阻断(P2)
- 大 PR 独立复核:133 文件/+33k 的提升涉及运行时与公开首屏;按 PR 自身门禁,router 安全契约与投影面需要独立、分片的复核证据(浏览器 smoke、CUA、router smoke 均需在 exact head 复跑并留证),建议在 CI 绿后分片完成复核再合并。
- 其余检查:build ×2 SUCCESS、dependency-review SUCCESS、deploy SKIPPED。
验证矩阵(exact head 实测)
| 场景 | 结果 |
|---|---|
| Sign-off(DCO) | FAILURE(20 commits 缺 trailer,含 head) |
| pytest(CLI base/head differential) | FAILURE(chars +712 / lines +25,超 allowance) |
| build ×2 / dependency-review | SUCCESS |
| deploy / upload-release / publish-pypi | SKIPPED |
| diff 范围 | 133 files, +33462/-289(API diff >20k 行) |
我的整体评价
能力方向清晰、安全边界设计合理,但当前 exact head 不满足合并门禁:DCO 缺 20 个 trailer、agent-facing CLI 输出差分超预算导致 pytest 红。按 PR 自己写的 gate,必须在 CI 全绿后再做独立的 router/投影分片复核。结论:REQUEST_CHANGES(窄化:补 DCO + 收敛 CLI 输出增长;随后分片复核安全面)。
English Verdict
Verdict: REQUEST_CHANGES — exact head 3269@19842750bf2a334eaa8dc2340d63b431e8c26d22.
Summary: The personal Agent workspace promotion has a sound safety design (constrained router, Preview/Apply boundary, authoritative Session projection), but two P1 blockers remain: (1) the DCO/Sign-off check fails because 20 commits (including the head) lack Signed-off-by trailers; (2) CI pytest fails because the agent-facing CLI base/head differential exceeds its budget (chars +712 vs allowance 137, lines +25 vs 4). Build and dependency-review pass. Per the PR's own gate, merge requires green CI plus a staged independent review of the router safety and projection surfaces.
Signed-off-by: maxliu <lualiudd@gmail.com>
Signed-off-by: maxliu <lualiudd@gmail.com>
huangruiteng
left a comment
There was a problem hiding this comment.
Request changes conclusion (author-owned PR; GitHub review-state fallback)
精确评审头(Exact Head): 3269@3856305c77f006f96933d274f485dee0cb94cc3a
Base: main | 类型: Agent workspace 提升后的输出收敛修复(2 files, +60/-2)
作者: huangruiteng(owner,多贡献者合入)
详细中文评审
动机
上一轮 REQUEST_CHANGES 指出两个 P1:DCO sign-off 缺失与 agent-facing CLI base/head 输出差分超预算。作者新增 fix(status): omit empty usage aggregates(仅在有实际 usage 样本的窗口输出 usage 指标),试图收敛输出。
改动思路
usage_summary.py 增加 USAGE_METRIC_NAMES 与 _strip_unobserved_usage_windows:totals 与每个 goal bucket 只保留 24h/7d 中确有 usage 样本的窗口字段;对应测试断言无样本窗口不再输出 input_tokens_*/cost_usd_*/duration_ms_*。方向正确:空聚合不再膨胀输出。
具体改动
loopx/control_plane/quota/usage_summary.py(+30):窗口级 usage 字段裁剪。tests/control_plane/test_usage_summary.py(+32/-2):两个新测试锁定“无样本窗口不输出字段”与“仅输出有样本的窗口”。
关键内容讲解
- 裁剪语义:
observed_usage_windows只在usage_sample is not None时记录24h/7d;_strip_unobserved_usage_windows移除未观察窗口的 5 类指标。totals 与 goal 行分别裁剪。 - 兼容性:
runs_24h/runs_7d计数保持,历史字段语义不变。
对主干的风险
阻断项(P1,两个,仍存在)
- DCO 仍未修复:Sign-off check 仍 FAILURE——新 commit
3856305c本身带 trailer,但 PR 历史中仍有 20+ 个 commit(含上一头19842750)缺Signed-off-by;DCO 要求全部 commit 签名。 - CLI 输出差分仍超预算:本地 exact head 复跑
cli-output-base-head-differential-smoke.py仍失败——surface/status/*/json行lines grew by 5; allowance is 4,surface/status/small/jsonchars +130 (allowance 129)、compact_payload_chars +95 (allowance 94)。较上一头(chars +712)已大幅收敛,但仍在 allowance 之外;需要继续收敛 status 输出或给出逐项证据并更新差分 allowance。
非阻断(P2)
test_usage_summary.py14 个测试通过,空窗口裁剪方向正确;build ×2 与 dependency-review SUCCESS;pytest CI 评审时刻 IN_PROGRESS。
验证矩阵(exact head 实测)
| 场景 | 结果 |
|---|---|
pytest tests/control_plane/test_usage_summary.py |
14 passed |
cli-output-base-head-differential-smoke.py(本地复跑) |
FAIL(lines +5 vs 4;small/json chars +130 vs 129) |
| Sign-off(DCO) | FAILURE(20+ commits 仍缺 trailer) |
| build ×2 / dependency-review | SUCCESS |
| pytest(CI) | IN_PROGRESS(评审时刻) |
我的整体评价
空窗口裁剪是正确且有效的收敛方向(+712 → ~+130),但尚未达到两个 P1 的完成标准:DCO 仍红、status 输出差分仍在 allowance 之外。结论:REQUEST_CHANGES(窄化:补全全部 commit 的 sign-off;把 status JSON 输出再收敛 ~130 chars 或给出逐项证据后更新 allowance)。
English Verdict
Verdict: REQUEST_CHANGES — exact head 3269@3856305c77f006f96933d274f485dee0cb94cc3a.
Summary: The new commit correctly trims unobserved usage windows (14 usage-summary tests pass; CLI differential improved from +712 to roughly +130 chars), but both P1 blockers remain: (1) the DCO/Sign-off check still fails because 20+ commits in the PR history (including the previous head) lack Signed-off-by trailers; (2) the agent-facing CLI base/head differential still exceeds its allowance (status rows: lines +5 vs allowance 4; small/json chars +130 vs allowance 129), reproduced locally at the exact head.
huangruiteng
left a comment
There was a problem hiding this comment.
Request changes conclusion (author-owned PR; GitHub review-state fallback)
精确评审头(Exact Head): 3269@765220b8244700d16f6b3944a65b1b1d482591a8
Base: main | 类型: Agent workspace 提升(sync latest main merge)
作者: huangruiteng(owner,多贡献者合入)
详细中文评审
动机
作者把 RFC 分支与最新 main(含已合并的 #3261)再次同步,产生 merge head 765220b82。上一轮两个 P1 是否已解决,是本轮核对重点。
改动思路
本头相对上一评审头 3856305c 的差异主要是 merge latest main(含 #3261 的 completion-continuation 内容)+ 冲突解决;PR 自身仍以 Agent workspace 前端与控制面投影提升为主体。
具体改动
merge 同步 + 上一轮的 usage 空窗口裁剪。未发现新的 PR 专属功能改动。
关键内容讲解
- merge 同步不改变两个 P1:CI 在本头完整跑完,Sign-off 与 pytest 仍为 FAILURE。
- pytest 失败细节(与上一头相同):
cli-output-base-head-differential-smoke.py——surface/status/*/jsonlines +5 (allowance 4);surface/status/small/jsonchars +130 (allowance 129)、compact_payload_chars +95 (allowance 94)。 - Sign-off 失败细节:DCO 日志共 104 条 missing-trailer 错误(同一批 RFC 历史 commit,含上一头
19842750)仍未补签。
对主干的风险
阻断项(P1,两个,均未解决)
- DCO:Sign-off check FAILURE,PR 历史仍有大量 commit 缺
Signed-off-by。 - CLI 输出差分:pytest FAILURE,agent-facing CLI base/head 差分仍在 allowance 之外(lines +5;small/json chars +130)。
非阻断(P2)
- build ×2 与 dependency-review 在 CI 中通过;usage 空窗口裁剪方向正确但不足以单独达标。
验证矩阵(exact head 实测/CI)
| 场景 | 结果 |
|---|---|
| Sign-off(DCO) | FAILURE(104 条 missing-trailer 错误) |
| pytest(CLI base/head differential) | FAILURE(lines +5 vs 4;small/json chars +130 vs 129) |
| build ×2 / dependency-review | SUCCESS |
| 相对上一头差异 | 主要为 merge latest main(含 #3261) |
我的整体评价
merge 同步本身干净,但两个 P1 完全未动:DCO 仍红、CLI 输出差分仍超 allowance。结论:REQUEST_CHANGES(修复范围与上一轮一致:补全全部 commit 的 sign-off;收敛 status JSON 输出 ~130 chars 或提供逐项证据更新 allowance)。
English Verdict
Verdict: REQUEST_CHANGES — exact head 3269@765220b8244700d16f6b3944a65b1b1d482591a8.
Summary: This head is a latest-main merge sync and does not change the two outstanding P1 blockers. CI completes with both still failing: the DCO/Sign-off check reports 104 missing-trailer errors across the RFC history, and the agent-facing CLI base/head differential still exceeds its allowance (status rows lines +5 vs 4; small/json chars +130 vs 129). Build and dependency-review pass.
Summary
Promote the personal Agent workspace and frontend control-plane RFC into
mainafter reconciling it with the latestorigin/main.The promoted surface provides:
Overview / Chat, four trustworthy work lanes, and folded history;Chat / Tasks / Filesviews with contextual replies and safe Task drafting;Integration and conflict resolution remain isolated in dedicated merge commits. Original authorship is preserved in the merged history.
Capability lineage and validation
maxliu)User-facing behavior
LoopX Managerand Goals.Overview / Chatnavigation.Needs yourows identify their source Goal, requested action, and waiting time.Chat / Tasks / Files.Safety contract
Free text enters a constrained router result:
Explicit actions keep highest priority. Typed actions still require canonical Preview, state fingerprint, explicit confirmation, and receipt. Ambiguous, negative, compound, low-confidence, or incomplete requests go through clarification.
Validation
npm run build— passed on the final latest-main merge.personal-workspace-contract.test.mjs— passed.personal-workspace-router-smoke.ts— passed.chat-route-smoke.ts— passed.personal-workspace-browser-smoke.mjs— passed.git diff --check— passed.Latest default and beast theme previews are attached in a PR comment.
Community Contributors / 社区贡献者
maxliu) — personal workspace, Goal/Lark/Session interaction model, and browser validation.感谢所有贡献者共同完成控制面能力、运行时安全边界和可审计验证链路。
Review gate
This PR contains runtime and public first-screen behavior. Merge only after required CI is green and an independent review confirms the safety and projection changes.