Skip to content

feat(content-ops): compose local video and editable Blender scenes - #6857

Merged
huangruiteng merged 9 commits into
mainfrom
codex/content-media-composition-20261019
Oct 19, 2026
Merged

huangruiteng merged 9 commits into
mainfrom
codex/content-media-composition-20261019

Conversation

@loopx-agent

@loopx-agent loopx-agent commented Oct 19, 2026 •

Copy link
Copy Markdown
Collaborator

Problem and resulting behavior

Agents can prepare a sourced brief but need one reviewable way to turn it into a local movie. This PR adds a Content-Ops composition journey shared by content-ops media prepare/render/inspect/list/cancel and Settings → Capabilities → Goal → Content production. The Agent prepares sources, timing and optional 3D geometry; the owner renders, cancels, retries and reviews the same composition in place.

The optional loopx-media distribution composes title scenes, animated diagrams, digest-bound image/video excerpts, captions, narration, and real editable Blender scenes. Shared TypeScript admission binds all executed fields into one plan digest. The Goal-local workspace keeps immutable source snapshots, revision/attempt state and content-item approval invalidation. A result becomes ready only after exact file readback, full video decode and, for Blender, a separate process reopening the saved project and checking every RGBA/depth pass.

Target: loopx-project/loopx:main. Base: 3a816411785fea545c379769a1ff98f5e881bd5d. Final reviewed head: 036ddced0abf7dc9015469bc149b661f4170bf46.

Scope and placement

  • Capability: existing content-ops; no new Goal, scheduler, account or publication authority.
  • Provider: optional loopx-media 0.2.0; normal installation remains 2D-only.
  • Shared owner: loopx/control_plane/capabilities/content_media.ts for plan/result admission and render transitions.
  • Python boundary: Goal-local filesystem, HTTP adaptation, locking and specialized media/Blender computation only.
  • Existing owners reused: content item lifecycle, layout catalog, canonical digest envelope, extension install/doctor/permission and Goal capability navigation.

This is a complete private composition slice. It does not claim creative quality, audience understanding, subjective listening, cross-platform Blender, production App installation or publication approval.

Review repairs

The independent review identified two P2 silent-loss paths. Both are fixed at shared admission and again at the real provider boundary:

Input Previous failure Final behavior
Caption with an internal blank line or ambiguous markup/entity syntax A real subtitle consumer kept only the first paragraph while the movie reported ready Preparation fails before creating an item; accepted single line breaks, ordinary & and quotes round-trip through real VTT/SRT consumers
Excerpt or Blender shot with nonempty body The body changed the digest but every movie/subtitle/poster output stayed identical validateMediaPlan rejects the unsupported body; a stale/direct provider request is also refused before creating output

Title/diagram body remains supported. A needed spatial qualifier must use a supported visible field, title scene or timed caption before a new revision. The protocol and renderer guide disclose this explicit narrowing.

Final exact-head review: APPROVE. Both discussion threads are resolved, the earlier CHANGES_REQUESTED review is dismissed with resolution evidence, and approval closeout is clear.

Validation

All results below are source-built/local validation for the final head; hosted CI was not polled or used as review evidence.

Check Result
Control-plane typecheck Passed
TypeScript media + canonical digest owner 26 passed
Real 2D/HTTP/subtitle/Blender provider suite 9 passed, 0 skipped; bpy 4.5.12, FFmpeg, actual editable provider
Blender artifacts Real RGB/depth pass sequences, 60 decoded movie frames, ZIP HTTP digest/MIME, .blend independently reopened with scripts disabled and middle frame rerendered
Lifecycle/negative cases Missing provider preserves prepared work; active cancel/retry uses one effect; damaged bytes cannot download; stale/direct spatial body creates no output
CI Ruff scope Passed
Dependency lock/top-level module invariants 7 passed
Production Chat bundle Passed; existing bundle-size warning remains
Packaged typed-actions browser scenario Passed
Final premerge 19/19 checks passed, 0 failures, 0 manual holds
Semantic inventory One local RESULT_FILES I/O allowlist reviewed; no shared Goal/Agent vocabulary added
Change quality cqr_ff6dc736b5b04db2e8dc, scope fingerprint ff6dc736b5b04db2e8dcc262d2a45f0f8a113c5f615c102e61cce533f59ba2b9, status valid, decision pass

Activation, disable and limits

Blender is an explicit extra: bpy==4.5.12, Python 3.11. The normal 2D provider does not install it.

uv tool install --python 3.11 './packages/loopx-media[blender]'
loopx extension install --manifest packages/loopx-media/extension.toml --execute
loopx extension doctor loopx-media --execute
loopx extension disable loopx-media --execute

The registered executable/environment is pinned. Changing another process's PATH does not replace it; install the extra in the registered environment or explicitly register the intended provider revision. Uploaded .blend files, arbitrary scene Python, add-ons and external asset discovery are rejected.

Bounds remain 90 seconds, 30 shots, 20 assets, 80 captions and a 120-second process budget. Blender scenes are limited to three per composition, 16 primitives, 3 lights, 24 connections and 120 frames each. Only Blender 4.5 LTS, Cycles CPU and the tested macOS host are qualified; Blender 5.x, GPU, Windows/Linux, peak memory and subjective media quality remain untested.

See renderer activation and recovery and the composition protocol.

Frontend evidence

The visual assets are from a2cc663d3e5bab455db2349598cabee5ce2ef2a6; the final diff leaves all Content production UI files byte-identical. Captures use the production Chat bundle, isolated SQLite and the installed source provider, not prototypes.

Ready composition with verified project and 3D pass/reopen result:

Blender composition and project readback

Missing optional dependency preserves the source and gives explicit retry guidance:

Blender dependency failure and recovery guidance

390×844 project/download checks with keyboard focus:

Narrow project download and checks

Boundaries

  • Rendering remains private/local and never grants approval, delivery or publication authority.
  • No private logs, credentials, local paths, generated media or raw provider output are committed.
  • No PostgreSQL authority store, benchmark scoring, scheduler, quota or Goal lifecycle behavior changes in this PR.

@loopx-agent loopx-agent left a comment

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Reviewer: model_agent; model=gpt-6.1-sol; provider=OpenAI; reasoning_effort=max; declaration_source=runtime_reported

准确 head:e88dce6330dc1c8d12afd65fc720803fe8070ede。REQUEST_CHANGES:实际播放器会丢失已接收的字幕段落,虽然作品显示生成成功。下面是完整评审;这条阻塞也附在具体代码上。

动机

用户的任务是把已经准备好的脚本、来源和时间线变成可观看、可检查和下载的视频。旧 Content-Ops 能准备提纲、来源与版式,缺少这条本机成片路径。让 Agent 处理路径、哈希与协议细节,再由用户在已有 Goal 能力页制作,是有用的有界扩展;无需为了这个任务新增模型、账号或发布执行器。

预期可观测结果是字幕、文字稿和视频共同保留已准入的内容;本次真实播放器反例表明字幕仍会无声丢失空行后的段落。

规格依据是 PR 声明的任务和既有 Content-Ops/item lifecycle 边界;没有独立于此 PR 的原始书面规格,新协议说明不能自证原始验收。此次没有宣称创意、试听、传播、学习效果或相对性能已验收。普通任务从一次意图出发,Agent 可准备已有材料;页面导航、选择作品和等待渲染分别属于导航与本机执行,不要求重复输入已知 JSON、路径或额外批准。

改动思路

以下表格是按准确 head 源码整理的示意,实际执行证据在后文;未额外验证图形渲染。

触发 处理 用户读回
Agent 准备来源与时间线 TS 验证;Python 保存哈希绑定的私有副本 同一 Goal 中的待制作作品
未安装或关闭扩展 现有 extension owner 拒绝新效果 作品保留、可见未就绪说明
制作/取消/重试 当前 revision、attempt 和执行锁;可选 renderer 编码 取消结算后可重试;成功后播放、下载
输出完成 文件哈希/字节数、完整视频解码;内容修订清除旧批准 私有成片;不获得发布许可
字幕含空行 当前实现把文本直接写进字幕容器 段落后半丢失,却仍报告 ready

共享决策属于 TS;Python 承担文件、锁、HTTP 与专门媒体计算。复用既有 layout tokens、item approval 和 extension lifecycle 是合理的同域收敛;无需为这个缺陷再建一个 QA authority。

具体改动

范围为25个文件,包括媒体计划/状态/结果、私有快照与渲染、可选包、CLI/HTTP、已有能力页、测试、示例及协议说明。既有风格素材入口保留在“内容制作 → 来源风格素材”;这个发现路径变化已在双语文案和文档披露。

  1. validateMediaPlan 约束帧对齐、总时长、来源、配音和布局,并让这些输入进入同一 digest。它拒绝越界来源、类型错误、未知字段与无效配音,但当前文本检查仍允许字幕内部空行。
  2. MediaWorkspace.render/_execute 复用已就绪绑定、保护一次 attempt、读回真实文件,再提交状态。源与结果校验、旧 revision 拒绝、取消完成和重试均有执行证据;读取不会自动恢复宿主中断。输出变化复用既有 item revise 清除批准。
  3. captions 同时生成 VTT、SRT 与文字稿,但67–68行直接插入任意已准入文本。空行对字幕格式具有结构意义,因此必须在准入或序列化层处理,而不是依赖视频解码 QA。

对主干的风险

[P2] 字幕内容完整性。 使用一个0–3秒的 cue,文本为 FIRST LINE\n\nSECOND LINE,实际 TS 准入和可选 renderer 都成功,生成36帧视频;工作台显示作品已生成、完整解码通过。通过实际打包播放器的 HTML track 读回,readyState=2,只有一条 cue,内容为 FIRST LINE,SECOND LINE 消失。文字稿仍保留原内容,因此这不是有意的任务缩减。最小修复是在准入时拒绝当前不支持的段落分隔,或序列化成合法且内容完整的字幕;增加真实字幕解析后的文本断言,不能只检查文件哈希或视频帧数。

独立执行记录:原 head 的13个 Python 媒体/生命周期用例和10个 TS 媒体/引用用例通过;50个相邻配置/来源用例通过。实际 renderer、编码器、HTTP 文件 route 和打包页面均执行,使用隔离的合成项目与 SQLite Goal,没有模型、云服务或现有用户数据。通过真实页面完成“扩展缺失 → 显式安装 → 制作 → 取消 → 取消完成 → 重试 → 播放/下载 → 关闭扩展仍可读”。重试成片为90秒、1920×1080、2700帧,播放器成功解码并推进播放时间;没有据此宣称性能提升。1200×878和390×844视口已实际查看,窄视口文档宽390,来源说明与下载可访问;既有设置页内部滚动仍然存在。

评审期间作者更新到本 head:仅 API/测试格式化和校验指引改变,两份 Python AST 等同,TS、renderer 和 UI 文件字节相同。因此保留上述真实浏览器与字幕反例证据;在最终 head 重新执行20个真实 renderer/生命周期/仓库不变量用例和现有 CI 所用 Ruff 范围,结果均通过。初次53条 Ruff 错误中17条属于这次修复的 CI 路径;其余36条在非该 lint gate 的可选/能力文件中,不能写成全仓 lint 已通过。前端生产构建与全局 TS typecheck 通过。曾因测试/advisory 路径写错产生准备错误,纠正后的命令已执行;这些准备错误没有算作通过。未查询、轮询或等待 CI。

实际字幕消费者的反例仍未修复。没有更改 PostgreSQL authority store,不把真实 PG 存储集成作为此次新增门;未验收安装桌面版本、跨平台语音、主观试听、创意质量或外部发布。字幕含元字符的显示也应在修复时覆盖,不能把一次视频解码通过泛化为字幕语义完整。

我的整体评价

REQUEST_CHANGES,限 e88dce6330dc1c8d12afd65fc720803fe8070ede。 架构、作用域与可选提供方边界基本合理,主流程和恢复路径确实可用;当前错误在“成功成片的字幕必须保留已接收内容”这个实际用户结果。请在本 PR 修复字幕并补消费者回读测试后再复评。

新增状态局限于 composition/render,未偷换 Goal、Agent 或发布生命周期;明确的 source visibility 也不证明来源权利或发布权限。受保护的机器检查与建议性创意审查保持区分。代码量主要对应真实调用路径和专门渲染,不建议扩大为新媒体框架。此评审不执行合并、安装本机或平台权限变更。

English verdict: REQUEST_CHANGES — e88dce6. A legal blank-line caption renders successfully but the actual packaged browser parses only FIRST LINE and silently drops SECOND LINE. Reject unsupported payloads or serialize them safely, and assert parsed caption preservation. Real renderer/HTTP/UI cancellation, retry, playback, download and disabled-provider readback were exercised; final required local lint and invariant/renderer tests pass. The final update preserves renderer/TS/UI bytes and Python API/test ASTs. CI was not consulted; no merge or machine upgrade performed.

Comment thread packages/loopx-media/src/loopx_media/renderer.py Outdated

@songoow songoow left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Reviewer: model_agent; model=GPT-6 Astra Pro; provider=OpenAI; declaration_source=self_reported

REQUEST_CHANGES — 6da63c3de80d0d08363c220a56b1df58e7cc3cc3。 新增一个 P2:摘录场景会接收并保存正文,却在成功生成的视频中完全省略正文。原评审的字幕空行问题已在当前版本处理,本次不重复提出。

动机

需要把已准备的脚本和素材做成视频的内容作者,是这次变化的直接使用者。此前已有来源检索、提纲和版式能力,制作视频仍需额外编排;本次让 Agent 准备一次素材与时间线,再由同一 Goal 的工作台制作、取消和读回结果。预期可观察结果是可播放、可下载且保留已接收内容的视频、字幕与文字稿;实际编码和字幕读回已验证,摘录正文仍会丢失。创意质量、主观试听、传播效果、外部发布与生产安装不在本次验收范围内。

不做这项变化会继续留下从提纲到本机成片的断点。更小的独立脚本能够编码一次视频,但不能同时保留既有 Goal 的来源绑定、修订、取消和工作台读回。复用 Content-Ops 是合理方向。普通请求需要用户表达一次内容意图;文件路径、哈希、标识符和时间线由 Agent 准备。后续页面导航、选择已有作品和等待编码是操作成本,无须重新向用户索取同一份 JSON 或来源信息。

改动思路

共享准入与状态转换留在现有 TypeScript 能力边界,私有文件和进程执行留在 Python,媒体计算放入显式安装的可选扩展,这一职责划分与现有 Content-Ops、extension 和 item lifecycle 相容。当前 PR 的合理边界是本机来源准备、一次受控渲染、结果验证及同一 Goal 的读回;应在这条边界内补齐摘录正文的处理,不需要新增媒体框架或第二套审批状态。

下表是按准确版本源码整理的说明,执行证据列在后文;它不是额外的图形渲染验收。

触发 主要处理 使用者看到的结果
Agent 准备来源和时间线 校验计划、保存哈希绑定副本和修订 可选择的待制作作品
扩展缺失或关闭 既有 extension owner 拒绝新效果 来源保留,制作不可用
制作、取消、重试 revision、attempt 和运行锁约束写入 完成、失败或取消后重新制作
编码完成 文件字节与哈希回读,修订内容 item 私有视频、字幕和文字稿;旧批准失效
摘录带正文 计划保存正文,但摘录绘制分支遗漏正文 显示生成成功,正文没有进入成片

渲染锁覆盖实际 effect,记录锁约束状态写入;ready 表示这次私有成片的机械检查结果,并不授予发布权限。未安装扩展也能发现和准备作品,安装与启用由既有 extension 生命周期负责。来源风格入口改到“内容制作”内部,属于已披露的导航变化;没有把媒体开关加入通用 Goal 调度或额度规则。

具体改动

已审阅相对 024a12d311149a78a8528c2738286c29a9b0c7b7 的完整 27 文件变化,包括 TypeScript owner、私有工作目录与 CLI、optional renderer、HTTP、工作台、导航与双语文案、协议、示例及测试。新增 1,921 行、删除 19 行,主要开销对应实际制作、恢复和读回路径,没有生成资产混入源码。

本 PR 没有提供独立于本实现的原始书面规格;按 PR 声明的制作任务、已有 content item 生命周期和 extension 边界评判。新增媒体协议用于核对实现声明,不能自行证明验收完成。它的 shots 定义允许可选 body,没有将正文限定为 title/diagram;该遗漏因此也不是已披露的输入限制。

关键代码讲解

  1. validateMediaPlan统一校验资源、帧对齐、字幕、配音及版式,并计算计划摘要。各场景共用的 base 保存正文,excerpt 返回时也保留它。当前新增的字幕检查在准入阶段拒绝内部空行和不支持的标记;真实 VTT/SRT 解析已验证普通换行、引号和 & 的保留。
  2. MediaWorkspace.prepare/render/_execute把来源复制到私有目录,拒绝过期修订,复用完好的结果,并在输出改变后复用 item 的 revise 事件清除旧批准。这里的哈希与帧数验证能证明字节绑定,不能发现输入正文从未被画出来。
  3. renderer.render执行真实图像、视频和音频计算。title/diagram 分支会绘制正文,摘录分支只贴入素材并绘制标题;两条分支的行为差异是本次新增问题的直接原因。
  4. ContentMediaRequestMixin绑定所选 Goal,限制动作字段,后台启动编码,并通过固定文件名和范围请求提供结果。实际 HTTP 检查覆盖错 Goal、外来 Origin、路径注入、损坏文件拒绝和部分字节下载。
  5. ContentMediaWorkbench展示准备、渲染、取消、重试和播放状态,以 generation/read sequence 防止旧请求覆盖新 Goal。inspect 只投影标题、时间、边界和来源,工作台也不会补回被 renderer 遗漏的正文。本次没有把源码检查称为重新执行了打包浏览器。

对主干的风险

[P2] 成功的摘录视频会省略已接收正文。 位置:renderer.py 214–218 行。使用合法图片摘录、3 秒、640×360、12 fps、静音且无字幕的合成计划,先制作空正文版本,再以同一 composition 的下一修订加入 IMPORTANT SYNTHETIC QUALIFIER。两次均经过真实 TypeScript 准入、私有持久化、已安装的 editable provider 和 FFmpeg,并返回 ready、36 帧。修订与计划摘要确实改变,正文也确实保存在 record 中;但视频、poster、字幕和文字稿全部字节相同,inspect 中也没有这段正文。用户因此可以把重要限定语写入已接受的计划,却得到缺少限定语的“成功”成片。

最小修复是在摘录版式中实际绘制正文并校验布局,或在 TypeScript 准入阶段明确拒绝摘录的非空正文并同步说明限制。请增加真实 renderer 回归:非空正文必须体现在输出中,或者必须在创建作品前被拒绝。仅断言计划摘要改变、输出哈希正确或完整解码通过都检测不到这个错误。修复后重跑 LOOPX_MEDIA_RENDERER_TEST=1 uv run --extra test --with-editable ./packages/loopx-media python -m pytest -q tests/test_content_media.py,并包含上述输入对照。

已执行的独立验证:媒体与 item lifecycle 的 14 项 Python 检查通过,包含实际 extension、字幕消费者、HTTP、取消及重试;来源检索与能力配置的同一组 35 项检查在精确 base 和 head 都通过;7 项仓库依赖锁/顶层模块不变量通过;媒体与规范摘要 owner 的两个 TypeScript 测试文件通过;control-plane typecheck 与当前 CI 采用的 Ruff 范围通过。语义 advisory 提示固定输出文件集合,人工确认它属于本地 composition,不扩张 Goal/Agent 生命周期。最初受主机 socket 权限阻止的运行单独保留,重新获准运行后的实际结果没有冒充最初那次执行。

CI 单独记录:当前 Windows job的三个长路径预算用例均为 10522 > 10500;已直接核对的先前主干 job具有相同三个用例和同一失败值。先前主干 294a254121a1e0a969bccd8366a34a6951880288 到本 PR base 的变化是 file-lock UTF-8 修复,当前 PR 未修改预算或 heartbeat 文本 owner。这个现存 Windows 资格问题不能用来证明媒体通过,也不应要求本 PR 扩大预算。尚在运行的远端检查保留为待完成,代码结论由已复现的正文遗漏决定。

我的整体评价

当前结论为 REQUEST_CHANGES。整体复用方向和代码规模与这条制作任务相称;应保留本机来源准备、受控渲染和既有工作台的组合,在当前 PR 修复正文遗漏。长期工作维度的保存、修订、取消和显式恢复路径已有通过证据,没有宣称长程性能收益;用户体验维度尚未达到完整保留所交付内容的要求。

相对原 e88dce6330dc1c8d12afd65fc720803fe8070ede 评审,字幕空行/标记限制已有准入和真实解析证据,旧问题不再作为阻塞。此次已核对工作台相关源码未改变,但没有重新执行打包浏览器、macOS system speech、Windows 媒体渲染或主观试听;原有页面截图和作者执行记录仍各自保留原版本与证据边界。content_ops_media_plan_v0/renderer 协议属于 Content-Ops 的局部扩展,继续复用既有 item 和 extension 词汇;无需为这个问题新建通用 authority 或审批语义。

修复后复评应验证非空摘录正文的真实消费,再重读准确 head 与受影响的调用链。本评审不授予合并、生产安装或发布权限。

English verdict: REQUEST_CHANGES — 6da63c3. The excerpt renderer accepts and persists a nonempty body but omits it from every output. Two real source-bound renders with different bodies both report ready with 36 frames while all output bytes remain identical. Render the body or explicitly reject it before preparation, and cover the behavior through the real provider. The previous caption-paragraph issue is addressed; focused renderer, lifecycle, HTTP, legacy base/head, invariant, TypeScript and lint checks pass. Browser/platform and remaining CI qualifications are stated separately.

Comment thread packages/loopx-media/src/loopx_media/renderer.py
@loopx-agent loopx-agent changed the title feat(content-ops): add local video composition and packaged workbench feat(content-ops): compose local video and editable Blender scenes Oct 19, 2026
loopx-agent and others added 9 commits October 19, 2026 17:29
… provider

Signed-off-by: LoopX Agent <337587101+loopx-agent@users.noreply.github.com>
Signed-off-by: LoopX Agent <337587101+loopx-agent@users.noreply.github.com>
Signed-off-by: LoopX Agent <337587101+loopx-agent@users.noreply.github.com>
Signed-off-by: LoopX Agent <337587101+loopx-agent@users.noreply.github.com>
Signed-off-by: LoopX Agent <337587101+loopx-agent@users.noreply.github.com>
Signed-off-by: LoopX Agent <337587101+loopx-agent@users.noreply.github.com>
…sitions

Signed-off-by: LoopX Agent <337587101+loopx-agent@users.noreply.github.com>
Signed-off-by: LoopX Agent <337587101+loopx-agent@users.noreply.github.com>
Signed-off-by: huangruiteng <huangrt01@163.com>
@huangruiteng
huangruiteng force-pushed the codex/content-media-composition-20261019 branch from 4ecf99f to 036ddce Compare October 19, 2026 09:45

@huangruiteng huangruiteng left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Reviewer: model_agent; model=GPT-5; provider=OpenAI; declaration_source=self_reported

准确 head:036ddced0abf7dc9015469bc149b661f4170bf46。没有发现阻塞级问题。原字幕与空间场景正文两条 P2 已在共享准入和实际 provider 两端修复,并用真实字幕消费者、FFmpeg、HTTP 与 Blender 4.5.12 重开流程复核。

动机

负责把已准备好的脚本、素材和时间线制作成本机视频的内容作者与 Agent,需要一个不必自行拼接编码、状态恢复和下载协议的完整路径。旧实现只能准备来源风格与提纲;当作者把限定语写进摘录或 Blender 场景正文时,系统会把正文持久化后从所有成片输出中静默丢掉,字幕中的空行也会在原生消费端截断,用户却看到 ready。

改动后的直接场景是:Agent 准备同一 Goal 的来源、时间线、字幕和可选三维场景,作者在工作台选择作品、制作或取消,结果只有在完整解码、来源哈希和三维工程重开检查通过后才显示为 ready。Observable outcome 是私有视频、字幕、文字稿、RGBA/深度画面及可重开 Blender 工程通过同一修订读回;编码通过仍不授予发布权限。

这不是全网媒体框架,也不宣称创意质量、受众理解、主观试听、外部发布或生产安装已经验收。Remaining gap 是更丰富的媒体生成与跨平台 Blender 资格仍由后续独立工作承接;当前边界保留本机来源、受控渲染、失败恢复和内容 item 现有审批语义。

改动思路

正向旅程由 Agent CLI 或工作台的私有请求进入:validateMediaPlan 统一准入并把故事、来源、时间、字幕与场景绑定为一个摘要,MediaWorkspace 保存不可变来源快照并约束 revision/attempt,可选 loopx-media 才执行编码,validateMediaResult 再拒绝越界文件名、错误帧数、错误 narration 或缺失三维 pass,最后通过 HTTP file route 和内容 item revise 读回。取消、宿主中断、失败与损坏分别有显式状态;已有完整结果复用,不重复编码。

设计保留现有 content-ops、content item lifecycle、layout catalog 与 extension runtime,不新增第二套审批或调度 owner。TypeScript 继续负责共享决策与结果边界,Python 只承担 Goal-local 文件、HTTP 与专用媒体计算;Blender 计算留在显式安装的可选包内。全局机制判断为 retain:私有渲染不产生发布权限,失败不会回填成图或冻结帧,可选 provider 的定位和恢复也已通过实际安装/禁用路径验证。

当前 PR 边界是完成一条可独立审查、测试和回滚的本机成片旅程;它没有把未来生成式媒体、交互学习或跨平台三维能力塞进本次契约。相比继续让 Agent 私写一次性脚本,复用既有 Goal 来源、修订、批准和 extension 生命周期能让后续 provider 变化继续落在同一 owner 上。

阶段 权威输入或决策 真实副作用与读回
准备 TypeScript 计划摘要与内容 item 私有快照、revision、来源哈希
制作或取消 revision 与 attempt 绑定 可选中 provider 执行、取消标志、单一生效 attempt
完成 全解码、结果摘要与 Blender 重开检查 ready 文件、item revise、旧批准失效
失败或损坏 明确错误、可重试 revision 无 ready 下载;依赖修复或新修订恢复

具体改动

本 head 相对 3a816411785fea545c379769a1ff98f5e881bd5d 共 29 个文件、+2802/−19。生产代码把媒体计划与结果校验放在共享 TypeScript owner,把来源复制、工作目录、后台尝试、取消、结果哈希和 HTTP 范围读取放在 Goal-scoped Python 边界;测试与示例覆盖真实 2D、字幕消费者、disabled provider、损坏文件、Blender ZIP 与独立重开。文档同步说明 caption 子集、空间正文拒绝、安装/禁用、平台限制和发布权限边界。没有生成媒体、私有日志或本机路径进入提交。本 PR 没有独立于任务的已接受书面规格,因此 spec basis 为 no_spec;评审以用户要求的本机成片旅程、既有 content item/extension 契约和复现的 review thread 为依据。

关键代码讲解

  1. validateMediaPlan 是准入 owner。它限制来源路径、大小与 SHA256、时间线、字幕、narration 和声明式 Blender 场景,并在 digest 前拒绝 excerpt/Blender 非空 body。任何字段变化都会形成新计划摘要,renderer 不能自行扩张要执行的内容。
  2. MediaWorkspace.prepare/render/_execute 负责私有快照、revision/attempt、单 effect 锁、取消文件与结果提交。成功后才 revise content item;计划或输出字节改变都会清除旧批准,provider 缺失时保留已准备作品和来源。
  3. renderer.render 真实生成 VTT/SRT/transcript、音频与视频。它在 provider 边界再次拒绝两个空间 kind 的非空正文,并在序列化前拒绝字幕结构空行和歧义标记,避免“编码成功但文本被消费端截断”。
  4. blender._render/_verify/project_archive 把准入的 geometry、camera、materials、lights 和 keyframes 写成 .blend,以独立进程禁用脚本重开并检查场景,再打包相对路径工程、RGBA/深度帧和 replay builder;失败不会退回二维替代。
  5. ContentMediaWorkbench 用 Goal generation/read sequence 防止旧请求覆盖新 Goal,只在渲染期间轮询,并区分 provider unavailable、失败、取消、中断和损坏。来源风格入口移到同一 Content production 页的详细区域,已有 item 审批与发布边界没有改变。

语义与 CI 对齐

新增 blender shot、渲染状态和固定结果文件名扩展的是现有 Content-Ops 局部词汇,不是新的 Goal、Todo 或发布生命周期。语义 advisory 只将 Python RESULT_FILES 报为局部 I/O 白名单;人工核对后无需注册为共享控制面词汇。旧 review 的语义修复是显式收窄:不支持的正文现在在准备前失败,或在 stale/direct provider 请求处失败,而不是成功丢字。

对主干的风险

最强的剩余回归场景是:本地记录或 provider 输出看似完整,但字幕、正文、帧数或三维工程实际不一致。当前代码通过计划摘要、两次空间正文拒绝、真实 VTT/SRT 解码、逐文件字节/哈希、全时间线解码、Blender pass 帧数与独立重开共同缩小该风险;若 provider 在运行中失败,作品进入 failed/cancelled/interrupted,不会用图或冻结帧伪装 ready。

可选安装是明确的 provider gate:未安装或禁用时,普通二维能力不被强制带依赖,prepare/list/inspect 与已完成下载仍可读,新 render 返回 provider unavailable;修复依赖后可对同一 revision 重试。Blender 只在 macOS CPU、Python 3.11 与 Blender 4.5 LTS 上做了真机资格,Windows/Linux、GPU、5.x、峰值内存和主观创意质量仍未验收;这些是残余风险,不是把未知写成通过。

已执行的 exact-head 或最终代码等价验证包括:control-plane typecheck;26 个 TypeScript media/digest 测试;9 个真实 Python 媒体测试,其中包含 bpy 4.5.12 的实际 BVH/Blender 工程生成、重开、渲染与 HTTP ZIP 下载;生产 Chat bundle;packaged typed-actions 浏览器场景;CI 同范围 Ruff;7 个 dependency-lock/top-level module 测试;最终 head 的 19 项 premerge 检查与公开边界扫描。没有 required failed 或 skipped case。Packet 明确不等待 CI,因此排队中的远端 job 未被当作本地通过证据。

我的整体评价

APPROVE,限 036ddced0abf7dc9015469bc149b661f4170bf46。 该 PR 给内容作者与 Agent 一条真实可用的 Goal-local 成片、恢复和读回路径;长期工作维度没有新增重复 effect、审批旁路或无界 Goal 状态,用户旅程也从“文本被静默丢弃却 ready”提升为可诊断、可取消、可重试并保留来源的明确结果。

代码量主要来自真实媒体计算、可选 Blender provider、HTTP/工作台与相应负向验收;没有发现应在本 PR 继续压缩的重复 authority。建议后续只在有真实消费者时扩展跨平台三维与媒体样式,不需要为当前完成边界新增框架。旧字幕与空间正文 finding 已解决,其余 carry-over 是平台、创意和性能资格,不影响本 head 的合并结论。

English verdict: APPROVE - 036ddce. Both prior P2 data-loss paths are closed at shared admission and the real provider boundary; caption consumers, Goal-scoped HTTP, lifecycle/cancellation, full decode, and real Blender 4.5.12 reopen/passes pass. No blocking finding remains; cross-platform Blender, creative quality, and subjective media assessment stay explicitly unverified.

@huangruiteng
huangruiteng dismissed songoow’s stale review October 19, 2026 09:49

Resolved and verified at 036ddce. Caption blank-line/markup inputs now fail shared admission and the provider boundary; accepted line breaks, ampersands and quotes round-trip through real VTT/SRT consumers. Excerpt and Blender bodies now fail typed admission and direct provider execution before output instead of being silently omitted. Both discussion threads are resolved with exact-head evidence; 26 TypeScript and 9 real Python provider/HTTP/Blender tests plus 19/19 premerge checks passed. Fresh exact-head review is APPROVE.

@huangruiteng

Copy link
Copy Markdown
Collaborator

Authorized admin-bypass merge record

Exact head: 036ddced0abf7dc9015469bc149b661f4170bf46

  • Final premerge: 19/19 passed, zero failures, zero manual holds.
  • Exact-scope change quality: cqr_ff6dc736b5b04db2e8dc, decision pass, verification valid.
  • Exact-head review: APPROVE; both review threads resolved; prior CHANGES_REQUESTED dismissed after current-head evidence.
  • Thread and approval closeout: clear.
  • Packet policy: wait_for_ci=false; hosted CI was not polled or used as review evidence.

loopx pr-review --check-merge-readiness still reports github_review_decision_not_approved because the approving account is also the latest pusher and GitHub branch protection does not count that approval for the final review decision. mergeable=MERGEABLE; the exact head is unchanged.

The repository owner has explicitly authorized this self-merge and admin bypass. This bypass is used only for the last-pusher review-decision condition. It does not replace the exact-head review, resolved findings, local/real-provider validation, or valid CQR receipt.

@huangruiteng
huangruiteng merged commit 1811e03 into main Oct 19, 2026
7 of 9 checks passed
@huangruiteng
huangruiteng deleted the codex/content-media-composition-20261019 branch October 19, 2026 09:52
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.

3 participants