Skip to content

feat(control-plane): implement generic observable_artifact_handle_v0 … - #3080

Closed
rootkiller6788 wants to merge 2 commits into
huangruiteng:mainfrom
rootkiller6788:feat/gh-c50-obs-handle
Closed

feat(control-plane): implement generic observable_artifact_handle_v0 …#3080
rootkiller6788 wants to merge 2 commits into
huangruiteng:mainfrom
rootkiller6788:feat/gh-c50-obs-handle

Conversation

@rootkiller6788

Copy link
Copy Markdown
Contributor

…protocol (GH-C50)

Summary

Issue Or Task

  • Closes #
  • Contributor task ID:

Validation

  • python3 -m py_compile loopx/*.py
  • loopx check --scan-root .
  • Other:

Type of Change

  • Bug fix
  • New feature
  • Breaking change
  • Refactoring (no functional changes)
  • Documentation update
  • Test update

LoopX Area

  • Control plane (goals, todos, quota, scheduler, registry, runtime)
  • Benchmark boundary (adapters, runners, verifiers, scoring, evidence)
  • Capability or extension (providers, adapters, skills)
  • Public docs or presentation surface (README, protocols, dashboard)
  • Build, packaging, installer, or CI
  • Host or runtime integration

Boundary Checklist

  • I did not commit .loopx/, .codex/goals/, live ACTIVE_GOAL_STATE.md, credentials, private benchmark traces, verifier output, raw agent sessions, internal document links, or local machine paths.
  • I did not duplicate maintainer-owned benchmark work unless a maintainer split out a public issue for it.
  • I kept the change scoped to the linked issue/task.

huangruiteng
huangruiteng previously approved these changes Aug 11, 2026

@huangruiteng huangruiteng left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

PR #3080 首轮评审(head c6a249dbde

详细中文评审

动机

作者按上一轮建议把 GH-C50(observable artifact handle)从 #3078 拆出为独立 PR。本 PR 仅含 3 个文件:loopx/observable_artifact_handle.py(722 行)、tests/test_observable_artifact_handle.py(521 行)、examples/observable-artifact-handle-smoke.py(182 行),与 #3078 head 46cd075 中的版本逐字节一致(该版本此前已在本 lane 审阅并通过本地验证)。

改动思路

默认 generic 的 observable_artifact_handle_v0 协议:紧凑 token/text 校验器拒绝本地路径、URL/remote、私密标记与父目录标记;frozen typed 模型 + builder/validate/project/policy/fixture/markdown;read_boundary 默认 compact-only,launch_actions_enabled/production_actions_enabled 恒 False;validate 强制 raw_handle_payload_recorded=False,非法输入 fail-closed。

验证

  • exact head c6a249dbpy_compile 通过;tests/test_observable_artifact_handle.py 46 passed;smoke 18 checks 通过(exit 0);build SUCCESS;pytest 运行时状态以 CI 终态为准。

我的整体评价

拆分后作用域清晰,协议边界严格、公开安全面干净,测试与 smoke 覆盖充分。达到合并条件,结论 APPROVE。


Review: APPROVE

Head: c6a249dbde

Verdict: APPROVE — the split PR is clean and correctly scoped to GH-C50 only. The observable_artifact_handle_v0 protocol uses strict compact public-safe validators (rejecting paths/URLs/private markers), a compact-only default read boundary, disabled launch/production actions, and fail-closed validation; 46 tests and the 18-check smoke pass locally, build is green, and the code is byte-identical to the already-validated implementation in #307846cd075. CI pytest status is the only remaining confirmation.

@huangruiteng huangruiteng mentioned this pull request Aug 11, 2026
18 tasks

@huangruiteng huangruiteng left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

PR #3080 新 head 复核(head c327c93e92

详细中文评审

动机(本次 head 更新)

作者推送一个聚焦 commit fix(observable-artifact): split private marker strings to avoid self-detection by public-boundary scanner:把 observable_artifact_handle.py、smoke 与测试里的私有标记字面量(authorization:larkofficepasswordbearer )拆成运行时拼接字符串,避免仓库的 public-boundary 扫描器把“标记定义本身”误判为凭据泄漏。行为不变(拼接结果与原先字面量完全一致)。

验证

  • exact head c327c93e:diff 仅 5 增/5 删;tests/test_observable_artifact_handle.py 46 passed;smoke 通过(exit 0);CI pytest/build/dependency-review 全 SUCCESS。

我的整体评价

变更极小且目的明确,不改变协议语义,消除了边界扫描自检出问题。达到合并条件,结论 APPROVE。


Review: APPROVE

Head: c327c93e92

Verdict: APPROVE — the new head is a 5+/5- self-detection fix that splits private-marker literals into runtime concatenations so the public-boundary scanner does not flag the module's own marker definitions; behavior is unchanged. 46 tests and the smoke pass locally, and CI pytest/build/dependency-review are all SUCCESS.

@huangruiteng huangruiteng left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

详细中文评审 — PR #3080(exact head c327c93e9278bdf37099479f70f7594ccf22f9d1

动机

GH-C50 的目标是给外部长任务(CI、benchmark、eval、deploy)提供一个通用的、可观测工件句柄:紧凑 handle、允许的 poll 命令、artifact refs、terminal markers、只读边界,并且不绑定任何具体 adapter。动机本身合理:LoopX 需要在不引入 benchmark/CI adapter 的前提下表达“外部工作还在跑/已结束/可收口”。本 PR 用 3 个文件(+1425/-0)交付了一个 typed dataclass 模型、builder、validator、projection、policy、fixture 和 markdown renderer。

改动思路

核心思路是“数据契约 + 严格 builder + 保守 read boundary”:build_observable_artifact_handle 对 handle_id/display_name/poll 命令/refs 做 public-safe 校验(拒绝绝对路径、URL、credential marker),产出 frozen dataclass;validate_observable_artifact_handle 校验序列化后的 handle;project_observable_artifact_handle / build_observable_artifact_handle_policy 把它投影成 first-screen 状态和 poll/cleanup 策略;markdown renderer 输出人读摘要。整体是“描述外部工作,而不是执行外部工作”,read boundary 默认全部 deny raw。

具体改动

关键代码讲解

  1. build_observable_artifact_handleobservable_artifact_handle.py):入口严格,但有两处静默 fallback——非法 state 直接变成 "unknown",未知 poll_observations 被静默丢弃并回退 ("task_state",)。实测 state="runing" 返回 ok=True, state="unknown",调用方完全不知道拼写错误。这违背“fail fast with actionable context”和“make illegal states hard to express”。
  2. _compact_public_text + _PRIVATE_MARKER_RE:用子串/单词黑名单判断“private”,把 "secret""password""bytedance""larkoffice" 等当 marker。实测 "The secret ingredient for this benchmark""ByteDance open-source blog" 被拒;同时源码用 "Author"+"ization:""la"+"rk"+"office"、smoke 里 "bear"+"er " 这类拆串写法绕开仓库自己的 public-boundary scanner。这是把安全判断建立在字符串启发式上,并刻意规避扫描器——不是 typed 契约。
  3. validate_observable_artifact_handle:作为外部 producer 的信任边界,只检查 schema/handle_id/kind/display_name 非空/state/poll_cmd dict/boundary 两个布尔字段。实测一个 display_name="/Users/me/.aws/credentials + https://internal.example/secret"allowed_poll_command="cat /Users/me/token" 的 handle 通过 validation(ok=True, errors=[])。builder 严格,validator 几乎不设防——外部 handle 一旦进入系统,private 内容可以在 renderer 里被原样输出。
  4. ObservableArtifactHandle.as_dict / project_observable_artifact_handle / render_observable_artifact_handle_markdown:输出侧没有做二次 sanitize,依赖“来自 builder”的假设;一旦输入来自外部 producer(validator 又不设防),markdown/render 会直接透传任意文本。
  5. 默认 allowed_poll_command="loopx observe":仓库里不存在 loopx observe 命令;fixture 里的 kubectl rollout status ...ci status ... 也只是 label(argv_recorded=False),没有任何 executor。作为“数据形状”可以,但“allowed poll command”这个名字暗示可执行,当前是悬空的命令引用。

正向路径

build_observable_artifact_handle(handle_id="ci-build-42", kind="ci_run", state="running", ...) → 校验通过 → as_dict() 输出 schema/state/refs/read_boundary/poll_contract → project_observable_artifact_handle 给出 first_screen.waiting_on=external_systemnext_safe_action=poll_observable_handle → markdown 渲染出人读摘要。46 个测试 + smoke 18 项全部通过。

负向路径

  • 外部 producer 提交含私有路径/URL/credential 的 handle → validate_observable_artifact_handle 返回 ok=True,内容进入渲染层(安全边界失效)。
  • 调用方把 state 拼错成 "runing" → 静默变成 "unknown",后续 policy 走 investigate_handle_state,真实原因被吞掉。
  • 合法公开文本含 "secret"/"bytedance" → builder 直接拒绝,误伤真实展示名。

对主干的风险

  • F1(blocking,安全/信任边界):validator 是外部 producer 的唯一入口,却几乎不校验 public-safe 字段;私有内容可原样通过并进入投影/渲染。必须让 validator 与 builder 使用同一套字段级校验并 fail closed。
  • F2(blocking,scope fit):全仓库没有任何生产调用方——没有 CLI 命令、没有 status/quota 接入、没有 loopx observe 实现,只有模块+测试+smoke。按 scope-fit 规则,700 行“default generic capability”没有 active production call site,属于未投入使用的生产结构;要么接一个真实 caller,要么收成 RFC/文档 + 最小契约切片。
  • F3(high,typed state rule):状态非法时静默回退 unknown,与“非法即失败”的仓库偏好冲突;unknown 既是合法状态又是 fallback 值,语义被混淆。应显式报错或把枚举设计成不含 fallback。
  • F4(high,字符串黑名单 + 扫描器规避):private 判断靠子串黑名单(误伤公开文本),并且源码用拆串方式绕过仓库自己的 public-boundary scanner。应改成结构化/allowlist 的边界判断,删除拆串规避,并修复 scanner 对该文件的误报根因。
  • F5(medium):公开 URL artifact refs 被一律拒绝(过度),而 validator 又完全不查 refs(不足),builder 与 validator 契约不一致。
  • F6(medium)allowed_poll_command 默认指向不存在的命令,poll 语义需要明确为“仅数据标签”或补齐命令。

我的整体评价

方向正确、类型化建模和 read-boundary 默认 deny 是加分项;46 测试 + smoke 通过,但测试固化了有问题的行为(静默 fallback、黑名单误伤、validator 盲区),且没有任何生产调用方。当前形态是一个“看起来完整的协议模块”,但不是可交付的 shipped behavior。结论:REQUEST_CHANGES——先补 validator 信任边界、消除静默 fallback、移除拆串规避,再接一个真实 caller(或砍成 RFC + 最小契约),再考虑合并。


English Verdict

  • Head: c327c93e9278bdf37099479f70f7594ccf22f9d1
  • Verdict: REQUEST_CHANGES
  • Key findings: (1) validate_observable_artifact_handle is the external trust boundary but accepts handles containing private paths/URLs/credentials (probe: ok=True for a handle with /Users/me/.aws/credentials and cat /Users/me/token); (2) no production caller exists — no CLI/status/quota wiring, and the default allowed_poll_command="loopx observe" is a nonexistent command (scope-fit violation); (3) invalid states silently fall back to "unknown" instead of failing fast; (4) private-marker detection is a substring denylist that rejects innocent public text and the source deliberately splits strings ("Author"+"ization:", "la"+"rk"+"office", "bear"+"er ") to evade the repo's own public-boundary scanner.
  • Validation: 46 PR tests pass, smoke passes 18 checks, public-boundary scan clean; probes above were reproduced against the exact head.

@huangruiteng huangruiteng left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

详细中文评审(重审,与 owner 阻断结论一致)

精确评审头: 3080@c327c93e9278bdf37099479f70f7594ccf22f9d1

动机

按全队列重审要求,用 scope-fit 与安全边界门槛重新审阅本 PR(此前我的 APPROVE 已被 owner 的 CHANGES_REQUESTED 取代)。本 PR 交付 722 行 observable_artifact_handle.py 通用模块 + 521 行测试 + 182 行 smoke。

改动思路

模块提供 builder/validator/projection/policy/markdown renderer,目标是表达“外部长任务的可观测工件句柄”。思路本身合理,但当前实现存在两个阻断问题,与 owner 在 10:57Z 提出的 F1/F2 完全一致。

具体改动(关键内容讲解)

  • F1(blocking,安全/信任边界)validate_observable_artifact_handle(observable_artifact_handle.py:443)只校验 schema/handle_id/kind/display_name 非空/state/poll_cmd 结构,不做任何 public-safe 字段校验。实测一个 display_name="/Users/me/.aws/credentials + https://internal.example/secret"allowed_poll_command.command_label="cat /Users/me/token" 的 handle 可通过校验(ok=True, errors=[])。外部 producer 一旦进入,私有内容会在 renderer 中原样输出。
  • F2(blocking,scope fit):全仓无任何生产调用方(rg 除模块/tests/examples 外零命中);没有 CLI、status/quota 接入,也没有 loopx observe 实现。700+ 行“default generic capability”没有 active production call site,违反 scope-fit 规则。
  • 静默 fallbackbuild_observable_artifact_handle 对非法 state 静默转 "unknown",未知 poll_observations 被静默丢弃;state="runing" 返回 ok=True,违背 fail-fast。

对主干的风险

若照此合并,外部 handle 可绕过校验进入投影/渲染层(安全边界失效),且 700+ 行无人消费的通用抽象会沉淀为待清理脚手架。风险等级:高。

我的整体评价

REQUEST_CHANGES。 修复要求:(1) validator 与 builder 使用同一套字段级 public-safe 校验并 fail closed;(2) 提供至少一个真实生产调用点(或按 owner 指示先接入 status/quota/loopx observe),否则不合并;(3) 消除静默 fallback。贡献行为警告:按 PR #3134 政策,若同一作者在警告后再提交此类低价值/越界 PR,将禁止该账号继续向本仓库提交 PR(owner 执行屏蔽)。


English Verdict

REQUEST_CHANGES — exact head c327c93e9278bdf37099479f70f7594ccf22f9d1.

Re-review confirms the owner's blocking findings: (F1) validate_observable_artifact_handle performs no public-safe field validation, so private paths/URLs/credentials pass through to projection/render; (F2) no production caller exists for this 700+ line module (no CLI/status/loopx observe integration). Also silent fallbacks violate fail-fast. Fix validator parity, add a real call site, and remove silent fallbacks before merge. Contribution warning applies.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants