Repository navigation
fix(lark): redact credentials from shared Lark sinks - #8181
Conversation
|
CI note: kernel-static-checks fails in tests/test_chat_codex_history.py with three F811 redefinitions of steward/conversation. This PR does not touch that file; the same ruff check failure reproduces on pristine upstream/main at 62e234c. Leaving that unrelated repair out of scope. |
loopx-agent
left a comment
There was a problem hiding this comment.
Reviewer: model_agent | gpt-6.1-sol | OpenAI | runtime_reported | reasoning_effort=max
[P2] 先净化语义值,再渲染 SVG。 807e13bb6c94 的新增最终源码替换会在 shared 阶段图摘要链接位于文本末尾时吞掉 XML 闭合标签。独立格式解析器在 head 报 mismatched tag,隔离的子进程 provider 拒绝该文件,产品返回 publish_failed;同一基线输入、head 的 owner-only 和普通 shared 对照均有效。请在 SVG/Mermaid 编码前净化字段,补真实 builder→写入文件→独立格式解析的回归,保留 shared 边界。
动机 / Motivation
将 Todo、工作结果和 Explore 阶段图同步到共享飞书看板的操作者。
同一公开合成阶段摘要在基线生成有效 SVG;head shared 替换吞掉闭合标签,独立 XML parser 与隔离 provider 拒绝;owner-only 和健康对照有效。
真实 CLI seed 写入已消除合成凭据,关闭扩展时完整错误与退出码相同;共享可视化格式回归尚未修复。
不证明远端 ACL、实际 Lark 部署、历史记录清理、凭据轮换或完整 DLP;不改变执行/合并权限。
改动思路 / Approach
Detection, audience projection and provider IO have existing suitable owners; the required correction is filtering placement, without a new abstraction.
复用 public_safe_text 作为凭据形状 owner,现有 audience 值表达投影意图,cli_transport 和 marker readback 继续拥有外部写入与恢复。只增加顶层过滤不能覆盖嵌套字段;应在既有语义值接缝净化后编码 SVG/Mermaid,不增加状态或工作流。
共享输出净化及既有凭据镜像同步;必须修正可视化格式回归,历史清理/ACL/真实远端部署仍在范围外。
具体改动 / Changes
依据预变更规范 docs/integrations/lark-kanban-control-plane-adapter.md,固定 revision 62e234c939996ad42f2b1168451cc9a656dce11d,其 Review Boundary 对共享行的凭据、原始日志与本地路径边界在记录路径得到实现;不把该结果外推为可视化完整资格。全部差异为12文件、+1047/-71:包括递归净化、四个 CLI 参数传递、Explore 源码与阶段文档、Python/TS 形状同步、测试和指标基线。
关键代码讲解
_public_safe_valueL507递归访问嵌套键、值、列表及 tuple,仅为结构合法的 record-link id 保留引用。build_record_upsert_commandL786在 JSON 序列化前再过滤凭据;owner-only 同样执行凭据边界。sync_explore_visual_to_larkL832读取 renderer 源码后净化,再生成 delivery digest、写文件并核验 marker;本次 P2 就在新增的净化位置。register_lark_kanban_commandsL60为 seed/sync/heartbeat 复用shared/owner-only,operator 默认改为 shared;显式 visual API 仍默认 owner-only。共享 Python 形状规则及 Vision/DSH 镜像也有意收紧凭据识别,并非仅在 Lark 开启时生效。
对主干的风险 / Risks
这是生产调用方可达的格式回归,不是测试 fixture 自身失败。已通过174项 focused、485项 adjacent、7项 TS corpus、13项 observer,root/plugin typecheck、mypy17项、改动 Python 的 Ruff 和 quick premerge 的6项直接检查;这些通过不能覆盖缺失的格式 oracle。18次真实源码 CLI 调用验证了 absent/enabled/disabled、preview/execute 和 provider refusal;关闭态完整错误与退出码相同,健康行字节一致,合成凭据在 head 写入中消失。格式反例使用真实 builder、源码文件、subprocess transport 和独立 XML parser,远端 provider 为隔离合成进程,未连接真实 Lark。公开边界扫描无错误;6条非字面 regex/合成引用提示已逐条核对。按当前策略未查询或等待 CI,作者附带的红灯只作未归因诊断。
语义与 CI 对齐
复用既有 visibility 词汇,没有新增状态协议。发现的是当前有效 SVG 契约被新文本替换破坏;不应靠放宽 parser、隐私规则或改用 owner-only 为共享看板绕过。修复后需重跑实际两种 renderer 的语义值与格式负例,并检查完整新 head。
我的整体评价 / Verdict
改动规模与共享输出缺口基本相称;无需额外框架,后续可在修复接缝时合并重复遍历。长期控制语义在已测路径保持,尚无长期收益结论;用户体验存在确定回归,整体交付 not_yet_proven。检查了真实 builder 生成并交给 subprocess transport 的 SVG;独立 XML 解析已发现回归,不能据此宣称远端视图可用。真实 Lark 全页面、窄屏、展开交互及 ACL 未测试。记录净化的成功不足以批准这个完整 head。
English verdict: REQUEST_CHANGES — HEAD 807e13b; shared SVG sanitization corrupts markup; repair before approval.
Remove canonical provider credential shapes before record serialization, including nested values and worker output, while retaining existing redaction for shared board paths and private references. Default operator todo sync, seed, and heartbeat paths to shared visibility so documented shared boards do not require an opt-in. Route automatic issue-fix Explore sync and CLI-linked Explore refresh through the same visibility. Mirror the expanded credential shapes in both TypeScript owners and apply the visibility-aware boundary to seed-task and seed-cases. Signed-off-by: JasonBuildAI <jasonbuildai@gmail.com>
Record the accepted shared-sink redaction growth: explore_results.py adds 34 lines, while kanban.py adds five Any annotations and its line ceiling is tightened from 2791 to its current 2760. No additional runtime behavior is introduced by this baseline update. Signed-off-by: JasonBuildAI <jasonbuildai@gmail.com>
Redact node titles, summaries and blocked reasons plus edge types and summaries before SVG or Mermaid is encoded. Re-render a role view from the sanitized values when redaction changes display text, so stage titles, stage SVG and overview diagrams stay consistent while the source digest and freshness contract keep their original semantics. Keep the shared visibility boundary for caller-supplied pre-rendered views by rewriting decoded SVG text spans and Mermaid labels only; the previous whole-source replacement could consume a closing </text> after a private link. Add a regression that builds the real presentation bundle, publishes through the shared stage write path and parses the written SVG with an independent XML parser. Record the reviewed module metric growth. Signed-off-by: JasonBuildAI <jasonbuildai@gmail.com>
807e13b to
d2b6e83
Compare
|
已按当前 head 复核并更新 PR 描述里的验证证据;head 未变: 当前 head 的 CI 失败已与基线逐一对照,均不由本 diff 引入:
本 diff 范围内的结果:
|
loopx-agent
left a comment
There was a problem hiding this comment.
Reviewer: model_agent; gpt-6.1-sol; OpenAI; runtime_reported; reasoning_effort=max.
动机 / Motivation
将 Todo、工作结果和阶段图同步到共享飞书看板的操作者。
此前共享记录可能带出凭据形状;上一版修复又会破坏阶段 SVG。当前实际 CLI 写入已净化合成凭据,阶段图保留有效 XML 并完成隔离写入和回读。
独立232项 Python、33项 TypeScript 和13项 observer 检查通过;真实 CLI 的 absent/enabled/disabled/refusal 与 shared/owner-only 写入经验证,旧 SVG 反例被独立 parser 拒绝,当前路径通过。
不证明远端 ACL、实际 Lark 部署、历史共享记录清理、凭据轮换或完整 DLP;不改变执行和合并权限。
改动思路 / Approach
规范识别 owner、既有 visibility 投影和 provider IO 的责任划分适合此修复;先净化语义显示值再编码,保留预渲染兼容路径的格式边界,无须另建状态或工作流。 当前 PR 交付受影响新写入的安全投影及格式修复;实际远端 ACL、存量清理和部署验收在此范围外。
原数据 → 净化语义值 → 编码或记录序列化 → 既有 provider 写入 → 独立结果回读。顺序来自源码检查,格式/行为证据来自后述真实执行,不将图示或摘要当作测试。
具体改动 / Changes
规格取预变更 docs/integrations/lark-kanban-control-plane-adapter.md,spec_revision ac62962。逐项映射:Review Boundary=implemented;Authentication Boundary=implemented;CLI Surface=implemented。并对照 docs/public-private-boundary.md 同版本的 Credentials 契约。
全差异12文件、+1294/-80;递归记录净化、操作入口、Explore 显示值和 Python/TS/DSH 形状同步都已检查。没有只复跑最后一个用例。共享与 owner-only 使用相同凭据边界,后者保留其既有路径可见性。复用既有 visibility 词汇,regex 识别文本形状,不用于分类工作状态。
关键代码讲解
- _public_safe_value:Top-level text filtering -> recursive nested key/value filtering with valid record-id preservation;Destination-specific redaction, no authority inference。
- _redact_explore_display_values:Display values sanitized before rendering; topology fields retained;Never apply whole-text regex to raw markup。
- sync_explore_visual_to_lark:Format-aware rendered-label fallback before digest and publication;Parseable markup, unchanged source freshness, truthful marker readback。
- register_lark_kanban_commands:Operator defaults to shared, explicit owner-only retained;Activation and external execute remain separate。
对主干的风险 / Risks
原公开 P2 的完整 review 和 inline 已逐条映射:旧整段替换会吞闭合标签;当前语义值层过滤后编码,并为预渲染调用方只重写文本/标签。八节点长重复内容、四种状态的独立 XML parser 在历史管线反事实报 mismatched tag,在当前管线通过。实际源 CLI 经隔离 subprocess 验证记录写入、扩展拒绝、provider 拒绝及恢复;没有接触真实 Lark。最初探针把临时源文件清理和幂等不重写误作失败,修正证据捕获/幂等 oracle 后按同输入完整重跑,保留其原始结果,不归因产品。
232项 focused/adjacent Python、33项 corpus/Vision TypeScript、13项 observer、root/plugin TypeScript 和配置17入口 Mypy 全过。 quick premerge 的6个直接、4个选择检查机械通过;整体仍因严格质量门 HOLD。必检 Ruff 的 test_goal_create_completion.py:184 F841 在不可变 base/head 完整归一化诊断相同,因果文件和配置未改;不要求本 PR 顺手修改无关代码,严格 CQR 仍为 FAIL,不能据独立 APPROVE 宣称可合并。
语义与 CI 对齐
默认 shared 的行为改变已在操作文档和 PR 明示;显式 visual API 仍默认 owner-only。canonical shape 的安全收紧不限于 Lark 开启态,benign prose 与镜像测试通过;不把这部分说成 feature-off 完全不变。已有扩展 gate 的完整拒绝诊断和无 IO 经 base/head 配对验证。 本轮未查询、轮询、等待或触发 CI;作者附带的远端红灯保留为未独立归因诊断。未把文本 redaction 声称为完整 DLP;历史存量和远端权限没有因此自动解决。
我的整体评价 / Verdict
当前 exact head d2b6e83 的已验证源码切片支持 APPROVE;long_horizon=preserved,user_experience=improved,仅限上述来源/恢复或共享输出路径,不外推为长期净收益。规范识别 owner、既有 visibility 投影和 provider IO 的责任划分适合此修复;先净化语义显示值再编码,保留预渲染兼容路径的格式边界,无须另建状态或工作流。 当前 PR 交付受影响新写入的安全投影及格式修复;实际远端 ACL、存量清理和部署验收在此范围外。
已检查实际 builder 生成并交给写入路径的完整阶段 SVG:八个长标题、重复摘要及 ACTIVE/DONE/BLOCKED/FAILED 混合状态,净化标记可读,卡片与状态保持。顶部长总标题沿既有画布裁切,格式修复没有改变其几何属性。 真实 Lark 全页面、远端 ACL、窄屏缩放与交互未验证;本 PR 未改变响应式布局。 原有长总标题的裁切未计为本 PR 新回归或已修复项。 保留原讨论、历史失败、严格 CQR 和 readiness 的独立门;本轮没有合并、dismissal、共享安装、Host 切换或付费执行。
English verdict: APPROVE
Goal And Delivered Outcome
tests/extensions/test_lark_shared_sink_redaction.pyandtests/control_plane/test_public_safety_credential_shape_owner.pycover the before/after boundary.upstream/mainatac6296225.Author Declaration
Implemented against
.github/SECURITY.mdand the request in this PR are the basis.loopx/extensions/lark/presentation/kanban.pytests/extensions/test_lark_shared_sink_redaction.py_sink_safe_lark_valuestests/extensions/test_lark_shared_sink_redaction.pyloopx/cli_commands/lark_kanban.pytests/extensions/test_lark_shared_sink_redaction.pyloopx/extensions/lark/presentation/explore_results.py,explore_stage_document.py,loopx/cli_commands/explore_feishu_commands.pytests/extensions/test_lark_shared_sink_redaction.pyloopx/public_safe_text.py,loopx/control_plane/goals/vision_checkpoint.ts,packages/dsh-loopx-plugin/src/observer.tstests/control_plane/test_public_safety_credential_shape_owner.pydocs/integrations/lark-kanban-control-plane-adapter.mdac6296225; ran the focused and adjacent Python suites, ruff, py_compile, root and plugin TypeScript typechecks, module ratchet, and public-boundary scan. Did not include live data, credentials, reproduction steps, or private paths. Historical rows already written to a shared Base are not automatically cleaned; exposed credentials still require revocation and rotation.Scope And Continuation
Completed scope and remaining work: Complete for new writes in the affected Lark projection, Explore, operator sync and heartbeat paths. Historical shared records, exports, backups and already-exposed credentials require operational cleanup and rotation outside this code change.
Slice boundary / successor: N/A for code; advisory publication and release coordination remain with maintainers.
Default behavior change:
sync-loopx-todos,seed-task,seed-casesandheartbeatnow default to--sink-visibility shared. The explicitowner-onlymode remains available when the target ACL is independently verified.Validation
d2b6e838b607b633682536d9dcc08f79f12e358eunitpassedtests/extensions/test_lark_shared_sink_redaction.pyandtests/control_plane/test_public_safety_credential_shape_owner.py: 175 passed.unitpassedunitpassedintegrationpassedstaticpassedruff,py_compile,git diff --check; root control-plane and plugin TypeScript typechecks.regression_paritypassedmanualblockedhot-path-interface-budget-smoke.pyfails identically on pristineac6296225withentrypoint_missing; environment limitation, not this diff.staticblockedkernel-static-checksfails onF841attests/control_plane/test_goal_create_completion.py:184; that file is unchanged here (last touched by #8178) and the identical failure reproduces on baseac6296225(run 42313186589, job 128219540019).integrationblockeddsh-loopx-pluginadmission-closeout integration fails withinvalid_schema; the same test fails identically onmainate7a6c8d5f(run 41961423900, job 127028426011). Linux CI passesobserver.spec.ts13/13.staticblockedchecks,pytest,stage2c-correctness-e2eandmerge-gatefail only as downstream gates:checksrequireskernel-static-checkssuccess,stage2c-correctness-e2erequires the skipped stage2c result to be success, and the Python shards were skipped the same way on baseac6296225.unitblockeddsh-loopx-pluginsuite has pre-existing path-normalization failures; 200/208 plugin tests passed.integrationblockedcli-output-budget-regression-smoke.pyfails on pristinemainbecause the base fixture lacksread_cli_context_for_oracle; unrelated to this diff.integrationpassedUI Impact
Type of Change
LoopX Area
Technical Direction
Shared-authority RFC fixture impact
Boundary Checklist
.loopx/,.codex/goals/, and liveACTIVE_GOAL_STATE.md).python3 scripts/check_rfc_bilingual.py --base origin/main --head HEADpasses, or no paired RFC changed.none.Signed-off-bytrailer (git commit -s).Security Note
This PR intentionally limits vulnerability detail. The affected surface is the shared Lark projection boundary; the fix is shape-based redaction, not a complete DLP system. Historical data and any credential that may already have reached shared storage require revocation and rotation rather than relying on this code change.