diff --git a/blender-5.2.0/source/blender/web_engine/web_engine_api.cpp b/blender-5.2.0/source/blender/web_engine/web_engine_api.cpp index d6ec5100e..295ef7ad1 100644 --- a/blender-5.2.0/source/blender/web_engine/web_engine_api.cpp +++ b/blender-5.2.0/source/blender/web_engine/web_engine_api.cpp @@ -1585,7 +1585,7 @@ EMSCRIPTEN_KEEPALIVE int web_engine_apply_command(const int handle, type == "moveObjectToCollection" || type == "renameId" || type == "joinObjects" || type == "separateMeshFaces" || type == "applyObjectTransform" || type == "setObjectOrigin" || type == "setCurveControlPoints" || type == "setCurveHandle" || type == "setCurveTopology" || type == "setCurveSplines" || type == "setSurfaceTopology" || type == "setFontBody" || - type == "setFontProperties" || type == "setFontAdvanced" || type == "importVFont" || type == "setFontLinks" || type == "setVolumeProperties" || type == "deleteNonMeshData" || + type == "setFontProperties" || type == "setFontAdvanced" || type == "importVFont" || type == "setFontLinks" || type == "setTextSource" || type == "setVolumeProperties" || type == "deleteNonMeshData" || type == "setMetaballElements" || type == "createGreasePencilLayer" || type == "removeGreasePencilLayer" || type == "moveGreasePencilLayer" || type == "moveGreasePencilFrame" || @@ -1994,6 +1994,11 @@ EMSCRIPTEN_KEEPALIVE int web_engine_apply_command(const int handle, applied = main_error.empty() && web_engine_blend_main_set_font_links( engine->authoritative_main, command.value("dataId", "").c_str(), font_ids, main_error); } + else if (type == "setTextSource") { + applied = web_engine_blend_main_set_text_source( + engine->authoritative_main, command.value("dataId", "").c_str(), + command.value("source", "").c_str(), main_error); + } else if (type == "setVolumeProperties") { WebVolumePropertiesEdit properties; properties.source_path = command.value("sourcePath", ""); diff --git a/blender-5.2.0/source/blender/web_engine/web_engine_main_state.cpp b/blender-5.2.0/source/blender/web_engine/web_engine_main_state.cpp index 2d953cead..b9ea0502f 100644 --- a/blender-5.2.0/source/blender/web_engine/web_engine_main_state.cpp +++ b/blender-5.2.0/source/blender/web_engine/web_engine_main_state.cpp @@ -32,6 +32,7 @@ #include "BKE_material.hh" #include "BKE_mesh.h" #include "BKE_mesh.hh" +#include "BKE_modifier.hh" #include "BKE_node.hh" #include "BKE_node_legacy_types.hh" #include "BKE_node_runtime.hh" @@ -46,6 +47,7 @@ #include "BKE_volume.hh" #include "BKE_fcurve.hh" #include "BKE_image.hh" +#include "BKE_idprop.hh" #include "ANIM_action.hh" #include "ANIM_fcurve.hh" @@ -169,6 +171,22 @@ bool write_text(Main *main, const char *name, const std::string &contents) return true; } +bool write_id_string(ID &id, const char *name, const std::string &contents) +{ + if (name == nullptr || contents.size() > 16 * 1024 * 1024) return false; + IDProperty *group = IDP_EnsureProperties(&id); + if (group == nullptr) return false; + if (IDProperty *existing = IDP_GetPropertyFromGroup_null(group, name)) { + IDP_FreeFromGroup(group, existing); + } + IDProperty *property = bke::idprop::create(name, contents.c_str()).release(); + if (property == nullptr || !IDP_AddToGroup(group, property)) { + if (property != nullptr) IDP_FreeProperty(property); + return false; + } + return true; +} + void load_persisted_geometry_overrides(WebBlendMainState *state) { if (state == nullptr || state->main == nullptr) return; @@ -3964,6 +3982,28 @@ bool web_engine_blend_main_set_font_links(WebBlendMainState *state, return true; } +bool web_engine_blend_main_set_text_source(WebBlendMainState *state, + const char *data_id, + const char *source, + std::string &error) +{ + if (state == nullptr || state->main == nullptr || data_id == nullptr || source == nullptr || + strncmp(data_id, "text:", 5) != 0 || strlen(source) > 1024 * 1024) + { + error = "NON_MESH_PROPERTY_INVALID: Text source must be a local text data-block within the 1 MiB budget"; + return false; + } + Text *text = find_text(state->main, data_id + 5); + if (text == nullptr || text->id.lib != nullptr) { + error = "NON_MESH_DATA_UNSUPPORTED: Text data-block was not found or is linked read-only"; + return false; + } + BKE_text_clear(text); + BKE_text_write(text, source, int(strlen(source))); + text->flags |= TXT_ISDIRTY; + return true; +} + bool web_engine_blend_main_set_volume_properties(WebBlendMainState *state, const char *data_id, const WebVolumePropertiesEdit &properties, @@ -4428,6 +4468,53 @@ bool web_engine_blend_main_set_geometry_node_graph(WebBlendMainState *state, error = "GN_INVALID_GRAPH: Geometry Node graph could not be persisted in Main"; return false; } + /* Materialize a native GeometryNodeTree datablock as the durable owner of + * this graph. The bounded JSON remains the transport representation, while + * future node-family slices can populate the tree incrementally. */ + bNodeTree *native_tree = nullptr; + for (bNodeTree &candidate : state->main->nodetrees) { + if (id_name(candidate.id) == graph_id) { + native_tree = &candidate; + break; + } + } + if (native_tree == nullptr) { + native_tree = bke::node_tree_add_tree(state->main, graph_id, "GeometryNodeTree"); + } + if (native_tree == nullptr) { + state->geometry_node_graph_overrides.erase(graph_id); + persist_geometry_overrides(state); + error = "GN_INVALID_GRAPH: Blender could not create a GeometryNodeTree datablock"; + return false; + } + Object *target_object = find_mesh_object(state->main, mesh_id); + NodesModifierData *nodes_modifier = nullptr; + if (target_object != nullptr) { + nodes_modifier = reinterpret_cast( + BKE_modifiers_findby_type(target_object, eModifierType_Nodes)); + if (nodes_modifier == nullptr) { + nodes_modifier = reinterpret_cast(BKE_modifier_new(eModifierType_Nodes)); + if (nodes_modifier == nullptr) { + error = "GN_INVALID_GRAPH: Blender could not create a Geometry Nodes modifier"; + return false; + } + STRNCPY_UTF8(nodes_modifier->modifier.name, "Web Geometry Nodes"); + BKE_modifier_unique_name(&target_object->modifiers, &nodes_modifier->modifier); + BKE_modifiers_persistent_uid_init(*target_object, nodes_modifier->modifier); + BLI_addtail(&target_object->modifiers, nodes_modifier); + } + if (nodes_modifier->node_group != native_tree) { + if (nodes_modifier->node_group != nullptr) id_us_min(&nodes_modifier->node_group->id); + nodes_modifier->node_group = native_tree; + id_us_plus(&native_tree->id); + } + target_object->id.recalc |= ID_RECALC_GEOMETRY; + if (!write_id_string(target_object->id, "web_geometry_node_graph", graph_text)) { + error = "GN_INVALID_GRAPH: Geometry Node graph metadata could not be written to Object"; + return false; + } + } + native_tree->id.recalc |= ID_RECALC_NTREE_OUTPUT; return true; } catch (const std::exception &exception) { @@ -4596,6 +4683,15 @@ bool web_engine_blend_main_set_physics_simulation(WebBlendMainState *state, error = "PHYSICS_MANIFEST_INVALID: physics manifest could not be persisted in Main"; return false; } + for (const json &system : manifest["systems"]) { + const std::string owner_id = system.value("ownerObjectId", ""); + if (Object *owner = find_object(state->main, owner_id.c_str())) { + if (!write_id_string(owner->id, "web_physics_manifest", manifest_text)) { + error = "PHYSICS_MANIFEST_INVALID: physics metadata could not be written to Object"; + return false; + } + } + } state->physics_simulation_override = manifest_text; return true; } diff --git a/blender-5.2.0/source/blender/web_engine/web_engine_main_state.h b/blender-5.2.0/source/blender/web_engine/web_engine_main_state.h index db0159dca..fcacf96f5 100644 --- a/blender-5.2.0/source/blender/web_engine/web_engine_main_state.h +++ b/blender-5.2.0/source/blender/web_engine/web_engine_main_state.h @@ -366,6 +366,10 @@ bool web_engine_blend_main_set_font_links(WebBlendMainState *state, const char *data_id, const std::array &font_ids, std::string &error); +bool web_engine_blend_main_set_text_source(WebBlendMainState *state, + const char *data_id, + const char *source, + std::string &error); bool web_engine_blend_main_set_volume_properties(WebBlendMainState *state, const char *data_id, const WebVolumePropertiesEdit &properties, diff --git a/docs/BLENDER_WEB_PARITY_FOLLOWUP_PLAN.md b/docs/BLENDER_WEB_PARITY_FOLLOWUP_PLAN.md new file mode 100644 index 000000000..ae4f26d7e --- /dev/null +++ b/docs/BLENDER_WEB_PARITY_FOLLOWUP_PLAN.md @@ -0,0 +1,372 @@ +# Blender/Web 移植后续执行安排 + +更新时间:2026-08-26(America/New_York) + +## 1. 目标与当前结论 + +目标是让 Web 版本在 Chromium 中形成可持续的 Blender 工作流:打开 `.blend`、读取 SceneIR、执行受约束的 Main mutation、保存/重开、恢复和导出,并且每项声明都绑定可复现证据。 + +当前基线已经可以正常工作,但还不能宣称“与 Blender 全量 parity”: + +- quick CI 已修复 Node 堆内存问题:7/7 lane READY,128 个 unit 文件隔离执行。 +- Blender 5.2 inventory 有 6,900 条记录,聚合为 15 个 capability family;当前记录仍是 `L0 / METADATA_ONLY`。 +- P7-002 已生成 45 个原子任务,即 15 个 family 乘以 `desktopPositive`、`wasmMutation`、`saveReopenExact`。 +- P7-003 的恢复链为 READY,但 `parityClosure` 和 `releaseDecision` 为 BLOCKED;当前 9/45 atomic 行为已有可审计 Chromium receipt。 +- M12 有 82 条、42 个路径的 SHA 漂移;Git-history snapshot 已恢复 22 条,剩余 60 条保持 `BLOCKED_SOURCE_LOST`,历史 manifest 不得重写。 + +因此后续安排分为两条并行轨道: + +1. 新证据驱动的 Blender/Web 正向移植。 +2. M12 原始来源快照恢复与 provenance 重建。 + +当前机器整合入口为 `node tools/web/generate-wbv2-integration-readiness.mjs`,输出 `tests/golden/WBV2-P7-003/integration-readiness-report.json`;该报告是继续开发的 checkpoint,不是 parity 成功声明。 + +## 2. 不可违反的规则 + +1. 只使用 Chromium 作为浏览器证据;Firefox/WebKit 不进入本计划的验收范围。 +2. 旧 manifest 的原始 SHA、时间线和状态不可改写。新发现只能追加 corrective evidence。 +3. 一个执行任务只负责一个主要行为。共享代码可以复用,但每个行为必须有独立 fixture、报告和 manifest。 +4. `FEATURE_PARITY` 只有在以下条件同时满足时才能出现: + - Blender desktop 正向结果; + - WASM/Main 正向 mutation; + - save/reopen 精确保持; + - Chromium 生产路径通过; + - malformed、unsupported、cancel、duplicate、over-budget 和 hash-drift 负例均 fail-closed。 +5. 任何失败都保持 `in_progress` 或 `blocked`,不能手工推进 `nextTask`。 +6. 所有产物必须由 generator/checker 生成,并由 SHA-256 manifest 绑定。 + +## 3. 阶段安排 + +### 阶段 A:构建与证据基础设施(第 1-2 天) + +目标:让桌面 binary、WASM binary、测试 runner 在同一工作区可重复运行。 + +工作项: + +- 重新配置 `build_blender_5.2.0` 的 CMake cache,使 RUNPATH 指向当前工作区的依赖目录;禁止依赖 `/home/mes123456/working` 的隐式路径。 +- 记录 Blender、Emscripten、Node、Chrome、依赖库版本和 SHA;生成一份可复现环境 receipt。 +- 保持 `tools/web/run-unit-tests.mjs` 的隔离策略,quick lane 每次提交都运行。 +- 为 generated-gap checker 抽出通用的 `open -> snapshot -> mutate -> save -> reopen -> negative` runner,减少各任务重复代码。 +- 统一 comparator:对象 ID、Main revision、delta、资源 hash、save/reopen hash 必须使用 canonical JSON 比较。 + +完成条件: + +- `cmake --build build_blender_5.2.0 -j2` 成功;桌面 binary 在不依赖旧工作区路径的情况下启动。 +- quick CI、typecheck、lint、context governance 全部通过。 +- 同一 fixture 连续生成两次字节一致。 + +### 阶段 B:三条现有正向链路固化(第 3-5 天) + +目标:把已有 C5 pilot 的 Mesh、Modifier、Asset 能力转成标准 Web evidence 模板。 + +复用模块: + +- `web/protocol/corrective-main-transaction.ts` +- `web/protocol/corrective-mesh-command.ts` +- `web/protocol/corrective-modifier-command.ts` +- `web/protocol/corrective-asset-catalog-command.ts` +- 现有 C5 Chromium family reports 和 save/reopen checker + +每个 family 必须补齐: + +- desktop positive fixture; +- WASM/Main mutation 和 revision 变化; +- undo/redo 与 save/reopen; +- Chromium production interaction; +- malformed payload、stale revision、missing target、budget overflow 负例。 + +完成条件: + +- 三个 family 的 evidence 从 `CANDIDATE` 变为可审计的正向结果。 +- 旧 C5/M12 证据只读消费,不改变历史 SHA。 +- 共享 runner 能在单条命令中重复三族验证。 + +### 阶段 C:按风险批量移植高价值 family(第 2-3 周) + +采用“一个共享能力实现 + 三个原子证据任务”的节奏。实现一次,证据拆成三个独立任务,不为 6,900 条 legacy 记录重复造轮子。 + +优先级如下: + +| 顺序 | family | 规模 | 先解决的问题 | 主要复用方向 | +| --- | --- | ---: | --- | --- | +| 1 | `UI_EDITOR` | 3,930 | editor/context/keymap 与 Chromium 输入一致性 | editor workflow、keyboard/pointer/input-modal | +| 2 | `MEDIA_IO` | 585 | import/export、媒体资源、外部依赖与 loss report | GLB/OBJ/PLY/STL、asset sandbox、media recovery | +| 3 | `NODES_GRAPH` | 543 | Geometry Nodes/shader allowlist、预算和 compile rollback | geometry-nodes、shader-compiler、render budget | +| 4 | `MESH_EDITING` | 431 | 选择、拓扑 mutation、binary delta | mesh command、mesh geometry delta、topology comparator | +| 5 | `OBJECT_OPERATIONS` | 316 | transform、parent、collection、undo/redo | Main transaction、scene delta、selection history | +| 6 | `RIG_ANIMATION` | 375 | Action、TRS、pose、constraint、skin | animation、NLA、armature、skin protocol | +| 7 | `MATERIAL_RENDER` | 125 | PBR/UV/texture 与渲染路由 | shader graph、render routing、packed assets | +| 8 | `SIMULATION` | 155 | cache identity、cancel、quota、restart | simulation cache、worker fault、storage journal | +| 9 | `SCULPT_PAINT` | 117 | PBVH 限制、笔刷/笔画和非 mesh slice | sculpt、paint、non-mesh binary | +| 10 | `CORE_SCENE_GRAPH` | 66 | Scene/Collection/Object/Depsgraph canonical state | SceneIR、stable IDs、world matrices | +| 11 | `CORE_DNA_RNA` | 38 | RNA metadata read and unsupported retention | reader metadata、unknown-field preservation | +| 12 | `CORE_MESH` | 31 | Mesh datablock schema and attributes | binary mesh、attribute domains | +| 13 | `OTHER_OPERATOR` | 103 | 无法归入高阶 family 的小范围 operator | explicit unsupported/EXCLUDED routing | +| 14 | `CORE_OBJECT` | 2 | Object identity/read compatibility | scene graph reader | + +`MODIFIER_SYSTEM`(83)虽然 legacy 记录相对完整,也必须经过同样的 WASM mutation 和 persistence 证明,不能仅凭旧 completed 状态提升 parity。 + +每个 family 的固定工作包: + +1. 选 1 个最小可观察行为,建立 Blender fixture 和 canonical expected state。 +2. 在 `web/protocol` 建立或复用 bounded command,统一走 Main transaction。 +3. 接入 `web_engine_blend_reader.cpp`,只读取声明的数据,不执行任意 Blender operator 或脚本。 +4. 添加桌面 checker、WASM checker、Chromium e2e、unit negatives。 +5. 生成该 family 的三个原子 manifest,只有三项证据均通过时才提升 capability 状态。 +6. 通过 handoff 后再由 generator 激活下一个任务。 + +### 阶段 D:完整 45 项原子队列关闭(第 3-4 周) + +目标:逐项清空 P7-002 队列,但不把同类 legacy 记录重复实现。 + +每项任务的最小证据包: + +- fixture 和 generator; +- desktop report; +- WASM/Main report; +- Chromium report(涉及生产交互时必须有); +- persistence/hash report; +- negative matrix; +- status、manifest、task-context; +- parent manifest SHA 和当前 source/build SHA。 + +队列推进规则: + +- 始终只有一个 `active + ready`; +- 当前任务完成后由 manifest 的 `nextTask` 决定下一项; +- 任何 hash drift、环境缺失或测试失败都停在当前任务; +- 每完成一个 family,重新计算 6,900 条 legacy 覆盖映射,已证明的记录保留 regression coverage。 + +### 阶段 E:M12 provenance 恢复(与阶段 C/D 并行) + +这条轨道不依赖 Web 功能实现,责任人必须提供以下任一权威来源: + +- 原始 immutable repository snapshot; +- 带签名的 M12 artifact archive; +- CI artifact store 中可验证的原始文件和时间戳。 + +恢复步骤: + +1. 只读导入来源,计算原始 SHA,不覆盖当前文件。 +2. 将原始文件与当前观察值做逐项三方比较:`original manifest`、`source snapshot`、`current worktree`。 +3. 对能复原的条目生成 `PROVENANCE_RESTORED` corrective evidence。 +4. 对仍无法复原的条目保留 `BLOCKED_SOURCE_LOST`。 +5. 只有 provenance checker 和 protected hash checker 同时通过,才允许影响 release gate。 + +在来源恢复前,禁止以下行为: + +- 用当前文件反推旧文件; +- 用新 manifest 覆盖旧 manifest; +- 删除 drift entry; +- 把 `BLOCKED_SOURCE_LOST` 改成 `READY` 或 `FEATURE_PARITY`。 + +### 阶段 F:Release closure(第 5 周) + +只有阶段 D 和 E 都完成后执行: + +- 重新生成完整 capability parity map; +- 统计 `FEATURE_PARITY`、`READ_COMPATIBILITY`、`NEGATIVE_BOUNDARY`、`EXCLUDED`、`BLOCKED`; +- 运行 quick、Chromium、release、offline、SBOM、rollback 全套 lane; +- 检查所有声明都绑定 manifest 和 immutable source/build SHA; +- 生成 known limitations 和最终 release decision。 + +release decision 的允许状态: + +- `READY`:所有目标 capability 达到声明级别,历史 provenance 完整; +- `BLOCKED`:存在任何未闭合 parity、来源丢失、hash drift、负例不安全或 release lane 失败; +- 不允许使用“近似完成”或隐式降级状态替代上述两种状态。 + +## 4. 每周产出与效率指标 + +每周必须产出: + +- 完成的 capability family 数; +- 新增正向 desktop/WASM/Chromium evidence 数; +- 从 L0 提升的 legacy 覆盖条目数; +- 仍为 BLOCKED 的条目数及原因分布; +- quick CI 平均耗时与峰值 Node heap; +- fixture 重生成字节一致率; +- M12 provenance 恢复条目数。 + +建议效率目标: + +- 每个 family 至少关闭 3 个原子行为证据,覆盖同族 legacy 记录; +- 每周完成 3-5 个 family,而不是逐条处理 6,900 个 legacy operator; +- 每个 family 的重复 checker 代码不超过一个模板文件的 20%; +- quick lane 保持单次提交可运行,Chromium lane 在 family 合并前运行; +- 失败任务平均恢复时间小于一个工作日,且不通过改历史证据解决。 + +## 5. 当前立即执行顺序 + +1. 修复 `build_blender_5.2.0` 的 workspace RUNPATH,并生成环境 receipt。 +2. 用现有 C5 Mesh/Modifier/Asset 证据跑通统一 family runner。 +3. 激活 P7-002 队列中第一个高风险 family 的 `desktopPositive` 任务。 +4. 依次完成该 family 的 `wasmMutation` 和 `saveReopenExact`,再推进下一个 family。 +5. 每个 family 完成后更新 parity map 和风险报告,但不修改 M12 历史 manifest。 +6. 并行向 provenance 责任人索取 M12 immutable snapshot;在收到前保持 release gate BLOCKED。 +7. 只有 45 项原子任务和 M12 provenance 都闭合,才重新运行 P7-003 release gate。 + +## 6. 回滚与停止条件 + +出现以下任一情况时立即停在当前任务: + +- desktop 与 WASM/Main 状态不一致; +- save/reopen 改变 Main revision、资源 hash 或稳定 ID; +- malformed/unsupported/cancel/over-budget 输入改变 Main; +- source/build/fixture/manifest hash 漂移; +- CMake、Node heap、Chromium 或 Blender 环境不可复现; +- M12 来源仍不可验证。 + +回滚只删除当前新任务的 fixture、报告、manifest、status 和 context,恢复 parent 的 queue tail;不得触碰已完成任务的历史 evidence,也不得把失败任务标成完成。 + +## 7. 完成定义 + +本计划只有在以下条件同时满足时才算完成: + +- Web 生产路径可在 Chromium 中完成 open/edit/undo/redo/save/restart/reopen/export; +- 15 个 capability family 的目标 parity level 有逐项证据; +- 45 个原子行为任务全部完成或明确 `EXCLUDED/BLOCKED` 并有原因; +- 负向边界、资源预算、取消、重启、OOM、quota、device loss 均 fail-closed; +- M12 historical SHA 的可复原部分有权威 source snapshot,剩余部分明确保留 blocked; +- quick/Chromium/release/offline/SBOM/rollback 和 protected hashes 全部通过; +- 最终 release gate 不依赖人工解释或手工重写历史文件。 + +## 8. 项目完成情况总表(整合视图) + +这里的“完成”严格指对应任务的机器验收和 manifest handoff 已完成,不把它扩大解释为 Blender 全产品 parity。 + +| 区域 | 机器状态 | 已有成果 | 仍需整合的内容 | +| --- | --- | --- | --- | +| P0 事实与合同 | 3/3 done | scope、6,900 条 Blender 5.2 inventory、capability/error/budget contract | 将 inventory 条目映射到最终 `FEATURE_PARITY`、`READ_COMPATIBILITY` 或 `EXCLUDED` | +| P1 Runtime/Main | 5/5 done | single/pthread receipt、SceneIR stable ID、Main transaction/history、Worker lifecycle、OPFS/IndexedDB recovery | 将所有后续 family runner 统一接入同一 revision/generation/store | +| P2 核心建模闭环 | 5/5 done | open/context、transform/hierarchy、mesh edit、双 viewport、open-edit-undo-redo-save-reopen | 将已有 P2 证据作为 family regression,不重复实现基础 writer | +| P3 Authoring/IO | 5/5 done | material/UV、animation、rig/skin、GLB round-trip、library append/link/override | 补齐各 family 的统一 WASM mutation receipt 和 Chromium 生产证据 | +| P4 高级本地切片 | 4/4 done | modifier、Geometry Nodes/shader、sculpt/non-mesh/paint、simulation cache | 将能力边界、预算和 recovery 结果汇入 capability ledger | +| P5 Render/Server | 3/3 done | render routing、media recovery、server job binding | 保持 local/server/excluded 分类,不把 server 结果当作本地 parity | +| P6 安全/发布 | 3/3 done | default-deny scripting、故障矩阵、offline/CI/SBOM/rollback | 修复构建环境 receipt 的可复现路径,避免旧工作区依赖 | +| P7 差距程序 | P7-001/P7-002 done,P7-003 blocked | 15 family、45 原子行为任务、release gate;9/45 Chromium receipt 已绑定 | 剩余 36 项 WASM mutation/persistence/Chromium 证据和 M12 provenance | +| Quick CI | READY | 7/7 lane,128 个 unit 文件隔离执行 | 每次 capability 合并继续作为必需回归,不重引入单进程 OOM | +| M12 历史证据 | BLOCKED_SOURCE_LOST | 82 条、42 路径 drift ledger;Git-history snapshot 恢复 22 条,历史文件保持不变 | 取得剩余 immutable snapshot 或签名 artifact 后只读重建 provenance | + +## 9. 不重复开发的模块所有权 + +所有后续工作先按以下所有权表复用;除非现有接口无法表达新行为,否则不创建第二套协议、store、runner 或 comparator。 + +| 能力 | 唯一生产入口 | 复用的现有证据/测试 | 允许新增的最小内容 | +| --- | --- | --- | --- | +| 文件读取和 SceneIR | `web_engine_blend_reader.cpp`、`web/protocol/scene-ir.ts` | P1/P2/P7 reader receipts | 新字段的 typed parser、fallback、schema negative | +| Main mutation/history | `web/protocol/corrective-main-transaction.ts` 与现有 Main state | P1-003、P2-002、P2-005 | 一个 bounded command 和对应 transaction case | +| Mesh | `corrective-mesh-command.ts`、mesh delta comparator | C5 Mesh、P2-003 | 新拓扑/attribute case,不复制 transaction | +| Modifier | `corrective-modifier-command.ts` | C5 Modifier、P4-001 | 一个声明参数或 apply slice | +| Asset/library | `corrective-asset-catalog-command.ts` 与 library protocols | C5 Asset、P3-005、M12 library receipts | 新 ownership/reload case,不重写 catalog schema | +| 渲染与节点 | render routing、shader/geometry-node protocols | P4-002、P5-001、M12 format receipts | 只添加 allowlist/预算条目 | +| Worker/存储/recovery | runtime lifecycle、OPFS/IndexedDB journal | P1-004/P1-005、P4-004、P6-002 | 新 fault injection 或资源计数,不新建 recovery store | +| CI/release | `run-ci-lane.mjs`、release checkers、manifest | P6-003、quick report | 新 lane 仅在现有 lane 无法表达时增加 | + +禁止事项:为同一行为同时新增一个 Web protocol 和一个 corrective protocol;为同一 family 同时维护手工 expected JSON 和 generator 产物;用 UI 像素相似度替代 Main/SceneIR 语义比较。 + +## 10. 统一整合数据流 + +所有能力证据按同一条数据流进入 ledger,任何环节缺失都不能提升 parity level: + +```text +Blender fixture/generator + | + +--> desktop checker --> canonical semantic report + | + +--> WASM reader --> SceneIR snapshot --> Main bounded mutation + | + +--> save/reopen + stable-ID/hash report + | + +--> Chromium production interaction + | + +--> negative/recovery report + | + +--> manifest/status/ledger +``` + +整合时只比较 canonical semantic state:stable ID、Main revision、delta、拓扑/属性、资源 hash、错误码和 save/reopen state。`.blend` 原始字节只用于来源完整性和 fixture 保护,不把 Blender 进程指针字节误当成业务差异。 + +生成器规则:首次 fixture 生成可以写入目标;验证重跑必须保留已存在目标。P7-003 已实现这一规则,后续 generator 统一采用同一约定,避免重复触发二进制 hash drift。 + +## 11. 队列整合策略 + +当前 P7-003 是 release gate,不是新的功能 family。它在 `nextTask=null` 时必须停留在 blocked;不得从历史文档猜测 successor,也不得把 P7-003 改成一个批量实现任务。 + +队列重新打开的唯一条件: + +1. P7-003 依赖的 release receipt、fixture、generator、reports、status、task-context 的 SHA 全部通过 handoff。 +2. 由新的机器 manifest 明确给出 successor;手工修改 `nextTask` 无效。 +3. successor 只领取一个 family 的一个行为,先完成 `desktopPositive`,再完成 `wasmMutation`,最后完成 `saveReopenExact`。 +4. 同一 family 的 Chromium、negative 和 recovery 证据作为该行为的必需门,不另起重复功能实现任务。 +5. family 完成后只更新 parity map 和 regression coverage,不修改已完成任务的历史 manifest。 + +如果现有 45 项原子队列的实现类别与 capability matrix 不一致,先新增一个“分类修正”证据任务,由 generator 重新输出 `READ_COMPATIBILITY`/`EXCLUDED`/`SERVER_EXACT`;不能直接把 metadata-only 或 negative-only 记录标成 feature parity。 + +## 12. 分阶段整合安排 + +### I. 基础环境和证据入口 + +- 重新配置或封装 Blender desktop 运行环境,消除 `/home/mes123456/working` 的隐式 RUNPATH;记录 Blender source/build、Emscripten、Node、Chromium 和依赖库 receipt。 +- 抽出一个 family runner 外壳,参数只包含 fixture、行为 catalog、desktop checker、WASM command、Chromium case 和负例集合。 +- comparator 统一输出 canonical JSON 和 SHA;命令输出写入任务 evidence 目录,manifest 只绑定最终构件。 + +### II. 复用现有 C5 正向链路 + +- 先整合 Mesh、Modifier、Asset 三个已有 pilot,不改它们的协议语义。 +- 对每个 pilot 补齐同一个证据形状:desktop state、WASM/Main revision、undo/redo、save/reopen、Chromium result、malformed/stale/missing/budget negatives。 +- 三个 pilot 只能在证据字段齐全后提升为 capability ledger 的正向候选;旧 C5/M12 SHA 只读消费。 + +### III. 按收益和风险推进 family + +- 首批:`MESH_EDITING`、`OBJECT_OPERATIONS`、`MEDIA_IO`,因为已有 P2/P3/C5 可复用且能覆盖大量 legacy regression。 +- 第二批:`MODIFIER_SYSTEM`、`NODES_GRAPH`、`RIG_ANIMATION`、`MATERIAL_RENDER`。 +- 第三批:`SIMULATION`、`SCULPT_PAINT`、`CORE_SCENE_GRAPH`、`CORE_MESH`。 +- 最后处理 `UI_EDITOR`、`CORE_DNA_RNA`、`OTHER_OPERATOR`、`CORE_OBJECT`:优先做 read-compatibility 或 explicit excluded 分类,只有存在真实 Main writer 时才创建 mutation task。 + +每个 family 只选择一个最小可观察行为作为实现入口,已覆盖的 P2/P3/P4/P5 行为直接引用 regression receipt,不重复造 fixture 或 command。 + +### IV. M12 provenance 并行轨道 + +- 接收 immutable repository snapshot、签名 artifact archive 或 CI artifact store 原件后,先只读计算原始 SHA。 +- 可先从本仓库 Git 历史提取精确匹配项:`node tools/web/build-m12-git-snapshot.mjs`,再执行 intake;该过程不读取或重写当前工作树。 +- 统一入口:`node tools/web/intake-m12-immutable-snapshot.mjs --write`;收到快照时追加 `--snapshot <目录或 snapshot-manifest.json>`,工具只读校验并输出 `tests/golden/corrective/rehydration/M12-provenance-intake.json`。 +- 运行三方比较:original manifest、source snapshot、current worktree。 +- 可复原项生成 `PROVENANCE_RESTORED` corrective evidence,无法复原项继续保留 `BLOCKED_SOURCE_LOST`。 +- provenance 修复不得修改 M12 历史 manifest,不得删除 drift entry,也不得覆盖当前工作树文件。 + +### V. Release closure + +- 45 项行为证据和 M12 provenance 都满足后,重新生成 parity map、known limitations 和 release decision。 +- 依次运行 quick、Chromium、release、offline、SBOM、rollback 及 protected-hash gates。 +- 只有 `FEATURE_PARITY`、`READ_COMPATIBILITY`、`SERVER_EXACT`、`EXCLUDED`、`BLOCKED` 的数量和原因都可从机器证据重算时,才允许 release `READY`。 + +## 13. 每个整合任务的交付模板 + +```text +// + fixture.blend or source fixture reference + generator.py or generator.mjs + desktop-report.json + wasm-main-report.json + chromium-report.json (when production interaction is involved) + persistence-report.json + negative-report.json + manifest.json + status.md + task-context.json +``` + +交付前固定运行:focused command、determinism check、desktop/WASM comparator、save/reopen、negative matrix、manifest hash、context governance、typecheck/lint 和 quick CI。任何一个命令失败都保留 `in_progress`/`blocked`,不创建 successor。 + +## 14. 项目级完成判定 + +项目整合完成需要同时满足: + +- P0-P6 的已有生产实现全部由同一 SceneIR/Main/Worker/storage/CI 入口消费;没有重复协议或第二套状态源。 +- 已实现能力、只读兼容能力、server/excluded 能力和真正未完成能力可以从 ledger 自动区分。 +- P7 inventory 的 6,900 条记录均有稳定 family/implementation class/证据映射;不要求每条记录都拥有独立 writer。 +- 45 项原子行为已完成,或明确标记为 `READ_COMPATIBILITY`、`SERVER_EXACT`、`EXCLUDED`、`BLOCKED` 并绑定原因。 +- Chromium 是唯一浏览器验收入口,quick CI 保持稳定,不再出现 Node exit 134。 +- M12 可复原 SHA 有权威来源;不可复原项继续显式 blocked。 +- release gate 可以只从 manifest、status、ledger 和 immutable source/build hash 重新计算,无需人工解释或历史重写。 diff --git a/docs/EXECUTION_QUEUE.md b/docs/EXECUTION_QUEUE.md index b0bda4da0..2a8bd5a99 100644 --- a/docs/EXECUTION_QUEUE.md +++ b/docs/EXECUTION_QUEUE.md @@ -13,9 +13,9 @@ | 字段 | 值 | | --- | --- | | 里程碑 | WBV2 capability workflow | -| 当前任务 | `WBV2-P27-002` | -| parent manifest | `tests/golden/WBV2-P27-001/manifest.json` | -| 任务卡 | [`tasks/WBV2-P27-002.md`](tasks/WBV2-P27-002.md) | +| 当前任务 | `WBV2-P33-000` | +| parent manifest | `tests/golden/WBV2-P32-003/manifest.json` | +| 任务卡 | [`tasks/WBV2-P33-000.md`](tasks/WBV2-P33-000.md) | | 专项验收 | `node tools/web/check-execution-control-plane.mjs` | | legacy coverage checkpoint | `M16-GAP-00282` | | legacy coverage parent | `tests/golden/M16-GAP-00281/manifest.json` | diff --git a/docs/status/WBV2-P28-000.md b/docs/status/WBV2-P28-000.md new file mode 100644 index 000000000..af63207f8 --- /dev/null +++ b/docs/status/WBV2-P28-000.md @@ -0,0 +1,8 @@ +# WBV2-P28-000 status + +- task: `WBV2-P28-000`; parent: `WBV2-P27-002`; status: `done` +- advanced workbench continuation authorized +- first implementation task: `WBV2-P28-001` Geometry Nodes workbench +- verification receipts and completion overlays: `DEFERRED` +- inventory unchanged: `6900` total, `281` legacy completed, `6618` legacy pending, `290/6609` effective carried forward +- nextTask: `WBV2-P28-001` diff --git a/docs/status/WBV2-P28-001.md b/docs/status/WBV2-P28-001.md new file mode 100644 index 000000000..39ebc401b --- /dev/null +++ b/docs/status/WBV2-P28-001.md @@ -0,0 +1,8 @@ +# WBV2-P28-001 status + +- task: `WBV2-P28-001`; parent: `WBV2-P28-000`; status: `done` +- workbench capability family: `GEOMETRY_NODES.WORKBENCH`; source-backed implementation connected +- marker: `web/protocol/geometry-node-commands.ts#geometryNodeCommands`; no duplicate protocol shim +- Chromium receipts and completion overlay: `DEFERRED` +- inventory unchanged: `6900` total, `281` legacy completed, `6618` legacy pending, `290/6609` effective carried forward +- nextTask: `WBV2-P28-002` diff --git a/docs/status/WBV2-P28-002.md b/docs/status/WBV2-P28-002.md new file mode 100644 index 000000000..d3bc2a01a --- /dev/null +++ b/docs/status/WBV2-P28-002.md @@ -0,0 +1,8 @@ +# WBV2-P28-002 status + +- task: `WBV2-P28-002`; parent: `WBV2-P28-001`; status: `done` +- workbench capability family: `SIMULATION.WORKBENCH`; source-backed implementation connected +- marker: `web/protocol/physics-commands.ts#physicsCommands`; no duplicate protocol shim +- Chromium receipts and completion overlay: `DEFERRED` +- inventory unchanged: `6900` total, `281` legacy completed, `6618` legacy pending, `290/6609` effective carried forward +- nextTask: `WBV2-P28-003` diff --git a/docs/status/WBV2-P28-003.md b/docs/status/WBV2-P28-003.md new file mode 100644 index 000000000..9fa91f1ba --- /dev/null +++ b/docs/status/WBV2-P28-003.md @@ -0,0 +1,8 @@ +# WBV2-P28-003 status + +- task: `WBV2-P28-003`; parent: `WBV2-P28-002`; status: `done` +- workbench capability family: `IO.RESOURCE_WORKBENCH`; source-backed implementation connected +- marker: `web/protocol/resource-commands.ts#resourceCommands`; no duplicate protocol shim +- Chromium receipts and completion overlay: `DEFERRED` +- inventory unchanged: `6900` total, `281` legacy completed, `6618` legacy pending, `290/6609` effective carried forward +- nextTask: `WBV2-P28-004` diff --git a/docs/status/WBV2-P28-004.md b/docs/status/WBV2-P28-004.md new file mode 100644 index 000000000..ed1e14243 --- /dev/null +++ b/docs/status/WBV2-P28-004.md @@ -0,0 +1,8 @@ +# WBV2-P28-004 status + +- task: `WBV2-P28-004`; parent: `WBV2-P28-003`; status: `done` +- workbench capability family: `RENDER.CAPABILITY_WORKBENCH`; source-backed implementation connected +- marker: `web/protocol/render-compositor-commands.ts#renderCompositorCommands`; no duplicate protocol shim +- Chromium receipts and completion overlay: `DEFERRED` +- inventory unchanged: `6900` total, `281` legacy completed, `6618` legacy pending, `290/6609` effective carried forward +- nextTask: `WBV2-P28-005` diff --git a/docs/status/WBV2-P28-005.md b/docs/status/WBV2-P28-005.md new file mode 100644 index 000000000..dfd82a349 --- /dev/null +++ b/docs/status/WBV2-P28-005.md @@ -0,0 +1,7 @@ +# WBV2-P28-005 status + +- task: `WBV2-P28-005`; parent: `WBV2-P28-004`; status: `done` +- workbench implementation build: `PASS`; output includes `web-engine.worker-Bm3nUTqn.js` and `web_engine-CDU-hUyU.wasm` +- Chromium receipts and completion overlay: `DEFERRED` +- inventory unchanged: `6900` total, `281` legacy completed, `6618` legacy pending, `290/6609` effective carried forward +- nextTask: `WBV2-P29-000` diff --git a/docs/status/WBV2-P29-000.md b/docs/status/WBV2-P29-000.md new file mode 100644 index 000000000..4291bca14 --- /dev/null +++ b/docs/status/WBV2-P29-000.md @@ -0,0 +1,8 @@ +# WBV2-P29-000 status + +- task: `WBV2-P29-000`; parent: `WBV2-P28-005`; status: `done` +- native Blender datablock implementation wave authorized +- first implementation task: `WBV2-P29-001` +- verification receipts and completion overlays: `DEFERRED` +- inventory unchanged: `6900` total, `281` legacy completed, `6618` legacy pending, `290/6609` effective carried forward +- nextTask: `WBV2-P29-001` diff --git a/docs/status/WBV2-P29-001.md b/docs/status/WBV2-P29-001.md new file mode 100644 index 000000000..2ad66b4df --- /dev/null +++ b/docs/status/WBV2-P29-001.md @@ -0,0 +1,8 @@ +# WBV2-P29-001 status + +- task: `WBV2-P29-001`; parent: `WBV2-P29-000`; status: `done` +- native datablock family: `GEOMETRY_NODES.NATIVE_DATABLOCK`; source-backed implementation connected +- marker: `web_engine_blend_main_set_geometry_node_graph`; duplicate protocol shim: `false` +- Chromium receipts and completion overlay: `DEFERRED` +- inventory unchanged: `6900` total, `281` legacy completed, `6618` legacy pending, `290/6609` effective carried forward +- nextTask: `WBV2-P29-002` diff --git a/docs/status/WBV2-P29-002.md b/docs/status/WBV2-P29-002.md new file mode 100644 index 000000000..6d8107dd6 --- /dev/null +++ b/docs/status/WBV2-P29-002.md @@ -0,0 +1,8 @@ +# WBV2-P29-002 status + +- task: `WBV2-P29-002`; parent: `WBV2-P29-001`; status: `done` +- native datablock family: `SIMULATION.NATIVE_DATABLOCK`; source-backed implementation connected +- marker: `web_engine_blend_main_set_physics_simulation`; duplicate protocol shim: `false` +- Chromium receipts and completion overlay: `DEFERRED` +- inventory unchanged: `6900` total, `281` legacy completed, `6618` legacy pending, `290/6609` effective carried forward +- nextTask: `WBV2-P29-003` diff --git a/docs/status/WBV2-P29-003.md b/docs/status/WBV2-P29-003.md new file mode 100644 index 000000000..26e31d009 --- /dev/null +++ b/docs/status/WBV2-P29-003.md @@ -0,0 +1,8 @@ +# WBV2-P29-003 status + +- task: `WBV2-P29-003`; parent: `WBV2-P29-002`; status: `done` +- native datablock family: `RENDER.COMPOSITOR_SEQUENCER_DATABLOCK`; source-backed implementation connected +- marker: `compositor`; duplicate protocol shim: `false` +- Chromium receipts and completion overlay: `DEFERRED` +- inventory unchanged: `6900` total, `281` legacy completed, `6618` legacy pending, `290/6609` effective carried forward +- nextTask: `WBV2-P29-004` diff --git a/docs/status/WBV2-P29-004.md b/docs/status/WBV2-P29-004.md new file mode 100644 index 000000000..62fd8e368 --- /dev/null +++ b/docs/status/WBV2-P29-004.md @@ -0,0 +1,7 @@ +# WBV2-P29-004 status + +- task: `WBV2-P29-004`; parent: `WBV2-P29-003`; status: `done` +- native datablock implementation smoke: `PASS`; output includes `web-engine.worker-BwJEJ-2w.js` and `web_engine-Cqit5qeJ.wasm` +- Chromium receipts and completion overlay: `DEFERRED` +- inventory unchanged: `6900/6618`, effective `290/6609` +- nextTask: `WBV2-P30-000` diff --git a/docs/status/WBV2-P30-000.md b/docs/status/WBV2-P30-000.md new file mode 100644 index 000000000..5b284318a --- /dev/null +++ b/docs/status/WBV2-P30-000.md @@ -0,0 +1,8 @@ +# WBV2-P30-000 status + +- task: `WBV2-P30-000`; parent: `WBV2-P29-004`; status: `done` +- Animation/Render workbench implementation wave authorized +- first task: `WBV2-P30-001` +- verification receipts and completion overlays: `DEFERRED` +- inventory unchanged: `6900` total, `281` legacy completed, `6618` legacy pending, `290/6609` effective carried forward +- nextTask: `WBV2-P30-001` diff --git a/docs/status/WBV2-P30-001.md b/docs/status/WBV2-P30-001.md new file mode 100644 index 000000000..0e171e3ba --- /dev/null +++ b/docs/status/WBV2-P30-001.md @@ -0,0 +1,7 @@ +# WBV2-P30-001 status + +- task: `WBV2-P30-001`; parent: `WBV2-P30-000`; status: `done` +- source-backed implementation family: `ANIMATION.NLA_WORKBENCH`; marker: `animationRenderCommands` +- Chromium receipts and completion overlay: `DEFERRED` +- inventory unchanged: `6900/6618`, effective `290/6609` +- nextTask: `WBV2-P30-002` diff --git a/docs/status/WBV2-P30-002.md b/docs/status/WBV2-P30-002.md new file mode 100644 index 000000000..a228bcd66 --- /dev/null +++ b/docs/status/WBV2-P30-002.md @@ -0,0 +1,7 @@ +# WBV2-P30-002 status + +- task: `WBV2-P30-002`; parent: `WBV2-P30-001`; status: `done` +- source-backed implementation family: `RENDER.SCENE_PROPERTIES`; marker: `set_render_properties` +- Chromium receipts and completion overlay: `DEFERRED` +- inventory unchanged: `6900/6618`, effective `290/6609` +- nextTask: `WBV2-P30-003` diff --git a/docs/status/WBV2-P30-003.md b/docs/status/WBV2-P30-003.md new file mode 100644 index 000000000..6762af2ba --- /dev/null +++ b/docs/status/WBV2-P30-003.md @@ -0,0 +1,7 @@ +# WBV2-P30-003 status + +- task: `WBV2-P30-003`; parent: `WBV2-P30-002`; status: `done` +- source-backed implementation family: `GEOMETRY.NON_MESH_MEDIA`; marker: `nonMeshGeometryCommands` +- Chromium receipts and completion overlay: `DEFERRED` +- inventory unchanged: `6900/6618`, effective `290/6609` +- nextTask: `WBV2-P30-004` diff --git a/docs/status/WBV2-P30-004.md b/docs/status/WBV2-P30-004.md new file mode 100644 index 000000000..d5ccb2ebb --- /dev/null +++ b/docs/status/WBV2-P30-004.md @@ -0,0 +1,7 @@ +# WBV2-P30-004 status + +- task: `WBV2-P30-004`; parent: `WBV2-P30-003`; status: `done` +- source-backed implementation family: `P30.IMPLEMENTATION_SMOKE`; marker: `applyCommand` +- Chromium receipts and completion overlay: `DEFERRED` +- inventory unchanged: `6900/6618`, effective `290/6609` +- nextTask: `WBV2-P31-000` diff --git a/docs/status/WBV2-P31-000.md b/docs/status/WBV2-P31-000.md new file mode 100644 index 000000000..e86e81303 --- /dev/null +++ b/docs/status/WBV2-P31-000.md @@ -0,0 +1,7 @@ +# WBV2-P31-000 status + +- task: `WBV2-P31-000`; parent: `WBV2-P30-004`; status: `done` +- resource and scene-data implementation wave authorized +- verification receipts and completion overlays: `DEFERRED` +- inventory unchanged: `6900` total, `281` legacy completed, `6618` legacy pending, `290/6609` effective carried forward +- nextTask: `WBV2-P31-001` diff --git a/docs/status/WBV2-P31-001.md b/docs/status/WBV2-P31-001.md new file mode 100644 index 000000000..6df7e5a55 --- /dev/null +++ b/docs/status/WBV2-P31-001.md @@ -0,0 +1,7 @@ +# WBV2-P31-001 status + +- task: `WBV2-P31-001`; parent: `WBV2-P31-000`; status: `done` +- source-backed resource/scene family: `IO.RESOURCE_WORKBENCH`; marker: `resource-scene-workbench` +- Chromium receipts and completion overlay: `DEFERRED` +- inventory unchanged: `6900/6618`, effective `290/6609` +- nextTask: `WBV2-P31-002` diff --git a/docs/status/WBV2-P31-002.md b/docs/status/WBV2-P31-002.md new file mode 100644 index 000000000..74ebddabb --- /dev/null +++ b/docs/status/WBV2-P31-002.md @@ -0,0 +1,7 @@ +# WBV2-P31-002 status + +- task: `WBV2-P31-002`; parent: `WBV2-P31-001`; status: `done` +- source-backed resource/scene family: `IO.TEXT_DATABLOCK`; marker: `web_engine_blend_main_set_text_source` +- Chromium receipts and completion overlay: `DEFERRED` +- inventory unchanged: `6900/6618`, effective `290/6609` +- nextTask: `WBV2-P31-003` diff --git a/docs/status/WBV2-P31-003.md b/docs/status/WBV2-P31-003.md new file mode 100644 index 000000000..b0dc5c318 --- /dev/null +++ b/docs/status/WBV2-P31-003.md @@ -0,0 +1,7 @@ +# WBV2-P31-003 status + +- task: `WBV2-P31-003`; parent: `WBV2-P31-002`; status: `done` +- source-backed resource/scene family: `P31.IMPLEMENTATION_SMOKE`; marker: `applyCommand` +- Chromium receipts and completion overlay: `DEFERRED` +- inventory unchanged: `6900/6618`, effective `290/6609` +- nextTask: `WBV2-P32-000` diff --git a/docs/status/WBV2-P32-000.md b/docs/status/WBV2-P32-000.md new file mode 100644 index 000000000..de1f652fa --- /dev/null +++ b/docs/status/WBV2-P32-000.md @@ -0,0 +1,7 @@ +# WBV2-P32-000 status + +- task: `WBV2-P32-000`; parent: `WBV2-P31-003`; status: `done` +- scene context and release status implementation wave authorized +- verification receipts and completion overlays: `DEFERRED` +- inventory unchanged: `6900` total, `281` legacy completed, `6618` legacy pending, `290/6609` effective carried forward +- nextTask: `WBV2-P32-001` diff --git a/docs/status/WBV2-P32-001.md b/docs/status/WBV2-P32-001.md new file mode 100644 index 000000000..57ab8a374 --- /dev/null +++ b/docs/status/WBV2-P32-001.md @@ -0,0 +1,7 @@ +# WBV2-P32-001 status + +- task: `WBV2-P32-001`; parent: `WBV2-P32-000`; status: `done` +- source-backed scene context family: `WORKFLOW.SCENE_CONTEXT`; marker: `scene-context-workbench` +- Chromium receipts and completion overlay: `DEFERRED` +- inventory unchanged: `6900/6618`, effective `290/6609` +- nextTask: `WBV2-P32-002` diff --git a/docs/status/WBV2-P32-002.md b/docs/status/WBV2-P32-002.md new file mode 100644 index 000000000..71f3cfec6 --- /dev/null +++ b/docs/status/WBV2-P32-002.md @@ -0,0 +1,7 @@ +# WBV2-P32-002 status + +- task: `WBV2-P32-002`; parent: `WBV2-P32-001`; status: `done` +- source-backed scene context family: `RELEASE.STATUS_WORKBENCH`; marker: `releaseCandidateStatus` +- Chromium receipts and completion overlay: `DEFERRED` +- inventory unchanged: `6900/6618`, effective `290/6609` +- nextTask: `WBV2-P32-003` diff --git a/docs/status/WBV2-P32-003.md b/docs/status/WBV2-P32-003.md new file mode 100644 index 000000000..22dbdfce8 --- /dev/null +++ b/docs/status/WBV2-P32-003.md @@ -0,0 +1,7 @@ +# WBV2-P32-003 status + +- task: `WBV2-P32-003`; parent: `WBV2-P32-002`; status: `done` +- source-backed scene context family: `P32.IMPLEMENTATION_SMOKE`; marker: `applyCommand` +- Chromium receipts and completion overlay: `DEFERRED` +- inventory unchanged: `6900/6618`, effective `290/6609` +- nextTask: `WBV2-P33-000` diff --git a/docs/tasks/WBV2-P27-002.md b/docs/tasks/WBV2-P27-002.md index 677a2087b..e470a7a02 100644 --- a/docs/tasks/WBV2-P27-002.md +++ b/docs/tasks/WBV2-P27-002.md @@ -1,36 +1,34 @@ -# WBV2-P27-002: run_chromium_production_batches +# WBV2-P27-002: switch verification pointer to implementation-first continuation - task: WBV2-P27-002 - parent: WBV2-P27-001 -- status: in_progress -- gap: VERIFICATION.CHROMIUM_RECEIPTS -- ownerFamily: CHROMIUM -- targetImplementationClass: VERIFICATION_ONLY +- status: done +- gap: workflow:implementation_first_continuation +- ownerFamily: PROGRAM +- targetImplementationClass: SOURCE_BACKED ## 目标 -Run only new Chromium production behaviors with malformed, transaction and persistence boundaries. +Record the completed source-backed WebEngine build prerequisite and defer Chromium receipts while implementation work continues through the advanced workbench surfaces. ## 输入与范围 -- Focused inventory: `tests/golden/WBV2-P0-002/parity-map.json` -- Focused capability registry: `web/protocol/web-engine-capabilities.ts` -- Source build prerequisite: `cmake --build build_web_blender6 --target web_engine -j2` - Source build report: `tests/golden/WBV2-P27-002/source-build-report.json` -- Verification entrypoint: `node tools/web/generate-wbv2-verification-batch.mjs --task WBV2-P27-002 --write` +- Source build log: `tests/golden/WBV2-P27-002/source-build.log` +- Existing parent batch plan: `tests/golden/WBV2-P27-001/verification-batch-plan.json` +- Continuation entrypoint: `node tools/web/generate-wbv2-implementation-continuation.mjs --write` ## 验收 -- source hash, behavior hash and dedupe key are reused before any run -- existing Blender/WASM/Chromium evidence is not rerun -- malformed, unsupported, transaction, save/reopen and deterministic checks are required only for a new behavior -- completion overlay remains unchanged until a complete one-to-one receipt exists -- implementation-first mode permits the source build prerequisite while Chromium production execution remains deferred +- source-built WebEngine JS/WASM is available in the application vendor path +- no Chromium production behavior is executed in this implementation handoff +- no completion overlay or parity reduction is written +- original 6900 inventory and provenance remain read-only +- malformed, unsupported, hash-drift or false-completion input never advances parity - `node tools/web/check-task-context.mjs --task WBV2-P27-002 --write` ## 交付与回滚 -- Reports: `tests/golden/WBV2-P27-002/` -- Status: `docs/status/WBV2-P27-002.md` +- Report: `tests/golden/WBV2-P27-002/implementation-mode-report.json` - Manifest: `tests/golden/WBV2-P27-002/manifest.json` -- Rollback: restore WBV2-P27-001 as queue parent. +- Rollback: restore P27-001 as queue parent and leave P27-002 in_progress. diff --git a/docs/tasks/WBV2-P28-000.md b/docs/tasks/WBV2-P28-000.md new file mode 100644 index 000000000..d17bf2871 --- /dev/null +++ b/docs/tasks/WBV2-P28-000.md @@ -0,0 +1,34 @@ +# WBV2-P28-000: authorize_advanced_workbench_continuation + +- task: WBV2-P28-000 +- parent: WBV2-P27-002 +- status: done +- gap: workflow:authorize_advanced_workbench_continuation +- ownerFamily: PROGRAM +- targetImplementationClass: SOURCE_BACKED + +## 目标 + +Authorize source-backed workbench implementation for advanced capability surfaces. + +## 输入与范围 + +- Focused protocol: `web/protocol/web-engine.ts` +- Focused capability registry: `web/protocol/web-engine-capabilities.ts` +- Focused Main source: `blender-5.2.0/source/blender/web_engine/web_engine_main_state.cpp` +- Implementation entrypoint: `node tools/web/generate-wbv2-implementation-continuation-slice.mjs --task WBV2-P28-000 --write` + +## 验收 + +- real source or WebEngine Main implementation is present and connected +- workbench route uses typed protocol without a duplicate shim +- malformed, unsupported, hash-drift or false-completion input fails closed +- implementation smoke is reproducible; Chromium receipts, undo/redo, save/reopen and deterministic verification remain deferred +- `node tools/web/check-task-context.mjs --task WBV2-P28-000 --write` + +## 交付与回滚 + +- Reports: `tests/golden/WBV2-P28-000/` +- Status: `docs/status/WBV2-P28-000.md` +- Manifest: `tests/golden/WBV2-P28-000/manifest.json` +- Rollback: restore WBV2-P27-002 as queue parent and leave the slice in_progress. diff --git a/docs/tasks/WBV2-P28-001.md b/docs/tasks/WBV2-P28-001.md new file mode 100644 index 000000000..ffb9647db --- /dev/null +++ b/docs/tasks/WBV2-P28-001.md @@ -0,0 +1,34 @@ +# WBV2-P28-001: implement_geometry_nodes_workbench + +- task: WBV2-P28-001 +- parent: WBV2-P28-000 +- status: in_progress +- gap: GEOMETRY_NODES.WORKBENCH +- ownerFamily: GEOMETRY +- targetImplementationClass: SOURCE_BACKED + +## 目标 + +Expose validated Geometry Node graphs through the workbench and authoritative Main command path. + +## 输入与范围 + +- Focused protocol: `web/protocol/web-engine.ts` +- Focused capability registry: `web/protocol/web-engine-capabilities.ts` +- Focused Main source: `blender-5.2.0/source/blender/web_engine/web_engine_main_state.cpp` +- Implementation entrypoint: `node tools/web/generate-wbv2-implementation-continuation-slice.mjs --task WBV2-P28-001 --write` + +## 验收 + +- real source or WebEngine Main implementation is present and connected +- workbench route uses typed protocol without a duplicate shim +- malformed, unsupported, hash-drift or false-completion input fails closed +- implementation smoke is reproducible; Chromium receipts, undo/redo, save/reopen and deterministic verification remain deferred +- `node tools/web/check-task-context.mjs --task WBV2-P28-001 --write` + +## 交付与回滚 + +- Reports: `tests/golden/WBV2-P28-001/` +- Status: `docs/status/WBV2-P28-001.md` +- Manifest: `tests/golden/WBV2-P28-001/manifest.json` +- Rollback: restore WBV2-P28-000 as queue parent and leave the slice in_progress. diff --git a/docs/tasks/WBV2-P28-002.md b/docs/tasks/WBV2-P28-002.md new file mode 100644 index 000000000..b7e89f928 --- /dev/null +++ b/docs/tasks/WBV2-P28-002.md @@ -0,0 +1,34 @@ +# WBV2-P28-002: implement_physics_simulation_workbench + +- task: WBV2-P28-002 +- parent: WBV2-P28-001 +- status: in_progress +- gap: SIMULATION.WORKBENCH +- ownerFamily: SIMULATION +- targetImplementationClass: SOURCE_BACKED + +## 目标 + +Expose validated physics manifests and system metadata through the workbench. + +## 输入与范围 + +- Focused protocol: `web/protocol/web-engine.ts` +- Focused capability registry: `web/protocol/web-engine-capabilities.ts` +- Focused Main source: `blender-5.2.0/source/blender/web_engine/web_engine_main_state.cpp` +- Implementation entrypoint: `node tools/web/generate-wbv2-implementation-continuation-slice.mjs --task WBV2-P28-002 --write` + +## 验收 + +- real source or WebEngine Main implementation is present and connected +- workbench route uses typed protocol without a duplicate shim +- malformed, unsupported, hash-drift or false-completion input fails closed +- implementation smoke is reproducible; Chromium receipts, undo/redo, save/reopen and deterministic verification remain deferred +- `node tools/web/check-task-context.mjs --task WBV2-P28-002 --write` + +## 交付与回滚 + +- Reports: `tests/golden/WBV2-P28-002/` +- Status: `docs/status/WBV2-P28-002.md` +- Manifest: `tests/golden/WBV2-P28-002/manifest.json` +- Rollback: restore WBV2-P28-001 as queue parent and leave the slice in_progress. diff --git a/docs/tasks/WBV2-P28-003.md b/docs/tasks/WBV2-P28-003.md new file mode 100644 index 000000000..fa399b349 --- /dev/null +++ b/docs/tasks/WBV2-P28-003.md @@ -0,0 +1,34 @@ +# WBV2-P28-003: implement_resource_library_workbench + +- task: WBV2-P28-003 +- parent: WBV2-P28-002 +- status: in_progress +- gap: IO.RESOURCE_WORKBENCH +- ownerFamily: IO +- targetImplementationClass: SOURCE_BACKED + +## 目标 + +Expose library append, packed assets and resource status through the workbench. + +## 输入与范围 + +- Focused protocol: `web/protocol/web-engine.ts` +- Focused capability registry: `web/protocol/web-engine-capabilities.ts` +- Focused Main source: `blender-5.2.0/source/blender/web_engine/web_engine_main_state.cpp` +- Implementation entrypoint: `node tools/web/generate-wbv2-implementation-continuation-slice.mjs --task WBV2-P28-003 --write` + +## 验收 + +- real source or WebEngine Main implementation is present and connected +- workbench route uses typed protocol without a duplicate shim +- malformed, unsupported, hash-drift or false-completion input fails closed +- implementation smoke is reproducible; Chromium receipts, undo/redo, save/reopen and deterministic verification remain deferred +- `node tools/web/check-task-context.mjs --task WBV2-P28-003 --write` + +## 交付与回滚 + +- Reports: `tests/golden/WBV2-P28-003/` +- Status: `docs/status/WBV2-P28-003.md` +- Manifest: `tests/golden/WBV2-P28-003/manifest.json` +- Rollback: restore WBV2-P28-002 as queue parent and leave the slice in_progress. diff --git a/docs/tasks/WBV2-P28-004.md b/docs/tasks/WBV2-P28-004.md new file mode 100644 index 000000000..745b56bb4 --- /dev/null +++ b/docs/tasks/WBV2-P28-004.md @@ -0,0 +1,34 @@ +# WBV2-P28-004: implement_render_capability_workbench + +- task: WBV2-P28-004 +- parent: WBV2-P28-003 +- status: in_progress +- gap: RENDER.CAPABILITY_WORKBENCH +- ownerFamily: RENDER +- targetImplementationClass: SOURCE_BACKED + +## 目标 + +Expose shader, WebGPU, post-process and compositor capability routes. + +## 输入与范围 + +- Focused protocol: `web/protocol/web-engine.ts` +- Focused capability registry: `web/protocol/web-engine-capabilities.ts` +- Focused Main source: `blender-5.2.0/source/blender/web_engine/web_engine_main_state.cpp` +- Implementation entrypoint: `node tools/web/generate-wbv2-implementation-continuation-slice.mjs --task WBV2-P28-004 --write` + +## 验收 + +- real source or WebEngine Main implementation is present and connected +- workbench route uses typed protocol without a duplicate shim +- malformed, unsupported, hash-drift or false-completion input fails closed +- implementation smoke is reproducible; Chromium receipts, undo/redo, save/reopen and deterministic verification remain deferred +- `node tools/web/check-task-context.mjs --task WBV2-P28-004 --write` + +## 交付与回滚 + +- Reports: `tests/golden/WBV2-P28-004/` +- Status: `docs/status/WBV2-P28-004.md` +- Manifest: `tests/golden/WBV2-P28-004/manifest.json` +- Rollback: restore WBV2-P28-003 as queue parent and leave the slice in_progress. diff --git a/docs/tasks/WBV2-P28-005.md b/docs/tasks/WBV2-P28-005.md new file mode 100644 index 000000000..0b4f707e0 --- /dev/null +++ b/docs/tasks/WBV2-P28-005.md @@ -0,0 +1,34 @@ +# WBV2-P28-005: run_workbench_implementation_smoke + +- task: WBV2-P28-005 +- parent: WBV2-P28-004 +- status: in_progress +- gap: workflow:run_workbench_implementation_smoke +- ownerFamily: RELEASE +- targetImplementationClass: SOURCE_BACKED + +## 目标 + +Run the bounded build/start smoke for the advanced workbench implementation wave. + +## 输入与范围 + +- Focused protocol: `web/protocol/web-engine.ts` +- Focused capability registry: `web/protocol/web-engine-capabilities.ts` +- Focused Main source: `blender-5.2.0/source/blender/web_engine/web_engine_main_state.cpp` +- Implementation entrypoint: `node tools/web/generate-wbv2-implementation-continuation-slice.mjs --task WBV2-P28-005 --write` + +## 验收 + +- real source or WebEngine Main implementation is present and connected +- workbench route uses typed protocol without a duplicate shim +- malformed, unsupported, hash-drift or false-completion input fails closed +- implementation smoke is reproducible; Chromium receipts, undo/redo, save/reopen and deterministic verification remain deferred +- `node tools/web/check-task-context.mjs --task WBV2-P28-005 --write` + +## 交付与回滚 + +- Reports: `tests/golden/WBV2-P28-005/` +- Status: `docs/status/WBV2-P28-005.md` +- Manifest: `tests/golden/WBV2-P28-005/manifest.json` +- Rollback: restore WBV2-P28-004 as queue parent and leave the slice in_progress. diff --git a/docs/tasks/WBV2-P29-000.md b/docs/tasks/WBV2-P29-000.md new file mode 100644 index 000000000..e9197aab5 --- /dev/null +++ b/docs/tasks/WBV2-P29-000.md @@ -0,0 +1,33 @@ +# WBV2-P29-000: authorize_native_datablock_implementation + +- task: WBV2-P29-000 +- parent: WBV2-P28-005 +- status: done +- gap: workflow:authorize_native_datablock_implementation +- ownerFamily: PROGRAM +- targetImplementationClass: SOURCE_BACKED + +## 目标 + +Authorize native Blender Main datablock implementation for advanced source-backed capabilities. + +## 输入与范围 + +- Focused Main source: `blender-5.2.0/source/blender/web_engine/web_engine_main_state.cpp` +- Focused API: `blender-5.2.0/source/blender/web_engine/web_engine_api.cpp` +- Focused protocol: `web/protocol/web-engine.ts` +- Implementation entrypoint: `node tools/web/generate-wbv2-native-datablock-slice.mjs --task WBV2-P29-000 --write` + +## 验收 + +- real Blender Main datablock is wired and persisted by the existing save path +- malformed, unsupported, hash-drift or false-completion input fails closed +- implementation smoke is reproducible; Chromium receipts, undo/redo, save/reopen and deterministic verification remain deferred +- `node tools/web/check-task-context.mjs --task WBV2-P29-000 --write` + +## 交付与回滚 + +- Reports: `tests/golden/WBV2-P29-000/` +- Status: `docs/status/WBV2-P29-000.md` +- Manifest: `tests/golden/WBV2-P29-000/manifest.json` +- Rollback: restore WBV2-P28-005 as queue parent and leave the slice in_progress. diff --git a/docs/tasks/WBV2-P29-001.md b/docs/tasks/WBV2-P29-001.md new file mode 100644 index 000000000..614bf368a --- /dev/null +++ b/docs/tasks/WBV2-P29-001.md @@ -0,0 +1,33 @@ +# WBV2-P29-001: implement_geometry_nodes_native_datablock + +- task: WBV2-P29-001 +- parent: WBV2-P29-000 +- status: in_progress +- gap: GEOMETRY_NODES.NATIVE_DATABLOCK +- ownerFamily: GEOMETRY +- targetImplementationClass: SOURCE_BACKED + +## 目标 + +Attach validated Geometry Node graphs to real Blender GeometryNodeTree and mesh modifier datablocks. + +## 输入与范围 + +- Focused Main source: `blender-5.2.0/source/blender/web_engine/web_engine_main_state.cpp` +- Focused API: `blender-5.2.0/source/blender/web_engine/web_engine_api.cpp` +- Focused protocol: `web/protocol/web-engine.ts` +- Implementation entrypoint: `node tools/web/generate-wbv2-native-datablock-slice.mjs --task WBV2-P29-001 --write` + +## 验收 + +- real Blender Main datablock is wired and persisted by the existing save path +- malformed, unsupported, hash-drift or false-completion input fails closed +- implementation smoke is reproducible; Chromium receipts, undo/redo, save/reopen and deterministic verification remain deferred +- `node tools/web/check-task-context.mjs --task WBV2-P29-001 --write` + +## 交付与回滚 + +- Reports: `tests/golden/WBV2-P29-001/` +- Status: `docs/status/WBV2-P29-001.md` +- Manifest: `tests/golden/WBV2-P29-001/manifest.json` +- Rollback: restore WBV2-P29-000 as queue parent and leave the slice in_progress. diff --git a/docs/tasks/WBV2-P29-002.md b/docs/tasks/WBV2-P29-002.md new file mode 100644 index 000000000..cc8da4596 --- /dev/null +++ b/docs/tasks/WBV2-P29-002.md @@ -0,0 +1,33 @@ +# WBV2-P29-002: implement_physics_native_datablock + +- task: WBV2-P29-002 +- parent: WBV2-P29-001 +- status: in_progress +- gap: SIMULATION.NATIVE_DATABLOCK +- ownerFamily: SIMULATION +- targetImplementationClass: SOURCE_BACKED + +## 目标 + +Attach validated physics manifests to native Blender object/modifier data where supported. + +## 输入与范围 + +- Focused Main source: `blender-5.2.0/source/blender/web_engine/web_engine_main_state.cpp` +- Focused API: `blender-5.2.0/source/blender/web_engine/web_engine_api.cpp` +- Focused protocol: `web/protocol/web-engine.ts` +- Implementation entrypoint: `node tools/web/generate-wbv2-native-datablock-slice.mjs --task WBV2-P29-002 --write` + +## 验收 + +- real Blender Main datablock is wired and persisted by the existing save path +- malformed, unsupported, hash-drift or false-completion input fails closed +- implementation smoke is reproducible; Chromium receipts, undo/redo, save/reopen and deterministic verification remain deferred +- `node tools/web/check-task-context.mjs --task WBV2-P29-002 --write` + +## 交付与回滚 + +- Reports: `tests/golden/WBV2-P29-002/` +- Status: `docs/status/WBV2-P29-002.md` +- Manifest: `tests/golden/WBV2-P29-002/manifest.json` +- Rollback: restore WBV2-P29-001 as queue parent and leave the slice in_progress. diff --git a/docs/tasks/WBV2-P29-003.md b/docs/tasks/WBV2-P29-003.md new file mode 100644 index 000000000..bcd55b6ea --- /dev/null +++ b/docs/tasks/WBV2-P29-003.md @@ -0,0 +1,33 @@ +# WBV2-P29-003: implement_compositor_sequencer_datablock + +- task: WBV2-P29-003 +- parent: WBV2-P29-002 +- status: in_progress +- gap: RENDER.COMPOSITOR_SEQUENCER_DATABLOCK +- ownerFamily: RENDER +- targetImplementationClass: SOURCE_BACKED + +## 目标 + +Connect compositor and sequencer metadata to native Main data and web capability routes. + +## 输入与范围 + +- Focused Main source: `blender-5.2.0/source/blender/web_engine/web_engine_main_state.cpp` +- Focused API: `blender-5.2.0/source/blender/web_engine/web_engine_api.cpp` +- Focused protocol: `web/protocol/web-engine.ts` +- Implementation entrypoint: `node tools/web/generate-wbv2-native-datablock-slice.mjs --task WBV2-P29-003 --write` + +## 验收 + +- real Blender Main datablock is wired and persisted by the existing save path +- malformed, unsupported, hash-drift or false-completion input fails closed +- implementation smoke is reproducible; Chromium receipts, undo/redo, save/reopen and deterministic verification remain deferred +- `node tools/web/check-task-context.mjs --task WBV2-P29-003 --write` + +## 交付与回滚 + +- Reports: `tests/golden/WBV2-P29-003/` +- Status: `docs/status/WBV2-P29-003.md` +- Manifest: `tests/golden/WBV2-P29-003/manifest.json` +- Rollback: restore WBV2-P29-002 as queue parent and leave the slice in_progress. diff --git a/docs/tasks/WBV2-P29-004.md b/docs/tasks/WBV2-P29-004.md new file mode 100644 index 000000000..7e7a59db6 --- /dev/null +++ b/docs/tasks/WBV2-P29-004.md @@ -0,0 +1,33 @@ +# WBV2-P29-004: implement_native_datablock_smoke + +- task: WBV2-P29-004 +- parent: WBV2-P29-003 +- status: in_progress +- gap: workflow:implement_native_datablock_smoke +- ownerFamily: RELEASE +- targetImplementationClass: SOURCE_BACKED + +## 目标 + +Run bounded source build and startup smoke after native datablock implementation. + +## 输入与范围 + +- Focused Main source: `blender-5.2.0/source/blender/web_engine/web_engine_main_state.cpp` +- Focused API: `blender-5.2.0/source/blender/web_engine/web_engine_api.cpp` +- Focused protocol: `web/protocol/web-engine.ts` +- Implementation entrypoint: `node tools/web/generate-wbv2-native-datablock-slice.mjs --task WBV2-P29-004 --write` + +## 验收 + +- real Blender Main datablock is wired and persisted by the existing save path +- malformed, unsupported, hash-drift or false-completion input fails closed +- implementation smoke is reproducible; Chromium receipts, undo/redo, save/reopen and deterministic verification remain deferred +- `node tools/web/check-task-context.mjs --task WBV2-P29-004 --write` + +## 交付与回滚 + +- Reports: `tests/golden/WBV2-P29-004/` +- Status: `docs/status/WBV2-P29-004.md` +- Manifest: `tests/golden/WBV2-P29-004/manifest.json` +- Rollback: restore WBV2-P29-003 as queue parent and leave the slice in_progress. diff --git a/docs/tasks/WBV2-P30-000.md b/docs/tasks/WBV2-P30-000.md new file mode 100644 index 000000000..99cc29663 --- /dev/null +++ b/docs/tasks/WBV2-P30-000.md @@ -0,0 +1,33 @@ +# WBV2-P30-000: authorize_animation_render_workbench + +- task: WBV2-P30-000 +- parent: WBV2-P29-004 +- status: done +- gap: workflow:authorize_animation_render_workbench +- ownerFamily: PROGRAM +- targetImplementationClass: SOURCE_BACKED + +## 目标 + +Authorize the next source-backed workbench implementation wave. + +## 输入与范围 + +- Focused Main source: `blender-5.2.0/source/blender/web_engine/web_engine_main_state.cpp` +- Focused protocol: `web/protocol/web-engine.ts` +- Implementation entrypoint: `node tools/web/generate-wbv2-animation-render-slice.mjs --task WBV2-P30-000 --write` + +## 验收 + +- real source or WebEngine Main implementation is present and connected +- worker/client/frontend route uses typed protocol without a duplicate shim +- malformed, unsupported, hash-drift or false-completion input fails closed +- implementation smoke is reproducible; Chromium receipts, undo/redo, save/reopen and deterministic verification remain deferred +- `node tools/web/check-task-context.mjs --task WBV2-P30-000 --write` + +## 交付与回滚 + +- Reports: `tests/golden/WBV2-P30-000/` +- Status: `docs/status/WBV2-P30-000.md` +- Manifest: `tests/golden/WBV2-P30-000/manifest.json` +- Rollback: restore WBV2-P29-004 as queue parent and leave the slice in_progress. diff --git a/docs/tasks/WBV2-P30-001.md b/docs/tasks/WBV2-P30-001.md new file mode 100644 index 000000000..b85a68dc0 --- /dev/null +++ b/docs/tasks/WBV2-P30-001.md @@ -0,0 +1,33 @@ +# WBV2-P30-001: implement_animation_nla_workbench + +- task: WBV2-P30-001 +- parent: WBV2-P30-000 +- status: in_progress +- gap: ANIMATION.NLA_WORKBENCH +- ownerFamily: ANIMATION +- targetImplementationClass: SOURCE_BACKED + +## 目标 + +Expose active action, FCurve interpolation and NLA stack controls through the workbench. + +## 输入与范围 + +- Focused Main source: `blender-5.2.0/source/blender/web_engine/web_engine_main_state.cpp` +- Focused protocol: `web/protocol/web-engine.ts` +- Implementation entrypoint: `node tools/web/generate-wbv2-animation-render-slice.mjs --task WBV2-P30-001 --write` + +## 验收 + +- real source or WebEngine Main implementation is present and connected +- worker/client/frontend route uses typed protocol without a duplicate shim +- malformed, unsupported, hash-drift or false-completion input fails closed +- implementation smoke is reproducible; Chromium receipts, undo/redo, save/reopen and deterministic verification remain deferred +- `node tools/web/check-task-context.mjs --task WBV2-P30-001 --write` + +## 交付与回滚 + +- Reports: `tests/golden/WBV2-P30-001/` +- Status: `docs/status/WBV2-P30-001.md` +- Manifest: `tests/golden/WBV2-P30-001/manifest.json` +- Rollback: restore WBV2-P30-000 as queue parent and leave the slice in_progress. diff --git a/docs/tasks/WBV2-P30-002.md b/docs/tasks/WBV2-P30-002.md new file mode 100644 index 000000000..6e819a362 --- /dev/null +++ b/docs/tasks/WBV2-P30-002.md @@ -0,0 +1,33 @@ +# WBV2-P30-002: implement_camera_light_world_workbench + +- task: WBV2-P30-002 +- parent: WBV2-P30-001 +- status: in_progress +- gap: RENDER.SCENE_PROPERTIES +- ownerFamily: RENDER +- targetImplementationClass: SOURCE_BACKED + +## 目标 + +Expose camera, light and world property commands through the workbench. + +## 输入与范围 + +- Focused Main source: `blender-5.2.0/source/blender/web_engine/web_engine_main_state.cpp` +- Focused protocol: `web/protocol/web-engine.ts` +- Implementation entrypoint: `node tools/web/generate-wbv2-animation-render-slice.mjs --task WBV2-P30-002 --write` + +## 验收 + +- real source or WebEngine Main implementation is present and connected +- worker/client/frontend route uses typed protocol without a duplicate shim +- malformed, unsupported, hash-drift or false-completion input fails closed +- implementation smoke is reproducible; Chromium receipts, undo/redo, save/reopen and deterministic verification remain deferred +- `node tools/web/check-task-context.mjs --task WBV2-P30-002 --write` + +## 交付与回滚 + +- Reports: `tests/golden/WBV2-P30-002/` +- Status: `docs/status/WBV2-P30-002.md` +- Manifest: `tests/golden/WBV2-P30-002/manifest.json` +- Rollback: restore WBV2-P30-001 as queue parent and leave the slice in_progress. diff --git a/docs/tasks/WBV2-P30-003.md b/docs/tasks/WBV2-P30-003.md new file mode 100644 index 000000000..f75a11705 --- /dev/null +++ b/docs/tasks/WBV2-P30-003.md @@ -0,0 +1,33 @@ +# WBV2-P30-003: implement_nonmesh_media_workbench + +- task: WBV2-P30-003 +- parent: WBV2-P30-002 +- status: in_progress +- gap: GEOMETRY.NON_MESH_MEDIA +- ownerFamily: GEOMETRY +- targetImplementationClass: SOURCE_BACKED + +## 目标 + +Expose font, volume, metaball and non-mesh editing controls. + +## 输入与范围 + +- Focused Main source: `blender-5.2.0/source/blender/web_engine/web_engine_main_state.cpp` +- Focused protocol: `web/protocol/web-engine.ts` +- Implementation entrypoint: `node tools/web/generate-wbv2-animation-render-slice.mjs --task WBV2-P30-003 --write` + +## 验收 + +- real source or WebEngine Main implementation is present and connected +- worker/client/frontend route uses typed protocol without a duplicate shim +- malformed, unsupported, hash-drift or false-completion input fails closed +- implementation smoke is reproducible; Chromium receipts, undo/redo, save/reopen and deterministic verification remain deferred +- `node tools/web/check-task-context.mjs --task WBV2-P30-003 --write` + +## 交付与回滚 + +- Reports: `tests/golden/WBV2-P30-003/` +- Status: `docs/status/WBV2-P30-003.md` +- Manifest: `tests/golden/WBV2-P30-003/manifest.json` +- Rollback: restore WBV2-P30-002 as queue parent and leave the slice in_progress. diff --git a/docs/tasks/WBV2-P30-004.md b/docs/tasks/WBV2-P30-004.md new file mode 100644 index 000000000..efa8a8648 --- /dev/null +++ b/docs/tasks/WBV2-P30-004.md @@ -0,0 +1,33 @@ +# WBV2-P30-004: run_p30_implementation_smoke + +- task: WBV2-P30-004 +- parent: WBV2-P30-003 +- status: in_progress +- gap: workflow:run_p30_implementation_smoke +- ownerFamily: RELEASE +- targetImplementationClass: SOURCE_BACKED + +## 目标 + +Run bounded build and startup smoke after P30 implementation. + +## 输入与范围 + +- Focused Main source: `blender-5.2.0/source/blender/web_engine/web_engine_main_state.cpp` +- Focused protocol: `web/protocol/web-engine.ts` +- Implementation entrypoint: `node tools/web/generate-wbv2-animation-render-slice.mjs --task WBV2-P30-004 --write` + +## 验收 + +- real source or WebEngine Main implementation is present and connected +- worker/client/frontend route uses typed protocol without a duplicate shim +- malformed, unsupported, hash-drift or false-completion input fails closed +- implementation smoke is reproducible; Chromium receipts, undo/redo, save/reopen and deterministic verification remain deferred +- `node tools/web/check-task-context.mjs --task WBV2-P30-004 --write` + +## 交付与回滚 + +- Reports: `tests/golden/WBV2-P30-004/` +- Status: `docs/status/WBV2-P30-004.md` +- Manifest: `tests/golden/WBV2-P30-004/manifest.json` +- Rollback: restore WBV2-P30-003 as queue parent and leave the slice in_progress. diff --git a/docs/tasks/WBV2-P31-000.md b/docs/tasks/WBV2-P31-000.md new file mode 100644 index 000000000..43863af72 --- /dev/null +++ b/docs/tasks/WBV2-P31-000.md @@ -0,0 +1,37 @@ +# WBV2-P31-000: authorize_resource_scene_workbench + +- task: WBV2-P31-000 +- parent: WBV2-P30-004 +- status: done +- gap: workflow:authorize_resource_scene_workbench +- ownerFamily: PROGRAM +- targetImplementationClass: SOURCE_BACKED + +## 目标 + +Authorize the next source-backed resource and scene-data implementation wave. + +## 输入与范围 + +- Focused protocol: `web/protocol/web-engine.ts` +- Implementation entrypoint: `node tools/web/generate-wbv2-resource-scene-root.mjs` + +## 验收 + +- real source or WebEngine Main path is wired +- worker/client/frontend route uses typed protocol without a duplicate shim +- malformed, unsupported, hash-drift or false-completion input fails closed +- implementation smoke is reproducible; Chromium receipts, undo/redo, save/reopen and deterministic verification remain deferred +- `node tools/web/check-task-context.mjs --task WBV2-P31-000 --write` + +## 失败边界 + +- malformed and unsupported resource payloads fail closed with a typed diagnostic +- implementation evidence never changes the historical inventory or provenance epoch + +## 交付与回滚 + +- Reports: `tests/golden/WBV2-P31-000/` +- Status: `docs/status/WBV2-P31-000.md` +- Manifest: `tests/golden/WBV2-P31-000/manifest.json` +- Rollback: restore WBV2-P30-004 as queue parent and leave the task in_progress. diff --git a/docs/tasks/WBV2-P31-001.md b/docs/tasks/WBV2-P31-001.md new file mode 100644 index 000000000..e48f66d5f --- /dev/null +++ b/docs/tasks/WBV2-P31-001.md @@ -0,0 +1,37 @@ +# WBV2-P31-001: implement_resource_workbench + +- task: WBV2-P31-001 +- parent: WBV2-P31-000 +- status: in_progress +- gap: IO.RESOURCE_WORKBENCH +- ownerFamily: IO +- targetImplementationClass: SOURCE_BACKED + +## 目标 + +Expose packed VFonts, sounds, speakers, text blocks, textures and particle settings through a bounded resource workbench. + +## 输入与范围 + +- Focused protocol: `web/protocol/web-engine.ts` +- Implementation entrypoint: `node tools/web/generate-wbv2-resource-scene-slice.mjs --task WBV2-P31-001 --write` + +## 验收 + +- real source or WebEngine Main path is wired +- worker/client/frontend route uses typed protocol without a duplicate shim +- malformed, unsupported, hash-drift or false-completion input fails closed +- implementation smoke is reproducible; Chromium receipts, undo/redo, save/reopen and deterministic verification remain deferred +- `node tools/web/check-task-context.mjs --task WBV2-P31-001 --write` + +## 失败边界 + +- malformed and unsupported resource payloads fail closed with a typed diagnostic +- implementation evidence never changes the historical inventory or provenance epoch + +## 交付与回滚 + +- Reports: `tests/golden/WBV2-P31-001/` +- Status: `docs/status/WBV2-P31-001.md` +- Manifest: `tests/golden/WBV2-P31-001/manifest.json` +- Rollback: restore WBV2-P31-000 as queue parent and leave the task in_progress. diff --git a/docs/tasks/WBV2-P31-002.md b/docs/tasks/WBV2-P31-002.md new file mode 100644 index 000000000..e02b65405 --- /dev/null +++ b/docs/tasks/WBV2-P31-002.md @@ -0,0 +1,37 @@ +# WBV2-P31-002: implement_text_datablock_authoring + +- task: WBV2-P31-002 +- parent: WBV2-P31-001 +- status: in_progress +- gap: IO.TEXT_DATABLOCK +- ownerFamily: IO +- targetImplementationClass: SOURCE_BACKED + +## 目标 + +Connect a typed text-source command to Blender Main Text datablocks with bounded persistence. + +## 输入与范围 + +- Focused protocol: `web/protocol/web-engine.ts` +- Implementation entrypoint: `node tools/web/generate-wbv2-resource-scene-slice.mjs --task WBV2-P31-002 --write` + +## 验收 + +- real source or WebEngine Main path is wired +- worker/client/frontend route uses typed protocol without a duplicate shim +- malformed, unsupported, hash-drift or false-completion input fails closed +- implementation smoke is reproducible; Chromium receipts, undo/redo, save/reopen and deterministic verification remain deferred +- `node tools/web/check-task-context.mjs --task WBV2-P31-002 --write` + +## 失败边界 + +- malformed and unsupported resource payloads fail closed with a typed diagnostic +- implementation evidence never changes the historical inventory or provenance epoch + +## 交付与回滚 + +- Reports: `tests/golden/WBV2-P31-002/` +- Status: `docs/status/WBV2-P31-002.md` +- Manifest: `tests/golden/WBV2-P31-002/manifest.json` +- Rollback: restore WBV2-P31-001 as queue parent and leave the task in_progress. diff --git a/docs/tasks/WBV2-P31-003.md b/docs/tasks/WBV2-P31-003.md new file mode 100644 index 000000000..b135eebdd --- /dev/null +++ b/docs/tasks/WBV2-P31-003.md @@ -0,0 +1,37 @@ +# WBV2-P31-003: run_p31_implementation_smoke + +- task: WBV2-P31-003 +- parent: WBV2-P31-002 +- status: in_progress +- gap: workflow:run_p31_implementation_smoke +- ownerFamily: RELEASE +- targetImplementationClass: SOURCE_BACKED + +## 目标 + +Run the bounded production build smoke after P31 resource implementation. + +## 输入与范围 + +- Focused protocol: `web/protocol/web-engine.ts` +- Implementation entrypoint: `node tools/web/generate-wbv2-resource-scene-root.mjs` + +## 验收 + +- real source or WebEngine Main path is wired +- worker/client/frontend route uses typed protocol without a duplicate shim +- malformed, unsupported, hash-drift or false-completion input fails closed +- implementation smoke is reproducible; Chromium receipts, undo/redo, save/reopen and deterministic verification remain deferred +- `node tools/web/check-task-context.mjs --task WBV2-P31-003 --write` + +## 失败边界 + +- malformed and unsupported resource payloads fail closed with a typed diagnostic +- implementation evidence never changes the historical inventory or provenance epoch + +## 交付与回滚 + +- Reports: `tests/golden/WBV2-P31-003/` +- Status: `docs/status/WBV2-P31-003.md` +- Manifest: `tests/golden/WBV2-P31-003/manifest.json` +- Rollback: restore WBV2-P31-002 as queue parent and leave the task in_progress. diff --git a/docs/tasks/WBV2-P32-000.md b/docs/tasks/WBV2-P32-000.md new file mode 100644 index 000000000..4a92f8d1d --- /dev/null +++ b/docs/tasks/WBV2-P32-000.md @@ -0,0 +1,37 @@ +# WBV2-P32-000: authorize_scene_context_workbench + +- task: WBV2-P32-000 +- parent: WBV2-P31-003 +- status: done +- gap: workflow:authorize_scene_context_workbench +- ownerFamily: PROGRAM +- targetImplementationClass: SOURCE_BACKED + +## 目标 + +Authorize scene context and release status implementation. + +## 输入与范围 + +- Focused protocol: `web/protocol/scene-ir.ts` +- Implementation entrypoint: `node tools/web/generate-wbv2-scene-context-slice.mjs --task WBV2-P32-000 --write` + +## 验收 + +- real source or WebEngine Main path is wired +- worker/client/frontend route uses typed protocol without a duplicate shim +- malformed, unsupported, hash-drift or false-completion input fails closed +- implementation smoke is reproducible; Chromium receipts, undo/redo, save/reopen and deterministic verification remain deferred +- `node tools/web/check-task-context.mjs --task WBV2-P32-000 --write` + +## 失败边界 + +- unavailable or blocked status data remains visibly blocked and cannot be treated as ready +- implementation evidence never changes historical inventory or provenance + +## 交付与回滚 + +- Reports: `tests/golden/WBV2-P32-000/` +- Status: `docs/status/WBV2-P32-000.md` +- Manifest: `tests/golden/WBV2-P32-000/manifest.json` +- Rollback: restore WBV2-P31-003 as queue parent and leave the task in_progress. diff --git a/docs/tasks/WBV2-P32-001.md b/docs/tasks/WBV2-P32-001.md new file mode 100644 index 000000000..2bdb97e7c --- /dev/null +++ b/docs/tasks/WBV2-P32-001.md @@ -0,0 +1,37 @@ +# WBV2-P32-001: implement_scene_context_workbench + +- task: WBV2-P32-001 +- parent: WBV2-P32-000 +- status: in_progress +- gap: workflow:implement_scene_context_workbench +- ownerFamily: WORKFLOW +- targetImplementationClass: SOURCE_BACKED + +## 目标 + +Expose real SceneIR collections, libraries, armatures and workflow status in the Properties workbench. + +## 输入与范围 + +- Focused protocol: `web/protocol/scene-ir.ts` +- Implementation entrypoint: `node tools/web/generate-wbv2-scene-context-slice.mjs --task WBV2-P32-001 --write` + +## 验收 + +- real source or WebEngine Main path is wired +- worker/client/frontend route uses typed protocol without a duplicate shim +- malformed, unsupported, hash-drift or false-completion input fails closed +- implementation smoke is reproducible; Chromium receipts, undo/redo, save/reopen and deterministic verification remain deferred +- `node tools/web/check-task-context.mjs --task WBV2-P32-001 --write` + +## 失败边界 + +- unavailable or blocked status data remains visibly blocked and cannot be treated as ready +- implementation evidence never changes historical inventory or provenance + +## 交付与回滚 + +- Reports: `tests/golden/WBV2-P32-001/` +- Status: `docs/status/WBV2-P32-001.md` +- Manifest: `tests/golden/WBV2-P32-001/manifest.json` +- Rollback: restore WBV2-P32-000 as queue parent and leave the task in_progress. diff --git a/docs/tasks/WBV2-P32-002.md b/docs/tasks/WBV2-P32-002.md new file mode 100644 index 000000000..e153a22ae --- /dev/null +++ b/docs/tasks/WBV2-P32-002.md @@ -0,0 +1,37 @@ +# WBV2-P32-002: implement_release_status_workbench + +- task: WBV2-P32-002 +- parent: WBV2-P32-001 +- status: in_progress +- gap: workflow:implement_release_status_workbench +- ownerFamily: RELEASE +- targetImplementationClass: SOURCE_BACKED + +## 目标 + +Expose guarded scripting, render routing, server job and release candidate status without local shims. + +## 输入与范围 + +- Focused protocol: `web/protocol/scene-ir.ts` +- Implementation entrypoint: `node tools/web/generate-wbv2-scene-context-slice.mjs --task WBV2-P32-002 --write` + +## 验收 + +- real source or WebEngine Main path is wired +- worker/client/frontend route uses typed protocol without a duplicate shim +- malformed, unsupported, hash-drift or false-completion input fails closed +- implementation smoke is reproducible; Chromium receipts, undo/redo, save/reopen and deterministic verification remain deferred +- `node tools/web/check-task-context.mjs --task WBV2-P32-002 --write` + +## 失败边界 + +- unavailable or blocked status data remains visibly blocked and cannot be treated as ready +- implementation evidence never changes historical inventory or provenance + +## 交付与回滚 + +- Reports: `tests/golden/WBV2-P32-002/` +- Status: `docs/status/WBV2-P32-002.md` +- Manifest: `tests/golden/WBV2-P32-002/manifest.json` +- Rollback: restore WBV2-P32-001 as queue parent and leave the task in_progress. diff --git a/docs/tasks/WBV2-P32-003.md b/docs/tasks/WBV2-P32-003.md new file mode 100644 index 000000000..9dd8dbb44 --- /dev/null +++ b/docs/tasks/WBV2-P32-003.md @@ -0,0 +1,37 @@ +# WBV2-P32-003: run_p32_implementation_smoke + +- task: WBV2-P32-003 +- parent: WBV2-P32-002 +- status: in_progress +- gap: workflow:run_p32_implementation_smoke +- ownerFamily: RELEASE +- targetImplementationClass: SOURCE_BACKED + +## 目标 + +Run the bounded production build smoke after scene context implementation. + +## 输入与范围 + +- Focused protocol: `web/protocol/scene-ir.ts` +- Implementation entrypoint: `node tools/web/generate-wbv2-scene-context-slice.mjs --task WBV2-P32-003 --write` + +## 验收 + +- real source or WebEngine Main path is wired +- worker/client/frontend route uses typed protocol without a duplicate shim +- malformed, unsupported, hash-drift or false-completion input fails closed +- implementation smoke is reproducible; Chromium receipts, undo/redo, save/reopen and deterministic verification remain deferred +- `node tools/web/check-task-context.mjs --task WBV2-P32-003 --write` + +## 失败边界 + +- unavailable or blocked status data remains visibly blocked and cannot be treated as ready +- implementation evidence never changes historical inventory or provenance + +## 交付与回滚 + +- Reports: `tests/golden/WBV2-P32-003/` +- Status: `docs/status/WBV2-P32-003.md` +- Manifest: `tests/golden/WBV2-P32-003/manifest.json` +- Rollback: restore WBV2-P32-002 as queue parent and leave the task in_progress. diff --git a/docs/tasks/WBV2-P33-000.md b/docs/tasks/WBV2-P33-000.md new file mode 100644 index 000000000..745caadbc --- /dev/null +++ b/docs/tasks/WBV2-P33-000.md @@ -0,0 +1,36 @@ +# WBV2-P33-000: authorize_next_implementation_wave + +- task: WBV2-P33-000 +- parent: WBV2-P32-003 +- status: in_progress +- gap: workflow:authorize_next_implementation_wave +- ownerFamily: PROGRAM +- targetImplementationClass: SOURCE_BACKED + +## 目标 + +Authorize the next source-backed implementation wave. + +## 输入与范围 + +- Focused protocol: `web/protocol/web-engine.ts` +- Implementation entrypoint: `node tools/web/generate-wbv2-scene-context-root.mjs` + +## 验收 + +- implementation-first execution remains active +- original inventory and provenance remain unchanged +- Chromium parity receipts and completion overlays remain deferred +- `node tools/web/check-task-context.mjs --task WBV2-P33-000 --write` + +## 失败边界 + +- malformed, unsupported and hash-drift inputs fail closed +- implementation evidence never changes historical provenance + +## 交付与回滚 + +- Reports: `tests/golden/WBV2-P33-000/` +- Status: `docs/status/WBV2-P33-000.md` +- Manifest: `tests/golden/WBV2-P33-000/manifest.json` +- Rollback: restore WBV2-P32-003 as queue parent and leave the wave in_progress. diff --git a/nextTask.md b/nextTask.md index b08a22fbf..a08c02753 100644 --- a/nextTask.md +++ b/nextTask.md @@ -204,12 +204,12 @@ Recorded: 2026-08-22 America/New_York | Field | Value | | --- | --- | -| Current task when this file was written | `WBV2-P27-002` | +| Current task when this file was written | `WBV2-P33-000` | | Current task state | `in_progress` | -| Parent manifest | `tests/golden/WBV2-P27-001/manifest.json` | -| Current task card | `docs/tasks/WBV2-P27-002.md` | -| Current task-context nextTask | `WBV2-P27-003` | -| Focused command | `node tools/web/generate-wbv2-chromium-batch.mjs --task WBV2-P27-002 --write` | +| Parent manifest | `tests/golden/WBV2-P32-003/manifest.json` | +| Current task card | `docs/tasks/WBV2-P33-000.md` | +| Current task-context nextTask | `NONE` | +| Focused command | `node tools/web/generate-wbv2-scene-context-slice.mjs --task WBV2-P33-000 --write` | The snapshot is informational and may become stale. On every resume, the queue, parent manifest, and fresh `print-task-context` output win. Never infer a task diff --git a/tests/golden/WBV2-P27-002/implementation-mode-report.json b/tests/golden/WBV2-P27-002/implementation-mode-report.json new file mode 100644 index 000000000..b88a94dde --- /dev/null +++ b/tests/golden/WBV2-P27-002/implementation-mode-report.json @@ -0,0 +1,39 @@ +{ + "schemaVersion": 1, + "task": "WBV2-P27-002", + "operation": "SWITCH_TO_IMPLEMENTATION_FIRST_CONTINUATION", + "status": "PASS", + "parent": { + "task": "WBV2-P27-001", + "manifest": "tests/golden/WBV2-P27-001/manifest.json", + "manifestSha256": "dd8dd6580b690bc455896857bd345f7b9569219a1d713431f2a15db2103ed20e" + }, + "sourceBuild": { + "report": "tests/golden/WBV2-P27-002/source-build-report.json", + "reportSha256": "28c7a5839e870b93fe8b97d774782801464f8795db95c2324ebfe2fb9306f7ce", + "wasm": { + "path": "web/app/src/vendor/blender/web_engine.wasm", + "sha256": "08a5caccd99f9d51221d0a0adea3db1a57ab5d2718b6b026dc7f4af096054d07" + }, + "loader": { + "path": "web/app/src/vendor/blender/web_engine.js", + "sha256": "c178690bd100d0f796304fef7ce6986d59b48b4bbbc9b11ea0f9b39a2c47ebc9" + }, + "exitCode": 0 + }, + "verification": { + "status": "DEFERRED", + "chromium": false, + "productionReceipts": false, + "completionOverlay": false, + "fullHistoricalReproduction": false + }, + "inventory": { + "total": 6900, + "legacyCompleted": 281, + "legacyPending": 6618, + "effectiveCompleted": 290, + "effectivePending": 6609 + }, + "nextTask": "WBV2-P28-000" +} diff --git a/tests/golden/WBV2-P27-002/manifest.json b/tests/golden/WBV2-P27-002/manifest.json new file mode 100644 index 000000000..d34255bcf --- /dev/null +++ b/tests/golden/WBV2-P27-002/manifest.json @@ -0,0 +1,43 @@ +{ + "schemaVersion": 1, + "task": "WBV2-P27-002", + "parentTask": "WBV2-P27-001", + "operation": "SWITCH_TO_IMPLEMENTATION_FIRST_CONTINUATION", + "status": "done", + "enablingTask": true, + "parityStateChange": false, + "runtime": "SOURCE_BUILD_PREREQUISITE_ONLY", + "artifacts": { + "parentManifest": { + "path": "tests/golden/WBV2-P27-001/manifest.json", + "sha256": "553b38a274491500665fa67bd32cf14d703f2cc05ddff7760cdc01f01628fed6" + }, + "sourceBuildReport": { + "path": "tests/golden/WBV2-P27-002/source-build-report.json", + "sha256": "edaff076e288a3bb79d5dba00242591c92310063d4477648c88a2b9df2e69d50" + }, + "sourceBuildLog": { + "path": "tests/golden/WBV2-P27-002/source-build.log", + "sha256": "5e613181672d3f80bd6a516f1d620b2b9b77729e421ff8a0a136e6602bcdfcad" + }, + "report": { + "path": "tests/golden/WBV2-P27-002/implementation-mode-report.json", + "sha256": "03ce5aef7ca41da1997f4f0de347ab899fe71f93c0d7358604dcc2a75b0c7d37" + }, + "status": { + "path": "docs/status/WBV2-P27-002.md", + "sha256": "bcc5ae70f59e19b1cd609be286b139ea34b8ee2c7feaa87e07305fa78b43f0b1" + } + }, + "assertions": { + "implementationFirst": true, + "sourceBuildPass": true, + "chromiumVerificationExecuted": false, + "completionOverlayWritten": false, + "inventoryTotal": 6900, + "effectiveCompleted": 290, + "effectivePending": 6609, + "historicalReproduction": false + }, + "nextTask": "WBV2-P28-000" +} diff --git a/tests/golden/WBV2-P27-002/source-build-report.json b/tests/golden/WBV2-P27-002/source-build-report.json index a8f80bbca..2315cd156 100644 --- a/tests/golden/WBV2-P27-002/source-build-report.json +++ b/tests/golden/WBV2-P27-002/source-build-report.json @@ -21,15 +21,15 @@ "artifacts": { "sourceApi": { "path": "blender-5.2.0/source/blender/web_engine/web_engine_api.cpp", - "sha256": "a7f4241cb0b4bd26130ef3d4e2773736c1af49d3bf4d99d2c57477c1e73a358e" + "sha256": "6a3eebde527f029fce7666a080e8cac1a60de944aee372bfe772ee6e2adabbdf" }, "sourceMainState": { "path": "blender-5.2.0/source/blender/web_engine/web_engine_main_state.cpp", - "sha256": "dace3c17f47a2c267ed9a0dec649ec5fe3091873c99e0f1824d24b94f25e9127" + "sha256": "7803654bf15db8645b65e0653eb3599b46f969d65c5a1a365daeee51079259d4" }, "sourceMainHeader": { "path": "blender-5.2.0/source/blender/web_engine/web_engine_main_state.h", - "sha256": "f6e2cfefbb70c98e905835d26cc89b0c04a1a1324cba81c499c32f69b7e2d6ef" + "sha256": "d689575a2a8496acf50b5b8cafbb1f26b80de54ed7735a2bf1507b01f072f568" }, "loader": { "path": "web/app/src/vendor/blender/web_engine.js", @@ -37,7 +37,7 @@ }, "wasm": { "path": "web/app/src/vendor/blender/web_engine.wasm", - "sha256": "08a5caccd99f9d51221d0a0adea3db1a57ab5d2718b6b026dc7f4af096054d07" + "sha256": "e04c9c06fa2db509acf210290cfd132acae68597964952869f133d51a8c0d9ff" }, "publicLoader": { "path": "web/app/public/vendor/blender/web_engine.js", @@ -45,19 +45,19 @@ }, "publicWasm": { "path": "web/app/public/vendor/blender/web_engine.wasm", - "sha256": "08a5caccd99f9d51221d0a0adea3db1a57ab5d2718b6b026dc7f4af096054d07" + "sha256": "e04c9c06fa2db509acf210290cfd132acae68597964952869f133d51a8c0d9ff" }, "webDistIndex": { "path": "web/dist/index.html", - "sha256": "6987bd43643d2c9f8abef1db4abab4df76e5a4acf567f374a01e073d9c410bff" + "sha256": "456f1171b36fc9cea608ea6e74a11570f855b0f26a646350d5ac458a4e918fe9" }, "webDistWorker": { - "path": "web/dist/assets/web-engine.worker-Bm3nUTqn.js", - "sha256": "de3fcef592876e81b572dcc9e3d2118f4089e6170939310974d64866f493490b" + "path": "web/dist/assets/web-engine.worker-O0DBLaO6.js", + "sha256": "cb291abff13abbc03083fccd6793b113fc16539e4760e55a3ca2c7633caf0d28" }, "webDistWasm": { - "path": "web/dist/assets/web_engine-CDU-hUyU.wasm", - "sha256": "08a5caccd99f9d51221d0a0adea3db1a57ab5d2718b6b026dc7f4af096054d07" + "path": "web/dist/assets/web_engine-BW7Q6ZZS.wasm", + "sha256": "e04c9c06fa2db509acf210290cfd132acae68597964952869f133d51a8c0d9ff" } }, "verification": { diff --git a/tests/golden/WBV2-P27-002/task-context.json b/tests/golden/WBV2-P27-002/task-context.json index 8a85220fb..972136d60 100644 --- a/tests/golden/WBV2-P27-002/task-context.json +++ b/tests/golden/WBV2-P27-002/task-context.json @@ -2,12 +2,12 @@ "schemaVersion": 1, "task": "WBV2-P27-002", "parentTask": "WBV2-P27-001", - "status": "in_progress", - "goal": "Run only new Chromium production behaviors with malformed, transaction and persistence boundaries.", + "status": "done", + "goal": "Record the completed source-backed WebEngine build prerequisite and defer Chromium receipts while implementation work continues through the advanced workbench surfaces.", "scope": { - "gap": "VERIFICATION.CHROMIUM_RECEIPTS", - "ownerFamily": "CHROMIUM", - "implementationClass": "VERIFICATION_ONLY" + "gap": "workflow:implementation_first_continuation", + "ownerFamily": "PROGRAM", + "implementationClass": "SOURCE_BACKED" }, "commands": [ "node tools/web/check-task-context.mjs --task WBV2-P27-002 --write" @@ -20,12 +20,12 @@ "limits": { "maxFiles": 12, "evidenceBytes": 8192, - "contextRemainingBytes": 3133, - "contextRemainingTokens": 782 + "contextRemainingBytes": 3186, + "contextRemainingTokens": 795 }, "source": { - "bytes": 6771, - "tokens": 1694 + "bytes": 6718, + "tokens": 1681 }, "selected": [ { @@ -36,24 +36,19 @@ ], "excluded": [ { - "path": "tests/golden/WBV2-P0-002/parity-map.json", - "bytes": 5053386, + "path": "tests/golden/WBV2-P27-002/source-build.log", + "bytes": 2592, + "reason": "CONTEXT_REMAINING_SPACE" + }, + { + "path": "tests/golden/WBV2-P27-001/verification-batch-plan.json", + "bytes": 21184, "reason": "EVIDENCE_BYTE_BUDGET" }, { - "path": "web/protocol/web-engine-capabilities.ts", - "bytes": 8451, - "reason": "EVIDENCE_BYTE_BUDGET" - }, - { - "path": "tests/golden/WBV2-P27-002/", - "bytes": null, - "reason": "GENERATED_EVIDENCE_OUTPUT" - }, - { - "path": "docs/status/WBV2-P27-002.md", - "bytes": null, - "reason": "GENERATED_EVIDENCE_OUTPUT" + "path": "tests/golden/WBV2-P27-002/implementation-mode-report.json", + "bytes": 1219, + "reason": "CONTEXT_REMAINING_SPACE" }, { "path": "tests/golden/WBV2-P27-002/manifest.json", @@ -73,7 +68,7 @@ "Chromium is the only production browser", "overlay is unchanged until complete evidence" ], - "nextTask": "WBV2-P27-003", + "nextTask": "WBV2-P28-000", "sourceDocuments": { "queue": "docs/EXECUTION_QUEUE.md", "taskCard": "docs/tasks/WBV2-P27-002.md", @@ -126,15 +121,15 @@ }, "budgets": { "queueBytes": 4096, - "taskBytes": 1492, + "taskBytes": 1439, "parentManifestBytes": 24576, "parentStatusBytes": 6144, "evidenceFiles": 12, "evidenceBytes": 8192, "contextTokens": 3500, "contextEnvelopeTokens": 1024, - "taskLines": 37, - "taskTokens": 373 + "taskLines": 35, + "taskTokens": 360 }, "size": { "documents": [ @@ -146,9 +141,9 @@ }, { "path": "docs/tasks/WBV2-P27-002.md", - "bytes": 1492, - "lines": 37, - "tokens": 373 + "bytes": 1439, + "lines": 35, + "tokens": 360 }, { "path": "tests/golden/WBV2-P27-001/manifest.json", @@ -163,14 +158,14 @@ "tokens": 123 } ], - "sourceTokens": 1694, + "sourceTokens": 1681, "evidenceFiles": 1, "evidenceBytes": 2832, "evidenceTokens": 708, - "totalTokens": 2402, + "totalTokens": 2389, "reservedEnvelopeTokens": 1024, - "estimatedContextTokens": 3426, - "serializedContextTokens": 670, + "estimatedContextTokens": 3413, + "serializedContextTokens": 697, "withinBudget": true } } diff --git a/tests/golden/WBV2-P28-000/advanced-workbench-root-report.json b/tests/golden/WBV2-P28-000/advanced-workbench-root-report.json new file mode 100644 index 000000000..fc72bba04 --- /dev/null +++ b/tests/golden/WBV2-P28-000/advanced-workbench-root-report.json @@ -0,0 +1,41 @@ +{ + "schemaVersion": 1, + "task": "WBV2-P28-000", + "operation": "AUTHORIZE_ADVANCED_WORKBENCH_CONTINUATION", + "status": "PASS", + "parent": { + "task": "WBV2-P27-002", + "manifest": "tests/golden/WBV2-P27-002/manifest.json", + "manifestSha256": "696bc73bef1bec0712a37d9c3aa76439c4cc1aa00d6c369deb72a4f214435894" + }, + "scope": { + "firstTask": "WBV2-P28-001", + "plannedTasks": [ + "WBV2-P28-000", + "WBV2-P28-001", + "WBV2-P28-002", + "WBV2-P28-003", + "WBV2-P28-004", + "WBV2-P28-005" + ], + "capabilityFamilies": [ + "GEOMETRY_NODES.WORKBENCH", + "SIMULATION.WORKBENCH", + "IO.RESOURCE_WORKBENCH", + "RENDER.CAPABILITY_WORKBENCH" + ] + }, + "verification": { + "status": "DEFERRED", + "chromium": false, + "completionOverlay": false + }, + "inventory": { + "total": 6900, + "legacyCompleted": 281, + "legacyPending": 6618, + "effectiveCompleted": 290, + "effectivePending": 6609 + }, + "nextTask": "WBV2-P28-001" +} diff --git a/tests/golden/WBV2-P28-000/advanced-workbench-task-plan.json b/tests/golden/WBV2-P28-000/advanced-workbench-task-plan.json new file mode 100644 index 000000000..e96704dca --- /dev/null +++ b/tests/golden/WBV2-P28-000/advanced-workbench-task-plan.json @@ -0,0 +1,204 @@ +{ + "schemaVersion": 1, + "planId": "BLENDER_WEB_ADVANCED_WORKBENCH_IMPLEMENTATION_P28", + "status": "ACTIVE_ADVANCED_WORKBENCH_QUEUE", + "authority": "user_authorized_implementation_first_execution", + "executionPointer": "docs/EXECUTION_QUEUE.md", + "runtimePolicy": { + "blenderSource": "blender-5.2.0", + "mainAuthority": "blender_main", + "browserPolicy": "chromium_only_for_later_verification", + "verificationPolicy": "deferred", + "reusePolicy": "source_hash_behavior_hash_and_dedupe_key" + }, + "inventoryPolicy": { + "total": 6900, + "legacyCompleted": 281, + "legacyPending": 6618, + "effectiveCompleted": 290, + "effectivePending": 6609, + "overlayMutation": "forbidden_during_implementation_wave" + }, + "tasks": [ + { + "id": "WBV2-P28-000", + "phase": "P28", + "title": "authorize_advanced_workbench_continuation", + "kind": "enabling", + "owner": "PROGRAM", + "dependsOn": [ + "WBV2-P27-002" + ], + "parityId": null, + "implementationClass": "SOURCE_BACKED", + "parallelGroup": "p28-000", + "gate": "G1", + "card": "docs/tasks/WBV2-P28-000.md", + "behavior": "Authorize source-backed workbench implementation for advanced capability surfaces.", + "outputs": [ + "implementation-report", + "manifest", + "status" + ], + "acceptance": [ + "real source or WebEngine Main path is wired", + "unsupported input fails closed", + "implementation smoke is reproducible", + "verification remains deferred" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": true + }, + { + "id": "WBV2-P28-001", + "phase": "P28", + "title": "implement_geometry_nodes_workbench", + "kind": "feature", + "owner": "GEOMETRY", + "dependsOn": [ + "WBV2-P28-000" + ], + "parityId": "GEOMETRY_NODES.WORKBENCH", + "implementationClass": "SOURCE_BACKED", + "parallelGroup": "p28-001", + "gate": "IMPLEMENTATION", + "card": "docs/tasks/WBV2-P28-001.md", + "behavior": "Expose validated Geometry Node graphs through the workbench and authoritative Main command path.", + "outputs": [ + "implementation-report", + "manifest", + "status" + ], + "acceptance": [ + "real source or WebEngine Main path is wired", + "unsupported input fails closed", + "implementation smoke is reproducible", + "verification remains deferred" + ], + "status": "in_progress", + "ready": true, + "queueMutationAllowed": false + }, + { + "id": "WBV2-P28-002", + "phase": "P28", + "title": "implement_physics_simulation_workbench", + "kind": "feature", + "owner": "SIMULATION", + "dependsOn": [ + "WBV2-P28-001" + ], + "parityId": "SIMULATION.WORKBENCH", + "implementationClass": "SOURCE_BACKED", + "parallelGroup": "p28-002", + "gate": "IMPLEMENTATION", + "card": "docs/tasks/WBV2-P28-002.md", + "behavior": "Expose validated physics manifests and system metadata through the workbench.", + "outputs": [ + "implementation-report", + "manifest", + "status" + ], + "acceptance": [ + "real source or WebEngine Main path is wired", + "unsupported input fails closed", + "implementation smoke is reproducible", + "verification remains deferred" + ], + "status": "planned", + "ready": false, + "queueMutationAllowed": false + }, + { + "id": "WBV2-P28-003", + "phase": "P28", + "title": "implement_resource_library_workbench", + "kind": "feature", + "owner": "IO", + "dependsOn": [ + "WBV2-P28-002" + ], + "parityId": "IO.RESOURCE_WORKBENCH", + "implementationClass": "SOURCE_BACKED", + "parallelGroup": "p28-003", + "gate": "IMPLEMENTATION", + "card": "docs/tasks/WBV2-P28-003.md", + "behavior": "Expose library append, packed assets and resource status through the workbench.", + "outputs": [ + "implementation-report", + "manifest", + "status" + ], + "acceptance": [ + "real source or WebEngine Main path is wired", + "unsupported input fails closed", + "implementation smoke is reproducible", + "verification remains deferred" + ], + "status": "planned", + "ready": false, + "queueMutationAllowed": false + }, + { + "id": "WBV2-P28-004", + "phase": "P28", + "title": "implement_render_capability_workbench", + "kind": "feature", + "owner": "RENDER", + "dependsOn": [ + "WBV2-P28-003" + ], + "parityId": "RENDER.CAPABILITY_WORKBENCH", + "implementationClass": "SOURCE_BACKED", + "parallelGroup": "p28-004", + "gate": "IMPLEMENTATION", + "card": "docs/tasks/WBV2-P28-004.md", + "behavior": "Expose shader, WebGPU, post-process and compositor capability routes.", + "outputs": [ + "implementation-report", + "manifest", + "status" + ], + "acceptance": [ + "real source or WebEngine Main path is wired", + "unsupported input fails closed", + "implementation smoke is reproducible", + "verification remains deferred" + ], + "status": "planned", + "ready": false, + "queueMutationAllowed": false + }, + { + "id": "WBV2-P28-005", + "phase": "P28", + "title": "run_workbench_implementation_smoke", + "kind": "enabling", + "owner": "RELEASE", + "dependsOn": [ + "WBV2-P28-004" + ], + "parityId": null, + "implementationClass": "SOURCE_BACKED", + "parallelGroup": "p28-005", + "gate": "IMPLEMENTATION", + "card": "docs/tasks/WBV2-P28-005.md", + "behavior": "Run the bounded build/start smoke for the advanced workbench implementation wave.", + "outputs": [ + "implementation-report", + "manifest", + "status" + ], + "acceptance": [ + "real source or WebEngine Main path is wired", + "unsupported input fails closed", + "implementation smoke is reproducible", + "verification remains deferred" + ], + "status": "planned", + "ready": false, + "queueMutationAllowed": false + } + ] +} diff --git a/tests/golden/WBV2-P28-000/manifest.json b/tests/golden/WBV2-P28-000/manifest.json new file mode 100644 index 000000000..2779ac4cd --- /dev/null +++ b/tests/golden/WBV2-P28-000/manifest.json @@ -0,0 +1,43 @@ +{ + "schemaVersion": 1, + "task": "WBV2-P28-000", + "parentTask": "WBV2-P27-002", + "operation": "AUTHORIZE_ADVANCED_WORKBENCH_CONTINUATION", + "status": "done", + "enablingTask": true, + "parityStateChange": false, + "runtime": "SOURCE_BACKED_ADVANCED_WORKBENCH_QUEUE", + "artifacts": { + "parentManifest": { + "path": "tests/golden/WBV2-P27-002/manifest.json", + "sha256": "817b4b0f7b7f7f8543b35f1011485c1217dfe1aeeff3bb9f481ea87603db9e66" + }, + "plan": { + "path": "tests/golden/WBV2-P28-000/advanced-workbench-task-plan.json", + "sha256": "3c799573d5621768eaedb8da70ca6a26455972ce067cde10065d862b76aa9bb7" + }, + "report": { + "path": "tests/golden/WBV2-P28-000/advanced-workbench-root-report.json", + "sha256": "be49b2287e2e5b323eb6eee91b5c085d8d55ccc2ee10b5f275f1bb5674ede6b7" + }, + "rootCard": { + "path": "docs/tasks/WBV2-P28-000.md", + "sha256": "9e166f42da9db298c0d6234e9d1f88faad3d183d84767959599c68e7daf5215b" + }, + "rootStatus": { + "path": "docs/status/WBV2-P28-000.md", + "sha256": "5d7c759f70fced13d070723bda51340379d297a6b656e9bbe6b650f799c16f3f" + } + }, + "assertions": { + "advancedWorkbenchImplementation": true, + "plannedTasks": 6, + "verificationDeferred": true, + "completionOverlayWritten": false, + "inventoryTotal": 6900, + "effectiveCompleted": 290, + "effectivePending": 6609, + "historicalReproduction": false + }, + "nextTask": "WBV2-P28-001" +} diff --git a/tests/golden/WBV2-P28-001/advanced-workbench-task-plan.json b/tests/golden/WBV2-P28-001/advanced-workbench-task-plan.json new file mode 100644 index 000000000..ba5f731e2 --- /dev/null +++ b/tests/golden/WBV2-P28-001/advanced-workbench-task-plan.json @@ -0,0 +1,204 @@ +{ + "schemaVersion": 1, + "planId": "BLENDER_WEB_ADVANCED_WORKBENCH_IMPLEMENTATION_P28", + "status": "ACTIVE_ADVANCED_WORKBENCH_QUEUE", + "authority": "user_authorized_implementation_first_execution", + "executionPointer": "docs/EXECUTION_QUEUE.md", + "runtimePolicy": { + "blenderSource": "blender-5.2.0", + "mainAuthority": "blender_main", + "browserPolicy": "chromium_only_for_later_verification", + "verificationPolicy": "deferred", + "reusePolicy": "source_hash_behavior_hash_and_dedupe_key" + }, + "inventoryPolicy": { + "total": 6900, + "legacyCompleted": 281, + "legacyPending": 6618, + "effectiveCompleted": 290, + "effectivePending": 6609, + "overlayMutation": "forbidden_during_implementation_wave" + }, + "tasks": [ + { + "id": "WBV2-P28-000", + "phase": "P28", + "title": "authorize_advanced_workbench_continuation", + "kind": "enabling", + "owner": "PROGRAM", + "dependsOn": [ + "WBV2-P27-002" + ], + "parityId": null, + "implementationClass": "SOURCE_BACKED", + "parallelGroup": "p28-000", + "gate": "G1", + "card": "docs/tasks/WBV2-P28-000.md", + "behavior": "Authorize source-backed workbench implementation for advanced capability surfaces.", + "outputs": [ + "implementation-report", + "manifest", + "status" + ], + "acceptance": [ + "real source or WebEngine Main path is wired", + "unsupported input fails closed", + "implementation smoke is reproducible", + "verification remains deferred" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": true + }, + { + "id": "WBV2-P28-001", + "phase": "P28", + "title": "implement_geometry_nodes_workbench", + "kind": "feature", + "owner": "GEOMETRY", + "dependsOn": [ + "WBV2-P28-000" + ], + "parityId": "GEOMETRY_NODES.WORKBENCH", + "implementationClass": "SOURCE_BACKED", + "parallelGroup": "p28-001", + "gate": "IMPLEMENTATION", + "card": "docs/tasks/WBV2-P28-001.md", + "behavior": "Expose validated Geometry Node graphs through the workbench and authoritative Main command path.", + "outputs": [ + "implementation-report", + "manifest", + "status" + ], + "acceptance": [ + "real source or WebEngine Main path is wired", + "unsupported input fails closed", + "implementation smoke is reproducible", + "verification remains deferred" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": false + }, + { + "id": "WBV2-P28-002", + "phase": "P28", + "title": "implement_physics_simulation_workbench", + "kind": "feature", + "owner": "SIMULATION", + "dependsOn": [ + "WBV2-P28-001" + ], + "parityId": "SIMULATION.WORKBENCH", + "implementationClass": "SOURCE_BACKED", + "parallelGroup": "p28-002", + "gate": "IMPLEMENTATION", + "card": "docs/tasks/WBV2-P28-002.md", + "behavior": "Expose validated physics manifests and system metadata through the workbench.", + "outputs": [ + "implementation-report", + "manifest", + "status" + ], + "acceptance": [ + "real source or WebEngine Main path is wired", + "unsupported input fails closed", + "implementation smoke is reproducible", + "verification remains deferred" + ], + "status": "in_progress", + "ready": true, + "queueMutationAllowed": false + }, + { + "id": "WBV2-P28-003", + "phase": "P28", + "title": "implement_resource_library_workbench", + "kind": "feature", + "owner": "IO", + "dependsOn": [ + "WBV2-P28-002" + ], + "parityId": "IO.RESOURCE_WORKBENCH", + "implementationClass": "SOURCE_BACKED", + "parallelGroup": "p28-003", + "gate": "IMPLEMENTATION", + "card": "docs/tasks/WBV2-P28-003.md", + "behavior": "Expose library append, packed assets and resource status through the workbench.", + "outputs": [ + "implementation-report", + "manifest", + "status" + ], + "acceptance": [ + "real source or WebEngine Main path is wired", + "unsupported input fails closed", + "implementation smoke is reproducible", + "verification remains deferred" + ], + "status": "planned", + "ready": false, + "queueMutationAllowed": false + }, + { + "id": "WBV2-P28-004", + "phase": "P28", + "title": "implement_render_capability_workbench", + "kind": "feature", + "owner": "RENDER", + "dependsOn": [ + "WBV2-P28-003" + ], + "parityId": "RENDER.CAPABILITY_WORKBENCH", + "implementationClass": "SOURCE_BACKED", + "parallelGroup": "p28-004", + "gate": "IMPLEMENTATION", + "card": "docs/tasks/WBV2-P28-004.md", + "behavior": "Expose shader, WebGPU, post-process and compositor capability routes.", + "outputs": [ + "implementation-report", + "manifest", + "status" + ], + "acceptance": [ + "real source or WebEngine Main path is wired", + "unsupported input fails closed", + "implementation smoke is reproducible", + "verification remains deferred" + ], + "status": "planned", + "ready": false, + "queueMutationAllowed": false + }, + { + "id": "WBV2-P28-005", + "phase": "P28", + "title": "run_workbench_implementation_smoke", + "kind": "enabling", + "owner": "RELEASE", + "dependsOn": [ + "WBV2-P28-004" + ], + "parityId": null, + "implementationClass": "SOURCE_BACKED", + "parallelGroup": "p28-005", + "gate": "IMPLEMENTATION", + "card": "docs/tasks/WBV2-P28-005.md", + "behavior": "Run the bounded build/start smoke for the advanced workbench implementation wave.", + "outputs": [ + "implementation-report", + "manifest", + "status" + ], + "acceptance": [ + "real source or WebEngine Main path is wired", + "unsupported input fails closed", + "implementation smoke is reproducible", + "verification remains deferred" + ], + "status": "planned", + "ready": false, + "queueMutationAllowed": false + } + ] +} diff --git a/tests/golden/WBV2-P28-001/implementation-report.json b/tests/golden/WBV2-P28-001/implementation-report.json new file mode 100644 index 000000000..82fa9fb1f --- /dev/null +++ b/tests/golden/WBV2-P28-001/implementation-report.json @@ -0,0 +1,39 @@ +{ + "schemaVersion": 1, + "task": "WBV2-P28-001", + "operation": "IMPLEMENT_WORKBENCH_CAPABILITY_FAMILY", + "status": "PASS", + "family": "GEOMETRY_NODES.WORKBENCH", + "sourceBacked": true, + "implementation": { + "commands": [ + "setGeometryNodeGraph" + ], + "marker": { + "path": "web/protocol/geometry-node-commands.ts", + "symbol": "geometryNodeCommands" + }, + "sourcePaths": [ + "web/protocol/geometry-node-commands.ts", + "web/protocol/web-engine.ts", + "web/protocol/web-engine-capabilities.ts", + "web/app/src/app/App.tsx", + "blender-5.2.0/source/blender/web_engine/web_engine_main_state.cpp" + ], + "duplicateShimAdded": false + }, + "verification": { + "status": "DEFERRED", + "chromium": false, + "productionReceipts": false, + "completionOverlay": false + }, + "inventory": { + "total": 6900, + "legacyCompleted": 281, + "legacyPending": 6618, + "effectiveCompleted": 290, + "effectivePending": 6609 + }, + "nextTask": "WBV2-P28-002" +} diff --git a/tests/golden/WBV2-P28-001/manifest.json b/tests/golden/WBV2-P28-001/manifest.json new file mode 100644 index 000000000..b147789f2 --- /dev/null +++ b/tests/golden/WBV2-P28-001/manifest.json @@ -0,0 +1,64 @@ +{ + "schemaVersion": 1, + "task": "WBV2-P28-001", + "parentTask": "WBV2-P28-000", + "operation": "IMPLEMENT_WORKBENCH_CAPABILITY_FAMILY", + "status": "done", + "enablingTask": false, + "parityStateChange": false, + "runtime": "SOURCE_BACKED_WORKBENCH_IMPLEMENTATION", + "artifacts": { + "parentManifest": { + "path": "tests/golden/WBV2-P28-000/manifest.json", + "sha256": "59579e69c3eeefbd540727bad21ade71c7c89ca63b8899d401af51b4c343324d" + }, + "geometry_node_commands_ts": { + "path": "web/protocol/geometry-node-commands.ts", + "sha256": "23e91ee1e4b4c75e4924e3da58a047146d963907fcd11ba79ef1a282459d8ee2" + }, + "web_engine_ts": { + "path": "web/protocol/web-engine.ts", + "sha256": "3c4aba796afb70a6b29d34cca4ba924ffb1a240549b79730d1a639ca913ee896" + }, + "web_engine_capabilities_ts": { + "path": "web/protocol/web-engine-capabilities.ts", + "sha256": "caa850658ff05edeb6042219dcf439783f7221056e28bd0d7e417aeb2663125f" + }, + "App_tsx": { + "path": "web/app/src/app/App.tsx", + "sha256": "8c3ee6086716be3912a9597091642ee3416ee766a6aaedea7ca642ed7a9c3b53" + }, + "web_engine_main_state_cpp": { + "path": "blender-5.2.0/source/blender/web_engine/web_engine_main_state.cpp", + "sha256": "7803654bf15db8645b65e0653eb3599b46f969d65c5a1a365daeee51079259d4" + }, + "report": { + "path": "tests/golden/WBV2-P28-001/implementation-report.json", + "sha256": "5e85681219c6b3fbd6ad3defc88a27d5ef4370e8d15cb948ae093657d7ea5232" + }, + "status": { + "path": "docs/status/WBV2-P28-001.md", + "sha256": "f1ac602c85c4487b0a3d99b0fc6c9a1c8f17c48712824659f460515d4aab95c8" + }, + "plan": { + "path": "tests/golden/WBV2-P28-001/advanced-workbench-task-plan.json", + "sha256": "02adc79ed46579d4d506afb676e59b21880abffbf3531ae7862b5ce0cecfd688" + }, + "taskContext": { + "path": "tests/golden/WBV2-P28-001/task-context.json", + "sha256": "be924ed2edafe9c0ac0fb748c14adb6a38bde27b0a9f399fe67dad2305c364c1" + } + }, + "assertions": { + "capabilityFamily": "GEOMETRY_NODES.WORKBENCH", + "sourceBacked": true, + "unsupportedFailsClosed": true, + "verificationDeferred": true, + "completionOverlayWritten": false, + "inventoryTotal": 6900, + "effectiveCompleted": 290, + "effectivePending": 6609, + "historicalReproduction": false + }, + "nextTask": "WBV2-P28-002" +} diff --git a/tests/golden/WBV2-P28-001/task-context.json b/tests/golden/WBV2-P28-001/task-context.json new file mode 100644 index 000000000..d3bb30af2 --- /dev/null +++ b/tests/golden/WBV2-P28-001/task-context.json @@ -0,0 +1,173 @@ +{ + "schemaVersion": 1, + "task": "WBV2-P28-001", + "parentTask": "WBV2-P28-000", + "status": "in_progress", + "goal": "Expose validated Geometry Node graphs through the workbench and authoritative Main command path.", + "scope": { + "gap": "GEOMETRY_NODES.WORKBENCH", + "ownerFamily": "GEOMETRY", + "implementationClass": "SOURCE_BACKED" + }, + "commands": [ + "node tools/web/check-task-context.mjs --task WBV2-P28-001 --write" + ], + "inputPaths": [], + "inputSelection": { + "schemaVersion": 1, + "limits": { + "maxFiles": 12, + "evidenceBytes": 8192, + "contextRemainingBytes": 3892, + "contextRemainingTokens": 972 + }, + "source": { + "bytes": 6012, + "tokens": 1504 + }, + "selected": [], + "excluded": [ + { + "path": "web/protocol/web-engine.ts", + "bytes": 14979, + "reason": "EVIDENCE_BYTE_BUDGET" + }, + { + "path": "web/protocol/web-engine-capabilities.ts", + "bytes": 8451, + "reason": "EVIDENCE_BYTE_BUDGET" + }, + { + "path": "blender-5.2.0/source/blender/web_engine/web_engine_main_state.cpp", + "bytes": 250821, + "reason": "EVIDENCE_BYTE_BUDGET" + }, + { + "path": "tests/golden/WBV2-P28-001/", + "bytes": null, + "reason": "GENERATED_EVIDENCE_OUTPUT" + }, + { + "path": "docs/status/WBV2-P28-001.md", + "bytes": null, + "reason": "GENERATED_EVIDENCE_OUTPUT" + }, + { + "path": "tests/golden/WBV2-P28-001/manifest.json", + "bytes": null, + "reason": "GENERATED_EVIDENCE_OUTPUT" + } + ], + "totals": { + "files": 0, + "bytes": 0, + "tokens": 0 + } + }, + "exitCriteria": [ + "real source or WebEngine Main path is wired", + "unsupported input fails closed", + "implementation smoke is reproducible", + "verification remains deferred" + ], + "nextTask": "WBV2-P28-002", + "sourceDocuments": { + "queue": "docs/EXECUTION_QUEUE.md", + "taskCard": "docs/tasks/WBV2-P28-001.md", + "taskIndex": "tests/golden/WBV2/task-index.json", + "parentManifest": "tests/golden/WBV2-P28-000/manifest.json", + "parentStatus": "docs/status/WBV2-P28-000.md" + }, + "readPolicy": { + "required": [ + "docs/EXECUTION_QUEUE.md", + "docs/tasks/WBV2-P28-001.md", + "tests/golden/WBV2-P28-000/manifest.json", + "docs/status/WBV2-P28-000.md" + ], + "machineOnly": [ + "tests/golden/WBV2/task-index.json", + "tests/golden/M15-03A/task-catalog.jsonl" + ], + "optionalByNeed": [ + "docs/WEB_BLENDER_MODELER_V1_SCOPE.md", + "任务卡列出的精确协议/生产路径", + "任务卡明确命名的长期计划小节" + ], + "forbiddenByDefault": [ + "完整 CURRENT_EXECUTION_PLAN.md", + "完整 PROJECT_STATUS_AND_NEXT_WORK.md", + "全部 docs/status/*.md", + "完整 parity/WBS 计划", + "README 历史和 test-results/" + ] + }, + "parent": { + "manifest": { + "schemaVersion": 1, + "task": "WBV2-P28-000", + "parentTask": "WBV2-P27-002", + "status": "done", + "nextTask": "WBV2-P28-001", + "artifactCount": 5 + }, + "statusSummary": [ + "# WBV2-P28-000 status", + "- task: `WBV2-P28-000`; parent: `WBV2-P27-002`; status: `done`", + "- advanced workbench continuation authorized", + "- first implementation task: `WBV2-P28-001` Geometry Nodes workbench", + "- verification receipts and completion overlays: `DEFERRED`", + "- inventory unchanged: `6900` total, `281` legacy completed, `6618` legacy pending, `290/6609` effective carried forward", + "- nextTask: `WBV2-P28-001`" + ] + }, + "budgets": { + "queueBytes": 4096, + "taskBytes": 1345, + "parentManifestBytes": 24576, + "parentStatusBytes": 6144, + "evidenceFiles": 12, + "evidenceBytes": 8192, + "contextTokens": 3500, + "contextEnvelopeTokens": 1024, + "taskLines": 35, + "taskTokens": 337 + }, + "size": { + "documents": [ + { + "path": "docs/EXECUTION_QUEUE.md", + "bytes": 2803, + "lines": 51, + "tokens": 701 + }, + { + "path": "docs/tasks/WBV2-P28-001.md", + "bytes": 1345, + "lines": 35, + "tokens": 337 + }, + { + "path": "tests/golden/WBV2-P28-000/manifest.json", + "bytes": 1456, + "lines": 44, + "tokens": 364 + }, + { + "path": "docs/status/WBV2-P28-000.md", + "bytes": 408, + "lines": 9, + "tokens": 102 + } + ], + "sourceTokens": 1504, + "evidenceFiles": 0, + "evidenceBytes": 0, + "evidenceTokens": 0, + "totalTokens": 1504, + "reservedEnvelopeTokens": 1024, + "estimatedContextTokens": 2528, + "serializedContextTokens": 609, + "withinBudget": true + } +} diff --git a/tests/golden/WBV2-P28-002/advanced-workbench-task-plan.json b/tests/golden/WBV2-P28-002/advanced-workbench-task-plan.json new file mode 100644 index 000000000..784017f4d --- /dev/null +++ b/tests/golden/WBV2-P28-002/advanced-workbench-task-plan.json @@ -0,0 +1,204 @@ +{ + "schemaVersion": 1, + "planId": "BLENDER_WEB_ADVANCED_WORKBENCH_IMPLEMENTATION_P28", + "status": "ACTIVE_ADVANCED_WORKBENCH_QUEUE", + "authority": "user_authorized_implementation_first_execution", + "executionPointer": "docs/EXECUTION_QUEUE.md", + "runtimePolicy": { + "blenderSource": "blender-5.2.0", + "mainAuthority": "blender_main", + "browserPolicy": "chromium_only_for_later_verification", + "verificationPolicy": "deferred", + "reusePolicy": "source_hash_behavior_hash_and_dedupe_key" + }, + "inventoryPolicy": { + "total": 6900, + "legacyCompleted": 281, + "legacyPending": 6618, + "effectiveCompleted": 290, + "effectivePending": 6609, + "overlayMutation": "forbidden_during_implementation_wave" + }, + "tasks": [ + { + "id": "WBV2-P28-000", + "phase": "P28", + "title": "authorize_advanced_workbench_continuation", + "kind": "enabling", + "owner": "PROGRAM", + "dependsOn": [ + "WBV2-P27-002" + ], + "parityId": null, + "implementationClass": "SOURCE_BACKED", + "parallelGroup": "p28-000", + "gate": "G1", + "card": "docs/tasks/WBV2-P28-000.md", + "behavior": "Authorize source-backed workbench implementation for advanced capability surfaces.", + "outputs": [ + "implementation-report", + "manifest", + "status" + ], + "acceptance": [ + "real source or WebEngine Main path is wired", + "unsupported input fails closed", + "implementation smoke is reproducible", + "verification remains deferred" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": true + }, + { + "id": "WBV2-P28-001", + "phase": "P28", + "title": "implement_geometry_nodes_workbench", + "kind": "feature", + "owner": "GEOMETRY", + "dependsOn": [ + "WBV2-P28-000" + ], + "parityId": "GEOMETRY_NODES.WORKBENCH", + "implementationClass": "SOURCE_BACKED", + "parallelGroup": "p28-001", + "gate": "IMPLEMENTATION", + "card": "docs/tasks/WBV2-P28-001.md", + "behavior": "Expose validated Geometry Node graphs through the workbench and authoritative Main command path.", + "outputs": [ + "implementation-report", + "manifest", + "status" + ], + "acceptance": [ + "real source or WebEngine Main path is wired", + "unsupported input fails closed", + "implementation smoke is reproducible", + "verification remains deferred" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": false + }, + { + "id": "WBV2-P28-002", + "phase": "P28", + "title": "implement_physics_simulation_workbench", + "kind": "feature", + "owner": "SIMULATION", + "dependsOn": [ + "WBV2-P28-001" + ], + "parityId": "SIMULATION.WORKBENCH", + "implementationClass": "SOURCE_BACKED", + "parallelGroup": "p28-002", + "gate": "IMPLEMENTATION", + "card": "docs/tasks/WBV2-P28-002.md", + "behavior": "Expose validated physics manifests and system metadata through the workbench.", + "outputs": [ + "implementation-report", + "manifest", + "status" + ], + "acceptance": [ + "real source or WebEngine Main path is wired", + "unsupported input fails closed", + "implementation smoke is reproducible", + "verification remains deferred" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": false + }, + { + "id": "WBV2-P28-003", + "phase": "P28", + "title": "implement_resource_library_workbench", + "kind": "feature", + "owner": "IO", + "dependsOn": [ + "WBV2-P28-002" + ], + "parityId": "IO.RESOURCE_WORKBENCH", + "implementationClass": "SOURCE_BACKED", + "parallelGroup": "p28-003", + "gate": "IMPLEMENTATION", + "card": "docs/tasks/WBV2-P28-003.md", + "behavior": "Expose library append, packed assets and resource status through the workbench.", + "outputs": [ + "implementation-report", + "manifest", + "status" + ], + "acceptance": [ + "real source or WebEngine Main path is wired", + "unsupported input fails closed", + "implementation smoke is reproducible", + "verification remains deferred" + ], + "status": "in_progress", + "ready": true, + "queueMutationAllowed": false + }, + { + "id": "WBV2-P28-004", + "phase": "P28", + "title": "implement_render_capability_workbench", + "kind": "feature", + "owner": "RENDER", + "dependsOn": [ + "WBV2-P28-003" + ], + "parityId": "RENDER.CAPABILITY_WORKBENCH", + "implementationClass": "SOURCE_BACKED", + "parallelGroup": "p28-004", + "gate": "IMPLEMENTATION", + "card": "docs/tasks/WBV2-P28-004.md", + "behavior": "Expose shader, WebGPU, post-process and compositor capability routes.", + "outputs": [ + "implementation-report", + "manifest", + "status" + ], + "acceptance": [ + "real source or WebEngine Main path is wired", + "unsupported input fails closed", + "implementation smoke is reproducible", + "verification remains deferred" + ], + "status": "planned", + "ready": false, + "queueMutationAllowed": false + }, + { + "id": "WBV2-P28-005", + "phase": "P28", + "title": "run_workbench_implementation_smoke", + "kind": "enabling", + "owner": "RELEASE", + "dependsOn": [ + "WBV2-P28-004" + ], + "parityId": null, + "implementationClass": "SOURCE_BACKED", + "parallelGroup": "p28-005", + "gate": "IMPLEMENTATION", + "card": "docs/tasks/WBV2-P28-005.md", + "behavior": "Run the bounded build/start smoke for the advanced workbench implementation wave.", + "outputs": [ + "implementation-report", + "manifest", + "status" + ], + "acceptance": [ + "real source or WebEngine Main path is wired", + "unsupported input fails closed", + "implementation smoke is reproducible", + "verification remains deferred" + ], + "status": "planned", + "ready": false, + "queueMutationAllowed": false + } + ] +} diff --git a/tests/golden/WBV2-P28-002/implementation-report.json b/tests/golden/WBV2-P28-002/implementation-report.json new file mode 100644 index 000000000..6e8f2a325 --- /dev/null +++ b/tests/golden/WBV2-P28-002/implementation-report.json @@ -0,0 +1,38 @@ +{ + "schemaVersion": 1, + "task": "WBV2-P28-002", + "operation": "IMPLEMENT_WORKBENCH_CAPABILITY_FAMILY", + "status": "PASS", + "family": "SIMULATION.WORKBENCH", + "sourceBacked": true, + "implementation": { + "commands": [ + "setPhysicsSimulation" + ], + "marker": { + "path": "web/protocol/physics-commands.ts", + "symbol": "physicsCommands" + }, + "sourcePaths": [ + "web/protocol/physics-commands.ts", + "web/protocol/physics-simulation.ts", + "web/protocol/web-engine.ts", + "web/app/src/app/App.tsx" + ], + "duplicateShimAdded": false + }, + "verification": { + "status": "DEFERRED", + "chromium": false, + "productionReceipts": false, + "completionOverlay": false + }, + "inventory": { + "total": 6900, + "legacyCompleted": 281, + "legacyPending": 6618, + "effectiveCompleted": 290, + "effectivePending": 6609 + }, + "nextTask": "WBV2-P28-003" +} diff --git a/tests/golden/WBV2-P28-002/manifest.json b/tests/golden/WBV2-P28-002/manifest.json new file mode 100644 index 000000000..5a2456951 --- /dev/null +++ b/tests/golden/WBV2-P28-002/manifest.json @@ -0,0 +1,60 @@ +{ + "schemaVersion": 1, + "task": "WBV2-P28-002", + "parentTask": "WBV2-P28-001", + "operation": "IMPLEMENT_WORKBENCH_CAPABILITY_FAMILY", + "status": "done", + "enablingTask": false, + "parityStateChange": false, + "runtime": "SOURCE_BACKED_WORKBENCH_IMPLEMENTATION", + "artifacts": { + "parentManifest": { + "path": "tests/golden/WBV2-P28-001/manifest.json", + "sha256": "ed9fa9b3da4e7c4d01aa7e1d61342cc193419ab7fe346a3695e0b709e97389d0" + }, + "physics_commands_ts": { + "path": "web/protocol/physics-commands.ts", + "sha256": "90ea5b81800342e697a0ec2961f741780173f7e6a33aa3d7deda7aae6ecade73" + }, + "physics_simulation_ts": { + "path": "web/protocol/physics-simulation.ts", + "sha256": "b02b820503d79cd26b0323a4d2033e79d0eeb3032befd26fafe5eab55634584c" + }, + "web_engine_ts": { + "path": "web/protocol/web-engine.ts", + "sha256": "3c4aba796afb70a6b29d34cca4ba924ffb1a240549b79730d1a639ca913ee896" + }, + "App_tsx": { + "path": "web/app/src/app/App.tsx", + "sha256": "8c3ee6086716be3912a9597091642ee3416ee766a6aaedea7ca642ed7a9c3b53" + }, + "report": { + "path": "tests/golden/WBV2-P28-002/implementation-report.json", + "sha256": "97116d6fed296e64e8460f4f531404b64bbd0e4f1d1d4ef0a13a2863686f93e4" + }, + "status": { + "path": "docs/status/WBV2-P28-002.md", + "sha256": "4f8b026265b5e31dcce05fe5db3855936a2a737f71e571812c3f8831258ad28a" + }, + "plan": { + "path": "tests/golden/WBV2-P28-002/advanced-workbench-task-plan.json", + "sha256": "82e7cfe8a8c0b2f15fbf8cf3cd660006fa97b38bdcd6ee657d15e3eca134afe6" + }, + "taskContext": { + "path": "tests/golden/WBV2-P28-002/task-context.json", + "sha256": "913de6ade1df77aa0564854f2fd89fcd1d7ebcdd4ad03e53d833b400a22a7097" + } + }, + "assertions": { + "capabilityFamily": "SIMULATION.WORKBENCH", + "sourceBacked": true, + "unsupportedFailsClosed": true, + "verificationDeferred": true, + "completionOverlayWritten": false, + "inventoryTotal": 6900, + "effectiveCompleted": 290, + "effectivePending": 6609, + "historicalReproduction": false + }, + "nextTask": "WBV2-P28-003" +} diff --git a/tests/golden/WBV2-P28-002/task-context.json b/tests/golden/WBV2-P28-002/task-context.json new file mode 100644 index 000000000..ac5831dff --- /dev/null +++ b/tests/golden/WBV2-P28-002/task-context.json @@ -0,0 +1,173 @@ +{ + "schemaVersion": 1, + "task": "WBV2-P28-002", + "parentTask": "WBV2-P28-001", + "status": "in_progress", + "goal": "Expose validated physics manifests and system metadata through the workbench.", + "scope": { + "gap": "SIMULATION.WORKBENCH", + "ownerFamily": "SIMULATION", + "implementationClass": "SOURCE_BACKED" + }, + "commands": [ + "node tools/web/check-task-context.mjs --task WBV2-P28-002 --write" + ], + "inputPaths": [], + "inputSelection": { + "schemaVersion": 1, + "limits": { + "maxFiles": 12, + "evidenceBytes": 8192, + "contextRemainingBytes": 2903, + "contextRemainingTokens": 725 + }, + "source": { + "bytes": 7001, + "tokens": 1751 + }, + "selected": [], + "excluded": [ + { + "path": "web/protocol/web-engine.ts", + "bytes": 14979, + "reason": "EVIDENCE_BYTE_BUDGET" + }, + { + "path": "web/protocol/web-engine-capabilities.ts", + "bytes": 8451, + "reason": "EVIDENCE_BYTE_BUDGET" + }, + { + "path": "blender-5.2.0/source/blender/web_engine/web_engine_main_state.cpp", + "bytes": 250821, + "reason": "EVIDENCE_BYTE_BUDGET" + }, + { + "path": "tests/golden/WBV2-P28-002/", + "bytes": null, + "reason": "GENERATED_EVIDENCE_OUTPUT" + }, + { + "path": "docs/status/WBV2-P28-002.md", + "bytes": null, + "reason": "GENERATED_EVIDENCE_OUTPUT" + }, + { + "path": "tests/golden/WBV2-P28-002/manifest.json", + "bytes": null, + "reason": "GENERATED_EVIDENCE_OUTPUT" + } + ], + "totals": { + "files": 0, + "bytes": 0, + "tokens": 0 + } + }, + "exitCriteria": [ + "real source or WebEngine Main path is wired", + "unsupported input fails closed", + "implementation smoke is reproducible", + "verification remains deferred" + ], + "nextTask": "WBV2-P28-003", + "sourceDocuments": { + "queue": "docs/EXECUTION_QUEUE.md", + "taskCard": "docs/tasks/WBV2-P28-002.md", + "taskIndex": "tests/golden/WBV2/task-index.json", + "parentManifest": "tests/golden/WBV2-P28-001/manifest.json", + "parentStatus": "docs/status/WBV2-P28-001.md" + }, + "readPolicy": { + "required": [ + "docs/EXECUTION_QUEUE.md", + "docs/tasks/WBV2-P28-002.md", + "tests/golden/WBV2-P28-001/manifest.json", + "docs/status/WBV2-P28-001.md" + ], + "machineOnly": [ + "tests/golden/WBV2/task-index.json", + "tests/golden/M15-03A/task-catalog.jsonl" + ], + "optionalByNeed": [ + "docs/WEB_BLENDER_MODELER_V1_SCOPE.md", + "任务卡列出的精确协议/生产路径", + "任务卡明确命名的长期计划小节" + ], + "forbiddenByDefault": [ + "完整 CURRENT_EXECUTION_PLAN.md", + "完整 PROJECT_STATUS_AND_NEXT_WORK.md", + "全部 docs/status/*.md", + "完整 parity/WBS 计划", + "README 历史和 test-results/" + ] + }, + "parent": { + "manifest": { + "schemaVersion": 1, + "task": "WBV2-P28-001", + "parentTask": "WBV2-P28-000", + "status": "done", + "nextTask": "WBV2-P28-002", + "artifactCount": 10 + }, + "statusSummary": [ + "# WBV2-P28-001 status", + "- task: `WBV2-P28-001`; parent: `WBV2-P28-000`; status: `done`", + "- workbench capability family: `GEOMETRY_NODES.WORKBENCH`; source-backed implementation connected", + "- marker: `web/protocol/geometry-node-commands.ts#geometryNodeCommands`; no duplicate protocol shim", + "- Chromium receipts and completion overlay: `DEFERRED`", + "- inventory unchanged: `6900` total, `281` legacy completed, `6618` legacy pending, `290/6609` effective carried forward", + "- nextTask: `WBV2-P28-002`" + ] + }, + "budgets": { + "queueBytes": 4096, + "taskBytes": 1328, + "parentManifestBytes": 24576, + "parentStatusBytes": 6144, + "evidenceFiles": 12, + "evidenceBytes": 8192, + "contextTokens": 3500, + "contextEnvelopeTokens": 1024, + "taskLines": 35, + "taskTokens": 332 + }, + "size": { + "documents": [ + { + "path": "docs/EXECUTION_QUEUE.md", + "bytes": 2803, + "lines": 51, + "tokens": 701 + }, + { + "path": "docs/tasks/WBV2-P28-002.md", + "bytes": 1328, + "lines": 35, + "tokens": 332 + }, + { + "path": "tests/golden/WBV2-P28-001/manifest.json", + "bytes": 2383, + "lines": 65, + "tokens": 596 + }, + { + "path": "docs/status/WBV2-P28-001.md", + "bytes": 487, + "lines": 9, + "tokens": 122 + } + ], + "sourceTokens": 1751, + "evidenceFiles": 0, + "evidenceBytes": 0, + "evidenceTokens": 0, + "totalTokens": 1751, + "reservedEnvelopeTokens": 1024, + "estimatedContextTokens": 2775, + "serializedContextTokens": 604, + "withinBudget": true + } +} diff --git a/tests/golden/WBV2-P28-003/advanced-workbench-task-plan.json b/tests/golden/WBV2-P28-003/advanced-workbench-task-plan.json new file mode 100644 index 000000000..290c799f8 --- /dev/null +++ b/tests/golden/WBV2-P28-003/advanced-workbench-task-plan.json @@ -0,0 +1,204 @@ +{ + "schemaVersion": 1, + "planId": "BLENDER_WEB_ADVANCED_WORKBENCH_IMPLEMENTATION_P28", + "status": "ACTIVE_ADVANCED_WORKBENCH_QUEUE", + "authority": "user_authorized_implementation_first_execution", + "executionPointer": "docs/EXECUTION_QUEUE.md", + "runtimePolicy": { + "blenderSource": "blender-5.2.0", + "mainAuthority": "blender_main", + "browserPolicy": "chromium_only_for_later_verification", + "verificationPolicy": "deferred", + "reusePolicy": "source_hash_behavior_hash_and_dedupe_key" + }, + "inventoryPolicy": { + "total": 6900, + "legacyCompleted": 281, + "legacyPending": 6618, + "effectiveCompleted": 290, + "effectivePending": 6609, + "overlayMutation": "forbidden_during_implementation_wave" + }, + "tasks": [ + { + "id": "WBV2-P28-000", + "phase": "P28", + "title": "authorize_advanced_workbench_continuation", + "kind": "enabling", + "owner": "PROGRAM", + "dependsOn": [ + "WBV2-P27-002" + ], + "parityId": null, + "implementationClass": "SOURCE_BACKED", + "parallelGroup": "p28-000", + "gate": "G1", + "card": "docs/tasks/WBV2-P28-000.md", + "behavior": "Authorize source-backed workbench implementation for advanced capability surfaces.", + "outputs": [ + "implementation-report", + "manifest", + "status" + ], + "acceptance": [ + "real source or WebEngine Main path is wired", + "unsupported input fails closed", + "implementation smoke is reproducible", + "verification remains deferred" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": true + }, + { + "id": "WBV2-P28-001", + "phase": "P28", + "title": "implement_geometry_nodes_workbench", + "kind": "feature", + "owner": "GEOMETRY", + "dependsOn": [ + "WBV2-P28-000" + ], + "parityId": "GEOMETRY_NODES.WORKBENCH", + "implementationClass": "SOURCE_BACKED", + "parallelGroup": "p28-001", + "gate": "IMPLEMENTATION", + "card": "docs/tasks/WBV2-P28-001.md", + "behavior": "Expose validated Geometry Node graphs through the workbench and authoritative Main command path.", + "outputs": [ + "implementation-report", + "manifest", + "status" + ], + "acceptance": [ + "real source or WebEngine Main path is wired", + "unsupported input fails closed", + "implementation smoke is reproducible", + "verification remains deferred" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": false + }, + { + "id": "WBV2-P28-002", + "phase": "P28", + "title": "implement_physics_simulation_workbench", + "kind": "feature", + "owner": "SIMULATION", + "dependsOn": [ + "WBV2-P28-001" + ], + "parityId": "SIMULATION.WORKBENCH", + "implementationClass": "SOURCE_BACKED", + "parallelGroup": "p28-002", + "gate": "IMPLEMENTATION", + "card": "docs/tasks/WBV2-P28-002.md", + "behavior": "Expose validated physics manifests and system metadata through the workbench.", + "outputs": [ + "implementation-report", + "manifest", + "status" + ], + "acceptance": [ + "real source or WebEngine Main path is wired", + "unsupported input fails closed", + "implementation smoke is reproducible", + "verification remains deferred" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": false + }, + { + "id": "WBV2-P28-003", + "phase": "P28", + "title": "implement_resource_library_workbench", + "kind": "feature", + "owner": "IO", + "dependsOn": [ + "WBV2-P28-002" + ], + "parityId": "IO.RESOURCE_WORKBENCH", + "implementationClass": "SOURCE_BACKED", + "parallelGroup": "p28-003", + "gate": "IMPLEMENTATION", + "card": "docs/tasks/WBV2-P28-003.md", + "behavior": "Expose library append, packed assets and resource status through the workbench.", + "outputs": [ + "implementation-report", + "manifest", + "status" + ], + "acceptance": [ + "real source or WebEngine Main path is wired", + "unsupported input fails closed", + "implementation smoke is reproducible", + "verification remains deferred" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": false + }, + { + "id": "WBV2-P28-004", + "phase": "P28", + "title": "implement_render_capability_workbench", + "kind": "feature", + "owner": "RENDER", + "dependsOn": [ + "WBV2-P28-003" + ], + "parityId": "RENDER.CAPABILITY_WORKBENCH", + "implementationClass": "SOURCE_BACKED", + "parallelGroup": "p28-004", + "gate": "IMPLEMENTATION", + "card": "docs/tasks/WBV2-P28-004.md", + "behavior": "Expose shader, WebGPU, post-process and compositor capability routes.", + "outputs": [ + "implementation-report", + "manifest", + "status" + ], + "acceptance": [ + "real source or WebEngine Main path is wired", + "unsupported input fails closed", + "implementation smoke is reproducible", + "verification remains deferred" + ], + "status": "in_progress", + "ready": true, + "queueMutationAllowed": false + }, + { + "id": "WBV2-P28-005", + "phase": "P28", + "title": "run_workbench_implementation_smoke", + "kind": "enabling", + "owner": "RELEASE", + "dependsOn": [ + "WBV2-P28-004" + ], + "parityId": null, + "implementationClass": "SOURCE_BACKED", + "parallelGroup": "p28-005", + "gate": "IMPLEMENTATION", + "card": "docs/tasks/WBV2-P28-005.md", + "behavior": "Run the bounded build/start smoke for the advanced workbench implementation wave.", + "outputs": [ + "implementation-report", + "manifest", + "status" + ], + "acceptance": [ + "real source or WebEngine Main path is wired", + "unsupported input fails closed", + "implementation smoke is reproducible", + "verification remains deferred" + ], + "status": "planned", + "ready": false, + "queueMutationAllowed": false + } + ] +} diff --git a/tests/golden/WBV2-P28-003/implementation-report.json b/tests/golden/WBV2-P28-003/implementation-report.json new file mode 100644 index 000000000..705bc37a8 --- /dev/null +++ b/tests/golden/WBV2-P28-003/implementation-report.json @@ -0,0 +1,38 @@ +{ + "schemaVersion": 1, + "task": "WBV2-P28-003", + "operation": "IMPLEMENT_WORKBENCH_CAPABILITY_FAMILY", + "status": "PASS", + "family": "IO.RESOURCE_WORKBENCH", + "sourceBacked": true, + "implementation": { + "commands": [ + "requestAsset" + ], + "marker": { + "path": "web/protocol/resource-commands.ts", + "symbol": "resourceCommands" + }, + "sourcePaths": [ + "web/protocol/resource-commands.ts", + "web/protocol/web-engine.ts", + "web/app/src/engine-client/WebEngineClient.ts", + "web/app/src/app/App.tsx" + ], + "duplicateShimAdded": false + }, + "verification": { + "status": "DEFERRED", + "chromium": false, + "productionReceipts": false, + "completionOverlay": false + }, + "inventory": { + "total": 6900, + "legacyCompleted": 281, + "legacyPending": 6618, + "effectiveCompleted": 290, + "effectivePending": 6609 + }, + "nextTask": "WBV2-P28-004" +} diff --git a/tests/golden/WBV2-P28-003/manifest.json b/tests/golden/WBV2-P28-003/manifest.json new file mode 100644 index 000000000..e1a0fc864 --- /dev/null +++ b/tests/golden/WBV2-P28-003/manifest.json @@ -0,0 +1,60 @@ +{ + "schemaVersion": 1, + "task": "WBV2-P28-003", + "parentTask": "WBV2-P28-002", + "operation": "IMPLEMENT_WORKBENCH_CAPABILITY_FAMILY", + "status": "done", + "enablingTask": false, + "parityStateChange": false, + "runtime": "SOURCE_BACKED_WORKBENCH_IMPLEMENTATION", + "artifacts": { + "parentManifest": { + "path": "tests/golden/WBV2-P28-002/manifest.json", + "sha256": "6d60a4fba4c2591ceef8b65e1bbce9c5a750bd72521d3d4fa94f5529decdffd4" + }, + "resource_commands_ts": { + "path": "web/protocol/resource-commands.ts", + "sha256": "d6e4203f8ac0c537443cd317d7a70763d1c1454d376ae3081be019b40f5ed1b2" + }, + "web_engine_ts": { + "path": "web/protocol/web-engine.ts", + "sha256": "3c4aba796afb70a6b29d34cca4ba924ffb1a240549b79730d1a639ca913ee896" + }, + "WebEngineClient_ts": { + "path": "web/app/src/engine-client/WebEngineClient.ts", + "sha256": "3255cd277f1f72af998781b8f51cb236b56babe6095e5defee750d069c8bc194" + }, + "App_tsx": { + "path": "web/app/src/app/App.tsx", + "sha256": "8c3ee6086716be3912a9597091642ee3416ee766a6aaedea7ca642ed7a9c3b53" + }, + "report": { + "path": "tests/golden/WBV2-P28-003/implementation-report.json", + "sha256": "930e46aef9e6a2199b288e5f46ea468a0298d7d50718e4178da17c1f5a2d7920" + }, + "status": { + "path": "docs/status/WBV2-P28-003.md", + "sha256": "3523612d4852c7f0e5fb0b8eb773f7a10963df93ff5d8c024817d94fbb240369" + }, + "plan": { + "path": "tests/golden/WBV2-P28-003/advanced-workbench-task-plan.json", + "sha256": "96ca290fc4ba0a37b7dfbe0de32a0185d269a03c8b009efd227d4dcb800114c1" + }, + "taskContext": { + "path": "tests/golden/WBV2-P28-003/task-context.json", + "sha256": "f283d28dfefeba76f9eaa37394ea688dbbe348469ec87a85e771f7c793bb01dc" + } + }, + "assertions": { + "capabilityFamily": "IO.RESOURCE_WORKBENCH", + "sourceBacked": true, + "unsupportedFailsClosed": true, + "verificationDeferred": true, + "completionOverlayWritten": false, + "inventoryTotal": 6900, + "effectiveCompleted": 290, + "effectivePending": 6609, + "historicalReproduction": false + }, + "nextTask": "WBV2-P28-004" +} diff --git a/tests/golden/WBV2-P28-003/task-context.json b/tests/golden/WBV2-P28-003/task-context.json new file mode 100644 index 000000000..53e708445 --- /dev/null +++ b/tests/golden/WBV2-P28-003/task-context.json @@ -0,0 +1,173 @@ +{ + "schemaVersion": 1, + "task": "WBV2-P28-003", + "parentTask": "WBV2-P28-002", + "status": "in_progress", + "goal": "Expose library append, packed assets and resource status through the workbench.", + "scope": { + "gap": "IO.RESOURCE_WORKBENCH", + "ownerFamily": "IO", + "implementationClass": "SOURCE_BACKED" + }, + "commands": [ + "node tools/web/check-task-context.mjs --task WBV2-P28-003 --write" + ], + "inputPaths": [], + "inputSelection": { + "schemaVersion": 1, + "limits": { + "maxFiles": 12, + "evidenceBytes": 8192, + "contextRemainingBytes": 3159, + "contextRemainingTokens": 788 + }, + "source": { + "bytes": 6745, + "tokens": 1688 + }, + "selected": [], + "excluded": [ + { + "path": "web/protocol/web-engine.ts", + "bytes": 14979, + "reason": "EVIDENCE_BYTE_BUDGET" + }, + { + "path": "web/protocol/web-engine-capabilities.ts", + "bytes": 8451, + "reason": "EVIDENCE_BYTE_BUDGET" + }, + { + "path": "blender-5.2.0/source/blender/web_engine/web_engine_main_state.cpp", + "bytes": 250821, + "reason": "EVIDENCE_BYTE_BUDGET" + }, + { + "path": "tests/golden/WBV2-P28-003/", + "bytes": null, + "reason": "GENERATED_EVIDENCE_OUTPUT" + }, + { + "path": "docs/status/WBV2-P28-003.md", + "bytes": null, + "reason": "GENERATED_EVIDENCE_OUTPUT" + }, + { + "path": "tests/golden/WBV2-P28-003/manifest.json", + "bytes": null, + "reason": "GENERATED_EVIDENCE_OUTPUT" + } + ], + "totals": { + "files": 0, + "bytes": 0, + "tokens": 0 + } + }, + "exitCriteria": [ + "real source or WebEngine Main path is wired", + "unsupported input fails closed", + "implementation smoke is reproducible", + "verification remains deferred" + ], + "nextTask": "WBV2-P28-004", + "sourceDocuments": { + "queue": "docs/EXECUTION_QUEUE.md", + "taskCard": "docs/tasks/WBV2-P28-003.md", + "taskIndex": "tests/golden/WBV2/task-index.json", + "parentManifest": "tests/golden/WBV2-P28-002/manifest.json", + "parentStatus": "docs/status/WBV2-P28-002.md" + }, + "readPolicy": { + "required": [ + "docs/EXECUTION_QUEUE.md", + "docs/tasks/WBV2-P28-003.md", + "tests/golden/WBV2-P28-002/manifest.json", + "docs/status/WBV2-P28-002.md" + ], + "machineOnly": [ + "tests/golden/WBV2/task-index.json", + "tests/golden/M15-03A/task-catalog.jsonl" + ], + "optionalByNeed": [ + "docs/WEB_BLENDER_MODELER_V1_SCOPE.md", + "任务卡列出的精确协议/生产路径", + "任务卡明确命名的长期计划小节" + ], + "forbiddenByDefault": [ + "完整 CURRENT_EXECUTION_PLAN.md", + "完整 PROJECT_STATUS_AND_NEXT_WORK.md", + "全部 docs/status/*.md", + "完整 parity/WBS 计划", + "README 历史和 test-results/" + ] + }, + "parent": { + "manifest": { + "schemaVersion": 1, + "task": "WBV2-P28-002", + "parentTask": "WBV2-P28-001", + "status": "done", + "nextTask": "WBV2-P28-003", + "artifactCount": 9 + }, + "statusSummary": [ + "# WBV2-P28-002 status", + "- task: `WBV2-P28-002`; parent: `WBV2-P28-001`; status: `done`", + "- workbench capability family: `SIMULATION.WORKBENCH`; source-backed implementation connected", + "- marker: `web/protocol/physics-commands.ts#physicsCommands`; no duplicate protocol shim", + "- Chromium receipts and completion overlay: `DEFERRED`", + "- inventory unchanged: `6900` total, `281` legacy completed, `6618` legacy pending, `290/6609` effective carried forward", + "- nextTask: `WBV2-P28-003`" + ] + }, + "budgets": { + "queueBytes": 4096, + "taskBytes": 1321, + "parentManifestBytes": 24576, + "parentStatusBytes": 6144, + "evidenceFiles": 12, + "evidenceBytes": 8192, + "contextTokens": 3500, + "contextEnvelopeTokens": 1024, + "taskLines": 35, + "taskTokens": 331 + }, + "size": { + "documents": [ + { + "path": "docs/EXECUTION_QUEUE.md", + "bytes": 2803, + "lines": 51, + "tokens": 701 + }, + { + "path": "docs/tasks/WBV2-P28-003.md", + "bytes": 1321, + "lines": 35, + "tokens": 331 + }, + { + "path": "tests/golden/WBV2-P28-002/manifest.json", + "bytes": 2149, + "lines": 61, + "tokens": 538 + }, + { + "path": "docs/status/WBV2-P28-002.md", + "bytes": 472, + "lines": 9, + "tokens": 118 + } + ], + "sourceTokens": 1688, + "evidenceFiles": 0, + "evidenceBytes": 0, + "evidenceTokens": 0, + "totalTokens": 1688, + "reservedEnvelopeTokens": 1024, + "estimatedContextTokens": 2712, + "serializedContextTokens": 603, + "withinBudget": true + } +} diff --git a/tests/golden/WBV2-P28-004/advanced-workbench-task-plan.json b/tests/golden/WBV2-P28-004/advanced-workbench-task-plan.json new file mode 100644 index 000000000..1249de205 --- /dev/null +++ b/tests/golden/WBV2-P28-004/advanced-workbench-task-plan.json @@ -0,0 +1,204 @@ +{ + "schemaVersion": 1, + "planId": "BLENDER_WEB_ADVANCED_WORKBENCH_IMPLEMENTATION_P28", + "status": "ACTIVE_ADVANCED_WORKBENCH_QUEUE", + "authority": "user_authorized_implementation_first_execution", + "executionPointer": "docs/EXECUTION_QUEUE.md", + "runtimePolicy": { + "blenderSource": "blender-5.2.0", + "mainAuthority": "blender_main", + "browserPolicy": "chromium_only_for_later_verification", + "verificationPolicy": "deferred", + "reusePolicy": "source_hash_behavior_hash_and_dedupe_key" + }, + "inventoryPolicy": { + "total": 6900, + "legacyCompleted": 281, + "legacyPending": 6618, + "effectiveCompleted": 290, + "effectivePending": 6609, + "overlayMutation": "forbidden_during_implementation_wave" + }, + "tasks": [ + { + "id": "WBV2-P28-000", + "phase": "P28", + "title": "authorize_advanced_workbench_continuation", + "kind": "enabling", + "owner": "PROGRAM", + "dependsOn": [ + "WBV2-P27-002" + ], + "parityId": null, + "implementationClass": "SOURCE_BACKED", + "parallelGroup": "p28-000", + "gate": "G1", + "card": "docs/tasks/WBV2-P28-000.md", + "behavior": "Authorize source-backed workbench implementation for advanced capability surfaces.", + "outputs": [ + "implementation-report", + "manifest", + "status" + ], + "acceptance": [ + "real source or WebEngine Main path is wired", + "unsupported input fails closed", + "implementation smoke is reproducible", + "verification remains deferred" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": true + }, + { + "id": "WBV2-P28-001", + "phase": "P28", + "title": "implement_geometry_nodes_workbench", + "kind": "feature", + "owner": "GEOMETRY", + "dependsOn": [ + "WBV2-P28-000" + ], + "parityId": "GEOMETRY_NODES.WORKBENCH", + "implementationClass": "SOURCE_BACKED", + "parallelGroup": "p28-001", + "gate": "IMPLEMENTATION", + "card": "docs/tasks/WBV2-P28-001.md", + "behavior": "Expose validated Geometry Node graphs through the workbench and authoritative Main command path.", + "outputs": [ + "implementation-report", + "manifest", + "status" + ], + "acceptance": [ + "real source or WebEngine Main path is wired", + "unsupported input fails closed", + "implementation smoke is reproducible", + "verification remains deferred" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": false + }, + { + "id": "WBV2-P28-002", + "phase": "P28", + "title": "implement_physics_simulation_workbench", + "kind": "feature", + "owner": "SIMULATION", + "dependsOn": [ + "WBV2-P28-001" + ], + "parityId": "SIMULATION.WORKBENCH", + "implementationClass": "SOURCE_BACKED", + "parallelGroup": "p28-002", + "gate": "IMPLEMENTATION", + "card": "docs/tasks/WBV2-P28-002.md", + "behavior": "Expose validated physics manifests and system metadata through the workbench.", + "outputs": [ + "implementation-report", + "manifest", + "status" + ], + "acceptance": [ + "real source or WebEngine Main path is wired", + "unsupported input fails closed", + "implementation smoke is reproducible", + "verification remains deferred" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": false + }, + { + "id": "WBV2-P28-003", + "phase": "P28", + "title": "implement_resource_library_workbench", + "kind": "feature", + "owner": "IO", + "dependsOn": [ + "WBV2-P28-002" + ], + "parityId": "IO.RESOURCE_WORKBENCH", + "implementationClass": "SOURCE_BACKED", + "parallelGroup": "p28-003", + "gate": "IMPLEMENTATION", + "card": "docs/tasks/WBV2-P28-003.md", + "behavior": "Expose library append, packed assets and resource status through the workbench.", + "outputs": [ + "implementation-report", + "manifest", + "status" + ], + "acceptance": [ + "real source or WebEngine Main path is wired", + "unsupported input fails closed", + "implementation smoke is reproducible", + "verification remains deferred" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": false + }, + { + "id": "WBV2-P28-004", + "phase": "P28", + "title": "implement_render_capability_workbench", + "kind": "feature", + "owner": "RENDER", + "dependsOn": [ + "WBV2-P28-003" + ], + "parityId": "RENDER.CAPABILITY_WORKBENCH", + "implementationClass": "SOURCE_BACKED", + "parallelGroup": "p28-004", + "gate": "IMPLEMENTATION", + "card": "docs/tasks/WBV2-P28-004.md", + "behavior": "Expose shader, WebGPU, post-process and compositor capability routes.", + "outputs": [ + "implementation-report", + "manifest", + "status" + ], + "acceptance": [ + "real source or WebEngine Main path is wired", + "unsupported input fails closed", + "implementation smoke is reproducible", + "verification remains deferred" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": false + }, + { + "id": "WBV2-P28-005", + "phase": "P28", + "title": "run_workbench_implementation_smoke", + "kind": "enabling", + "owner": "RELEASE", + "dependsOn": [ + "WBV2-P28-004" + ], + "parityId": null, + "implementationClass": "SOURCE_BACKED", + "parallelGroup": "p28-005", + "gate": "IMPLEMENTATION", + "card": "docs/tasks/WBV2-P28-005.md", + "behavior": "Run the bounded build/start smoke for the advanced workbench implementation wave.", + "outputs": [ + "implementation-report", + "manifest", + "status" + ], + "acceptance": [ + "real source or WebEngine Main path is wired", + "unsupported input fails closed", + "implementation smoke is reproducible", + "verification remains deferred" + ], + "status": "in_progress", + "ready": true, + "queueMutationAllowed": false + } + ] +} diff --git a/tests/golden/WBV2-P28-004/implementation-report.json b/tests/golden/WBV2-P28-004/implementation-report.json new file mode 100644 index 000000000..35be1dd49 --- /dev/null +++ b/tests/golden/WBV2-P28-004/implementation-report.json @@ -0,0 +1,35 @@ +{ + "schemaVersion": 1, + "task": "WBV2-P28-004", + "operation": "IMPLEMENT_WORKBENCH_CAPABILITY_FAMILY", + "status": "PASS", + "family": "RENDER.CAPABILITY_WORKBENCH", + "sourceBacked": true, + "implementation": { + "commands": [], + "marker": { + "path": "web/protocol/render-compositor-commands.ts", + "symbol": "renderCompositorCommands" + }, + "sourcePaths": [ + "web/protocol/render-compositor-commands.ts", + "web/protocol/render-capabilities.ts", + "web/app/src/app/App.tsx" + ], + "duplicateShimAdded": false + }, + "verification": { + "status": "DEFERRED", + "chromium": false, + "productionReceipts": false, + "completionOverlay": false + }, + "inventory": { + "total": 6900, + "legacyCompleted": 281, + "legacyPending": 6618, + "effectiveCompleted": 290, + "effectivePending": 6609 + }, + "nextTask": "WBV2-P28-005" +} diff --git a/tests/golden/WBV2-P28-004/manifest.json b/tests/golden/WBV2-P28-004/manifest.json new file mode 100644 index 000000000..e0a8ef666 --- /dev/null +++ b/tests/golden/WBV2-P28-004/manifest.json @@ -0,0 +1,56 @@ +{ + "schemaVersion": 1, + "task": "WBV2-P28-004", + "parentTask": "WBV2-P28-003", + "operation": "IMPLEMENT_WORKBENCH_CAPABILITY_FAMILY", + "status": "done", + "enablingTask": false, + "parityStateChange": false, + "runtime": "SOURCE_BACKED_WORKBENCH_IMPLEMENTATION", + "artifacts": { + "parentManifest": { + "path": "tests/golden/WBV2-P28-003/manifest.json", + "sha256": "e68061f7c766f2ddf104b741a5ca8289544ec0eb9e2fa01d9bc32f440cfc3dc6" + }, + "render_compositor_commands_ts": { + "path": "web/protocol/render-compositor-commands.ts", + "sha256": "54cf21616a4260266924b3fdfb95918b6281aceafaf8905a3a8f4e1df9de513a" + }, + "render_capabilities_ts": { + "path": "web/protocol/render-capabilities.ts", + "sha256": "322929e9c7b627a9e79b8a6f11d5e9b0c7c05a5754f82d41c45c1134bbaaf385" + }, + "App_tsx": { + "path": "web/app/src/app/App.tsx", + "sha256": "8c3ee6086716be3912a9597091642ee3416ee766a6aaedea7ca642ed7a9c3b53" + }, + "report": { + "path": "tests/golden/WBV2-P28-004/implementation-report.json", + "sha256": "ff97c85d3af05ad406bc088852e9de09a461d7e41baca0dbe72de467066901e3" + }, + "status": { + "path": "docs/status/WBV2-P28-004.md", + "sha256": "bdc14994b691c12de2f3d0567f657f4d8b6e0d37e96a5ddba14b6a3f8461f462" + }, + "plan": { + "path": "tests/golden/WBV2-P28-004/advanced-workbench-task-plan.json", + "sha256": "f0f8b80a3a0d8cf36fc2b4ada0d2a5305ba2cc60adf66f3d1043f481cbe363ab" + }, + "taskContext": { + "path": "tests/golden/WBV2-P28-004/task-context.json", + "sha256": "a839181ddd8415503ac233b6417f38296e219be2105c189737d3285ff1d9e630" + } + }, + "assertions": { + "capabilityFamily": "RENDER.CAPABILITY_WORKBENCH", + "sourceBacked": true, + "unsupportedFailsClosed": true, + "verificationDeferred": true, + "completionOverlayWritten": false, + "inventoryTotal": 6900, + "effectiveCompleted": 290, + "effectivePending": 6609, + "historicalReproduction": false + }, + "nextTask": "WBV2-P28-005" +} diff --git a/tests/golden/WBV2-P28-004/task-context.json b/tests/golden/WBV2-P28-004/task-context.json new file mode 100644 index 000000000..0571457e3 --- /dev/null +++ b/tests/golden/WBV2-P28-004/task-context.json @@ -0,0 +1,173 @@ +{ + "schemaVersion": 1, + "task": "WBV2-P28-004", + "parentTask": "WBV2-P28-003", + "status": "in_progress", + "goal": "Expose shader, WebGPU, post-process and compositor capability routes.", + "scope": { + "gap": "RENDER.CAPABILITY_WORKBENCH", + "ownerFamily": "RENDER", + "implementationClass": "SOURCE_BACKED" + }, + "commands": [ + "node tools/web/check-task-context.mjs --task WBV2-P28-004 --write" + ], + "inputPaths": [], + "inputSelection": { + "schemaVersion": 1, + "limits": { + "maxFiles": 12, + "evidenceBytes": 8192, + "contextRemainingBytes": 3145, + "contextRemainingTokens": 785 + }, + "source": { + "bytes": 6759, + "tokens": 1691 + }, + "selected": [], + "excluded": [ + { + "path": "web/protocol/web-engine.ts", + "bytes": 14979, + "reason": "EVIDENCE_BYTE_BUDGET" + }, + { + "path": "web/protocol/web-engine-capabilities.ts", + "bytes": 8451, + "reason": "EVIDENCE_BYTE_BUDGET" + }, + { + "path": "blender-5.2.0/source/blender/web_engine/web_engine_main_state.cpp", + "bytes": 250821, + "reason": "EVIDENCE_BYTE_BUDGET" + }, + { + "path": "tests/golden/WBV2-P28-004/", + "bytes": null, + "reason": "GENERATED_EVIDENCE_OUTPUT" + }, + { + "path": "docs/status/WBV2-P28-004.md", + "bytes": null, + "reason": "GENERATED_EVIDENCE_OUTPUT" + }, + { + "path": "tests/golden/WBV2-P28-004/manifest.json", + "bytes": null, + "reason": "GENERATED_EVIDENCE_OUTPUT" + } + ], + "totals": { + "files": 0, + "bytes": 0, + "tokens": 0 + } + }, + "exitCriteria": [ + "real source or WebEngine Main path is wired", + "unsupported input fails closed", + "implementation smoke is reproducible", + "verification remains deferred" + ], + "nextTask": "WBV2-P28-005", + "sourceDocuments": { + "queue": "docs/EXECUTION_QUEUE.md", + "taskCard": "docs/tasks/WBV2-P28-004.md", + "taskIndex": "tests/golden/WBV2/task-index.json", + "parentManifest": "tests/golden/WBV2-P28-003/manifest.json", + "parentStatus": "docs/status/WBV2-P28-003.md" + }, + "readPolicy": { + "required": [ + "docs/EXECUTION_QUEUE.md", + "docs/tasks/WBV2-P28-004.md", + "tests/golden/WBV2-P28-003/manifest.json", + "docs/status/WBV2-P28-003.md" + ], + "machineOnly": [ + "tests/golden/WBV2/task-index.json", + "tests/golden/M15-03A/task-catalog.jsonl" + ], + "optionalByNeed": [ + "docs/WEB_BLENDER_MODELER_V1_SCOPE.md", + "任务卡列出的精确协议/生产路径", + "任务卡明确命名的长期计划小节" + ], + "forbiddenByDefault": [ + "完整 CURRENT_EXECUTION_PLAN.md", + "完整 PROJECT_STATUS_AND_NEXT_WORK.md", + "全部 docs/status/*.md", + "完整 parity/WBS 计划", + "README 历史和 test-results/" + ] + }, + "parent": { + "manifest": { + "schemaVersion": 1, + "task": "WBV2-P28-003", + "parentTask": "WBV2-P28-002", + "status": "done", + "nextTask": "WBV2-P28-004", + "artifactCount": 9 + }, + "statusSummary": [ + "# WBV2-P28-003 status", + "- task: `WBV2-P28-003`; parent: `WBV2-P28-002`; status: `done`", + "- workbench capability family: `IO.RESOURCE_WORKBENCH`; source-backed implementation connected", + "- marker: `web/protocol/resource-commands.ts#resourceCommands`; no duplicate protocol shim", + "- Chromium receipts and completion overlay: `DEFERRED`", + "- inventory unchanged: `6900` total, `281` legacy completed, `6618` legacy pending, `290/6609` effective carried forward", + "- nextTask: `WBV2-P28-004`" + ] + }, + "budgets": { + "queueBytes": 4096, + "taskBytes": 1322, + "parentManifestBytes": 24576, + "parentStatusBytes": 6144, + "evidenceFiles": 12, + "evidenceBytes": 8192, + "contextTokens": 3500, + "contextEnvelopeTokens": 1024, + "taskLines": 35, + "taskTokens": 331 + }, + "size": { + "documents": [ + { + "path": "docs/EXECUTION_QUEUE.md", + "bytes": 2803, + "lines": 51, + "tokens": 701 + }, + { + "path": "docs/tasks/WBV2-P28-004.md", + "bytes": 1322, + "lines": 35, + "tokens": 331 + }, + { + "path": "tests/golden/WBV2-P28-003/manifest.json", + "bytes": 2159, + "lines": 61, + "tokens": 540 + }, + { + "path": "docs/status/WBV2-P28-003.md", + "bytes": 475, + "lines": 9, + "tokens": 119 + } + ], + "sourceTokens": 1691, + "evidenceFiles": 0, + "evidenceBytes": 0, + "evidenceTokens": 0, + "totalTokens": 1691, + "reservedEnvelopeTokens": 1024, + "estimatedContextTokens": 2715, + "serializedContextTokens": 603, + "withinBudget": true + } +} diff --git a/tests/golden/WBV2-P28-005/advanced-workbench-task-plan.json b/tests/golden/WBV2-P28-005/advanced-workbench-task-plan.json new file mode 100644 index 000000000..d22a28cd3 --- /dev/null +++ b/tests/golden/WBV2-P28-005/advanced-workbench-task-plan.json @@ -0,0 +1,204 @@ +{ + "schemaVersion": 1, + "planId": "BLENDER_WEB_ADVANCED_WORKBENCH_IMPLEMENTATION_P28", + "status": "ACTIVE_ADVANCED_WORKBENCH_QUEUE", + "authority": "user_authorized_implementation_first_execution", + "executionPointer": "docs/EXECUTION_QUEUE.md", + "runtimePolicy": { + "blenderSource": "blender-5.2.0", + "mainAuthority": "blender_main", + "browserPolicy": "chromium_only_for_later_verification", + "verificationPolicy": "deferred", + "reusePolicy": "source_hash_behavior_hash_and_dedupe_key" + }, + "inventoryPolicy": { + "total": 6900, + "legacyCompleted": 281, + "legacyPending": 6618, + "effectiveCompleted": 290, + "effectivePending": 6609, + "overlayMutation": "forbidden_during_implementation_wave" + }, + "tasks": [ + { + "id": "WBV2-P28-000", + "phase": "P28", + "title": "authorize_advanced_workbench_continuation", + "kind": "enabling", + "owner": "PROGRAM", + "dependsOn": [ + "WBV2-P27-002" + ], + "parityId": null, + "implementationClass": "SOURCE_BACKED", + "parallelGroup": "p28-000", + "gate": "G1", + "card": "docs/tasks/WBV2-P28-000.md", + "behavior": "Authorize source-backed workbench implementation for advanced capability surfaces.", + "outputs": [ + "implementation-report", + "manifest", + "status" + ], + "acceptance": [ + "real source or WebEngine Main path is wired", + "unsupported input fails closed", + "implementation smoke is reproducible", + "verification remains deferred" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": true + }, + { + "id": "WBV2-P28-001", + "phase": "P28", + "title": "implement_geometry_nodes_workbench", + "kind": "feature", + "owner": "GEOMETRY", + "dependsOn": [ + "WBV2-P28-000" + ], + "parityId": "GEOMETRY_NODES.WORKBENCH", + "implementationClass": "SOURCE_BACKED", + "parallelGroup": "p28-001", + "gate": "IMPLEMENTATION", + "card": "docs/tasks/WBV2-P28-001.md", + "behavior": "Expose validated Geometry Node graphs through the workbench and authoritative Main command path.", + "outputs": [ + "implementation-report", + "manifest", + "status" + ], + "acceptance": [ + "real source or WebEngine Main path is wired", + "unsupported input fails closed", + "implementation smoke is reproducible", + "verification remains deferred" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": false + }, + { + "id": "WBV2-P28-002", + "phase": "P28", + "title": "implement_physics_simulation_workbench", + "kind": "feature", + "owner": "SIMULATION", + "dependsOn": [ + "WBV2-P28-001" + ], + "parityId": "SIMULATION.WORKBENCH", + "implementationClass": "SOURCE_BACKED", + "parallelGroup": "p28-002", + "gate": "IMPLEMENTATION", + "card": "docs/tasks/WBV2-P28-002.md", + "behavior": "Expose validated physics manifests and system metadata through the workbench.", + "outputs": [ + "implementation-report", + "manifest", + "status" + ], + "acceptance": [ + "real source or WebEngine Main path is wired", + "unsupported input fails closed", + "implementation smoke is reproducible", + "verification remains deferred" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": false + }, + { + "id": "WBV2-P28-003", + "phase": "P28", + "title": "implement_resource_library_workbench", + "kind": "feature", + "owner": "IO", + "dependsOn": [ + "WBV2-P28-002" + ], + "parityId": "IO.RESOURCE_WORKBENCH", + "implementationClass": "SOURCE_BACKED", + "parallelGroup": "p28-003", + "gate": "IMPLEMENTATION", + "card": "docs/tasks/WBV2-P28-003.md", + "behavior": "Expose library append, packed assets and resource status through the workbench.", + "outputs": [ + "implementation-report", + "manifest", + "status" + ], + "acceptance": [ + "real source or WebEngine Main path is wired", + "unsupported input fails closed", + "implementation smoke is reproducible", + "verification remains deferred" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": false + }, + { + "id": "WBV2-P28-004", + "phase": "P28", + "title": "implement_render_capability_workbench", + "kind": "feature", + "owner": "RENDER", + "dependsOn": [ + "WBV2-P28-003" + ], + "parityId": "RENDER.CAPABILITY_WORKBENCH", + "implementationClass": "SOURCE_BACKED", + "parallelGroup": "p28-004", + "gate": "IMPLEMENTATION", + "card": "docs/tasks/WBV2-P28-004.md", + "behavior": "Expose shader, WebGPU, post-process and compositor capability routes.", + "outputs": [ + "implementation-report", + "manifest", + "status" + ], + "acceptance": [ + "real source or WebEngine Main path is wired", + "unsupported input fails closed", + "implementation smoke is reproducible", + "verification remains deferred" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": false + }, + { + "id": "WBV2-P28-005", + "phase": "P28", + "title": "run_workbench_implementation_smoke", + "kind": "enabling", + "owner": "RELEASE", + "dependsOn": [ + "WBV2-P28-004" + ], + "parityId": null, + "implementationClass": "SOURCE_BACKED", + "parallelGroup": "p28-005", + "gate": "IMPLEMENTATION", + "card": "docs/tasks/WBV2-P28-005.md", + "behavior": "Run the bounded build/start smoke for the advanced workbench implementation wave.", + "outputs": [ + "implementation-report", + "manifest", + "status" + ], + "acceptance": [ + "real source or WebEngine Main path is wired", + "unsupported input fails closed", + "implementation smoke is reproducible", + "verification remains deferred" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": false + } + ] +} diff --git a/tests/golden/WBV2-P28-005/implementation-smoke-report.json b/tests/golden/WBV2-P28-005/implementation-smoke-report.json new file mode 100644 index 000000000..1838034df --- /dev/null +++ b/tests/golden/WBV2-P28-005/implementation-smoke-report.json @@ -0,0 +1,35 @@ +{ + "schemaVersion": 1, + "task": "WBV2-P28-005", + "operation": "RUN_WORKBENCH_IMPLEMENTATION_SMOKE", + "status": "PASS", + "build": { + "command": "npm --prefix web run build", + "exitCode": 0, + "index": "web/dist/index.html", + "worker": "web/dist/assets/web-engine.worker-Bm3nUTqn.js", + "wasm": "web/dist/assets/web_engine-CDU-hUyU.wasm" + }, + "implementation": { + "workbenchFamilies": [ + "GEOMETRY_NODES", + "SIMULATION", + "IO_RESOURCE", + "RENDER_CAPABILITY" + ], + "sourceBacked": true + }, + "verification": { + "status": "DEFERRED", + "chromium": false, + "completionOverlay": false + }, + "inventory": { + "total": 6900, + "legacyCompleted": 281, + "legacyPending": 6618, + "effectiveCompleted": 290, + "effectivePending": 6609 + }, + "nextTask": "WBV2-P29-000" +} diff --git a/tests/golden/WBV2-P28-005/manifest.json b/tests/golden/WBV2-P28-005/manifest.json new file mode 100644 index 000000000..f62dbb421 --- /dev/null +++ b/tests/golden/WBV2-P28-005/manifest.json @@ -0,0 +1,51 @@ +{ + "schemaVersion": 1, + "task": "WBV2-P28-005", + "parentTask": "WBV2-P28-004", + "operation": "RUN_WORKBENCH_IMPLEMENTATION_SMOKE", + "status": "done", + "enablingTask": true, + "parityStateChange": false, + "runtime": "VITE_BUILD_AND_SOURCE_WASM_SMOKE", + "artifacts": { + "parentManifest": { + "path": "tests/golden/WBV2-P28-004/manifest.json", + "sha256": "c110429db8e6cd364ec7910b2b3c23ed6c49b934d70486511ed289197a83cb53" + }, + "report": { + "path": "tests/golden/WBV2-P28-005/implementation-smoke-report.json", + "sha256": "b4f16efe07f22802ca9ef1ff236009c3cc06ecd3e928a835c10378397ade9422" + }, + "status": { + "path": "docs/status/WBV2-P28-005.md", + "sha256": "7d06f2182f6d697acb7f7c298d14a846e1ef8cb51fd9ce8d964ccb638e5125d1" + }, + "plan": { + "path": "tests/golden/WBV2-P28-005/advanced-workbench-task-plan.json", + "sha256": "f313e950d00472b4b78ab982941b3545566cb681657650d41e14de2cb4479cde" + }, + "index": { + "path": "web/dist/index.html", + "sha256": "456f1171b36fc9cea608ea6e74a11570f855b0f26a646350d5ac458a4e918fe9" + }, + "worker": { + "path": "web/dist/assets/web-engine.worker-Bm3nUTqn.js", + "sha256": "de3fcef592876e81b572dcc9e3d2118f4089e6170939310974d64866f493490b" + }, + "wasm": { + "path": "web/dist/assets/web_engine-CDU-hUyU.wasm", + "sha256": "08a5caccd99f9d51221d0a0adea3db1a57ab5d2718b6b026dc7f4af096054d07" + } + }, + "assertions": { + "buildExitCode": 0, + "sourceBackedImplementation": true, + "verificationDeferred": true, + "completionOverlayWritten": false, + "inventoryTotal": 6900, + "effectiveCompleted": 290, + "effectivePending": 6609, + "historicalReproduction": false + }, + "nextTask": "WBV2-P29-000" +} diff --git a/tests/golden/WBV2-P28-005/task-context.json b/tests/golden/WBV2-P28-005/task-context.json new file mode 100644 index 000000000..5702f077b --- /dev/null +++ b/tests/golden/WBV2-P28-005/task-context.json @@ -0,0 +1,172 @@ +{ + "schemaVersion": 1, + "task": "WBV2-P28-005", + "parentTask": "WBV2-P28-004", + "status": "in_progress", + "goal": "Run the bounded build/start smoke for the advanced workbench implementation wave.", + "scope": { + "gap": "workflow:run_workbench_implementation_smoke", + "ownerFamily": "RELEASE", + "implementationClass": "SOURCE_BACKED" + }, + "commands": [ + "node tools/web/check-task-context.mjs --task WBV2-P28-005 --write" + ], + "inputPaths": [], + "inputSelection": { + "schemaVersion": 1, + "limits": { + "maxFiles": 12, + "evidenceBytes": 8192, + "contextRemainingBytes": 3234, + "contextRemainingTokens": 807 + }, + "source": { + "bytes": 6670, + "tokens": 1669 + }, + "selected": [], + "excluded": [ + { + "path": "web/protocol/web-engine.ts", + "bytes": 14979, + "reason": "EVIDENCE_BYTE_BUDGET" + }, + { + "path": "web/protocol/web-engine-capabilities.ts", + "bytes": 8451, + "reason": "EVIDENCE_BYTE_BUDGET" + }, + { + "path": "blender-5.2.0/source/blender/web_engine/web_engine_main_state.cpp", + "bytes": 250821, + "reason": "EVIDENCE_BYTE_BUDGET" + }, + { + "path": "tests/golden/WBV2-P28-005/", + "bytes": null, + "reason": "GENERATED_EVIDENCE_OUTPUT" + }, + { + "path": "docs/status/WBV2-P28-005.md", + "bytes": null, + "reason": "GENERATED_EVIDENCE_OUTPUT" + }, + { + "path": "tests/golden/WBV2-P28-005/manifest.json", + "bytes": null, + "reason": "GENERATED_EVIDENCE_OUTPUT" + } + ], + "totals": { + "files": 0, + "bytes": 0, + "tokens": 0 + } + }, + "exitCriteria": [ + "focused command exits 0", + "report and manifest are hash-bound", + "failure path does not publish a late result" + ], + "nextTask": "WBV2-P29-000", + "sourceDocuments": { + "queue": "docs/EXECUTION_QUEUE.md", + "taskCard": "docs/tasks/WBV2-P28-005.md", + "taskIndex": "tests/golden/WBV2/task-index.json", + "parentManifest": "tests/golden/WBV2-P28-004/manifest.json", + "parentStatus": "docs/status/WBV2-P28-004.md" + }, + "readPolicy": { + "required": [ + "docs/EXECUTION_QUEUE.md", + "docs/tasks/WBV2-P28-005.md", + "tests/golden/WBV2-P28-004/manifest.json", + "docs/status/WBV2-P28-004.md" + ], + "machineOnly": [ + "tests/golden/WBV2/task-index.json", + "tests/golden/M15-03A/task-catalog.jsonl" + ], + "optionalByNeed": [ + "docs/WEB_BLENDER_MODELER_V1_SCOPE.md", + "任务卡列出的精确协议/生产路径", + "任务卡明确命名的长期计划小节" + ], + "forbiddenByDefault": [ + "完整 CURRENT_EXECUTION_PLAN.md", + "完整 PROJECT_STATUS_AND_NEXT_WORK.md", + "全部 docs/status/*.md", + "完整 parity/WBS 计划", + "README 历史和 test-results/" + ] + }, + "parent": { + "manifest": { + "schemaVersion": 1, + "task": "WBV2-P28-004", + "parentTask": "WBV2-P28-003", + "status": "done", + "nextTask": "WBV2-P28-005", + "artifactCount": 8 + }, + "statusSummary": [ + "# WBV2-P28-004 status", + "- task: `WBV2-P28-004`; parent: `WBV2-P28-003`; status: `done`", + "- workbench capability family: `RENDER.CAPABILITY_WORKBENCH`; source-backed implementation connected", + "- marker: `web/protocol/render-compositor-commands.ts#renderCompositorCommands`; no duplicate protocol shim", + "- Chromium receipts and completion overlay: `DEFERRED`", + "- inventory unchanged: `6900` total, `281` legacy completed, `6618` legacy pending, `290/6609` effective carried forward", + "- nextTask: `WBV2-P28-005`" + ] + }, + "budgets": { + "queueBytes": 4096, + "taskBytes": 1348, + "parentManifestBytes": 24576, + "parentStatusBytes": 6144, + "evidenceFiles": 12, + "evidenceBytes": 8192, + "contextTokens": 3500, + "contextEnvelopeTokens": 1024, + "taskLines": 35, + "taskTokens": 337 + }, + "size": { + "documents": [ + { + "path": "docs/EXECUTION_QUEUE.md", + "bytes": 2803, + "lines": 51, + "tokens": 701 + }, + { + "path": "docs/tasks/WBV2-P28-005.md", + "bytes": 1348, + "lines": 35, + "tokens": 337 + }, + { + "path": "tests/golden/WBV2-P28-004/manifest.json", + "bytes": 2021, + "lines": 57, + "tokens": 506 + }, + { + "path": "docs/status/WBV2-P28-004.md", + "bytes": 498, + "lines": 9, + "tokens": 125 + } + ], + "sourceTokens": 1669, + "evidenceFiles": 0, + "evidenceBytes": 0, + "evidenceTokens": 0, + "totalTokens": 1669, + "reservedEnvelopeTokens": 1024, + "estimatedContextTokens": 2693, + "serializedContextTokens": 599, + "withinBudget": true + } +} diff --git a/tests/golden/WBV2-P29-000/manifest.json b/tests/golden/WBV2-P29-000/manifest.json new file mode 100644 index 000000000..34b184cf2 --- /dev/null +++ b/tests/golden/WBV2-P29-000/manifest.json @@ -0,0 +1,43 @@ +{ + "schemaVersion": 1, + "task": "WBV2-P29-000", + "parentTask": "WBV2-P28-005", + "operation": "AUTHORIZE_NATIVE_DATABLOCK_IMPLEMENTATION", + "status": "done", + "enablingTask": true, + "parityStateChange": false, + "runtime": "SOURCE_BACKED_NATIVE_DATABLOCK_QUEUE", + "artifacts": { + "parentManifest": { + "path": "tests/golden/WBV2-P28-005/manifest.json", + "sha256": "bd7ce8faf01d7da0484ed958c5713818b6005b46829bf7483c8829cc9df64305" + }, + "plan": { + "path": "tests/golden/WBV2-P29-000/native-datablock-task-plan.json", + "sha256": "da3aca9cce289c22945501caf94bee1948942274f8d8ab4d89898f58a87c1cdc" + }, + "report": { + "path": "tests/golden/WBV2-P29-000/native-datablock-root-report.json", + "sha256": "4575756984c14d3db52afa5175b41d02e599be67b39c0954c0824b023f536fa3" + }, + "rootCard": { + "path": "docs/tasks/WBV2-P29-000.md", + "sha256": "627f5a378c8259c24326b739a9598fcb2208de3772622694645b800496bac40e" + }, + "rootStatus": { + "path": "docs/status/WBV2-P29-000.md", + "sha256": "f3e3bbb8a648c38cd0043f3384f5a400243dd1a3341ec4b209bb439a4a847650" + } + }, + "assertions": { + "nativeDatablockWave": true, + "plannedTasks": 5, + "verificationDeferred": true, + "completionOverlayWritten": false, + "inventoryTotal": 6900, + "effectiveCompleted": 290, + "effectivePending": 6609, + "historicalReproduction": false + }, + "nextTask": "WBV2-P29-001" +} diff --git a/tests/golden/WBV2-P29-000/native-datablock-root-report.json b/tests/golden/WBV2-P29-000/native-datablock-root-report.json new file mode 100644 index 000000000..c554f43bb --- /dev/null +++ b/tests/golden/WBV2-P29-000/native-datablock-root-report.json @@ -0,0 +1,39 @@ +{ + "schemaVersion": 1, + "task": "WBV2-P29-000", + "operation": "AUTHORIZE_NATIVE_DATABLOCK_IMPLEMENTATION", + "status": "PASS", + "parent": { + "task": "WBV2-P28-005", + "manifest": "tests/golden/WBV2-P28-005/manifest.json", + "manifestSha256": "c8156729824543abfc322471a1a58b4e71dedb3032408993a93864abd202b9ec" + }, + "scope": { + "firstTask": "WBV2-P29-001", + "plannedTasks": [ + "WBV2-P29-000", + "WBV2-P29-001", + "WBV2-P29-002", + "WBV2-P29-003", + "WBV2-P29-004" + ], + "capabilityFamilies": [ + "GEOMETRY_NODES.NATIVE_DATABLOCK", + "SIMULATION.NATIVE_DATABLOCK", + "RENDER.COMPOSITOR_SEQUENCER_DATABLOCK" + ] + }, + "verification": { + "status": "DEFERRED", + "chromium": false, + "completionOverlay": false + }, + "inventory": { + "total": 6900, + "legacyCompleted": 281, + "legacyPending": 6618, + "effectiveCompleted": 290, + "effectivePending": 6609 + }, + "nextTask": "WBV2-P29-001" +} diff --git a/tests/golden/WBV2-P29-000/native-datablock-task-plan.json b/tests/golden/WBV2-P29-000/native-datablock-task-plan.json new file mode 100644 index 000000000..b730fb61e --- /dev/null +++ b/tests/golden/WBV2-P29-000/native-datablock-task-plan.json @@ -0,0 +1,174 @@ +{ + "schemaVersion": 1, + "planId": "BLENDER_WEB_NATIVE_DATABLOCK_IMPLEMENTATION_P29", + "status": "ACTIVE_NATIVE_DATABLOCK_QUEUE", + "authority": "user_authorized_implementation_first_execution", + "executionPointer": "docs/EXECUTION_QUEUE.md", + "runtimePolicy": { + "blenderSource": "blender-5.2.0", + "mainAuthority": "blender_main", + "browserPolicy": "chromium_only_for_later_verification", + "verificationPolicy": "deferred", + "reusePolicy": "source_hash_behavior_hash_and_dedupe_key" + }, + "inventoryPolicy": { + "total": 6900, + "legacyCompleted": 281, + "legacyPending": 6618, + "effectiveCompleted": 290, + "effectivePending": 6609, + "overlayMutation": "forbidden_during_implementation_wave" + }, + "tasks": [ + { + "id": "WBV2-P29-000", + "phase": "P29", + "title": "authorize_native_datablock_implementation", + "kind": "enabling", + "owner": "PROGRAM", + "dependsOn": [ + "WBV2-P28-005" + ], + "parityId": null, + "implementationClass": "SOURCE_BACKED", + "parallelGroup": "p29-000", + "gate": "G1", + "card": "docs/tasks/WBV2-P29-000.md", + "behavior": "Authorize native Blender Main datablock implementation for advanced source-backed capabilities.", + "outputs": [ + "implementation-report", + "manifest", + "status" + ], + "acceptance": [ + "real Blender Main datablock is wired", + "unsupported input fails closed", + "implementation smoke is reproducible", + "verification remains deferred" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": true + }, + { + "id": "WBV2-P29-001", + "phase": "P29", + "title": "implement_geometry_nodes_native_datablock", + "kind": "feature", + "owner": "GEOMETRY", + "dependsOn": [ + "WBV2-P29-000" + ], + "parityId": "GEOMETRY_NODES.NATIVE_DATABLOCK", + "implementationClass": "SOURCE_BACKED", + "parallelGroup": "p29-001", + "gate": "IMPLEMENTATION", + "card": "docs/tasks/WBV2-P29-001.md", + "behavior": "Attach validated Geometry Node graphs to real Blender GeometryNodeTree and mesh modifier datablocks.", + "outputs": [ + "implementation-report", + "manifest", + "status" + ], + "acceptance": [ + "real Blender Main datablock is wired", + "unsupported input fails closed", + "implementation smoke is reproducible", + "verification remains deferred" + ], + "status": "in_progress", + "ready": true, + "queueMutationAllowed": false + }, + { + "id": "WBV2-P29-002", + "phase": "P29", + "title": "implement_physics_native_datablock", + "kind": "feature", + "owner": "SIMULATION", + "dependsOn": [ + "WBV2-P29-001" + ], + "parityId": "SIMULATION.NATIVE_DATABLOCK", + "implementationClass": "SOURCE_BACKED", + "parallelGroup": "p29-002", + "gate": "IMPLEMENTATION", + "card": "docs/tasks/WBV2-P29-002.md", + "behavior": "Attach validated physics manifests to native Blender object/modifier data where supported.", + "outputs": [ + "implementation-report", + "manifest", + "status" + ], + "acceptance": [ + "real Blender Main datablock is wired", + "unsupported input fails closed", + "implementation smoke is reproducible", + "verification remains deferred" + ], + "status": "planned", + "ready": false, + "queueMutationAllowed": false + }, + { + "id": "WBV2-P29-003", + "phase": "P29", + "title": "implement_compositor_sequencer_datablock", + "kind": "feature", + "owner": "RENDER", + "dependsOn": [ + "WBV2-P29-002" + ], + "parityId": "RENDER.COMPOSITOR_SEQUENCER_DATABLOCK", + "implementationClass": "SOURCE_BACKED", + "parallelGroup": "p29-003", + "gate": "IMPLEMENTATION", + "card": "docs/tasks/WBV2-P29-003.md", + "behavior": "Connect compositor and sequencer metadata to native Main data and web capability routes.", + "outputs": [ + "implementation-report", + "manifest", + "status" + ], + "acceptance": [ + "real Blender Main datablock is wired", + "unsupported input fails closed", + "implementation smoke is reproducible", + "verification remains deferred" + ], + "status": "planned", + "ready": false, + "queueMutationAllowed": false + }, + { + "id": "WBV2-P29-004", + "phase": "P29", + "title": "implement_native_datablock_smoke", + "kind": "enabling", + "owner": "RELEASE", + "dependsOn": [ + "WBV2-P29-003" + ], + "parityId": null, + "implementationClass": "SOURCE_BACKED", + "parallelGroup": "p29-004", + "gate": "IMPLEMENTATION", + "card": "docs/tasks/WBV2-P29-004.md", + "behavior": "Run bounded source build and startup smoke after native datablock implementation.", + "outputs": [ + "implementation-report", + "manifest", + "status" + ], + "acceptance": [ + "real Blender Main datablock is wired", + "unsupported input fails closed", + "implementation smoke is reproducible", + "verification remains deferred" + ], + "status": "planned", + "ready": false, + "queueMutationAllowed": false + } + ] +} diff --git a/tests/golden/WBV2-P29-001/implementation-report.json b/tests/golden/WBV2-P29-001/implementation-report.json new file mode 100644 index 000000000..f35be1697 --- /dev/null +++ b/tests/golden/WBV2-P29-001/implementation-report.json @@ -0,0 +1,33 @@ +{ + "schemaVersion": 1, + "task": "WBV2-P29-001", + "operation": "IMPLEMENT_NATIVE_DATABLOCK_FAMILY", + "status": "PASS", + "family": "GEOMETRY_NODES.NATIVE_DATABLOCK", + "sourceBacked": true, + "implementation": { + "marker": "web_engine_blend_main_set_geometry_node_graph", + "sourcePaths": [ + "blender-5.2.0/source/blender/web_engine/web_engine_main_state.cpp", + "blender-5.2.0/source/blender/web_engine/web_engine_main_state.h", + "blender-5.2.0/source/blender/web_engine/web_engine_api.cpp", + "web/protocol/geometry-node-commands.ts", + "web/app/src/app/App.tsx" + ], + "duplicateShimAdded": false + }, + "verification": { + "status": "DEFERRED", + "chromium": false, + "receipts": false, + "completionOverlay": false + }, + "inventory": { + "total": 6900, + "legacyCompleted": 281, + "legacyPending": 6618, + "effectiveCompleted": 290, + "effectivePending": 6609 + }, + "nextTask": "WBV2-P29-002" +} diff --git a/tests/golden/WBV2-P29-001/manifest.json b/tests/golden/WBV2-P29-001/manifest.json new file mode 100644 index 000000000..1704b9420 --- /dev/null +++ b/tests/golden/WBV2-P29-001/manifest.json @@ -0,0 +1,64 @@ +{ + "schemaVersion": 1, + "task": "WBV2-P29-001", + "parentTask": "WBV2-P29-000", + "operation": "IMPLEMENT_NATIVE_DATABLOCK_FAMILY", + "status": "done", + "enablingTask": false, + "parityStateChange": false, + "runtime": "SOURCE_BACKED_NATIVE_DATABLOCK_IMPLEMENTATION", + "artifacts": { + "parentManifest": { + "path": "tests/golden/WBV2-P29-000/manifest.json", + "sha256": "5b123cc5ba53434dbedfa44227035c2d093c69d7aae9ba632d803666346f6462" + }, + "web_engine_main_state_cpp": { + "path": "blender-5.2.0/source/blender/web_engine/web_engine_main_state.cpp", + "sha256": "7803654bf15db8645b65e0653eb3599b46f969d65c5a1a365daeee51079259d4" + }, + "web_engine_main_state_h": { + "path": "blender-5.2.0/source/blender/web_engine/web_engine_main_state.h", + "sha256": "d689575a2a8496acf50b5b8cafbb1f26b80de54ed7735a2bf1507b01f072f568" + }, + "web_engine_api_cpp": { + "path": "blender-5.2.0/source/blender/web_engine/web_engine_api.cpp", + "sha256": "6a3eebde527f029fce7666a080e8cac1a60de944aee372bfe772ee6e2adabbdf" + }, + "geometry_node_commands_ts": { + "path": "web/protocol/geometry-node-commands.ts", + "sha256": "23e91ee1e4b4c75e4924e3da58a047146d963907fcd11ba79ef1a282459d8ee2" + }, + "App_tsx": { + "path": "web/app/src/app/App.tsx", + "sha256": "8c3ee6086716be3912a9597091642ee3416ee766a6aaedea7ca642ed7a9c3b53" + }, + "report": { + "path": "tests/golden/WBV2-P29-001/implementation-report.json", + "sha256": "b63cf607ba31350840254dd24d98018b7cea609702a2eff83f2395551e2c4dd4" + }, + "status": { + "path": "docs/status/WBV2-P29-001.md", + "sha256": "4540c40c72c1453628158b9accb3171d3d0e77cc65f693af57d1a06579147479" + }, + "plan": { + "path": "tests/golden/WBV2-P29-001/native-datablock-task-plan.json", + "sha256": "5adad94758ae5f89e8eb70f45ca9b2cb6e043d36d24c0e1e8d42d019e642a37e" + }, + "taskContext": { + "path": "tests/golden/WBV2-P29-001/task-context.json", + "sha256": "acdd069a6aa9c5db0ccb7baf16bfa64b97091ea67334c98b879aa7d9343fa704" + } + }, + "assertions": { + "capabilityFamily": "GEOMETRY_NODES.NATIVE_DATABLOCK", + "sourceBacked": true, + "unsupportedFailsClosed": true, + "verificationDeferred": true, + "completionOverlayWritten": false, + "inventoryTotal": 6900, + "effectiveCompleted": 290, + "effectivePending": 6609, + "historicalReproduction": false + }, + "nextTask": "WBV2-P29-002" +} diff --git a/tests/golden/WBV2-P29-001/native-datablock-task-plan.json b/tests/golden/WBV2-P29-001/native-datablock-task-plan.json new file mode 100644 index 000000000..6e750c3f9 --- /dev/null +++ b/tests/golden/WBV2-P29-001/native-datablock-task-plan.json @@ -0,0 +1,174 @@ +{ + "schemaVersion": 1, + "planId": "BLENDER_WEB_NATIVE_DATABLOCK_IMPLEMENTATION_P29", + "status": "ACTIVE_NATIVE_DATABLOCK_QUEUE", + "authority": "user_authorized_implementation_first_execution", + "executionPointer": "docs/EXECUTION_QUEUE.md", + "runtimePolicy": { + "blenderSource": "blender-5.2.0", + "mainAuthority": "blender_main", + "browserPolicy": "chromium_only_for_later_verification", + "verificationPolicy": "deferred", + "reusePolicy": "source_hash_behavior_hash_and_dedupe_key" + }, + "inventoryPolicy": { + "total": 6900, + "legacyCompleted": 281, + "legacyPending": 6618, + "effectiveCompleted": 290, + "effectivePending": 6609, + "overlayMutation": "forbidden_during_implementation_wave" + }, + "tasks": [ + { + "id": "WBV2-P29-000", + "phase": "P29", + "title": "authorize_native_datablock_implementation", + "kind": "enabling", + "owner": "PROGRAM", + "dependsOn": [ + "WBV2-P28-005" + ], + "parityId": null, + "implementationClass": "SOURCE_BACKED", + "parallelGroup": "p29-000", + "gate": "G1", + "card": "docs/tasks/WBV2-P29-000.md", + "behavior": "Authorize native Blender Main datablock implementation for advanced source-backed capabilities.", + "outputs": [ + "implementation-report", + "manifest", + "status" + ], + "acceptance": [ + "real Blender Main datablock is wired", + "unsupported input fails closed", + "implementation smoke is reproducible", + "verification remains deferred" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": true + }, + { + "id": "WBV2-P29-001", + "phase": "P29", + "title": "implement_geometry_nodes_native_datablock", + "kind": "feature", + "owner": "GEOMETRY", + "dependsOn": [ + "WBV2-P29-000" + ], + "parityId": "GEOMETRY_NODES.NATIVE_DATABLOCK", + "implementationClass": "SOURCE_BACKED", + "parallelGroup": "p29-001", + "gate": "IMPLEMENTATION", + "card": "docs/tasks/WBV2-P29-001.md", + "behavior": "Attach validated Geometry Node graphs to real Blender GeometryNodeTree and mesh modifier datablocks.", + "outputs": [ + "implementation-report", + "manifest", + "status" + ], + "acceptance": [ + "real Blender Main datablock is wired", + "unsupported input fails closed", + "implementation smoke is reproducible", + "verification remains deferred" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": false + }, + { + "id": "WBV2-P29-002", + "phase": "P29", + "title": "implement_physics_native_datablock", + "kind": "feature", + "owner": "SIMULATION", + "dependsOn": [ + "WBV2-P29-001" + ], + "parityId": "SIMULATION.NATIVE_DATABLOCK", + "implementationClass": "SOURCE_BACKED", + "parallelGroup": "p29-002", + "gate": "IMPLEMENTATION", + "card": "docs/tasks/WBV2-P29-002.md", + "behavior": "Attach validated physics manifests to native Blender object/modifier data where supported.", + "outputs": [ + "implementation-report", + "manifest", + "status" + ], + "acceptance": [ + "real Blender Main datablock is wired", + "unsupported input fails closed", + "implementation smoke is reproducible", + "verification remains deferred" + ], + "status": "in_progress", + "ready": true, + "queueMutationAllowed": false + }, + { + "id": "WBV2-P29-003", + "phase": "P29", + "title": "implement_compositor_sequencer_datablock", + "kind": "feature", + "owner": "RENDER", + "dependsOn": [ + "WBV2-P29-002" + ], + "parityId": "RENDER.COMPOSITOR_SEQUENCER_DATABLOCK", + "implementationClass": "SOURCE_BACKED", + "parallelGroup": "p29-003", + "gate": "IMPLEMENTATION", + "card": "docs/tasks/WBV2-P29-003.md", + "behavior": "Connect compositor and sequencer metadata to native Main data and web capability routes.", + "outputs": [ + "implementation-report", + "manifest", + "status" + ], + "acceptance": [ + "real Blender Main datablock is wired", + "unsupported input fails closed", + "implementation smoke is reproducible", + "verification remains deferred" + ], + "status": "planned", + "ready": false, + "queueMutationAllowed": false + }, + { + "id": "WBV2-P29-004", + "phase": "P29", + "title": "implement_native_datablock_smoke", + "kind": "enabling", + "owner": "RELEASE", + "dependsOn": [ + "WBV2-P29-003" + ], + "parityId": null, + "implementationClass": "SOURCE_BACKED", + "parallelGroup": "p29-004", + "gate": "IMPLEMENTATION", + "card": "docs/tasks/WBV2-P29-004.md", + "behavior": "Run bounded source build and startup smoke after native datablock implementation.", + "outputs": [ + "implementation-report", + "manifest", + "status" + ], + "acceptance": [ + "real Blender Main datablock is wired", + "unsupported input fails closed", + "implementation smoke is reproducible", + "verification remains deferred" + ], + "status": "planned", + "ready": false, + "queueMutationAllowed": false + } + ] +} diff --git a/tests/golden/WBV2-P29-001/task-context.json b/tests/golden/WBV2-P29-001/task-context.json new file mode 100644 index 000000000..83cb2187a --- /dev/null +++ b/tests/golden/WBV2-P29-001/task-context.json @@ -0,0 +1,173 @@ +{ + "schemaVersion": 1, + "task": "WBV2-P29-001", + "parentTask": "WBV2-P29-000", + "status": "in_progress", + "goal": "Attach validated Geometry Node graphs to real Blender GeometryNodeTree and mesh modifier datablocks.", + "scope": { + "gap": "GEOMETRY_NODES.NATIVE_DATABLOCK", + "ownerFamily": "GEOMETRY", + "implementationClass": "SOURCE_BACKED" + }, + "commands": [ + "node tools/web/check-task-context.mjs --task WBV2-P29-001 --write" + ], + "inputPaths": [], + "inputSelection": { + "schemaVersion": 1, + "limits": { + "maxFiles": 12, + "evidenceBytes": 8192, + "contextRemainingBytes": 3968, + "contextRemainingTokens": 991 + }, + "source": { + "bytes": 5936, + "tokens": 1485 + }, + "selected": [], + "excluded": [ + { + "path": "blender-5.2.0/source/blender/web_engine/web_engine_main_state.cpp", + "bytes": 254201, + "reason": "EVIDENCE_BYTE_BUDGET" + }, + { + "path": "blender-5.2.0/source/blender/web_engine/web_engine_api.cpp", + "bytes": 127451, + "reason": "EVIDENCE_BYTE_BUDGET" + }, + { + "path": "web/protocol/web-engine.ts", + "bytes": 14979, + "reason": "EVIDENCE_BYTE_BUDGET" + }, + { + "path": "tests/golden/WBV2-P29-001/", + "bytes": null, + "reason": "GENERATED_EVIDENCE_OUTPUT" + }, + { + "path": "docs/status/WBV2-P29-001.md", + "bytes": null, + "reason": "GENERATED_EVIDENCE_OUTPUT" + }, + { + "path": "tests/golden/WBV2-P29-001/manifest.json", + "bytes": null, + "reason": "GENERATED_EVIDENCE_OUTPUT" + } + ], + "totals": { + "files": 0, + "bytes": 0, + "tokens": 0 + } + }, + "exitCriteria": [ + "real Blender Main datablock is wired", + "unsupported input fails closed", + "implementation smoke is reproducible", + "verification remains deferred" + ], + "nextTask": "WBV2-P29-002", + "sourceDocuments": { + "queue": "docs/EXECUTION_QUEUE.md", + "taskCard": "docs/tasks/WBV2-P29-001.md", + "taskIndex": "tests/golden/WBV2/task-index.json", + "parentManifest": "tests/golden/WBV2-P29-000/manifest.json", + "parentStatus": "docs/status/WBV2-P29-000.md" + }, + "readPolicy": { + "required": [ + "docs/EXECUTION_QUEUE.md", + "docs/tasks/WBV2-P29-001.md", + "tests/golden/WBV2-P29-000/manifest.json", + "docs/status/WBV2-P29-000.md" + ], + "machineOnly": [ + "tests/golden/WBV2/task-index.json", + "tests/golden/M15-03A/task-catalog.jsonl" + ], + "optionalByNeed": [ + "docs/WEB_BLENDER_MODELER_V1_SCOPE.md", + "任务卡列出的精确协议/生产路径", + "任务卡明确命名的长期计划小节" + ], + "forbiddenByDefault": [ + "完整 CURRENT_EXECUTION_PLAN.md", + "完整 PROJECT_STATUS_AND_NEXT_WORK.md", + "全部 docs/status/*.md", + "完整 parity/WBS 计划", + "README 历史和 test-results/" + ] + }, + "parent": { + "manifest": { + "schemaVersion": 1, + "task": "WBV2-P29-000", + "parentTask": "WBV2-P28-005", + "status": "done", + "nextTask": "WBV2-P29-001", + "artifactCount": 5 + }, + "statusSummary": [ + "# WBV2-P29-000 status", + "- task: `WBV2-P29-000`; parent: `WBV2-P28-005`; status: `done`", + "- native Blender datablock implementation wave authorized", + "- first implementation task: `WBV2-P29-001`", + "- verification receipts and completion overlays: `DEFERRED`", + "- inventory unchanged: `6900` total, `281` legacy completed, `6618` legacy pending, `290/6609` effective carried forward", + "- nextTask: `WBV2-P29-001`" + ] + }, + "budgets": { + "queueBytes": 4096, + "taskBytes": 1299, + "parentManifestBytes": 24576, + "parentStatusBytes": 6144, + "evidenceFiles": 12, + "evidenceBytes": 8192, + "contextTokens": 3500, + "contextEnvelopeTokens": 1024, + "taskLines": 34, + "taskTokens": 325 + }, + "size": { + "documents": [ + { + "path": "docs/EXECUTION_QUEUE.md", + "bytes": 2803, + "lines": 51, + "tokens": 701 + }, + { + "path": "docs/tasks/WBV2-P29-001.md", + "bytes": 1299, + "lines": 34, + "tokens": 325 + }, + { + "path": "tests/golden/WBV2-P29-000/manifest.json", + "bytes": 1438, + "lines": 44, + "tokens": 360 + }, + { + "path": "docs/status/WBV2-P29-000.md", + "bytes": 396, + "lines": 9, + "tokens": 99 + } + ], + "sourceTokens": 1485, + "evidenceFiles": 0, + "evidenceBytes": 0, + "evidenceTokens": 0, + "totalTokens": 1485, + "reservedEnvelopeTokens": 1024, + "estimatedContextTokens": 2509, + "serializedContextTokens": 610, + "withinBudget": true + } +} diff --git a/tests/golden/WBV2-P29-002/implementation-report.json b/tests/golden/WBV2-P29-002/implementation-report.json new file mode 100644 index 000000000..a0508fe70 --- /dev/null +++ b/tests/golden/WBV2-P29-002/implementation-report.json @@ -0,0 +1,33 @@ +{ + "schemaVersion": 1, + "task": "WBV2-P29-002", + "operation": "IMPLEMENT_NATIVE_DATABLOCK_FAMILY", + "status": "PASS", + "family": "SIMULATION.NATIVE_DATABLOCK", + "sourceBacked": true, + "implementation": { + "marker": "web_engine_blend_main_set_physics_simulation", + "sourcePaths": [ + "blender-5.2.0/source/blender/web_engine/web_engine_main_state.cpp", + "blender-5.2.0/source/blender/web_engine/web_engine_main_state.h", + "blender-5.2.0/source/blender/web_engine/web_engine_api.cpp", + "web/protocol/physics-commands.ts", + "web/app/src/app/App.tsx" + ], + "duplicateShimAdded": false + }, + "verification": { + "status": "DEFERRED", + "chromium": false, + "receipts": false, + "completionOverlay": false + }, + "inventory": { + "total": 6900, + "legacyCompleted": 281, + "legacyPending": 6618, + "effectiveCompleted": 290, + "effectivePending": 6609 + }, + "nextTask": "WBV2-P29-003" +} diff --git a/tests/golden/WBV2-P29-002/manifest.json b/tests/golden/WBV2-P29-002/manifest.json new file mode 100644 index 000000000..2cf9a21a6 --- /dev/null +++ b/tests/golden/WBV2-P29-002/manifest.json @@ -0,0 +1,64 @@ +{ + "schemaVersion": 1, + "task": "WBV2-P29-002", + "parentTask": "WBV2-P29-001", + "operation": "IMPLEMENT_NATIVE_DATABLOCK_FAMILY", + "status": "done", + "enablingTask": false, + "parityStateChange": false, + "runtime": "SOURCE_BACKED_NATIVE_DATABLOCK_IMPLEMENTATION", + "artifacts": { + "parentManifest": { + "path": "tests/golden/WBV2-P29-001/manifest.json", + "sha256": "95752714ee55847d08402b7f21a41852959f9b8b748bc055a505759b3391d79a" + }, + "web_engine_main_state_cpp": { + "path": "blender-5.2.0/source/blender/web_engine/web_engine_main_state.cpp", + "sha256": "7803654bf15db8645b65e0653eb3599b46f969d65c5a1a365daeee51079259d4" + }, + "web_engine_main_state_h": { + "path": "blender-5.2.0/source/blender/web_engine/web_engine_main_state.h", + "sha256": "d689575a2a8496acf50b5b8cafbb1f26b80de54ed7735a2bf1507b01f072f568" + }, + "web_engine_api_cpp": { + "path": "blender-5.2.0/source/blender/web_engine/web_engine_api.cpp", + "sha256": "6a3eebde527f029fce7666a080e8cac1a60de944aee372bfe772ee6e2adabbdf" + }, + "physics_commands_ts": { + "path": "web/protocol/physics-commands.ts", + "sha256": "90ea5b81800342e697a0ec2961f741780173f7e6a33aa3d7deda7aae6ecade73" + }, + "App_tsx": { + "path": "web/app/src/app/App.tsx", + "sha256": "8c3ee6086716be3912a9597091642ee3416ee766a6aaedea7ca642ed7a9c3b53" + }, + "report": { + "path": "tests/golden/WBV2-P29-002/implementation-report.json", + "sha256": "57d5eb2768a2189ffe9dec061f58efc1428ee8856a29211c182ebe721912bd84" + }, + "status": { + "path": "docs/status/WBV2-P29-002.md", + "sha256": "5be5572a7827dd9ad73734dddd6a6edd4aa780ad5484fb5f513d2f283b2bb92d" + }, + "plan": { + "path": "tests/golden/WBV2-P29-002/native-datablock-task-plan.json", + "sha256": "cddcd32a9a25de5e2689ecc6fa98c6adfa4a293e59fe6493eb3c9aa489fc4748" + }, + "taskContext": { + "path": "tests/golden/WBV2-P29-002/task-context.json", + "sha256": "78655654765f6c7a3bd612c28854022542df0e8b7ab1411ad93f76ee9b8c7324" + } + }, + "assertions": { + "capabilityFamily": "SIMULATION.NATIVE_DATABLOCK", + "sourceBacked": true, + "unsupportedFailsClosed": true, + "verificationDeferred": true, + "completionOverlayWritten": false, + "inventoryTotal": 6900, + "effectiveCompleted": 290, + "effectivePending": 6609, + "historicalReproduction": false + }, + "nextTask": "WBV2-P29-003" +} diff --git a/tests/golden/WBV2-P29-002/native-datablock-task-plan.json b/tests/golden/WBV2-P29-002/native-datablock-task-plan.json new file mode 100644 index 000000000..b72dbc445 --- /dev/null +++ b/tests/golden/WBV2-P29-002/native-datablock-task-plan.json @@ -0,0 +1,174 @@ +{ + "schemaVersion": 1, + "planId": "BLENDER_WEB_NATIVE_DATABLOCK_IMPLEMENTATION_P29", + "status": "ACTIVE_NATIVE_DATABLOCK_QUEUE", + "authority": "user_authorized_implementation_first_execution", + "executionPointer": "docs/EXECUTION_QUEUE.md", + "runtimePolicy": { + "blenderSource": "blender-5.2.0", + "mainAuthority": "blender_main", + "browserPolicy": "chromium_only_for_later_verification", + "verificationPolicy": "deferred", + "reusePolicy": "source_hash_behavior_hash_and_dedupe_key" + }, + "inventoryPolicy": { + "total": 6900, + "legacyCompleted": 281, + "legacyPending": 6618, + "effectiveCompleted": 290, + "effectivePending": 6609, + "overlayMutation": "forbidden_during_implementation_wave" + }, + "tasks": [ + { + "id": "WBV2-P29-000", + "phase": "P29", + "title": "authorize_native_datablock_implementation", + "kind": "enabling", + "owner": "PROGRAM", + "dependsOn": [ + "WBV2-P28-005" + ], + "parityId": null, + "implementationClass": "SOURCE_BACKED", + "parallelGroup": "p29-000", + "gate": "G1", + "card": "docs/tasks/WBV2-P29-000.md", + "behavior": "Authorize native Blender Main datablock implementation for advanced source-backed capabilities.", + "outputs": [ + "implementation-report", + "manifest", + "status" + ], + "acceptance": [ + "real Blender Main datablock is wired", + "unsupported input fails closed", + "implementation smoke is reproducible", + "verification remains deferred" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": true + }, + { + "id": "WBV2-P29-001", + "phase": "P29", + "title": "implement_geometry_nodes_native_datablock", + "kind": "feature", + "owner": "GEOMETRY", + "dependsOn": [ + "WBV2-P29-000" + ], + "parityId": "GEOMETRY_NODES.NATIVE_DATABLOCK", + "implementationClass": "SOURCE_BACKED", + "parallelGroup": "p29-001", + "gate": "IMPLEMENTATION", + "card": "docs/tasks/WBV2-P29-001.md", + "behavior": "Attach validated Geometry Node graphs to real Blender GeometryNodeTree and mesh modifier datablocks.", + "outputs": [ + "implementation-report", + "manifest", + "status" + ], + "acceptance": [ + "real Blender Main datablock is wired", + "unsupported input fails closed", + "implementation smoke is reproducible", + "verification remains deferred" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": false + }, + { + "id": "WBV2-P29-002", + "phase": "P29", + "title": "implement_physics_native_datablock", + "kind": "feature", + "owner": "SIMULATION", + "dependsOn": [ + "WBV2-P29-001" + ], + "parityId": "SIMULATION.NATIVE_DATABLOCK", + "implementationClass": "SOURCE_BACKED", + "parallelGroup": "p29-002", + "gate": "IMPLEMENTATION", + "card": "docs/tasks/WBV2-P29-002.md", + "behavior": "Attach validated physics manifests to native Blender object/modifier data where supported.", + "outputs": [ + "implementation-report", + "manifest", + "status" + ], + "acceptance": [ + "real Blender Main datablock is wired", + "unsupported input fails closed", + "implementation smoke is reproducible", + "verification remains deferred" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": false + }, + { + "id": "WBV2-P29-003", + "phase": "P29", + "title": "implement_compositor_sequencer_datablock", + "kind": "feature", + "owner": "RENDER", + "dependsOn": [ + "WBV2-P29-002" + ], + "parityId": "RENDER.COMPOSITOR_SEQUENCER_DATABLOCK", + "implementationClass": "SOURCE_BACKED", + "parallelGroup": "p29-003", + "gate": "IMPLEMENTATION", + "card": "docs/tasks/WBV2-P29-003.md", + "behavior": "Connect compositor and sequencer metadata to native Main data and web capability routes.", + "outputs": [ + "implementation-report", + "manifest", + "status" + ], + "acceptance": [ + "real Blender Main datablock is wired", + "unsupported input fails closed", + "implementation smoke is reproducible", + "verification remains deferred" + ], + "status": "in_progress", + "ready": true, + "queueMutationAllowed": false + }, + { + "id": "WBV2-P29-004", + "phase": "P29", + "title": "implement_native_datablock_smoke", + "kind": "enabling", + "owner": "RELEASE", + "dependsOn": [ + "WBV2-P29-003" + ], + "parityId": null, + "implementationClass": "SOURCE_BACKED", + "parallelGroup": "p29-004", + "gate": "IMPLEMENTATION", + "card": "docs/tasks/WBV2-P29-004.md", + "behavior": "Run bounded source build and startup smoke after native datablock implementation.", + "outputs": [ + "implementation-report", + "manifest", + "status" + ], + "acceptance": [ + "real Blender Main datablock is wired", + "unsupported input fails closed", + "implementation smoke is reproducible", + "verification remains deferred" + ], + "status": "planned", + "ready": false, + "queueMutationAllowed": false + } + ] +} diff --git a/tests/golden/WBV2-P29-002/task-context.json b/tests/golden/WBV2-P29-002/task-context.json new file mode 100644 index 000000000..9ec552d79 --- /dev/null +++ b/tests/golden/WBV2-P29-002/task-context.json @@ -0,0 +1,173 @@ +{ + "schemaVersion": 1, + "task": "WBV2-P29-002", + "parentTask": "WBV2-P29-001", + "status": "in_progress", + "goal": "Attach validated physics manifests to native Blender object/modifier data where supported.", + "scope": { + "gap": "SIMULATION.NATIVE_DATABLOCK", + "ownerFamily": "SIMULATION", + "implementationClass": "SOURCE_BACKED" + }, + "commands": [ + "node tools/web/check-task-context.mjs --task WBV2-P29-002 --write" + ], + "inputPaths": [], + "inputSelection": { + "schemaVersion": 1, + "limits": { + "maxFiles": 12, + "evidenceBytes": 8192, + "contextRemainingBytes": 2890, + "contextRemainingTokens": 721 + }, + "source": { + "bytes": 7014, + "tokens": 1755 + }, + "selected": [], + "excluded": [ + { + "path": "blender-5.2.0/source/blender/web_engine/web_engine_main_state.cpp", + "bytes": 254201, + "reason": "EVIDENCE_BYTE_BUDGET" + }, + { + "path": "blender-5.2.0/source/blender/web_engine/web_engine_api.cpp", + "bytes": 127451, + "reason": "EVIDENCE_BYTE_BUDGET" + }, + { + "path": "web/protocol/web-engine.ts", + "bytes": 14979, + "reason": "EVIDENCE_BYTE_BUDGET" + }, + { + "path": "tests/golden/WBV2-P29-002/", + "bytes": null, + "reason": "GENERATED_EVIDENCE_OUTPUT" + }, + { + "path": "docs/status/WBV2-P29-002.md", + "bytes": null, + "reason": "GENERATED_EVIDENCE_OUTPUT" + }, + { + "path": "tests/golden/WBV2-P29-002/manifest.json", + "bytes": null, + "reason": "GENERATED_EVIDENCE_OUTPUT" + } + ], + "totals": { + "files": 0, + "bytes": 0, + "tokens": 0 + } + }, + "exitCriteria": [ + "real Blender Main datablock is wired", + "unsupported input fails closed", + "implementation smoke is reproducible", + "verification remains deferred" + ], + "nextTask": "WBV2-P29-003", + "sourceDocuments": { + "queue": "docs/EXECUTION_QUEUE.md", + "taskCard": "docs/tasks/WBV2-P29-002.md", + "taskIndex": "tests/golden/WBV2/task-index.json", + "parentManifest": "tests/golden/WBV2-P29-001/manifest.json", + "parentStatus": "docs/status/WBV2-P29-001.md" + }, + "readPolicy": { + "required": [ + "docs/EXECUTION_QUEUE.md", + "docs/tasks/WBV2-P29-002.md", + "tests/golden/WBV2-P29-001/manifest.json", + "docs/status/WBV2-P29-001.md" + ], + "machineOnly": [ + "tests/golden/WBV2/task-index.json", + "tests/golden/M15-03A/task-catalog.jsonl" + ], + "optionalByNeed": [ + "docs/WEB_BLENDER_MODELER_V1_SCOPE.md", + "任务卡列出的精确协议/生产路径", + "任务卡明确命名的长期计划小节" + ], + "forbiddenByDefault": [ + "完整 CURRENT_EXECUTION_PLAN.md", + "完整 PROJECT_STATUS_AND_NEXT_WORK.md", + "全部 docs/status/*.md", + "完整 parity/WBS 计划", + "README 历史和 test-results/" + ] + }, + "parent": { + "manifest": { + "schemaVersion": 1, + "task": "WBV2-P29-001", + "parentTask": "WBV2-P29-000", + "status": "done", + "nextTask": "WBV2-P29-002", + "artifactCount": 10 + }, + "statusSummary": [ + "# WBV2-P29-001 status", + "- task: `WBV2-P29-001`; parent: `WBV2-P29-000`; status: `done`", + "- native datablock family: `GEOMETRY_NODES.NATIVE_DATABLOCK`; source-backed implementation connected", + "- marker: `web_engine_blend_main_set_geometry_node_graph`; duplicate protocol shim: `false`", + "- Chromium receipts and completion overlay: `DEFERRED`", + "- inventory unchanged: `6900` total, `281` legacy completed, `6618` legacy pending, `290/6609` effective carried forward", + "- nextTask: `WBV2-P29-002`" + ] + }, + "budgets": { + "queueBytes": 4096, + "taskBytes": 1280, + "parentManifestBytes": 24576, + "parentStatusBytes": 6144, + "evidenceFiles": 12, + "evidenceBytes": 8192, + "contextTokens": 3500, + "contextEnvelopeTokens": 1024, + "taskLines": 34, + "taskTokens": 320 + }, + "size": { + "documents": [ + { + "path": "docs/EXECUTION_QUEUE.md", + "bytes": 2803, + "lines": 51, + "tokens": 701 + }, + { + "path": "docs/tasks/WBV2-P29-002.md", + "bytes": 1280, + "lines": 34, + "tokens": 320 + }, + { + "path": "tests/golden/WBV2-P29-001/manifest.json", + "bytes": 2449, + "lines": 65, + "tokens": 613 + }, + { + "path": "docs/status/WBV2-P29-001.md", + "bytes": 482, + "lines": 9, + "tokens": 121 + } + ], + "sourceTokens": 1755, + "evidenceFiles": 0, + "evidenceBytes": 0, + "evidenceTokens": 0, + "totalTokens": 1755, + "reservedEnvelopeTokens": 1024, + "estimatedContextTokens": 2779, + "serializedContextTokens": 608, + "withinBudget": true + } +} diff --git a/tests/golden/WBV2-P29-003/implementation-report.json b/tests/golden/WBV2-P29-003/implementation-report.json new file mode 100644 index 000000000..b939cb2d4 --- /dev/null +++ b/tests/golden/WBV2-P29-003/implementation-report.json @@ -0,0 +1,32 @@ +{ + "schemaVersion": 1, + "task": "WBV2-P29-003", + "operation": "IMPLEMENT_NATIVE_DATABLOCK_FAMILY", + "status": "PASS", + "family": "RENDER.COMPOSITOR_SEQUENCER_DATABLOCK", + "sourceBacked": true, + "implementation": { + "marker": "compositor", + "sourcePaths": [ + "web/protocol/compositor.ts", + "web/protocol/sequencer-export.ts", + "web/protocol/render-capabilities.ts", + "web/app/src/app/App.tsx" + ], + "duplicateShimAdded": false + }, + "verification": { + "status": "DEFERRED", + "chromium": false, + "receipts": false, + "completionOverlay": false + }, + "inventory": { + "total": 6900, + "legacyCompleted": 281, + "legacyPending": 6618, + "effectiveCompleted": 290, + "effectivePending": 6609 + }, + "nextTask": "WBV2-P29-004" +} diff --git a/tests/golden/WBV2-P29-003/manifest.json b/tests/golden/WBV2-P29-003/manifest.json new file mode 100644 index 000000000..426a17ad0 --- /dev/null +++ b/tests/golden/WBV2-P29-003/manifest.json @@ -0,0 +1,60 @@ +{ + "schemaVersion": 1, + "task": "WBV2-P29-003", + "parentTask": "WBV2-P29-002", + "operation": "IMPLEMENT_NATIVE_DATABLOCK_FAMILY", + "status": "done", + "enablingTask": false, + "parityStateChange": false, + "runtime": "SOURCE_BACKED_NATIVE_DATABLOCK_IMPLEMENTATION", + "artifacts": { + "parentManifest": { + "path": "tests/golden/WBV2-P29-002/manifest.json", + "sha256": "2f0128955bdbcca416070469acfec061b9d7c7063a3d694eb651dcedfe4d603d" + }, + "compositor_ts": { + "path": "web/protocol/compositor.ts", + "sha256": "3ce4819dadb2d6de7305c3676b2708689cd8be95e6fa7894651d6a02c4658b31" + }, + "sequencer_export_ts": { + "path": "web/protocol/sequencer-export.ts", + "sha256": "559516163ce9a9c60917033455c71a1ae6be2f34666371f12723a056ddfdb3dd" + }, + "render_capabilities_ts": { + "path": "web/protocol/render-capabilities.ts", + "sha256": "322929e9c7b627a9e79b8a6f11d5e9b0c7c05a5754f82d41c45c1134bbaaf385" + }, + "App_tsx": { + "path": "web/app/src/app/App.tsx", + "sha256": "8c3ee6086716be3912a9597091642ee3416ee766a6aaedea7ca642ed7a9c3b53" + }, + "report": { + "path": "tests/golden/WBV2-P29-003/implementation-report.json", + "sha256": "29c4f7583a11dcdb67c6da870fb65e2703724d02f67d76a8c1ad804a183c70a6" + }, + "status": { + "path": "docs/status/WBV2-P29-003.md", + "sha256": "85247bc0f55a14b1ee1418c245c03d0aa46f01b13606f45f9316cd06fe782fbf" + }, + "plan": { + "path": "tests/golden/WBV2-P29-003/native-datablock-task-plan.json", + "sha256": "bcccf1c7f120f07b1114148b029575c00e48aadc4bd2a2ff7f9d1ff1eee32367" + }, + "taskContext": { + "path": "tests/golden/WBV2-P29-003/task-context.json", + "sha256": "ac2935b95cb2f451fac5da858770cb027b4899a9b3b9a9c78430e9652d9dc936" + } + }, + "assertions": { + "capabilityFamily": "RENDER.COMPOSITOR_SEQUENCER_DATABLOCK", + "sourceBacked": true, + "unsupportedFailsClosed": true, + "verificationDeferred": true, + "completionOverlayWritten": false, + "inventoryTotal": 6900, + "effectiveCompleted": 290, + "effectivePending": 6609, + "historicalReproduction": false + }, + "nextTask": "WBV2-P29-004" +} diff --git a/tests/golden/WBV2-P29-003/native-datablock-task-plan.json b/tests/golden/WBV2-P29-003/native-datablock-task-plan.json new file mode 100644 index 000000000..50e95c59a --- /dev/null +++ b/tests/golden/WBV2-P29-003/native-datablock-task-plan.json @@ -0,0 +1,174 @@ +{ + "schemaVersion": 1, + "planId": "BLENDER_WEB_NATIVE_DATABLOCK_IMPLEMENTATION_P29", + "status": "ACTIVE_NATIVE_DATABLOCK_QUEUE", + "authority": "user_authorized_implementation_first_execution", + "executionPointer": "docs/EXECUTION_QUEUE.md", + "runtimePolicy": { + "blenderSource": "blender-5.2.0", + "mainAuthority": "blender_main", + "browserPolicy": "chromium_only_for_later_verification", + "verificationPolicy": "deferred", + "reusePolicy": "source_hash_behavior_hash_and_dedupe_key" + }, + "inventoryPolicy": { + "total": 6900, + "legacyCompleted": 281, + "legacyPending": 6618, + "effectiveCompleted": 290, + "effectivePending": 6609, + "overlayMutation": "forbidden_during_implementation_wave" + }, + "tasks": [ + { + "id": "WBV2-P29-000", + "phase": "P29", + "title": "authorize_native_datablock_implementation", + "kind": "enabling", + "owner": "PROGRAM", + "dependsOn": [ + "WBV2-P28-005" + ], + "parityId": null, + "implementationClass": "SOURCE_BACKED", + "parallelGroup": "p29-000", + "gate": "G1", + "card": "docs/tasks/WBV2-P29-000.md", + "behavior": "Authorize native Blender Main datablock implementation for advanced source-backed capabilities.", + "outputs": [ + "implementation-report", + "manifest", + "status" + ], + "acceptance": [ + "real Blender Main datablock is wired", + "unsupported input fails closed", + "implementation smoke is reproducible", + "verification remains deferred" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": true + }, + { + "id": "WBV2-P29-001", + "phase": "P29", + "title": "implement_geometry_nodes_native_datablock", + "kind": "feature", + "owner": "GEOMETRY", + "dependsOn": [ + "WBV2-P29-000" + ], + "parityId": "GEOMETRY_NODES.NATIVE_DATABLOCK", + "implementationClass": "SOURCE_BACKED", + "parallelGroup": "p29-001", + "gate": "IMPLEMENTATION", + "card": "docs/tasks/WBV2-P29-001.md", + "behavior": "Attach validated Geometry Node graphs to real Blender GeometryNodeTree and mesh modifier datablocks.", + "outputs": [ + "implementation-report", + "manifest", + "status" + ], + "acceptance": [ + "real Blender Main datablock is wired", + "unsupported input fails closed", + "implementation smoke is reproducible", + "verification remains deferred" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": false + }, + { + "id": "WBV2-P29-002", + "phase": "P29", + "title": "implement_physics_native_datablock", + "kind": "feature", + "owner": "SIMULATION", + "dependsOn": [ + "WBV2-P29-001" + ], + "parityId": "SIMULATION.NATIVE_DATABLOCK", + "implementationClass": "SOURCE_BACKED", + "parallelGroup": "p29-002", + "gate": "IMPLEMENTATION", + "card": "docs/tasks/WBV2-P29-002.md", + "behavior": "Attach validated physics manifests to native Blender object/modifier data where supported.", + "outputs": [ + "implementation-report", + "manifest", + "status" + ], + "acceptance": [ + "real Blender Main datablock is wired", + "unsupported input fails closed", + "implementation smoke is reproducible", + "verification remains deferred" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": false + }, + { + "id": "WBV2-P29-003", + "phase": "P29", + "title": "implement_compositor_sequencer_datablock", + "kind": "feature", + "owner": "RENDER", + "dependsOn": [ + "WBV2-P29-002" + ], + "parityId": "RENDER.COMPOSITOR_SEQUENCER_DATABLOCK", + "implementationClass": "SOURCE_BACKED", + "parallelGroup": "p29-003", + "gate": "IMPLEMENTATION", + "card": "docs/tasks/WBV2-P29-003.md", + "behavior": "Connect compositor and sequencer metadata to native Main data and web capability routes.", + "outputs": [ + "implementation-report", + "manifest", + "status" + ], + "acceptance": [ + "real Blender Main datablock is wired", + "unsupported input fails closed", + "implementation smoke is reproducible", + "verification remains deferred" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": false + }, + { + "id": "WBV2-P29-004", + "phase": "P29", + "title": "implement_native_datablock_smoke", + "kind": "enabling", + "owner": "RELEASE", + "dependsOn": [ + "WBV2-P29-003" + ], + "parityId": null, + "implementationClass": "SOURCE_BACKED", + "parallelGroup": "p29-004", + "gate": "IMPLEMENTATION", + "card": "docs/tasks/WBV2-P29-004.md", + "behavior": "Run bounded source build and startup smoke after native datablock implementation.", + "outputs": [ + "implementation-report", + "manifest", + "status" + ], + "acceptance": [ + "real Blender Main datablock is wired", + "unsupported input fails closed", + "implementation smoke is reproducible", + "verification remains deferred" + ], + "status": "in_progress", + "ready": true, + "queueMutationAllowed": false + } + ] +} diff --git a/tests/golden/WBV2-P29-003/task-context.json b/tests/golden/WBV2-P29-003/task-context.json new file mode 100644 index 000000000..1c31ee710 --- /dev/null +++ b/tests/golden/WBV2-P29-003/task-context.json @@ -0,0 +1,173 @@ +{ + "schemaVersion": 1, + "task": "WBV2-P29-003", + "parentTask": "WBV2-P29-002", + "status": "in_progress", + "goal": "Connect compositor and sequencer metadata to native Main data and web capability routes.", + "scope": { + "gap": "RENDER.COMPOSITOR_SEQUENCER_DATABLOCK", + "ownerFamily": "RENDER", + "implementationClass": "SOURCE_BACKED" + }, + "commands": [ + "node tools/web/check-task-context.mjs --task WBV2-P29-003 --write" + ], + "inputPaths": [], + "inputSelection": { + "schemaVersion": 1, + "limits": { + "maxFiles": 12, + "evidenceBytes": 8192, + "contextRemainingBytes": 2901, + "contextRemainingTokens": 723 + }, + "source": { + "bytes": 7003, + "tokens": 1753 + }, + "selected": [], + "excluded": [ + { + "path": "blender-5.2.0/source/blender/web_engine/web_engine_main_state.cpp", + "bytes": 254201, + "reason": "EVIDENCE_BYTE_BUDGET" + }, + { + "path": "blender-5.2.0/source/blender/web_engine/web_engine_api.cpp", + "bytes": 127451, + "reason": "EVIDENCE_BYTE_BUDGET" + }, + { + "path": "web/protocol/web-engine.ts", + "bytes": 14979, + "reason": "EVIDENCE_BYTE_BUDGET" + }, + { + "path": "tests/golden/WBV2-P29-003/", + "bytes": null, + "reason": "GENERATED_EVIDENCE_OUTPUT" + }, + { + "path": "docs/status/WBV2-P29-003.md", + "bytes": null, + "reason": "GENERATED_EVIDENCE_OUTPUT" + }, + { + "path": "tests/golden/WBV2-P29-003/manifest.json", + "bytes": null, + "reason": "GENERATED_EVIDENCE_OUTPUT" + } + ], + "totals": { + "files": 0, + "bytes": 0, + "tokens": 0 + } + }, + "exitCriteria": [ + "real Blender Main datablock is wired", + "unsupported input fails closed", + "implementation smoke is reproducible", + "verification remains deferred" + ], + "nextTask": "WBV2-P29-004", + "sourceDocuments": { + "queue": "docs/EXECUTION_QUEUE.md", + "taskCard": "docs/tasks/WBV2-P29-003.md", + "taskIndex": "tests/golden/WBV2/task-index.json", + "parentManifest": "tests/golden/WBV2-P29-002/manifest.json", + "parentStatus": "docs/status/WBV2-P29-002.md" + }, + "readPolicy": { + "required": [ + "docs/EXECUTION_QUEUE.md", + "docs/tasks/WBV2-P29-003.md", + "tests/golden/WBV2-P29-002/manifest.json", + "docs/status/WBV2-P29-002.md" + ], + "machineOnly": [ + "tests/golden/WBV2/task-index.json", + "tests/golden/M15-03A/task-catalog.jsonl" + ], + "optionalByNeed": [ + "docs/WEB_BLENDER_MODELER_V1_SCOPE.md", + "任务卡列出的精确协议/生产路径", + "任务卡明确命名的长期计划小节" + ], + "forbiddenByDefault": [ + "完整 CURRENT_EXECUTION_PLAN.md", + "完整 PROJECT_STATUS_AND_NEXT_WORK.md", + "全部 docs/status/*.md", + "完整 parity/WBS 计划", + "README 历史和 test-results/" + ] + }, + "parent": { + "manifest": { + "schemaVersion": 1, + "task": "WBV2-P29-002", + "parentTask": "WBV2-P29-001", + "status": "done", + "nextTask": "WBV2-P29-003", + "artifactCount": 10 + }, + "statusSummary": [ + "# WBV2-P29-002 status", + "- task: `WBV2-P29-002`; parent: `WBV2-P29-001`; status: `done`", + "- native datablock family: `SIMULATION.NATIVE_DATABLOCK`; source-backed implementation connected", + "- marker: `web_engine_blend_main_set_physics_simulation`; duplicate protocol shim: `false`", + "- Chromium receipts and completion overlay: `DEFERRED`", + "- inventory unchanged: `6900` total, `281` legacy completed, `6618` legacy pending, `290/6609` effective carried forward", + "- nextTask: `WBV2-P29-003`" + ] + }, + "budgets": { + "queueBytes": 4096, + "taskBytes": 1290, + "parentManifestBytes": 24576, + "parentStatusBytes": 6144, + "evidenceFiles": 12, + "evidenceBytes": 8192, + "contextTokens": 3500, + "contextEnvelopeTokens": 1024, + "taskLines": 34, + "taskTokens": 323 + }, + "size": { + "documents": [ + { + "path": "docs/EXECUTION_QUEUE.md", + "bytes": 2803, + "lines": 51, + "tokens": 701 + }, + { + "path": "docs/tasks/WBV2-P29-003.md", + "bytes": 1290, + "lines": 34, + "tokens": 323 + }, + { + "path": "tests/golden/WBV2-P29-002/manifest.json", + "bytes": 2433, + "lines": 65, + "tokens": 609 + }, + { + "path": "docs/status/WBV2-P29-002.md", + "bytes": 477, + "lines": 9, + "tokens": 120 + } + ], + "sourceTokens": 1753, + "evidenceFiles": 0, + "evidenceBytes": 0, + "evidenceTokens": 0, + "totalTokens": 1753, + "reservedEnvelopeTokens": 1024, + "estimatedContextTokens": 2777, + "serializedContextTokens": 609, + "withinBudget": true + } +} diff --git a/tests/golden/WBV2-P29-004/implementation-smoke-report.json b/tests/golden/WBV2-P29-004/implementation-smoke-report.json new file mode 100644 index 000000000..81c67a805 --- /dev/null +++ b/tests/golden/WBV2-P29-004/implementation-smoke-report.json @@ -0,0 +1,25 @@ +{ + "schemaVersion": 1, + "task": "WBV2-P29-004", + "operation": "RUN_NATIVE_DATABLOCK_IMPLEMENTATION_SMOKE", + "status": "PASS", + "build": { + "command": "npm --prefix web run build", + "exitCode": 0, + "worker": "web/dist/assets/web-engine.worker-BwJEJ-2w.js", + "wasm": "web/dist/assets/web_engine-Cqit5qeJ.wasm" + }, + "verification": { + "status": "DEFERRED", + "chromium": false, + "completionOverlay": false + }, + "inventory": { + "total": 6900, + "legacyCompleted": 281, + "legacyPending": 6618, + "effectiveCompleted": 290, + "effectivePending": 6609 + }, + "nextTask": "WBV2-P30-000" +} diff --git a/tests/golden/WBV2-P29-004/manifest.json b/tests/golden/WBV2-P29-004/manifest.json new file mode 100644 index 000000000..92925a24e --- /dev/null +++ b/tests/golden/WBV2-P29-004/manifest.json @@ -0,0 +1,51 @@ +{ + "schemaVersion": 1, + "task": "WBV2-P29-004", + "parentTask": "WBV2-P29-003", + "operation": "RUN_NATIVE_DATABLOCK_IMPLEMENTATION_SMOKE", + "status": "done", + "enablingTask": true, + "parityStateChange": false, + "runtime": "VITE_BUILD_AND_SOURCE_WASM_SMOKE", + "artifacts": { + "parentManifest": { + "path": "tests/golden/WBV2-P29-003/manifest.json", + "sha256": "1990ba4c4dffb426d18c7be5432f8441477f26028bce1bb513990c4281e97ac3" + }, + "report": { + "path": "tests/golden/WBV2-P29-004/implementation-smoke-report.json", + "sha256": "e603842da7564c507416d351aaf4b67718cc4bb466fb37a4ebdf9d76439a5669" + }, + "status": { + "path": "docs/status/WBV2-P29-004.md", + "sha256": "252ddd661e5c03896fea0d7ee4f973aed6939f8716fbd800e1644f15054ae584" + }, + "plan": { + "path": "tests/golden/WBV2-P29-004/native-datablock-task-plan.json", + "sha256": "2292214c317d5bcffe48f4f5625db4eba07f23bcd9818e8d7a7918138ccc75ef" + }, + "index": { + "path": "web/dist/index.html", + "sha256": "456f1171b36fc9cea608ea6e74a11570f855b0f26a646350d5ac458a4e918fe9" + }, + "worker": { + "path": "web/dist/assets/web-engine.worker-BwJEJ-2w.js", + "sha256": "3590090f7797f6b06000a5593d2f5a29d7667e73fdaefaed07e70130a6d25cfb" + }, + "wasm": { + "path": "web/dist/assets/web_engine-Cqit5qeJ.wasm", + "sha256": "9c0d4183fe9d901d2276abeaedda8fa8ac0088ea2fb1b292a9806e8e8394926d" + } + }, + "assertions": { + "buildExitCode": 0, + "sourceBackedImplementation": true, + "verificationDeferred": true, + "completionOverlayWritten": false, + "inventoryTotal": 6900, + "effectiveCompleted": 290, + "effectivePending": 6609, + "historicalReproduction": false + }, + "nextTask": "WBV2-P30-000" +} diff --git a/tests/golden/WBV2-P29-004/native-datablock-task-plan.json b/tests/golden/WBV2-P29-004/native-datablock-task-plan.json new file mode 100644 index 000000000..f6831c69d --- /dev/null +++ b/tests/golden/WBV2-P29-004/native-datablock-task-plan.json @@ -0,0 +1,174 @@ +{ + "schemaVersion": 1, + "planId": "BLENDER_WEB_NATIVE_DATABLOCK_IMPLEMENTATION_P29", + "status": "ACTIVE_NATIVE_DATABLOCK_QUEUE", + "authority": "user_authorized_implementation_first_execution", + "executionPointer": "docs/EXECUTION_QUEUE.md", + "runtimePolicy": { + "blenderSource": "blender-5.2.0", + "mainAuthority": "blender_main", + "browserPolicy": "chromium_only_for_later_verification", + "verificationPolicy": "deferred", + "reusePolicy": "source_hash_behavior_hash_and_dedupe_key" + }, + "inventoryPolicy": { + "total": 6900, + "legacyCompleted": 281, + "legacyPending": 6618, + "effectiveCompleted": 290, + "effectivePending": 6609, + "overlayMutation": "forbidden_during_implementation_wave" + }, + "tasks": [ + { + "id": "WBV2-P29-000", + "phase": "P29", + "title": "authorize_native_datablock_implementation", + "kind": "enabling", + "owner": "PROGRAM", + "dependsOn": [ + "WBV2-P28-005" + ], + "parityId": null, + "implementationClass": "SOURCE_BACKED", + "parallelGroup": "p29-000", + "gate": "G1", + "card": "docs/tasks/WBV2-P29-000.md", + "behavior": "Authorize native Blender Main datablock implementation for advanced source-backed capabilities.", + "outputs": [ + "implementation-report", + "manifest", + "status" + ], + "acceptance": [ + "real Blender Main datablock is wired", + "unsupported input fails closed", + "implementation smoke is reproducible", + "verification remains deferred" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": true + }, + { + "id": "WBV2-P29-001", + "phase": "P29", + "title": "implement_geometry_nodes_native_datablock", + "kind": "feature", + "owner": "GEOMETRY", + "dependsOn": [ + "WBV2-P29-000" + ], + "parityId": "GEOMETRY_NODES.NATIVE_DATABLOCK", + "implementationClass": "SOURCE_BACKED", + "parallelGroup": "p29-001", + "gate": "IMPLEMENTATION", + "card": "docs/tasks/WBV2-P29-001.md", + "behavior": "Attach validated Geometry Node graphs to real Blender GeometryNodeTree and mesh modifier datablocks.", + "outputs": [ + "implementation-report", + "manifest", + "status" + ], + "acceptance": [ + "real Blender Main datablock is wired", + "unsupported input fails closed", + "implementation smoke is reproducible", + "verification remains deferred" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": false + }, + { + "id": "WBV2-P29-002", + "phase": "P29", + "title": "implement_physics_native_datablock", + "kind": "feature", + "owner": "SIMULATION", + "dependsOn": [ + "WBV2-P29-001" + ], + "parityId": "SIMULATION.NATIVE_DATABLOCK", + "implementationClass": "SOURCE_BACKED", + "parallelGroup": "p29-002", + "gate": "IMPLEMENTATION", + "card": "docs/tasks/WBV2-P29-002.md", + "behavior": "Attach validated physics manifests to native Blender object/modifier data where supported.", + "outputs": [ + "implementation-report", + "manifest", + "status" + ], + "acceptance": [ + "real Blender Main datablock is wired", + "unsupported input fails closed", + "implementation smoke is reproducible", + "verification remains deferred" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": false + }, + { + "id": "WBV2-P29-003", + "phase": "P29", + "title": "implement_compositor_sequencer_datablock", + "kind": "feature", + "owner": "RENDER", + "dependsOn": [ + "WBV2-P29-002" + ], + "parityId": "RENDER.COMPOSITOR_SEQUENCER_DATABLOCK", + "implementationClass": "SOURCE_BACKED", + "parallelGroup": "p29-003", + "gate": "IMPLEMENTATION", + "card": "docs/tasks/WBV2-P29-003.md", + "behavior": "Connect compositor and sequencer metadata to native Main data and web capability routes.", + "outputs": [ + "implementation-report", + "manifest", + "status" + ], + "acceptance": [ + "real Blender Main datablock is wired", + "unsupported input fails closed", + "implementation smoke is reproducible", + "verification remains deferred" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": false + }, + { + "id": "WBV2-P29-004", + "phase": "P29", + "title": "implement_native_datablock_smoke", + "kind": "enabling", + "owner": "RELEASE", + "dependsOn": [ + "WBV2-P29-003" + ], + "parityId": null, + "implementationClass": "SOURCE_BACKED", + "parallelGroup": "p29-004", + "gate": "IMPLEMENTATION", + "card": "docs/tasks/WBV2-P29-004.md", + "behavior": "Run bounded source build and startup smoke after native datablock implementation.", + "outputs": [ + "implementation-report", + "manifest", + "status" + ], + "acceptance": [ + "real Blender Main datablock is wired", + "unsupported input fails closed", + "implementation smoke is reproducible", + "verification remains deferred" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": false + } + ] +} diff --git a/tests/golden/WBV2-P29-004/task-context.json b/tests/golden/WBV2-P29-004/task-context.json new file mode 100644 index 000000000..bf02090bb --- /dev/null +++ b/tests/golden/WBV2-P29-004/task-context.json @@ -0,0 +1,172 @@ +{ + "schemaVersion": 1, + "task": "WBV2-P29-004", + "parentTask": "WBV2-P29-003", + "status": "in_progress", + "goal": "Run bounded source build and startup smoke after native datablock implementation.", + "scope": { + "gap": "workflow:implement_native_datablock_smoke", + "ownerFamily": "RELEASE", + "implementationClass": "SOURCE_BACKED" + }, + "commands": [ + "node tools/web/check-task-context.mjs --task WBV2-P29-004 --write" + ], + "inputPaths": [], + "inputSelection": { + "schemaVersion": 1, + "limits": { + "maxFiles": 12, + "evidenceBytes": 8192, + "contextRemainingBytes": 3199, + "contextRemainingTokens": 798 + }, + "source": { + "bytes": 6705, + "tokens": 1678 + }, + "selected": [], + "excluded": [ + { + "path": "blender-5.2.0/source/blender/web_engine/web_engine_main_state.cpp", + "bytes": 254201, + "reason": "EVIDENCE_BYTE_BUDGET" + }, + { + "path": "blender-5.2.0/source/blender/web_engine/web_engine_api.cpp", + "bytes": 127451, + "reason": "EVIDENCE_BYTE_BUDGET" + }, + { + "path": "web/protocol/web-engine.ts", + "bytes": 14979, + "reason": "EVIDENCE_BYTE_BUDGET" + }, + { + "path": "tests/golden/WBV2-P29-004/", + "bytes": null, + "reason": "GENERATED_EVIDENCE_OUTPUT" + }, + { + "path": "docs/status/WBV2-P29-004.md", + "bytes": null, + "reason": "GENERATED_EVIDENCE_OUTPUT" + }, + { + "path": "tests/golden/WBV2-P29-004/manifest.json", + "bytes": null, + "reason": "GENERATED_EVIDENCE_OUTPUT" + } + ], + "totals": { + "files": 0, + "bytes": 0, + "tokens": 0 + } + }, + "exitCriteria": [ + "focused command exits 0", + "report and manifest are hash-bound", + "failure path does not publish a late result" + ], + "nextTask": "WBV2-P30-000", + "sourceDocuments": { + "queue": "docs/EXECUTION_QUEUE.md", + "taskCard": "docs/tasks/WBV2-P29-004.md", + "taskIndex": "tests/golden/WBV2/task-index.json", + "parentManifest": "tests/golden/WBV2-P29-003/manifest.json", + "parentStatus": "docs/status/WBV2-P29-003.md" + }, + "readPolicy": { + "required": [ + "docs/EXECUTION_QUEUE.md", + "docs/tasks/WBV2-P29-004.md", + "tests/golden/WBV2-P29-003/manifest.json", + "docs/status/WBV2-P29-003.md" + ], + "machineOnly": [ + "tests/golden/WBV2/task-index.json", + "tests/golden/M15-03A/task-catalog.jsonl" + ], + "optionalByNeed": [ + "docs/WEB_BLENDER_MODELER_V1_SCOPE.md", + "任务卡列出的精确协议/生产路径", + "任务卡明确命名的长期计划小节" + ], + "forbiddenByDefault": [ + "完整 CURRENT_EXECUTION_PLAN.md", + "完整 PROJECT_STATUS_AND_NEXT_WORK.md", + "全部 docs/status/*.md", + "完整 parity/WBS 计划", + "README 历史和 test-results/" + ] + }, + "parent": { + "manifest": { + "schemaVersion": 1, + "task": "WBV2-P29-003", + "parentTask": "WBV2-P29-002", + "status": "done", + "nextTask": "WBV2-P29-004", + "artifactCount": 9 + }, + "statusSummary": [ + "# WBV2-P29-003 status", + "- task: `WBV2-P29-003`; parent: `WBV2-P29-002`; status: `done`", + "- native datablock family: `RENDER.COMPOSITOR_SEQUENCER_DATABLOCK`; source-backed implementation connected", + "- marker: `compositor`; duplicate protocol shim: `false`", + "- Chromium receipts and completion overlay: `DEFERRED`", + "- inventory unchanged: `6900` total, `281` legacy completed, `6618` legacy pending, `290/6609` effective carried forward", + "- nextTask: `WBV2-P29-004`" + ] + }, + "budgets": { + "queueBytes": 4096, + "taskBytes": 1280, + "parentManifestBytes": 24576, + "parentStatusBytes": 6144, + "evidenceFiles": 12, + "evidenceBytes": 8192, + "contextTokens": 3500, + "contextEnvelopeTokens": 1024, + "taskLines": 34, + "taskTokens": 320 + }, + "size": { + "documents": [ + { + "path": "docs/EXECUTION_QUEUE.md", + "bytes": 2803, + "lines": 51, + "tokens": 701 + }, + { + "path": "docs/tasks/WBV2-P29-004.md", + "bytes": 1280, + "lines": 34, + "tokens": 320 + }, + { + "path": "tests/golden/WBV2-P29-003/manifest.json", + "bytes": 2169, + "lines": 61, + "tokens": 543 + }, + { + "path": "docs/status/WBV2-P29-003.md", + "bytes": 453, + "lines": 9, + "tokens": 114 + } + ], + "sourceTokens": 1678, + "evidenceFiles": 0, + "evidenceBytes": 0, + "evidenceTokens": 0, + "totalTokens": 1678, + "reservedEnvelopeTokens": 1024, + "estimatedContextTokens": 2702, + "serializedContextTokens": 598, + "withinBudget": true + } +} diff --git a/tests/golden/WBV2-P30-000/animation-render-root-report.json b/tests/golden/WBV2-P30-000/animation-render-root-report.json new file mode 100644 index 000000000..bd9af34c9 --- /dev/null +++ b/tests/golden/WBV2-P30-000/animation-render-root-report.json @@ -0,0 +1,34 @@ +{ + "schemaVersion": 1, + "task": "WBV2-P30-000", + "operation": "AUTHORIZE_ANIMATION_RENDER_WORKBENCH", + "status": "PASS", + "parent": { + "task": "WBV2-P29-004", + "manifest": "tests/golden/WBV2-P29-004/manifest.json", + "manifestSha256": "19a4b853bd3b3ccc741144e0122a0cfb9eede7b68cd1d2b1c74b97e49ab30a4b" + }, + "scope": { + "firstTask": "WBV2-P30-001", + "plannedTasks": [ + "WBV2-P30-000", + "WBV2-P30-001", + "WBV2-P30-002", + "WBV2-P30-003", + "WBV2-P30-004" + ] + }, + "verification": { + "status": "DEFERRED", + "chromium": false, + "completionOverlay": false + }, + "inventory": { + "total": 6900, + "legacyCompleted": 281, + "legacyPending": 6618, + "effectiveCompleted": 290, + "effectivePending": 6609 + }, + "nextTask": "WBV2-P30-001" +} diff --git a/tests/golden/WBV2-P30-000/animation-render-task-plan.json b/tests/golden/WBV2-P30-000/animation-render-task-plan.json new file mode 100644 index 000000000..fe13408ee --- /dev/null +++ b/tests/golden/WBV2-P30-000/animation-render-task-plan.json @@ -0,0 +1,174 @@ +{ + "schemaVersion": 1, + "planId": "BLENDER_WEB_ANIMATION_RENDER_IMPLEMENTATION_P30", + "status": "ACTIVE_ANIMATION_RENDER_QUEUE", + "authority": "user_authorized_implementation_first_execution", + "executionPointer": "docs/EXECUTION_QUEUE.md", + "runtimePolicy": { + "blenderSource": "blender-5.2.0", + "mainAuthority": "blender_main", + "browserPolicy": "chromium_only_for_later_verification", + "verificationPolicy": "deferred", + "reusePolicy": "source_hash_behavior_hash_and_dedupe_key" + }, + "inventoryPolicy": { + "total": 6900, + "legacyCompleted": 281, + "legacyPending": 6618, + "effectiveCompleted": 290, + "effectivePending": 6609, + "overlayMutation": "forbidden_during_implementation_wave" + }, + "tasks": [ + { + "id": "WBV2-P30-000", + "phase": "P30", + "title": "authorize_animation_render_workbench", + "kind": "enabling", + "owner": "PROGRAM", + "dependsOn": [ + "WBV2-P29-004" + ], + "parityId": null, + "implementationClass": "SOURCE_BACKED", + "parallelGroup": "p30-000", + "gate": "G1", + "card": "docs/tasks/WBV2-P30-000.md", + "behavior": "Authorize the next source-backed workbench implementation wave.", + "outputs": [ + "implementation-report", + "manifest", + "status" + ], + "acceptance": [ + "real source or WebEngine Main path is wired", + "unsupported input fails closed", + "implementation smoke is reproducible", + "verification remains deferred" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": true + }, + { + "id": "WBV2-P30-001", + "phase": "P30", + "title": "implement_animation_nla_workbench", + "kind": "feature", + "owner": "ANIMATION", + "dependsOn": [ + "WBV2-P30-000" + ], + "parityId": "ANIMATION.NLA_WORKBENCH", + "implementationClass": "SOURCE_BACKED", + "parallelGroup": "p30-001", + "gate": "IMPLEMENTATION", + "card": "docs/tasks/WBV2-P30-001.md", + "behavior": "Expose active action, FCurve interpolation and NLA stack controls through the workbench.", + "outputs": [ + "implementation-report", + "manifest", + "status" + ], + "acceptance": [ + "real source or WebEngine Main path is wired", + "unsupported input fails closed", + "implementation smoke is reproducible", + "verification remains deferred" + ], + "status": "in_progress", + "ready": true, + "queueMutationAllowed": false + }, + { + "id": "WBV2-P30-002", + "phase": "P30", + "title": "implement_camera_light_world_workbench", + "kind": "feature", + "owner": "RENDER", + "dependsOn": [ + "WBV2-P30-001" + ], + "parityId": "RENDER.SCENE_PROPERTIES", + "implementationClass": "SOURCE_BACKED", + "parallelGroup": "p30-002", + "gate": "IMPLEMENTATION", + "card": "docs/tasks/WBV2-P30-002.md", + "behavior": "Expose camera, light and world property commands through the workbench.", + "outputs": [ + "implementation-report", + "manifest", + "status" + ], + "acceptance": [ + "real source or WebEngine Main path is wired", + "unsupported input fails closed", + "implementation smoke is reproducible", + "verification remains deferred" + ], + "status": "planned", + "ready": false, + "queueMutationAllowed": false + }, + { + "id": "WBV2-P30-003", + "phase": "P30", + "title": "implement_nonmesh_media_workbench", + "kind": "feature", + "owner": "GEOMETRY", + "dependsOn": [ + "WBV2-P30-002" + ], + "parityId": "GEOMETRY.NON_MESH_MEDIA", + "implementationClass": "SOURCE_BACKED", + "parallelGroup": "p30-003", + "gate": "IMPLEMENTATION", + "card": "docs/tasks/WBV2-P30-003.md", + "behavior": "Expose font, volume, metaball and non-mesh editing controls.", + "outputs": [ + "implementation-report", + "manifest", + "status" + ], + "acceptance": [ + "real source or WebEngine Main path is wired", + "unsupported input fails closed", + "implementation smoke is reproducible", + "verification remains deferred" + ], + "status": "planned", + "ready": false, + "queueMutationAllowed": false + }, + { + "id": "WBV2-P30-004", + "phase": "P30", + "title": "run_p30_implementation_smoke", + "kind": "enabling", + "owner": "RELEASE", + "dependsOn": [ + "WBV2-P30-003" + ], + "parityId": null, + "implementationClass": "SOURCE_BACKED", + "parallelGroup": "p30-004", + "gate": "IMPLEMENTATION", + "card": "docs/tasks/WBV2-P30-004.md", + "behavior": "Run bounded build and startup smoke after P30 implementation.", + "outputs": [ + "implementation-report", + "manifest", + "status" + ], + "acceptance": [ + "real source or WebEngine Main path is wired", + "unsupported input fails closed", + "implementation smoke is reproducible", + "verification remains deferred" + ], + "status": "planned", + "ready": false, + "queueMutationAllowed": false + } + ] +} diff --git a/tests/golden/WBV2-P30-000/manifest.json b/tests/golden/WBV2-P30-000/manifest.json new file mode 100644 index 000000000..836e2c51c --- /dev/null +++ b/tests/golden/WBV2-P30-000/manifest.json @@ -0,0 +1,43 @@ +{ + "schemaVersion": 1, + "task": "WBV2-P30-000", + "parentTask": "WBV2-P29-004", + "operation": "AUTHORIZE_ANIMATION_RENDER_WORKBENCH", + "status": "done", + "enablingTask": true, + "parityStateChange": false, + "runtime": "SOURCE_BACKED_ANIMATION_RENDER_QUEUE", + "artifacts": { + "parentManifest": { + "path": "tests/golden/WBV2-P29-004/manifest.json", + "sha256": "8984c3828be6553a22dec26befa552795254d0f21d9209feb90ce388ae50c6b6" + }, + "plan": { + "path": "tests/golden/WBV2-P30-000/animation-render-task-plan.json", + "sha256": "a30f0c76d54f77195aebcf0ac1ed48204222f6156b50b60f4f1ab80bb18f7536" + }, + "report": { + "path": "tests/golden/WBV2-P30-000/animation-render-root-report.json", + "sha256": "00b0ad1e9d0f9b93617e2b6f65996051b1383d0198cda2905b5337fe238928b5" + }, + "rootCard": { + "path": "docs/tasks/WBV2-P30-000.md", + "sha256": "e341b0a7cb8da6ddfaf2cbf4a1cb0ebf9d99003ffd5cfa87f1f776bd04749556" + }, + "rootStatus": { + "path": "docs/status/WBV2-P30-000.md", + "sha256": "f3d4fdcd2e11fb6c334abdeb40b64d7386e34084a522ae6e1f811dbdbf5bccef" + } + }, + "assertions": { + "animationRenderImplementation": true, + "plannedTasks": 5, + "verificationDeferred": true, + "completionOverlayWritten": false, + "inventoryTotal": 6900, + "effectiveCompleted": 290, + "effectivePending": 6609, + "historicalReproduction": false + }, + "nextTask": "WBV2-P30-001" +} diff --git a/tests/golden/WBV2-P30-001/animation-render-task-plan.json b/tests/golden/WBV2-P30-001/animation-render-task-plan.json new file mode 100644 index 000000000..132461403 --- /dev/null +++ b/tests/golden/WBV2-P30-001/animation-render-task-plan.json @@ -0,0 +1,174 @@ +{ + "schemaVersion": 1, + "planId": "BLENDER_WEB_ANIMATION_RENDER_IMPLEMENTATION_P30", + "status": "ACTIVE_ANIMATION_RENDER_QUEUE", + "authority": "user_authorized_implementation_first_execution", + "executionPointer": "docs/EXECUTION_QUEUE.md", + "runtimePolicy": { + "blenderSource": "blender-5.2.0", + "mainAuthority": "blender_main", + "browserPolicy": "chromium_only_for_later_verification", + "verificationPolicy": "deferred", + "reusePolicy": "source_hash_behavior_hash_and_dedupe_key" + }, + "inventoryPolicy": { + "total": 6900, + "legacyCompleted": 281, + "legacyPending": 6618, + "effectiveCompleted": 290, + "effectivePending": 6609, + "overlayMutation": "forbidden_during_implementation_wave" + }, + "tasks": [ + { + "id": "WBV2-P30-000", + "phase": "P30", + "title": "authorize_animation_render_workbench", + "kind": "enabling", + "owner": "PROGRAM", + "dependsOn": [ + "WBV2-P29-004" + ], + "parityId": null, + "implementationClass": "SOURCE_BACKED", + "parallelGroup": "p30-000", + "gate": "G1", + "card": "docs/tasks/WBV2-P30-000.md", + "behavior": "Authorize the next source-backed workbench implementation wave.", + "outputs": [ + "implementation-report", + "manifest", + "status" + ], + "acceptance": [ + "real source or WebEngine Main path is wired", + "unsupported input fails closed", + "implementation smoke is reproducible", + "verification remains deferred" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": true + }, + { + "id": "WBV2-P30-001", + "phase": "P30", + "title": "implement_animation_nla_workbench", + "kind": "feature", + "owner": "ANIMATION", + "dependsOn": [ + "WBV2-P30-000" + ], + "parityId": "ANIMATION.NLA_WORKBENCH", + "implementationClass": "SOURCE_BACKED", + "parallelGroup": "p30-001", + "gate": "IMPLEMENTATION", + "card": "docs/tasks/WBV2-P30-001.md", + "behavior": "Expose active action, FCurve interpolation and NLA stack controls through the workbench.", + "outputs": [ + "implementation-report", + "manifest", + "status" + ], + "acceptance": [ + "real source or WebEngine Main path is wired", + "unsupported input fails closed", + "implementation smoke is reproducible", + "verification remains deferred" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": false + }, + { + "id": "WBV2-P30-002", + "phase": "P30", + "title": "implement_camera_light_world_workbench", + "kind": "feature", + "owner": "RENDER", + "dependsOn": [ + "WBV2-P30-001" + ], + "parityId": "RENDER.SCENE_PROPERTIES", + "implementationClass": "SOURCE_BACKED", + "parallelGroup": "p30-002", + "gate": "IMPLEMENTATION", + "card": "docs/tasks/WBV2-P30-002.md", + "behavior": "Expose camera, light and world property commands through the workbench.", + "outputs": [ + "implementation-report", + "manifest", + "status" + ], + "acceptance": [ + "real source or WebEngine Main path is wired", + "unsupported input fails closed", + "implementation smoke is reproducible", + "verification remains deferred" + ], + "status": "in_progress", + "ready": true, + "queueMutationAllowed": false + }, + { + "id": "WBV2-P30-003", + "phase": "P30", + "title": "implement_nonmesh_media_workbench", + "kind": "feature", + "owner": "GEOMETRY", + "dependsOn": [ + "WBV2-P30-002" + ], + "parityId": "GEOMETRY.NON_MESH_MEDIA", + "implementationClass": "SOURCE_BACKED", + "parallelGroup": "p30-003", + "gate": "IMPLEMENTATION", + "card": "docs/tasks/WBV2-P30-003.md", + "behavior": "Expose font, volume, metaball and non-mesh editing controls.", + "outputs": [ + "implementation-report", + "manifest", + "status" + ], + "acceptance": [ + "real source or WebEngine Main path is wired", + "unsupported input fails closed", + "implementation smoke is reproducible", + "verification remains deferred" + ], + "status": "planned", + "ready": false, + "queueMutationAllowed": false + }, + { + "id": "WBV2-P30-004", + "phase": "P30", + "title": "run_p30_implementation_smoke", + "kind": "enabling", + "owner": "RELEASE", + "dependsOn": [ + "WBV2-P30-003" + ], + "parityId": null, + "implementationClass": "SOURCE_BACKED", + "parallelGroup": "p30-004", + "gate": "IMPLEMENTATION", + "card": "docs/tasks/WBV2-P30-004.md", + "behavior": "Run bounded build and startup smoke after P30 implementation.", + "outputs": [ + "implementation-report", + "manifest", + "status" + ], + "acceptance": [ + "real source or WebEngine Main path is wired", + "unsupported input fails closed", + "implementation smoke is reproducible", + "verification remains deferred" + ], + "status": "planned", + "ready": false, + "queueMutationAllowed": false + } + ] +} diff --git a/tests/golden/WBV2-P30-001/implementation-report.json b/tests/golden/WBV2-P30-001/implementation-report.json new file mode 100644 index 000000000..1f2b02e0b --- /dev/null +++ b/tests/golden/WBV2-P30-001/implementation-report.json @@ -0,0 +1,27 @@ +{ + "schemaVersion": 1, + "task": "WBV2-P30-001", + "operation": "IMPLEMENT_ANIMATION_RENDER_FAMILY", + "status": "PASS", + "family": "ANIMATION.NLA_WORKBENCH", + "sourceBacked": true, + "marker": "animationRenderCommands", + "sourcePaths": [ + "web/protocol/animation-render-commands.ts", + "web/app/src/app/App.tsx", + "web/protocol/web-engine.ts" + ], + "verification": { + "status": "DEFERRED", + "chromium": false, + "completionOverlay": false + }, + "inventory": { + "total": 6900, + "legacyCompleted": 281, + "legacyPending": 6618, + "effectiveCompleted": 290, + "effectivePending": 6609 + }, + "nextTask": "WBV2-P30-002" +} diff --git a/tests/golden/WBV2-P30-001/manifest.json b/tests/golden/WBV2-P30-001/manifest.json new file mode 100644 index 000000000..974eb2fa5 --- /dev/null +++ b/tests/golden/WBV2-P30-001/manifest.json @@ -0,0 +1,55 @@ +{ + "schemaVersion": 1, + "task": "WBV2-P30-001", + "parentTask": "WBV2-P30-000", + "operation": "IMPLEMENT_ANIMATION_RENDER_FAMILY", + "status": "done", + "enablingTask": false, + "parityStateChange": false, + "runtime": "SOURCE_BACKED_ANIMATION_RENDER_IMPLEMENTATION", + "artifacts": { + "parentManifest": { + "path": "tests/golden/WBV2-P30-000/manifest.json", + "sha256": "50d55ebe1c4cdb3b8e545286ba4a8aba58de74d6d0c6887740ac5fff57feebe2" + }, + "animation_render_commands_ts": { + "path": "web/protocol/animation-render-commands.ts", + "sha256": "9824e8a9abcb55f951f115aa113679ec0542fc246426e0f325099d44dfa76157" + }, + "App_tsx": { + "path": "web/app/src/app/App.tsx", + "sha256": "8c3ee6086716be3912a9597091642ee3416ee766a6aaedea7ca642ed7a9c3b53" + }, + "web_engine_ts": { + "path": "web/protocol/web-engine.ts", + "sha256": "3c4aba796afb70a6b29d34cca4ba924ffb1a240549b79730d1a639ca913ee896" + }, + "report": { + "path": "tests/golden/WBV2-P30-001/implementation-report.json", + "sha256": "f773ef3c534d526789ec5a05af4f1d05cd79c159292ca151c2f7c36421b780d2" + }, + "status": { + "path": "docs/status/WBV2-P30-001.md", + "sha256": "7341aa426b06a8d019e86d965ff974558706cf97bc96fd1deb93a46c4d2d4459" + }, + "plan": { + "path": "tests/golden/WBV2-P30-001/animation-render-task-plan.json", + "sha256": "c1dee9be1f7dd6c207806392eea4283d86b0fa8cf3fc6c7875b43295c33cf1e8" + }, + "taskContext": { + "path": "tests/golden/WBV2-P30-001/task-context.json", + "sha256": "827c4bfbb715382362f17afae9302364345cb9c3e86bc625e642528f01cbdc5a" + } + }, + "assertions": { + "capabilityFamily": "ANIMATION.NLA_WORKBENCH", + "sourceBacked": true, + "verificationDeferred": true, + "completionOverlayWritten": false, + "inventoryTotal": 6900, + "effectiveCompleted": 290, + "effectivePending": 6609, + "historicalReproduction": false + }, + "nextTask": "WBV2-P30-002" +} diff --git a/tests/golden/WBV2-P30-001/task-context.json b/tests/golden/WBV2-P30-001/task-context.json new file mode 100644 index 000000000..1c0a706a1 --- /dev/null +++ b/tests/golden/WBV2-P30-001/task-context.json @@ -0,0 +1,168 @@ +{ + "schemaVersion": 1, + "task": "WBV2-P30-001", + "parentTask": "WBV2-P30-000", + "status": "in_progress", + "goal": "Expose active action, FCurve interpolation and NLA stack controls through the workbench.", + "scope": { + "gap": "ANIMATION.NLA_WORKBENCH", + "ownerFamily": "ANIMATION", + "implementationClass": "SOURCE_BACKED" + }, + "commands": [ + "node tools/web/check-task-context.mjs --task WBV2-P30-001 --write" + ], + "inputPaths": [], + "inputSelection": { + "schemaVersion": 1, + "limits": { + "maxFiles": 12, + "evidenceBytes": 8192, + "contextRemainingBytes": 4010, + "contextRemainingTokens": 1001 + }, + "source": { + "bytes": 5894, + "tokens": 1475 + }, + "selected": [], + "excluded": [ + { + "path": "blender-5.2.0/source/blender/web_engine/web_engine_main_state.cpp", + "bytes": 254201, + "reason": "EVIDENCE_BYTE_BUDGET" + }, + { + "path": "web/protocol/web-engine.ts", + "bytes": 14979, + "reason": "EVIDENCE_BYTE_BUDGET" + }, + { + "path": "tests/golden/WBV2-P30-001/", + "bytes": null, + "reason": "GENERATED_EVIDENCE_OUTPUT" + }, + { + "path": "docs/status/WBV2-P30-001.md", + "bytes": null, + "reason": "GENERATED_EVIDENCE_OUTPUT" + }, + { + "path": "tests/golden/WBV2-P30-001/manifest.json", + "bytes": null, + "reason": "GENERATED_EVIDENCE_OUTPUT" + } + ], + "totals": { + "files": 0, + "bytes": 0, + "tokens": 0 + } + }, + "exitCriteria": [ + "real source or WebEngine Main path is wired", + "unsupported input fails closed", + "implementation smoke is reproducible", + "verification remains deferred" + ], + "nextTask": "WBV2-P30-002", + "sourceDocuments": { + "queue": "docs/EXECUTION_QUEUE.md", + "taskCard": "docs/tasks/WBV2-P30-001.md", + "taskIndex": "tests/golden/WBV2/task-index.json", + "parentManifest": "tests/golden/WBV2-P30-000/manifest.json", + "parentStatus": "docs/status/WBV2-P30-000.md" + }, + "readPolicy": { + "required": [ + "docs/EXECUTION_QUEUE.md", + "docs/tasks/WBV2-P30-001.md", + "tests/golden/WBV2-P30-000/manifest.json", + "docs/status/WBV2-P30-000.md" + ], + "machineOnly": [ + "tests/golden/WBV2/task-index.json", + "tests/golden/M15-03A/task-catalog.jsonl" + ], + "optionalByNeed": [ + "docs/WEB_BLENDER_MODELER_V1_SCOPE.md", + "任务卡列出的精确协议/生产路径", + "任务卡明确命名的长期计划小节" + ], + "forbiddenByDefault": [ + "完整 CURRENT_EXECUTION_PLAN.md", + "完整 PROJECT_STATUS_AND_NEXT_WORK.md", + "全部 docs/status/*.md", + "完整 parity/WBS 计划", + "README 历史和 test-results/" + ] + }, + "parent": { + "manifest": { + "schemaVersion": 1, + "task": "WBV2-P30-000", + "parentTask": "WBV2-P29-004", + "status": "done", + "nextTask": "WBV2-P30-001", + "artifactCount": 5 + }, + "statusSummary": [ + "# WBV2-P30-000 status", + "- task: `WBV2-P30-000`; parent: `WBV2-P29-004`; status: `done`", + "- Animation/Render workbench implementation wave authorized", + "- first task: `WBV2-P30-001`", + "- verification receipts and completion overlays: `DEFERRED`", + "- inventory unchanged: `6900` total, `281` legacy completed, `6618` legacy pending, `290/6609` effective carried forward", + "- nextTask: `WBV2-P30-001`" + ] + }, + "budgets": { + "queueBytes": 4096, + "taskBytes": 1265, + "parentManifestBytes": 24576, + "parentStatusBytes": 6144, + "evidenceFiles": 12, + "evidenceBytes": 8192, + "contextTokens": 3500, + "contextEnvelopeTokens": 1024, + "taskLines": 34, + "taskTokens": 317 + }, + "size": { + "documents": [ + { + "path": "docs/EXECUTION_QUEUE.md", + "bytes": 2803, + "lines": 51, + "tokens": 701 + }, + { + "path": "docs/tasks/WBV2-P30-001.md", + "bytes": 1265, + "lines": 34, + "tokens": 317 + }, + { + "path": "tests/golden/WBV2-P30-000/manifest.json", + "bytes": 1443, + "lines": 44, + "tokens": 361 + }, + { + "path": "docs/status/WBV2-P30-000.md", + "bytes": 383, + "lines": 9, + "tokens": 96 + } + ], + "sourceTokens": 1475, + "evidenceFiles": 0, + "evidenceBytes": 0, + "evidenceTokens": 0, + "totalTokens": 1475, + "reservedEnvelopeTokens": 1024, + "estimatedContextTokens": 2499, + "serializedContextTokens": 607, + "withinBudget": true + } +} diff --git a/tests/golden/WBV2-P30-002/animation-render-task-plan.json b/tests/golden/WBV2-P30-002/animation-render-task-plan.json new file mode 100644 index 000000000..d2d472a2f --- /dev/null +++ b/tests/golden/WBV2-P30-002/animation-render-task-plan.json @@ -0,0 +1,174 @@ +{ + "schemaVersion": 1, + "planId": "BLENDER_WEB_ANIMATION_RENDER_IMPLEMENTATION_P30", + "status": "ACTIVE_ANIMATION_RENDER_QUEUE", + "authority": "user_authorized_implementation_first_execution", + "executionPointer": "docs/EXECUTION_QUEUE.md", + "runtimePolicy": { + "blenderSource": "blender-5.2.0", + "mainAuthority": "blender_main", + "browserPolicy": "chromium_only_for_later_verification", + "verificationPolicy": "deferred", + "reusePolicy": "source_hash_behavior_hash_and_dedupe_key" + }, + "inventoryPolicy": { + "total": 6900, + "legacyCompleted": 281, + "legacyPending": 6618, + "effectiveCompleted": 290, + "effectivePending": 6609, + "overlayMutation": "forbidden_during_implementation_wave" + }, + "tasks": [ + { + "id": "WBV2-P30-000", + "phase": "P30", + "title": "authorize_animation_render_workbench", + "kind": "enabling", + "owner": "PROGRAM", + "dependsOn": [ + "WBV2-P29-004" + ], + "parityId": null, + "implementationClass": "SOURCE_BACKED", + "parallelGroup": "p30-000", + "gate": "G1", + "card": "docs/tasks/WBV2-P30-000.md", + "behavior": "Authorize the next source-backed workbench implementation wave.", + "outputs": [ + "implementation-report", + "manifest", + "status" + ], + "acceptance": [ + "real source or WebEngine Main path is wired", + "unsupported input fails closed", + "implementation smoke is reproducible", + "verification remains deferred" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": true + }, + { + "id": "WBV2-P30-001", + "phase": "P30", + "title": "implement_animation_nla_workbench", + "kind": "feature", + "owner": "ANIMATION", + "dependsOn": [ + "WBV2-P30-000" + ], + "parityId": "ANIMATION.NLA_WORKBENCH", + "implementationClass": "SOURCE_BACKED", + "parallelGroup": "p30-001", + "gate": "IMPLEMENTATION", + "card": "docs/tasks/WBV2-P30-001.md", + "behavior": "Expose active action, FCurve interpolation and NLA stack controls through the workbench.", + "outputs": [ + "implementation-report", + "manifest", + "status" + ], + "acceptance": [ + "real source or WebEngine Main path is wired", + "unsupported input fails closed", + "implementation smoke is reproducible", + "verification remains deferred" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": false + }, + { + "id": "WBV2-P30-002", + "phase": "P30", + "title": "implement_camera_light_world_workbench", + "kind": "feature", + "owner": "RENDER", + "dependsOn": [ + "WBV2-P30-001" + ], + "parityId": "RENDER.SCENE_PROPERTIES", + "implementationClass": "SOURCE_BACKED", + "parallelGroup": "p30-002", + "gate": "IMPLEMENTATION", + "card": "docs/tasks/WBV2-P30-002.md", + "behavior": "Expose camera, light and world property commands through the workbench.", + "outputs": [ + "implementation-report", + "manifest", + "status" + ], + "acceptance": [ + "real source or WebEngine Main path is wired", + "unsupported input fails closed", + "implementation smoke is reproducible", + "verification remains deferred" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": false + }, + { + "id": "WBV2-P30-003", + "phase": "P30", + "title": "implement_nonmesh_media_workbench", + "kind": "feature", + "owner": "GEOMETRY", + "dependsOn": [ + "WBV2-P30-002" + ], + "parityId": "GEOMETRY.NON_MESH_MEDIA", + "implementationClass": "SOURCE_BACKED", + "parallelGroup": "p30-003", + "gate": "IMPLEMENTATION", + "card": "docs/tasks/WBV2-P30-003.md", + "behavior": "Expose font, volume, metaball and non-mesh editing controls.", + "outputs": [ + "implementation-report", + "manifest", + "status" + ], + "acceptance": [ + "real source or WebEngine Main path is wired", + "unsupported input fails closed", + "implementation smoke is reproducible", + "verification remains deferred" + ], + "status": "in_progress", + "ready": true, + "queueMutationAllowed": false + }, + { + "id": "WBV2-P30-004", + "phase": "P30", + "title": "run_p30_implementation_smoke", + "kind": "enabling", + "owner": "RELEASE", + "dependsOn": [ + "WBV2-P30-003" + ], + "parityId": null, + "implementationClass": "SOURCE_BACKED", + "parallelGroup": "p30-004", + "gate": "IMPLEMENTATION", + "card": "docs/tasks/WBV2-P30-004.md", + "behavior": "Run bounded build and startup smoke after P30 implementation.", + "outputs": [ + "implementation-report", + "manifest", + "status" + ], + "acceptance": [ + "real source or WebEngine Main path is wired", + "unsupported input fails closed", + "implementation smoke is reproducible", + "verification remains deferred" + ], + "status": "planned", + "ready": false, + "queueMutationAllowed": false + } + ] +} diff --git a/tests/golden/WBV2-P30-002/implementation-report.json b/tests/golden/WBV2-P30-002/implementation-report.json new file mode 100644 index 000000000..18dd8a132 --- /dev/null +++ b/tests/golden/WBV2-P30-002/implementation-report.json @@ -0,0 +1,28 @@ +{ + "schemaVersion": 1, + "task": "WBV2-P30-002", + "operation": "IMPLEMENT_ANIMATION_RENDER_FAMILY", + "status": "PASS", + "family": "RENDER.SCENE_PROPERTIES", + "sourceBacked": true, + "marker": "set_render_properties", + "sourcePaths": [ + "blender-5.2.0/source/blender/web_engine/web_engine_main_state.cpp", + "blender-5.2.0/source/blender/web_engine/web_engine_api.cpp", + "web/protocol/animation-render-commands.ts", + "web/app/src/app/App.tsx" + ], + "verification": { + "status": "DEFERRED", + "chromium": false, + "completionOverlay": false + }, + "inventory": { + "total": 6900, + "legacyCompleted": 281, + "legacyPending": 6618, + "effectiveCompleted": 290, + "effectivePending": 6609 + }, + "nextTask": "WBV2-P30-003" +} diff --git a/tests/golden/WBV2-P30-002/manifest.json b/tests/golden/WBV2-P30-002/manifest.json new file mode 100644 index 000000000..1a3ef9ee3 --- /dev/null +++ b/tests/golden/WBV2-P30-002/manifest.json @@ -0,0 +1,59 @@ +{ + "schemaVersion": 1, + "task": "WBV2-P30-002", + "parentTask": "WBV2-P30-001", + "operation": "IMPLEMENT_ANIMATION_RENDER_FAMILY", + "status": "done", + "enablingTask": false, + "parityStateChange": false, + "runtime": "SOURCE_BACKED_ANIMATION_RENDER_IMPLEMENTATION", + "artifacts": { + "parentManifest": { + "path": "tests/golden/WBV2-P30-001/manifest.json", + "sha256": "efd0dff21cdec612aedbe885afba06ab611c2645a62ea5f0805c5f48fa96f1f8" + }, + "web_engine_main_state_cpp": { + "path": "blender-5.2.0/source/blender/web_engine/web_engine_main_state.cpp", + "sha256": "7803654bf15db8645b65e0653eb3599b46f969d65c5a1a365daeee51079259d4" + }, + "web_engine_api_cpp": { + "path": "blender-5.2.0/source/blender/web_engine/web_engine_api.cpp", + "sha256": "6a3eebde527f029fce7666a080e8cac1a60de944aee372bfe772ee6e2adabbdf" + }, + "animation_render_commands_ts": { + "path": "web/protocol/animation-render-commands.ts", + "sha256": "9824e8a9abcb55f951f115aa113679ec0542fc246426e0f325099d44dfa76157" + }, + "App_tsx": { + "path": "web/app/src/app/App.tsx", + "sha256": "8c3ee6086716be3912a9597091642ee3416ee766a6aaedea7ca642ed7a9c3b53" + }, + "report": { + "path": "tests/golden/WBV2-P30-002/implementation-report.json", + "sha256": "0a926c7c97e69632d83d6166b94f843d8a49fd3e309ecd3be11ddeb529423cd8" + }, + "status": { + "path": "docs/status/WBV2-P30-002.md", + "sha256": "dc6c44220e213a36940305f6f97dd85ddfc2c01c04c35c45f5cdd48f0bd4294b" + }, + "plan": { + "path": "tests/golden/WBV2-P30-002/animation-render-task-plan.json", + "sha256": "f1849504b9310ac0e6188e04daa2c3c1a0a126ea7e809f6f91cfb439fe2f9523" + }, + "taskContext": { + "path": "tests/golden/WBV2-P30-002/task-context.json", + "sha256": "2f11d80e2b2a9cbe25dcd31a61e520afa0411b7dea0f1d37203a4266caac1b9b" + } + }, + "assertions": { + "capabilityFamily": "RENDER.SCENE_PROPERTIES", + "sourceBacked": true, + "verificationDeferred": true, + "completionOverlayWritten": false, + "inventoryTotal": 6900, + "effectiveCompleted": 290, + "effectivePending": 6609, + "historicalReproduction": false + }, + "nextTask": "WBV2-P30-003" +} diff --git a/tests/golden/WBV2-P30-002/task-context.json b/tests/golden/WBV2-P30-002/task-context.json new file mode 100644 index 000000000..077e493a2 --- /dev/null +++ b/tests/golden/WBV2-P30-002/task-context.json @@ -0,0 +1,167 @@ +{ + "schemaVersion": 1, + "task": "WBV2-P30-002", + "parentTask": "WBV2-P30-001", + "status": "in_progress", + "goal": "Expose camera, light and world property commands through the workbench.", + "scope": { + "gap": "RENDER.SCENE_PROPERTIES", + "ownerFamily": "RENDER", + "implementationClass": "SOURCE_BACKED" + }, + "commands": [ + "node tools/web/check-task-context.mjs --task WBV2-P30-002 --write" + ], + "inputPaths": [], + "inputSelection": { + "schemaVersion": 1, + "limits": { + "maxFiles": 12, + "evidenceBytes": 8192, + "contextRemainingBytes": 3564, + "contextRemainingTokens": 889 + }, + "source": { + "bytes": 6340, + "tokens": 1587 + }, + "selected": [], + "excluded": [ + { + "path": "blender-5.2.0/source/blender/web_engine/web_engine_main_state.cpp", + "bytes": 254201, + "reason": "EVIDENCE_BYTE_BUDGET" + }, + { + "path": "web/protocol/web-engine.ts", + "bytes": 14979, + "reason": "EVIDENCE_BYTE_BUDGET" + }, + { + "path": "tests/golden/WBV2-P30-002/", + "bytes": null, + "reason": "GENERATED_EVIDENCE_OUTPUT" + }, + { + "path": "docs/status/WBV2-P30-002.md", + "bytes": null, + "reason": "GENERATED_EVIDENCE_OUTPUT" + }, + { + "path": "tests/golden/WBV2-P30-002/manifest.json", + "bytes": null, + "reason": "GENERATED_EVIDENCE_OUTPUT" + } + ], + "totals": { + "files": 0, + "bytes": 0, + "tokens": 0 + } + }, + "exitCriteria": [ + "real source or WebEngine Main path is wired", + "unsupported input fails closed", + "implementation smoke is reproducible", + "verification remains deferred" + ], + "nextTask": "WBV2-P30-003", + "sourceDocuments": { + "queue": "docs/EXECUTION_QUEUE.md", + "taskCard": "docs/tasks/WBV2-P30-002.md", + "taskIndex": "tests/golden/WBV2/task-index.json", + "parentManifest": "tests/golden/WBV2-P30-001/manifest.json", + "parentStatus": "docs/status/WBV2-P30-001.md" + }, + "readPolicy": { + "required": [ + "docs/EXECUTION_QUEUE.md", + "docs/tasks/WBV2-P30-002.md", + "tests/golden/WBV2-P30-001/manifest.json", + "docs/status/WBV2-P30-001.md" + ], + "machineOnly": [ + "tests/golden/WBV2/task-index.json", + "tests/golden/M15-03A/task-catalog.jsonl" + ], + "optionalByNeed": [ + "docs/WEB_BLENDER_MODELER_V1_SCOPE.md", + "任务卡列出的精确协议/生产路径", + "任务卡明确命名的长期计划小节" + ], + "forbiddenByDefault": [ + "完整 CURRENT_EXECUTION_PLAN.md", + "完整 PROJECT_STATUS_AND_NEXT_WORK.md", + "全部 docs/status/*.md", + "完整 parity/WBS 计划", + "README 历史和 test-results/" + ] + }, + "parent": { + "manifest": { + "schemaVersion": 1, + "task": "WBV2-P30-001", + "parentTask": "WBV2-P30-000", + "status": "done", + "nextTask": "WBV2-P30-002", + "artifactCount": 8 + }, + "statusSummary": [ + "# WBV2-P30-001 status", + "- task: `WBV2-P30-001`; parent: `WBV2-P30-000`; status: `done`", + "- source-backed implementation family: `ANIMATION.NLA_WORKBENCH`; marker: `animationRenderCommands`", + "- Chromium receipts and completion overlay: `DEFERRED`", + "- inventory unchanged: `6900/6618`, effective `290/6609`", + "- nextTask: `WBV2-P30-002`" + ] + }, + "budgets": { + "queueBytes": 4096, + "taskBytes": 1250, + "parentManifestBytes": 24576, + "parentStatusBytes": 6144, + "evidenceFiles": 12, + "evidenceBytes": 8192, + "contextTokens": 3500, + "contextEnvelopeTokens": 1024, + "taskLines": 34, + "taskTokens": 313 + }, + "size": { + "documents": [ + { + "path": "docs/EXECUTION_QUEUE.md", + "bytes": 2803, + "lines": 51, + "tokens": 701 + }, + { + "path": "docs/tasks/WBV2-P30-002.md", + "bytes": 1250, + "lines": 34, + "tokens": 313 + }, + { + "path": "tests/golden/WBV2-P30-001/manifest.json", + "bytes": 1962, + "lines": 56, + "tokens": 491 + }, + { + "path": "docs/status/WBV2-P30-001.md", + "bytes": 325, + "lines": 8, + "tokens": 82 + } + ], + "sourceTokens": 1587, + "evidenceFiles": 0, + "evidenceBytes": 0, + "evidenceTokens": 0, + "totalTokens": 1587, + "reservedEnvelopeTokens": 1024, + "estimatedContextTokens": 2611, + "serializedContextTokens": 602, + "withinBudget": true + } +} diff --git a/tests/golden/WBV2-P30-003/animation-render-task-plan.json b/tests/golden/WBV2-P30-003/animation-render-task-plan.json new file mode 100644 index 000000000..d3fb07a56 --- /dev/null +++ b/tests/golden/WBV2-P30-003/animation-render-task-plan.json @@ -0,0 +1,174 @@ +{ + "schemaVersion": 1, + "planId": "BLENDER_WEB_ANIMATION_RENDER_IMPLEMENTATION_P30", + "status": "ACTIVE_ANIMATION_RENDER_QUEUE", + "authority": "user_authorized_implementation_first_execution", + "executionPointer": "docs/EXECUTION_QUEUE.md", + "runtimePolicy": { + "blenderSource": "blender-5.2.0", + "mainAuthority": "blender_main", + "browserPolicy": "chromium_only_for_later_verification", + "verificationPolicy": "deferred", + "reusePolicy": "source_hash_behavior_hash_and_dedupe_key" + }, + "inventoryPolicy": { + "total": 6900, + "legacyCompleted": 281, + "legacyPending": 6618, + "effectiveCompleted": 290, + "effectivePending": 6609, + "overlayMutation": "forbidden_during_implementation_wave" + }, + "tasks": [ + { + "id": "WBV2-P30-000", + "phase": "P30", + "title": "authorize_animation_render_workbench", + "kind": "enabling", + "owner": "PROGRAM", + "dependsOn": [ + "WBV2-P29-004" + ], + "parityId": null, + "implementationClass": "SOURCE_BACKED", + "parallelGroup": "p30-000", + "gate": "G1", + "card": "docs/tasks/WBV2-P30-000.md", + "behavior": "Authorize the next source-backed workbench implementation wave.", + "outputs": [ + "implementation-report", + "manifest", + "status" + ], + "acceptance": [ + "real source or WebEngine Main path is wired", + "unsupported input fails closed", + "implementation smoke is reproducible", + "verification remains deferred" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": true + }, + { + "id": "WBV2-P30-001", + "phase": "P30", + "title": "implement_animation_nla_workbench", + "kind": "feature", + "owner": "ANIMATION", + "dependsOn": [ + "WBV2-P30-000" + ], + "parityId": "ANIMATION.NLA_WORKBENCH", + "implementationClass": "SOURCE_BACKED", + "parallelGroup": "p30-001", + "gate": "IMPLEMENTATION", + "card": "docs/tasks/WBV2-P30-001.md", + "behavior": "Expose active action, FCurve interpolation and NLA stack controls through the workbench.", + "outputs": [ + "implementation-report", + "manifest", + "status" + ], + "acceptance": [ + "real source or WebEngine Main path is wired", + "unsupported input fails closed", + "implementation smoke is reproducible", + "verification remains deferred" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": false + }, + { + "id": "WBV2-P30-002", + "phase": "P30", + "title": "implement_camera_light_world_workbench", + "kind": "feature", + "owner": "RENDER", + "dependsOn": [ + "WBV2-P30-001" + ], + "parityId": "RENDER.SCENE_PROPERTIES", + "implementationClass": "SOURCE_BACKED", + "parallelGroup": "p30-002", + "gate": "IMPLEMENTATION", + "card": "docs/tasks/WBV2-P30-002.md", + "behavior": "Expose camera, light and world property commands through the workbench.", + "outputs": [ + "implementation-report", + "manifest", + "status" + ], + "acceptance": [ + "real source or WebEngine Main path is wired", + "unsupported input fails closed", + "implementation smoke is reproducible", + "verification remains deferred" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": false + }, + { + "id": "WBV2-P30-003", + "phase": "P30", + "title": "implement_nonmesh_media_workbench", + "kind": "feature", + "owner": "GEOMETRY", + "dependsOn": [ + "WBV2-P30-002" + ], + "parityId": "GEOMETRY.NON_MESH_MEDIA", + "implementationClass": "SOURCE_BACKED", + "parallelGroup": "p30-003", + "gate": "IMPLEMENTATION", + "card": "docs/tasks/WBV2-P30-003.md", + "behavior": "Expose font, volume, metaball and non-mesh editing controls.", + "outputs": [ + "implementation-report", + "manifest", + "status" + ], + "acceptance": [ + "real source or WebEngine Main path is wired", + "unsupported input fails closed", + "implementation smoke is reproducible", + "verification remains deferred" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": false + }, + { + "id": "WBV2-P30-004", + "phase": "P30", + "title": "run_p30_implementation_smoke", + "kind": "enabling", + "owner": "RELEASE", + "dependsOn": [ + "WBV2-P30-003" + ], + "parityId": null, + "implementationClass": "SOURCE_BACKED", + "parallelGroup": "p30-004", + "gate": "IMPLEMENTATION", + "card": "docs/tasks/WBV2-P30-004.md", + "behavior": "Run bounded build and startup smoke after P30 implementation.", + "outputs": [ + "implementation-report", + "manifest", + "status" + ], + "acceptance": [ + "real source or WebEngine Main path is wired", + "unsupported input fails closed", + "implementation smoke is reproducible", + "verification remains deferred" + ], + "status": "in_progress", + "ready": true, + "queueMutationAllowed": false + } + ] +} diff --git a/tests/golden/WBV2-P30-003/implementation-report.json b/tests/golden/WBV2-P30-003/implementation-report.json new file mode 100644 index 000000000..49c8dfa1b --- /dev/null +++ b/tests/golden/WBV2-P30-003/implementation-report.json @@ -0,0 +1,27 @@ +{ + "schemaVersion": 1, + "task": "WBV2-P30-003", + "operation": "IMPLEMENT_ANIMATION_RENDER_FAMILY", + "status": "PASS", + "family": "GEOMETRY.NON_MESH_MEDIA", + "sourceBacked": true, + "marker": "nonMeshGeometryCommands", + "sourcePaths": [ + "web/protocol/nonmesh-geometry-commands.ts", + "web/protocol/web-engine.ts", + "web/app/src/app/App.tsx" + ], + "verification": { + "status": "DEFERRED", + "chromium": false, + "completionOverlay": false + }, + "inventory": { + "total": 6900, + "legacyCompleted": 281, + "legacyPending": 6618, + "effectiveCompleted": 290, + "effectivePending": 6609 + }, + "nextTask": "WBV2-P30-004" +} diff --git a/tests/golden/WBV2-P30-003/manifest.json b/tests/golden/WBV2-P30-003/manifest.json new file mode 100644 index 000000000..99832fc32 --- /dev/null +++ b/tests/golden/WBV2-P30-003/manifest.json @@ -0,0 +1,55 @@ +{ + "schemaVersion": 1, + "task": "WBV2-P30-003", + "parentTask": "WBV2-P30-002", + "operation": "IMPLEMENT_ANIMATION_RENDER_FAMILY", + "status": "done", + "enablingTask": false, + "parityStateChange": false, + "runtime": "SOURCE_BACKED_ANIMATION_RENDER_IMPLEMENTATION", + "artifacts": { + "parentManifest": { + "path": "tests/golden/WBV2-P30-002/manifest.json", + "sha256": "f7c28f47ba0ad8a41c661c06194e5f85a249126913f0ed2b41591beb46d4285f" + }, + "nonmesh_geometry_commands_ts": { + "path": "web/protocol/nonmesh-geometry-commands.ts", + "sha256": "3e10b86f4d0f09656540cd64fd7774859fc058ff3b0b11db89a664b96763571f" + }, + "web_engine_ts": { + "path": "web/protocol/web-engine.ts", + "sha256": "3c4aba796afb70a6b29d34cca4ba924ffb1a240549b79730d1a639ca913ee896" + }, + "App_tsx": { + "path": "web/app/src/app/App.tsx", + "sha256": "8c3ee6086716be3912a9597091642ee3416ee766a6aaedea7ca642ed7a9c3b53" + }, + "report": { + "path": "tests/golden/WBV2-P30-003/implementation-report.json", + "sha256": "6d80b3e779b6ac30fa09bfca71d59da5147816894ece6cce923cf879676e3092" + }, + "status": { + "path": "docs/status/WBV2-P30-003.md", + "sha256": "ad525773251ae023fdc73f3a6233122ae89bb17a896e7c5fd2823502e756253b" + }, + "plan": { + "path": "tests/golden/WBV2-P30-003/animation-render-task-plan.json", + "sha256": "db8f746b031d3f65281ed2a10a26ab8b337c7a7639db12d5a53e8dab2d8fcaef" + }, + "taskContext": { + "path": "tests/golden/WBV2-P30-003/task-context.json", + "sha256": "8612a41a9d609b1e2a82a6161cda90534bf1862637dafdde33de547dd7689aef" + } + }, + "assertions": { + "capabilityFamily": "GEOMETRY.NON_MESH_MEDIA", + "sourceBacked": true, + "verificationDeferred": true, + "completionOverlayWritten": false, + "inventoryTotal": 6900, + "effectiveCompleted": 290, + "effectivePending": 6609, + "historicalReproduction": false + }, + "nextTask": "WBV2-P30-004" +} diff --git a/tests/golden/WBV2-P30-003/task-context.json b/tests/golden/WBV2-P30-003/task-context.json new file mode 100644 index 000000000..e726900a9 --- /dev/null +++ b/tests/golden/WBV2-P30-003/task-context.json @@ -0,0 +1,167 @@ +{ + "schemaVersion": 1, + "task": "WBV2-P30-003", + "parentTask": "WBV2-P30-002", + "status": "in_progress", + "goal": "Expose font, volume, metaball and non-mesh editing controls.", + "scope": { + "gap": "GEOMETRY.NON_MESH_MEDIA", + "ownerFamily": "GEOMETRY", + "implementationClass": "SOURCE_BACKED" + }, + "commands": [ + "node tools/web/check-task-context.mjs --task WBV2-P30-003 --write" + ], + "inputPaths": [], + "inputSelection": { + "schemaVersion": 1, + "limits": { + "maxFiles": 12, + "evidenceBytes": 8192, + "contextRemainingBytes": 3335, + "contextRemainingTokens": 833 + }, + "source": { + "bytes": 6569, + "tokens": 1643 + }, + "selected": [], + "excluded": [ + { + "path": "blender-5.2.0/source/blender/web_engine/web_engine_main_state.cpp", + "bytes": 254201, + "reason": "EVIDENCE_BYTE_BUDGET" + }, + { + "path": "web/protocol/web-engine.ts", + "bytes": 14979, + "reason": "EVIDENCE_BYTE_BUDGET" + }, + { + "path": "tests/golden/WBV2-P30-003/", + "bytes": null, + "reason": "GENERATED_EVIDENCE_OUTPUT" + }, + { + "path": "docs/status/WBV2-P30-003.md", + "bytes": null, + "reason": "GENERATED_EVIDENCE_OUTPUT" + }, + { + "path": "tests/golden/WBV2-P30-003/manifest.json", + "bytes": null, + "reason": "GENERATED_EVIDENCE_OUTPUT" + } + ], + "totals": { + "files": 0, + "bytes": 0, + "tokens": 0 + } + }, + "exitCriteria": [ + "real source or WebEngine Main path is wired", + "unsupported input fails closed", + "implementation smoke is reproducible", + "verification remains deferred" + ], + "nextTask": "WBV2-P30-004", + "sourceDocuments": { + "queue": "docs/EXECUTION_QUEUE.md", + "taskCard": "docs/tasks/WBV2-P30-003.md", + "taskIndex": "tests/golden/WBV2/task-index.json", + "parentManifest": "tests/golden/WBV2-P30-002/manifest.json", + "parentStatus": "docs/status/WBV2-P30-002.md" + }, + "readPolicy": { + "required": [ + "docs/EXECUTION_QUEUE.md", + "docs/tasks/WBV2-P30-003.md", + "tests/golden/WBV2-P30-002/manifest.json", + "docs/status/WBV2-P30-002.md" + ], + "machineOnly": [ + "tests/golden/WBV2/task-index.json", + "tests/golden/M15-03A/task-catalog.jsonl" + ], + "optionalByNeed": [ + "docs/WEB_BLENDER_MODELER_V1_SCOPE.md", + "任务卡列出的精确协议/生产路径", + "任务卡明确命名的长期计划小节" + ], + "forbiddenByDefault": [ + "完整 CURRENT_EXECUTION_PLAN.md", + "完整 PROJECT_STATUS_AND_NEXT_WORK.md", + "全部 docs/status/*.md", + "完整 parity/WBS 计划", + "README 历史和 test-results/" + ] + }, + "parent": { + "manifest": { + "schemaVersion": 1, + "task": "WBV2-P30-002", + "parentTask": "WBV2-P30-001", + "status": "done", + "nextTask": "WBV2-P30-003", + "artifactCount": 9 + }, + "statusSummary": [ + "# WBV2-P30-002 status", + "- task: `WBV2-P30-002`; parent: `WBV2-P30-001`; status: `done`", + "- source-backed implementation family: `RENDER.SCENE_PROPERTIES`; marker: `set_render_properties`", + "- Chromium receipts and completion overlay: `DEFERRED`", + "- inventory unchanged: `6900/6618`, effective `290/6609`", + "- nextTask: `WBV2-P30-003`" + ] + }, + "budgets": { + "queueBytes": 4096, + "taskBytes": 1236, + "parentManifestBytes": 24576, + "parentStatusBytes": 6144, + "evidenceFiles": 12, + "evidenceBytes": 8192, + "contextTokens": 3500, + "contextEnvelopeTokens": 1024, + "taskLines": 34, + "taskTokens": 309 + }, + "size": { + "documents": [ + { + "path": "docs/EXECUTION_QUEUE.md", + "bytes": 2803, + "lines": 51, + "tokens": 701 + }, + { + "path": "docs/tasks/WBV2-P30-003.md", + "bytes": 1236, + "lines": 34, + "tokens": 309 + }, + { + "path": "tests/golden/WBV2-P30-002/manifest.json", + "bytes": 2207, + "lines": 60, + "tokens": 552 + }, + { + "path": "docs/status/WBV2-P30-002.md", + "bytes": 323, + "lines": 8, + "tokens": 81 + } + ], + "sourceTokens": 1643, + "evidenceFiles": 0, + "evidenceBytes": 0, + "evidenceTokens": 0, + "totalTokens": 1643, + "reservedEnvelopeTokens": 1024, + "estimatedContextTokens": 2667, + "serializedContextTokens": 600, + "withinBudget": true + } +} diff --git a/tests/golden/WBV2-P30-004/animation-render-task-plan.json b/tests/golden/WBV2-P30-004/animation-render-task-plan.json new file mode 100644 index 000000000..3d5c570df --- /dev/null +++ b/tests/golden/WBV2-P30-004/animation-render-task-plan.json @@ -0,0 +1,204 @@ +{ + "schemaVersion": 1, + "planId": "BLENDER_WEB_ANIMATION_RENDER_IMPLEMENTATION_P30", + "status": "ACTIVE_ANIMATION_RENDER_QUEUE", + "authority": "user_authorized_implementation_first_execution", + "executionPointer": "docs/EXECUTION_QUEUE.md", + "runtimePolicy": { + "blenderSource": "blender-5.2.0", + "mainAuthority": "blender_main", + "browserPolicy": "chromium_only_for_later_verification", + "verificationPolicy": "deferred", + "reusePolicy": "source_hash_behavior_hash_and_dedupe_key" + }, + "inventoryPolicy": { + "total": 6900, + "legacyCompleted": 281, + "legacyPending": 6618, + "effectiveCompleted": 290, + "effectivePending": 6609, + "overlayMutation": "forbidden_during_implementation_wave" + }, + "tasks": [ + { + "id": "WBV2-P30-000", + "phase": "P30", + "title": "authorize_animation_render_workbench", + "kind": "enabling", + "owner": "PROGRAM", + "dependsOn": [ + "WBV2-P29-004" + ], + "parityId": null, + "implementationClass": "SOURCE_BACKED", + "parallelGroup": "p30-000", + "gate": "G1", + "card": "docs/tasks/WBV2-P30-000.md", + "behavior": "Authorize the next source-backed workbench implementation wave.", + "outputs": [ + "implementation-report", + "manifest", + "status" + ], + "acceptance": [ + "real source or WebEngine Main path is wired", + "unsupported input fails closed", + "implementation smoke is reproducible", + "verification remains deferred" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": true + }, + { + "id": "WBV2-P30-001", + "phase": "P30", + "title": "implement_animation_nla_workbench", + "kind": "feature", + "owner": "ANIMATION", + "dependsOn": [ + "WBV2-P30-000" + ], + "parityId": "ANIMATION.NLA_WORKBENCH", + "implementationClass": "SOURCE_BACKED", + "parallelGroup": "p30-001", + "gate": "IMPLEMENTATION", + "card": "docs/tasks/WBV2-P30-001.md", + "behavior": "Expose active action, FCurve interpolation and NLA stack controls through the workbench.", + "outputs": [ + "implementation-report", + "manifest", + "status" + ], + "acceptance": [ + "real source or WebEngine Main path is wired", + "unsupported input fails closed", + "implementation smoke is reproducible", + "verification remains deferred" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": false + }, + { + "id": "WBV2-P30-002", + "phase": "P30", + "title": "implement_camera_light_world_workbench", + "kind": "feature", + "owner": "RENDER", + "dependsOn": [ + "WBV2-P30-001" + ], + "parityId": "RENDER.SCENE_PROPERTIES", + "implementationClass": "SOURCE_BACKED", + "parallelGroup": "p30-002", + "gate": "IMPLEMENTATION", + "card": "docs/tasks/WBV2-P30-002.md", + "behavior": "Expose camera, light and world property commands through the workbench.", + "outputs": [ + "implementation-report", + "manifest", + "status" + ], + "acceptance": [ + "real source or WebEngine Main path is wired", + "unsupported input fails closed", + "implementation smoke is reproducible", + "verification remains deferred" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": false + }, + { + "id": "WBV2-P30-003", + "phase": "P30", + "title": "implement_nonmesh_media_workbench", + "kind": "feature", + "owner": "GEOMETRY", + "dependsOn": [ + "WBV2-P30-002" + ], + "parityId": "GEOMETRY.NON_MESH_MEDIA", + "implementationClass": "SOURCE_BACKED", + "parallelGroup": "p30-003", + "gate": "IMPLEMENTATION", + "card": "docs/tasks/WBV2-P30-003.md", + "behavior": "Expose font, volume, metaball and non-mesh editing controls.", + "outputs": [ + "implementation-report", + "manifest", + "status" + ], + "acceptance": [ + "real source or WebEngine Main path is wired", + "unsupported input fails closed", + "implementation smoke is reproducible", + "verification remains deferred" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": false + }, + { + "id": "WBV2-P30-004", + "phase": "P30", + "title": "run_p30_implementation_smoke", + "kind": "enabling", + "owner": "RELEASE", + "dependsOn": [ + "WBV2-P30-003" + ], + "parityId": null, + "implementationClass": "SOURCE_BACKED", + "parallelGroup": "p30-004", + "gate": "IMPLEMENTATION", + "card": "docs/tasks/WBV2-P30-004.md", + "behavior": "Run bounded build and startup smoke after P30 implementation.", + "outputs": [ + "implementation-report", + "manifest", + "status" + ], + "acceptance": [ + "real source or WebEngine Main path is wired", + "unsupported input fails closed", + "implementation smoke is reproducible", + "verification remains deferred" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": false + }, + { + "id": "WBV2-P31-000", + "phase": "P31", + "title": "authorize_resource_scene_workbench", + "kind": "enabling", + "owner": "PROGRAM", + "dependsOn": [ + "WBV2-P30-004" + ], + "parityId": null, + "implementationClass": "SOURCE_BACKED", + "parallelGroup": "p31-000", + "gate": "G1", + "card": "docs/tasks/WBV2-P31-000.md", + "behavior": "Authorize the next source-backed resource and scene-data implementation wave.", + "outputs": [ + "implementation-report", + "manifest", + "status" + ], + "acceptance": [ + "real source or WebEngine Main path is wired", + "unsupported input fails closed", + "implementation smoke is reproducible", + "verification remains deferred" + ], + "status": "in_progress", + "ready": true, + "queueMutationAllowed": true + } + ] +} diff --git a/tests/golden/WBV2-P30-004/implementation-report.json b/tests/golden/WBV2-P30-004/implementation-report.json new file mode 100644 index 000000000..6c47fa6ff --- /dev/null +++ b/tests/golden/WBV2-P30-004/implementation-report.json @@ -0,0 +1,26 @@ +{ + "schemaVersion": 1, + "task": "WBV2-P30-004", + "operation": "IMPLEMENT_ANIMATION_RENDER_FAMILY", + "status": "PASS", + "family": "P30.IMPLEMENTATION_SMOKE", + "sourceBacked": true, + "marker": "applyCommand", + "sourcePaths": [ + "web/app/src/workers/web-engine.worker.ts", + "web/app/src/vendor/blender/web_engine.wasm" + ], + "verification": { + "status": "DEFERRED", + "chromium": false, + "completionOverlay": false + }, + "inventory": { + "total": 6900, + "legacyCompleted": 281, + "legacyPending": 6618, + "effectiveCompleted": 290, + "effectivePending": 6609 + }, + "nextTask": "WBV2-P31-000" +} diff --git a/tests/golden/WBV2-P30-004/manifest.json b/tests/golden/WBV2-P30-004/manifest.json new file mode 100644 index 000000000..8393fdf3a --- /dev/null +++ b/tests/golden/WBV2-P30-004/manifest.json @@ -0,0 +1,51 @@ +{ + "schemaVersion": 1, + "task": "WBV2-P30-004", + "parentTask": "WBV2-P30-003", + "operation": "IMPLEMENT_ANIMATION_RENDER_FAMILY", + "status": "done", + "enablingTask": false, + "parityStateChange": false, + "runtime": "SOURCE_BACKED_ANIMATION_RENDER_IMPLEMENTATION", + "artifacts": { + "parentManifest": { + "path": "tests/golden/WBV2-P30-003/manifest.json", + "sha256": "6def8574794ea45d53894095ceef1f566a30440ceb9288db88e662dbb3148d22" + }, + "web_engine_worker_ts": { + "path": "web/app/src/workers/web-engine.worker.ts", + "sha256": "72242855c47eb33b1f440f3a586f290e074876bda6e5c1369d83444b0cb3e0af" + }, + "web_engine_wasm": { + "path": "web/app/src/vendor/blender/web_engine.wasm", + "sha256": "e04c9c06fa2db509acf210290cfd132acae68597964952869f133d51a8c0d9ff" + }, + "report": { + "path": "tests/golden/WBV2-P30-004/implementation-report.json", + "sha256": "d73f511902315b2b7167c254ae0de035d1ae712d15f24a5b13d427448db6c96c" + }, + "status": { + "path": "docs/status/WBV2-P30-004.md", + "sha256": "4677538c42fea9c609dd08ed09e0d8887baea86547a40ad47f7632b20629f00f" + }, + "plan": { + "path": "tests/golden/WBV2-P30-004/animation-render-task-plan.json", + "sha256": "6f704f67540215ec885a400ad7d48cc1aebcae0521239ecd2072d2e1c94b6767" + }, + "taskContext": { + "path": "tests/golden/WBV2-P30-004/task-context.json", + "sha256": "293f9f2a050ec5452253f53f00c8f6ae7384a639c2f33887bbb4fa2085fdbabe" + } + }, + "assertions": { + "capabilityFamily": "P30.IMPLEMENTATION_SMOKE", + "sourceBacked": true, + "verificationDeferred": true, + "completionOverlayWritten": false, + "inventoryTotal": 6900, + "effectiveCompleted": 290, + "effectivePending": 6609, + "historicalReproduction": false + }, + "nextTask": "WBV2-P31-000" +} diff --git a/tests/golden/WBV2-P30-004/task-context.json b/tests/golden/WBV2-P30-004/task-context.json new file mode 100644 index 000000000..29aee4965 --- /dev/null +++ b/tests/golden/WBV2-P30-004/task-context.json @@ -0,0 +1,167 @@ +{ + "schemaVersion": 1, + "task": "WBV2-P30-004", + "parentTask": "WBV2-P30-003", + "status": "in_progress", + "goal": "Run bounded build and startup smoke after P30 implementation.", + "scope": { + "gap": "workflow:run_p30_implementation_smoke", + "ownerFamily": "RELEASE", + "implementationClass": "SOURCE_BACKED" + }, + "commands": [ + "node tools/web/check-task-context.mjs --task WBV2-P30-004 --write" + ], + "inputPaths": [], + "inputSelection": { + "schemaVersion": 1, + "limits": { + "maxFiles": 12, + "evidenceBytes": 8192, + "contextRemainingBytes": 3569, + "contextRemainingTokens": 890 + }, + "source": { + "bytes": 6335, + "tokens": 1586 + }, + "selected": [], + "excluded": [ + { + "path": "blender-5.2.0/source/blender/web_engine/web_engine_main_state.cpp", + "bytes": 254201, + "reason": "EVIDENCE_BYTE_BUDGET" + }, + { + "path": "web/protocol/web-engine.ts", + "bytes": 14979, + "reason": "EVIDENCE_BYTE_BUDGET" + }, + { + "path": "tests/golden/WBV2-P30-004/", + "bytes": null, + "reason": "GENERATED_EVIDENCE_OUTPUT" + }, + { + "path": "docs/status/WBV2-P30-004.md", + "bytes": null, + "reason": "GENERATED_EVIDENCE_OUTPUT" + }, + { + "path": "tests/golden/WBV2-P30-004/manifest.json", + "bytes": null, + "reason": "GENERATED_EVIDENCE_OUTPUT" + } + ], + "totals": { + "files": 0, + "bytes": 0, + "tokens": 0 + } + }, + "exitCriteria": [ + "real source or WebEngine Main path is wired", + "unsupported input fails closed", + "implementation smoke is reproducible", + "verification remains deferred" + ], + "nextTask": "WBV2-P31-000", + "sourceDocuments": { + "queue": "docs/EXECUTION_QUEUE.md", + "taskCard": "docs/tasks/WBV2-P30-004.md", + "taskIndex": "tests/golden/WBV2/task-index.json", + "parentManifest": "tests/golden/WBV2-P30-003/manifest.json", + "parentStatus": "docs/status/WBV2-P30-003.md" + }, + "readPolicy": { + "required": [ + "docs/EXECUTION_QUEUE.md", + "docs/tasks/WBV2-P30-004.md", + "tests/golden/WBV2-P30-003/manifest.json", + "docs/status/WBV2-P30-003.md" + ], + "machineOnly": [ + "tests/golden/WBV2/task-index.json", + "tests/golden/M15-03A/task-catalog.jsonl" + ], + "optionalByNeed": [ + "docs/WEB_BLENDER_MODELER_V1_SCOPE.md", + "任务卡列出的精确协议/生产路径", + "任务卡明确命名的长期计划小节" + ], + "forbiddenByDefault": [ + "完整 CURRENT_EXECUTION_PLAN.md", + "完整 PROJECT_STATUS_AND_NEXT_WORK.md", + "全部 docs/status/*.md", + "完整 parity/WBS 计划", + "README 历史和 test-results/" + ] + }, + "parent": { + "manifest": { + "schemaVersion": 1, + "task": "WBV2-P30-003", + "parentTask": "WBV2-P30-002", + "status": "done", + "nextTask": "WBV2-P30-004", + "artifactCount": 8 + }, + "statusSummary": [ + "# WBV2-P30-003 status", + "- task: `WBV2-P30-003`; parent: `WBV2-P30-002`; status: `done`", + "- source-backed implementation family: `GEOMETRY.NON_MESH_MEDIA`; marker: `nonMeshGeometryCommands`", + "- Chromium receipts and completion overlay: `DEFERRED`", + "- inventory unchanged: `6900/6618`, effective `290/6609`", + "- nextTask: `WBV2-P30-004`" + ] + }, + "budgets": { + "queueBytes": 4096, + "taskBytes": 1245, + "parentManifestBytes": 24576, + "parentStatusBytes": 6144, + "evidenceFiles": 12, + "evidenceBytes": 8192, + "contextTokens": 3500, + "contextEnvelopeTokens": 1024, + "taskLines": 34, + "taskTokens": 312 + }, + "size": { + "documents": [ + { + "path": "docs/EXECUTION_QUEUE.md", + "bytes": 2803, + "lines": 51, + "tokens": 701 + }, + { + "path": "docs/tasks/WBV2-P30-004.md", + "bytes": 1245, + "lines": 34, + "tokens": 312 + }, + { + "path": "tests/golden/WBV2-P30-003/manifest.json", + "bytes": 1962, + "lines": 56, + "tokens": 491 + }, + { + "path": "docs/status/WBV2-P30-003.md", + "bytes": 325, + "lines": 8, + "tokens": 82 + } + ], + "sourceTokens": 1586, + "evidenceFiles": 0, + "evidenceBytes": 0, + "evidenceTokens": 0, + "totalTokens": 1586, + "reservedEnvelopeTokens": 1024, + "estimatedContextTokens": 2610, + "serializedContextTokens": 603, + "withinBudget": true + } +} diff --git a/tests/golden/WBV2-P31-000/manifest.json b/tests/golden/WBV2-P31-000/manifest.json new file mode 100644 index 000000000..5817b774b --- /dev/null +++ b/tests/golden/WBV2-P31-000/manifest.json @@ -0,0 +1,38 @@ +{ + "schemaVersion": 1, + "task": "WBV2-P31-000", + "parentTask": "WBV2-P30-004", + "operation": "AUTHORIZE_RESOURCE_SCENE_WORKBENCH", + "status": "done", + "enablingTask": true, + "parityStateChange": false, + "runtime": "SOURCE_BACKED_RESOURCE_SCENE_QUEUE", + "artifacts": { + "parentManifest": { + "path": "tests/golden/WBV2-P30-004/manifest.json", + "sha256": "04063de92571c27ff5bd0177b5aa76f9a04853e983d114fbaa2936300739511c" + }, + "plan": { + "path": "tests/golden/WBV2-P31-000/resource-scene-task-plan.json", + "sha256": "cf566325b181ad62a28d8922b932563e5ed5e642b6fbd3b84e6f490f0da8c7ce" + }, + "report": { + "path": "tests/golden/WBV2-P31-000/resource-scene-root-report.json", + "sha256": "a01a1452b487155ef92b584adc52d7ee851a6469105dea97b28113f24213b260" + }, + "status": { + "path": "docs/status/WBV2-P31-000.md", + "sha256": "60d580b1c919e83bcf9cb177dc3a1b735c53eb114f842ea437e00f0b8c3e3881" + } + }, + "assertions": { + "plannedTasks": 4, + "verificationDeferred": true, + "completionOverlayWritten": false, + "inventoryTotal": 6900, + "effectiveCompleted": 290, + "effectivePending": 6609, + "historicalReproduction": false + }, + "nextTask": "WBV2-P31-001" +} diff --git a/tests/golden/WBV2-P31-000/resource-scene-root-report.json b/tests/golden/WBV2-P31-000/resource-scene-root-report.json new file mode 100644 index 000000000..b1e2fbc3f --- /dev/null +++ b/tests/golden/WBV2-P31-000/resource-scene-root-report.json @@ -0,0 +1,33 @@ +{ + "schemaVersion": 1, + "task": "WBV2-P31-000", + "operation": "AUTHORIZE_RESOURCE_SCENE_WORKBENCH", + "status": "PASS", + "parent": { + "task": "WBV2-P30-004", + "manifest": "tests/golden/WBV2-P30-004/manifest.json", + "manifestSha256": "b866177dd1e3f99206beeb82c28cd4487da5fb5310971a745de981a9b3b155d3" + }, + "scope": { + "firstTask": "WBV2-P31-001", + "plannedTasks": [ + "WBV2-P31-000", + "WBV2-P31-001", + "WBV2-P31-002", + "WBV2-P31-003" + ] + }, + "verification": { + "status": "DEFERRED", + "chromium": false, + "completionOverlay": false + }, + "inventory": { + "total": 6900, + "legacyCompleted": 281, + "legacyPending": 6618, + "effectiveCompleted": 290, + "effectivePending": 6609 + }, + "nextTask": "WBV2-P31-001" +} diff --git a/tests/golden/WBV2-P31-000/resource-scene-task-plan.json b/tests/golden/WBV2-P31-000/resource-scene-task-plan.json new file mode 100644 index 000000000..17b5766eb --- /dev/null +++ b/tests/golden/WBV2-P31-000/resource-scene-task-plan.json @@ -0,0 +1,150 @@ +{ + "schemaVersion": 1, + "planId": "BLENDER_WEB_RESOURCE_SCENE_IMPLEMENTATION_P31", + "status": "ACTIVE_RESOURCE_SCENE_QUEUE", + "authority": "user_authorized_implementation_first_execution", + "executionPointer": "docs/EXECUTION_QUEUE.md", + "runtimePolicy": { + "blenderSource": "blender-5.2.0", + "mainAuthority": "blender_main", + "browserPolicy": "chromium_only_for_later_verification", + "verificationPolicy": "deferred", + "reusePolicy": "source_hash_behavior_hash_and_dedupe_key" + }, + "inventoryPolicy": { + "total": 6900, + "legacyCompleted": 281, + "legacyPending": 6618, + "effectiveCompleted": 290, + "effectivePending": 6609, + "overlayMutation": "forbidden_during_implementation_wave" + }, + "tasks": [ + { + "id": "WBV2-P31-000", + "title": "authorize_resource_scene_workbench", + "owner": "PROGRAM", + "parent": "WBV2-P30-004", + "status": "done", + "ready": false, + "kind": "enabling", + "behavior": "Authorize the next source-backed resource and scene-data implementation wave.", + "dependsOn": [ + "WBV2-P30-004" + ], + "phase": "P31", + "parityId": null, + "implementationClass": "SOURCE_BACKED", + "parallelGroup": "p31-000", + "gate": "G1", + "card": "docs/tasks/WBV2-P31-000.md", + "outputs": [ + "implementation-report", + "manifest", + "status" + ], + "acceptance": [ + "real source or WebEngine Main path is wired", + "unsupported input fails closed", + "implementation smoke is reproducible", + "verification remains deferred" + ], + "queueMutationAllowed": true + }, + { + "id": "WBV2-P31-001", + "title": "implement_resource_workbench", + "owner": "IO", + "parent": "WBV2-P31-000", + "status": "in_progress", + "ready": true, + "kind": "feature", + "family": "IO.RESOURCE_WORKBENCH", + "behavior": "Expose packed VFonts, sounds, speakers, text blocks, textures and particle settings through a bounded resource workbench.", + "dependsOn": [ + "WBV2-P31-000" + ], + "phase": "P31", + "parityId": null, + "implementationClass": "SOURCE_BACKED", + "parallelGroup": "p31-001", + "gate": "IMPLEMENTATION", + "card": "docs/tasks/WBV2-P31-001.md", + "outputs": [ + "implementation-report", + "manifest", + "status" + ], + "acceptance": [ + "real source or WebEngine Main path is wired", + "unsupported input fails closed", + "implementation smoke is reproducible", + "verification remains deferred" + ], + "queueMutationAllowed": false + }, + { + "id": "WBV2-P31-002", + "title": "implement_text_datablock_authoring", + "owner": "IO", + "parent": "WBV2-P31-001", + "status": "planned", + "ready": false, + "kind": "feature", + "family": "IO.TEXT_DATABLOCK", + "behavior": "Connect a typed text-source command to Blender Main Text datablocks with bounded persistence.", + "dependsOn": [ + "WBV2-P31-001" + ], + "phase": "P31", + "parityId": null, + "implementationClass": "SOURCE_BACKED", + "parallelGroup": "p31-002", + "gate": "IMPLEMENTATION", + "card": "docs/tasks/WBV2-P31-002.md", + "outputs": [ + "implementation-report", + "manifest", + "status" + ], + "acceptance": [ + "real source or WebEngine Main path is wired", + "unsupported input fails closed", + "implementation smoke is reproducible", + "verification remains deferred" + ], + "queueMutationAllowed": false + }, + { + "id": "WBV2-P31-003", + "title": "run_p31_implementation_smoke", + "owner": "RELEASE", + "parent": "WBV2-P31-002", + "status": "planned", + "ready": false, + "kind": "enabling", + "behavior": "Run the bounded production build smoke after P31 resource implementation.", + "dependsOn": [ + "WBV2-P31-002" + ], + "phase": "P31", + "parityId": null, + "implementationClass": "SOURCE_BACKED", + "parallelGroup": "p31-003", + "gate": "G1", + "card": "docs/tasks/WBV2-P31-003.md", + "outputs": [ + "implementation-report", + "manifest", + "status" + ], + "acceptance": [ + "real source or WebEngine Main path is wired", + "unsupported input fails closed", + "implementation smoke is reproducible", + "verification remains deferred" + ], + "queueMutationAllowed": true + } + ] +} diff --git a/tests/golden/WBV2-P31-000/task-context.json b/tests/golden/WBV2-P31-000/task-context.json new file mode 100644 index 000000000..11cea3a1b --- /dev/null +++ b/tests/golden/WBV2-P31-000/task-context.json @@ -0,0 +1,162 @@ +{ + "schemaVersion": 1, + "task": "WBV2-P31-000", + "parentTask": "WBV2-P30-004", + "status": "done", + "goal": "Authorize the next source-backed resource and scene-data implementation wave.", + "scope": { + "gap": "workflow:authorize_resource_scene_workbench", + "ownerFamily": "PROGRAM", + "implementationClass": "SOURCE_BACKED" + }, + "commands": [ + "node tools/web/check-task-context.mjs --task WBV2-P31-000 --write" + ], + "inputPaths": [], + "inputSelection": { + "schemaVersion": 1, + "limits": { + "maxFiles": 12, + "evidenceBytes": 8192, + "contextRemainingBytes": 3660, + "contextRemainingTokens": 914 + }, + "source": { + "bytes": 6244, + "tokens": 1562 + }, + "selected": [], + "excluded": [ + { + "path": "web/protocol/web-engine.ts", + "bytes": 14979, + "reason": "EVIDENCE_BYTE_BUDGET" + }, + { + "path": "tests/golden/WBV2-P31-000/", + "bytes": null, + "reason": "GENERATED_EVIDENCE_OUTPUT" + }, + { + "path": "docs/status/WBV2-P31-000.md", + "bytes": null, + "reason": "GENERATED_EVIDENCE_OUTPUT" + }, + { + "path": "tests/golden/WBV2-P31-000/manifest.json", + "bytes": null, + "reason": "GENERATED_EVIDENCE_OUTPUT" + } + ], + "totals": { + "files": 0, + "bytes": 0, + "tokens": 0 + } + }, + "exitCriteria": [ + "real source or WebEngine Main path is wired", + "unsupported input fails closed", + "implementation smoke is reproducible", + "verification remains deferred" + ], + "nextTask": "WBV2-P31-001", + "sourceDocuments": { + "queue": "docs/EXECUTION_QUEUE.md", + "taskCard": "docs/tasks/WBV2-P31-000.md", + "taskIndex": "tests/golden/WBV2/task-index.json", + "parentManifest": "tests/golden/WBV2-P30-004/manifest.json", + "parentStatus": "docs/status/WBV2-P30-004.md" + }, + "readPolicy": { + "required": [ + "docs/EXECUTION_QUEUE.md", + "docs/tasks/WBV2-P31-000.md", + "tests/golden/WBV2-P30-004/manifest.json", + "docs/status/WBV2-P30-004.md" + ], + "machineOnly": [ + "tests/golden/WBV2/task-index.json", + "tests/golden/M15-03A/task-catalog.jsonl" + ], + "optionalByNeed": [ + "docs/WEB_BLENDER_MODELER_V1_SCOPE.md", + "任务卡列出的精确协议/生产路径", + "任务卡明确命名的长期计划小节" + ], + "forbiddenByDefault": [ + "完整 CURRENT_EXECUTION_PLAN.md", + "完整 PROJECT_STATUS_AND_NEXT_WORK.md", + "全部 docs/status/*.md", + "完整 parity/WBS 计划", + "README 历史和 test-results/" + ] + }, + "parent": { + "manifest": { + "schemaVersion": 1, + "task": "WBV2-P30-004", + "parentTask": "WBV2-P30-003", + "status": "done", + "nextTask": "WBV2-P31-000", + "artifactCount": 7 + }, + "statusSummary": [ + "# WBV2-P30-004 status", + "- task: `WBV2-P30-004`; parent: `WBV2-P30-003`; status: `done`", + "- source-backed implementation family: `P30.IMPLEMENTATION_SMOKE`; marker: `applyCommand`", + "- Chromium receipts and completion overlay: `DEFERRED`", + "- inventory unchanged: `6900/6618`, effective `290/6609`", + "- nextTask: `WBV2-P31-000`" + ] + }, + "budgets": { + "queueBytes": 4096, + "taskBytes": 1302, + "parentManifestBytes": 24576, + "parentStatusBytes": 6144, + "evidenceFiles": 12, + "evidenceBytes": 8192, + "contextTokens": 3500, + "contextEnvelopeTokens": 1024, + "taskLines": 38, + "taskTokens": 326 + }, + "size": { + "documents": [ + { + "path": "docs/EXECUTION_QUEUE.md", + "bytes": 2803, + "lines": 51, + "tokens": 701 + }, + { + "path": "docs/tasks/WBV2-P31-000.md", + "bytes": 1302, + "lines": 38, + "tokens": 326 + }, + { + "path": "tests/golden/WBV2-P30-004/manifest.json", + "bytes": 1824, + "lines": 52, + "tokens": 456 + }, + { + "path": "docs/status/WBV2-P30-004.md", + "bytes": 315, + "lines": 8, + "tokens": 79 + } + ], + "sourceTokens": 1562, + "evidenceFiles": 0, + "evidenceBytes": 0, + "evidenceTokens": 0, + "totalTokens": 1562, + "reservedEnvelopeTokens": 1024, + "estimatedContextTokens": 2586, + "serializedContextTokens": 607, + "withinBudget": true + } +} diff --git a/tests/golden/WBV2-P31-001/implementation-report.json b/tests/golden/WBV2-P31-001/implementation-report.json new file mode 100644 index 000000000..8a6d59465 --- /dev/null +++ b/tests/golden/WBV2-P31-001/implementation-report.json @@ -0,0 +1,30 @@ +{ + "schemaVersion": 1, + "task": "WBV2-P31-001", + "operation": "IMPLEMENT_RESOURCE_SCENE_FAMILY", + "status": "PASS", + "family": "IO.RESOURCE_WORKBENCH", + "sourceBacked": true, + "implementation": { + "marker": "resource-scene-workbench", + "sourcePaths": [ + "web/app/src/app/App.tsx", + "web/protocol/scene-ir.ts" + ], + "duplicateShimAdded": false + }, + "verification": { + "status": "DEFERRED", + "chromium": false, + "receipts": false, + "completionOverlay": false + }, + "inventory": { + "total": 6900, + "legacyCompleted": 281, + "legacyPending": 6618, + "effectiveCompleted": 290, + "effectivePending": 6609 + }, + "nextTask": "WBV2-P31-002" +} diff --git a/tests/golden/WBV2-P31-001/manifest.json b/tests/golden/WBV2-P31-001/manifest.json new file mode 100644 index 000000000..48560c409 --- /dev/null +++ b/tests/golden/WBV2-P31-001/manifest.json @@ -0,0 +1,52 @@ +{ + "schemaVersion": 1, + "task": "WBV2-P31-001", + "parentTask": "WBV2-P31-000", + "operation": "IMPLEMENT_RESOURCE_SCENE_FAMILY", + "status": "done", + "enablingTask": false, + "parityStateChange": false, + "runtime": "SOURCE_BACKED_RESOURCE_SCENE_IMPLEMENTATION", + "artifacts": { + "parentManifest": { + "path": "tests/golden/WBV2-P31-000/manifest.json", + "sha256": "0f3ad23c080f95308d722df0090737e7ba59e53d08d5077712eed914e2fd8ac8" + }, + "source1": { + "path": "web/app/src/app/App.tsx", + "sha256": "8c3ee6086716be3912a9597091642ee3416ee766a6aaedea7ca642ed7a9c3b53" + }, + "source2": { + "path": "web/protocol/scene-ir.ts", + "sha256": "7c3582a11cfbab47ebb0dced99034a43591500f70ca2a24c58bd5dc183d977cb" + }, + "report": { + "path": "tests/golden/WBV2-P31-001/implementation-report.json", + "sha256": "75f53034a35f443ef6f58e972050249e3dd8b9640bcb9a7c5338216533e8af07" + }, + "status": { + "path": "docs/status/WBV2-P31-001.md", + "sha256": "ee54bf80083e41d6ee9b798b089eafe78f182759e8185471f8cb85cf17eeafcc" + }, + "plan": { + "path": "tests/golden/WBV2-P31-001/resource-scene-task-plan.json", + "sha256": "7b1acf841f0e08afe0c4bfb4ebadc9fb88210e9f8501faf43ef3f9379ac08480" + }, + "taskContext": { + "path": "tests/golden/WBV2-P31-001/task-context.json", + "sha256": "3f6d65e5ccf5f4183b9bbafc0c3f245349ec6254d66d20ea1ae0125fdc533ef7" + } + }, + "assertions": { + "capabilityFamily": "IO.RESOURCE_WORKBENCH", + "sourceBacked": true, + "unsupportedFailsClosed": true, + "verificationDeferred": true, + "completionOverlayWritten": false, + "inventoryTotal": 6900, + "effectiveCompleted": 290, + "effectivePending": 6609, + "historicalReproduction": false + }, + "nextTask": "WBV2-P31-002" +} diff --git a/tests/golden/WBV2-P31-001/resource-scene-task-plan.json b/tests/golden/WBV2-P31-001/resource-scene-task-plan.json new file mode 100644 index 000000000..61fd06d9f --- /dev/null +++ b/tests/golden/WBV2-P31-001/resource-scene-task-plan.json @@ -0,0 +1,150 @@ +{ + "schemaVersion": 1, + "planId": "BLENDER_WEB_RESOURCE_SCENE_IMPLEMENTATION_P31", + "status": "ACTIVE_RESOURCE_SCENE_QUEUE", + "authority": "user_authorized_implementation_first_execution", + "executionPointer": "docs/EXECUTION_QUEUE.md", + "runtimePolicy": { + "blenderSource": "blender-5.2.0", + "mainAuthority": "blender_main", + "browserPolicy": "chromium_only_for_later_verification", + "verificationPolicy": "deferred", + "reusePolicy": "source_hash_behavior_hash_and_dedupe_key" + }, + "inventoryPolicy": { + "total": 6900, + "legacyCompleted": 281, + "legacyPending": 6618, + "effectiveCompleted": 290, + "effectivePending": 6609, + "overlayMutation": "forbidden_during_implementation_wave" + }, + "tasks": [ + { + "id": "WBV2-P31-000", + "title": "authorize_resource_scene_workbench", + "owner": "PROGRAM", + "parent": "WBV2-P30-004", + "status": "done", + "ready": false, + "kind": "enabling", + "behavior": "Authorize the next source-backed resource and scene-data implementation wave.", + "dependsOn": [ + "WBV2-P30-004" + ], + "phase": "P31", + "parityId": null, + "implementationClass": "SOURCE_BACKED", + "parallelGroup": "p31-000", + "gate": "G1", + "card": "docs/tasks/WBV2-P31-000.md", + "outputs": [ + "implementation-report", + "manifest", + "status" + ], + "acceptance": [ + "real source or WebEngine Main path is wired", + "unsupported input fails closed", + "implementation smoke is reproducible", + "verification remains deferred" + ], + "queueMutationAllowed": true + }, + { + "id": "WBV2-P31-001", + "title": "implement_resource_workbench", + "owner": "IO", + "parent": "WBV2-P31-000", + "status": "done", + "ready": false, + "kind": "feature", + "family": "IO.RESOURCE_WORKBENCH", + "behavior": "Expose packed VFonts, sounds, speakers, text blocks, textures and particle settings through a bounded resource workbench.", + "dependsOn": [ + "WBV2-P31-000" + ], + "phase": "P31", + "parityId": null, + "implementationClass": "SOURCE_BACKED", + "parallelGroup": "p31-001", + "gate": "IMPLEMENTATION", + "card": "docs/tasks/WBV2-P31-001.md", + "outputs": [ + "implementation-report", + "manifest", + "status" + ], + "acceptance": [ + "real source or WebEngine Main path is wired", + "unsupported input fails closed", + "implementation smoke is reproducible", + "verification remains deferred" + ], + "queueMutationAllowed": false + }, + { + "id": "WBV2-P31-002", + "title": "implement_text_datablock_authoring", + "owner": "IO", + "parent": "WBV2-P31-001", + "status": "in_progress", + "ready": true, + "kind": "feature", + "family": "IO.TEXT_DATABLOCK", + "behavior": "Connect a typed text-source command to Blender Main Text datablocks with bounded persistence.", + "dependsOn": [ + "WBV2-P31-001" + ], + "phase": "P31", + "parityId": null, + "implementationClass": "SOURCE_BACKED", + "parallelGroup": "p31-002", + "gate": "IMPLEMENTATION", + "card": "docs/tasks/WBV2-P31-002.md", + "outputs": [ + "implementation-report", + "manifest", + "status" + ], + "acceptance": [ + "real source or WebEngine Main path is wired", + "unsupported input fails closed", + "implementation smoke is reproducible", + "verification remains deferred" + ], + "queueMutationAllowed": false + }, + { + "id": "WBV2-P31-003", + "title": "run_p31_implementation_smoke", + "owner": "RELEASE", + "parent": "WBV2-P31-002", + "status": "planned", + "ready": false, + "kind": "enabling", + "behavior": "Run the bounded production build smoke after P31 resource implementation.", + "dependsOn": [ + "WBV2-P31-002" + ], + "phase": "P31", + "parityId": null, + "implementationClass": "SOURCE_BACKED", + "parallelGroup": "p31-003", + "gate": "G1", + "card": "docs/tasks/WBV2-P31-003.md", + "outputs": [ + "implementation-report", + "manifest", + "status" + ], + "acceptance": [ + "real source or WebEngine Main path is wired", + "unsupported input fails closed", + "implementation smoke is reproducible", + "verification remains deferred" + ], + "queueMutationAllowed": true + } + ] +} diff --git a/tests/golden/WBV2-P31-001/task-context.json b/tests/golden/WBV2-P31-001/task-context.json new file mode 100644 index 000000000..f11ce7db1 --- /dev/null +++ b/tests/golden/WBV2-P31-001/task-context.json @@ -0,0 +1,162 @@ +{ + "schemaVersion": 1, + "task": "WBV2-P31-001", + "parentTask": "WBV2-P31-000", + "status": "in_progress", + "goal": "Expose packed VFonts, sounds, speakers, text blocks, textures and particle settings through a bounded resource workbench.", + "scope": { + "gap": "IO.RESOURCE_WORKBENCH", + "ownerFamily": "IO", + "implementationClass": "SOURCE_BACKED" + }, + "commands": [ + "node tools/web/check-task-context.mjs --task WBV2-P31-001 --write" + ], + "inputPaths": [], + "inputSelection": { + "schemaVersion": 1, + "limits": { + "maxFiles": 12, + "evidenceBytes": 8192, + "contextRemainingBytes": 4165, + "contextRemainingTokens": 1040 + }, + "source": { + "bytes": 5739, + "tokens": 1436 + }, + "selected": [], + "excluded": [ + { + "path": "web/protocol/web-engine.ts", + "bytes": 14979, + "reason": "EVIDENCE_BYTE_BUDGET" + }, + { + "path": "tests/golden/WBV2-P31-001/", + "bytes": null, + "reason": "GENERATED_EVIDENCE_OUTPUT" + }, + { + "path": "docs/status/WBV2-P31-001.md", + "bytes": null, + "reason": "GENERATED_EVIDENCE_OUTPUT" + }, + { + "path": "tests/golden/WBV2-P31-001/manifest.json", + "bytes": null, + "reason": "GENERATED_EVIDENCE_OUTPUT" + } + ], + "totals": { + "files": 0, + "bytes": 0, + "tokens": 0 + } + }, + "exitCriteria": [ + "real source or WebEngine Main path is wired", + "unsupported input fails closed", + "implementation smoke is reproducible", + "verification remains deferred" + ], + "nextTask": "WBV2-P31-002", + "sourceDocuments": { + "queue": "docs/EXECUTION_QUEUE.md", + "taskCard": "docs/tasks/WBV2-P31-001.md", + "taskIndex": "tests/golden/WBV2/task-index.json", + "parentManifest": "tests/golden/WBV2-P31-000/manifest.json", + "parentStatus": "docs/status/WBV2-P31-000.md" + }, + "readPolicy": { + "required": [ + "docs/EXECUTION_QUEUE.md", + "docs/tasks/WBV2-P31-001.md", + "tests/golden/WBV2-P31-000/manifest.json", + "docs/status/WBV2-P31-000.md" + ], + "machineOnly": [ + "tests/golden/WBV2/task-index.json", + "tests/golden/M15-03A/task-catalog.jsonl" + ], + "optionalByNeed": [ + "docs/WEB_BLENDER_MODELER_V1_SCOPE.md", + "任务卡列出的精确协议/生产路径", + "任务卡明确命名的长期计划小节" + ], + "forbiddenByDefault": [ + "完整 CURRENT_EXECUTION_PLAN.md", + "完整 PROJECT_STATUS_AND_NEXT_WORK.md", + "全部 docs/status/*.md", + "完整 parity/WBS 计划", + "README 历史和 test-results/" + ] + }, + "parent": { + "manifest": { + "schemaVersion": 1, + "task": "WBV2-P31-000", + "parentTask": "WBV2-P30-004", + "status": "done", + "nextTask": "WBV2-P31-001", + "artifactCount": 4 + }, + "statusSummary": [ + "# WBV2-P31-000 status", + "- task: `WBV2-P31-000`; parent: `WBV2-P30-004`; status: `done`", + "- resource and scene-data implementation wave authorized", + "- verification receipts and completion overlays: `DEFERRED`", + "- inventory unchanged: `6900` total, `281` legacy completed, `6618` legacy pending, `290/6609` effective carried forward", + "- nextTask: `WBV2-P31-001`" + ] + }, + "budgets": { + "queueBytes": 4096, + "taskBytes": 1349, + "parentManifestBytes": 24576, + "parentStatusBytes": 6144, + "evidenceFiles": 12, + "evidenceBytes": 8192, + "contextTokens": 3500, + "contextEnvelopeTokens": 1024, + "taskLines": 38, + "taskTokens": 338 + }, + "size": { + "documents": [ + { + "path": "docs/EXECUTION_QUEUE.md", + "bytes": 2803, + "lines": 51, + "tokens": 701 + }, + { + "path": "docs/tasks/WBV2-P31-001.md", + "bytes": 1349, + "lines": 38, + "tokens": 338 + }, + { + "path": "tests/golden/WBV2-P31-000/manifest.json", + "bytes": 1236, + "lines": 39, + "tokens": 309 + }, + { + "path": "docs/status/WBV2-P31-000.md", + "bytes": 351, + "lines": 8, + "tokens": 88 + } + ], + "sourceTokens": 1436, + "evidenceFiles": 0, + "evidenceBytes": 0, + "evidenceTokens": 0, + "totalTokens": 1436, + "reservedEnvelopeTokens": 1024, + "estimatedContextTokens": 2460, + "serializedContextTokens": 613, + "withinBudget": true + } +} diff --git a/tests/golden/WBV2-P31-002/implementation-report.json b/tests/golden/WBV2-P31-002/implementation-report.json new file mode 100644 index 000000000..ce0c933c2 --- /dev/null +++ b/tests/golden/WBV2-P31-002/implementation-report.json @@ -0,0 +1,34 @@ +{ + "schemaVersion": 1, + "task": "WBV2-P31-002", + "operation": "IMPLEMENT_RESOURCE_SCENE_FAMILY", + "status": "PASS", + "family": "IO.TEXT_DATABLOCK", + "sourceBacked": true, + "implementation": { + "marker": "web_engine_blend_main_set_text_source", + "sourcePaths": [ + "blender-5.2.0/source/blender/web_engine/web_engine_main_state.cpp", + "blender-5.2.0/source/blender/web_engine/web_engine_main_state.h", + "blender-5.2.0/source/blender/web_engine/web_engine_api.cpp", + "web/protocol/web-engine.ts", + "web/app/src/workers/web-engine.worker.ts", + "web/app/src/app/App.tsx" + ], + "duplicateShimAdded": false + }, + "verification": { + "status": "DEFERRED", + "chromium": false, + "receipts": false, + "completionOverlay": false + }, + "inventory": { + "total": 6900, + "legacyCompleted": 281, + "legacyPending": 6618, + "effectiveCompleted": 290, + "effectivePending": 6609 + }, + "nextTask": "WBV2-P31-003" +} diff --git a/tests/golden/WBV2-P31-002/manifest.json b/tests/golden/WBV2-P31-002/manifest.json new file mode 100644 index 000000000..a3c4c896c --- /dev/null +++ b/tests/golden/WBV2-P31-002/manifest.json @@ -0,0 +1,68 @@ +{ + "schemaVersion": 1, + "task": "WBV2-P31-002", + "parentTask": "WBV2-P31-001", + "operation": "IMPLEMENT_RESOURCE_SCENE_FAMILY", + "status": "done", + "enablingTask": false, + "parityStateChange": false, + "runtime": "SOURCE_BACKED_RESOURCE_SCENE_IMPLEMENTATION", + "artifacts": { + "parentManifest": { + "path": "tests/golden/WBV2-P31-001/manifest.json", + "sha256": "9d0e856506d562e42fa23d7a7c7c75320e4d506566eb27f48d212a6b188f53ee" + }, + "source1": { + "path": "blender-5.2.0/source/blender/web_engine/web_engine_main_state.cpp", + "sha256": "7803654bf15db8645b65e0653eb3599b46f969d65c5a1a365daeee51079259d4" + }, + "source2": { + "path": "blender-5.2.0/source/blender/web_engine/web_engine_main_state.h", + "sha256": "d689575a2a8496acf50b5b8cafbb1f26b80de54ed7735a2bf1507b01f072f568" + }, + "source3": { + "path": "blender-5.2.0/source/blender/web_engine/web_engine_api.cpp", + "sha256": "6a3eebde527f029fce7666a080e8cac1a60de944aee372bfe772ee6e2adabbdf" + }, + "source4": { + "path": "web/protocol/web-engine.ts", + "sha256": "3c4aba796afb70a6b29d34cca4ba924ffb1a240549b79730d1a639ca913ee896" + }, + "source5": { + "path": "web/app/src/workers/web-engine.worker.ts", + "sha256": "72242855c47eb33b1f440f3a586f290e074876bda6e5c1369d83444b0cb3e0af" + }, + "source6": { + "path": "web/app/src/app/App.tsx", + "sha256": "8c3ee6086716be3912a9597091642ee3416ee766a6aaedea7ca642ed7a9c3b53" + }, + "report": { + "path": "tests/golden/WBV2-P31-002/implementation-report.json", + "sha256": "cc4372f305a024e7cb14b7dbc3d96e1ed015872353b0f284119c7b2c1fd7830f" + }, + "status": { + "path": "docs/status/WBV2-P31-002.md", + "sha256": "600b3c7ed3882db0829a65db2b394ce03883335b7f44319493804768ab8b0765" + }, + "plan": { + "path": "tests/golden/WBV2-P31-002/resource-scene-task-plan.json", + "sha256": "ecf8fdcd3e479a7aae279755534e0783f2181f5c0edf9026767ba371d805c8e0" + }, + "taskContext": { + "path": "tests/golden/WBV2-P31-002/task-context.json", + "sha256": "21548c06fb936d80ef1ea8083d7682c8a8a9faa7fb61aa10618412f9f0615537" + } + }, + "assertions": { + "capabilityFamily": "IO.TEXT_DATABLOCK", + "sourceBacked": true, + "unsupportedFailsClosed": true, + "verificationDeferred": true, + "completionOverlayWritten": false, + "inventoryTotal": 6900, + "effectiveCompleted": 290, + "effectivePending": 6609, + "historicalReproduction": false + }, + "nextTask": "WBV2-P31-003" +} diff --git a/tests/golden/WBV2-P31-002/resource-scene-task-plan.json b/tests/golden/WBV2-P31-002/resource-scene-task-plan.json new file mode 100644 index 000000000..6b52a1ce4 --- /dev/null +++ b/tests/golden/WBV2-P31-002/resource-scene-task-plan.json @@ -0,0 +1,150 @@ +{ + "schemaVersion": 1, + "planId": "BLENDER_WEB_RESOURCE_SCENE_IMPLEMENTATION_P31", + "status": "ACTIVE_RESOURCE_SCENE_QUEUE", + "authority": "user_authorized_implementation_first_execution", + "executionPointer": "docs/EXECUTION_QUEUE.md", + "runtimePolicy": { + "blenderSource": "blender-5.2.0", + "mainAuthority": "blender_main", + "browserPolicy": "chromium_only_for_later_verification", + "verificationPolicy": "deferred", + "reusePolicy": "source_hash_behavior_hash_and_dedupe_key" + }, + "inventoryPolicy": { + "total": 6900, + "legacyCompleted": 281, + "legacyPending": 6618, + "effectiveCompleted": 290, + "effectivePending": 6609, + "overlayMutation": "forbidden_during_implementation_wave" + }, + "tasks": [ + { + "id": "WBV2-P31-000", + "title": "authorize_resource_scene_workbench", + "owner": "PROGRAM", + "parent": "WBV2-P30-004", + "status": "done", + "ready": false, + "kind": "enabling", + "behavior": "Authorize the next source-backed resource and scene-data implementation wave.", + "dependsOn": [ + "WBV2-P30-004" + ], + "phase": "P31", + "parityId": null, + "implementationClass": "SOURCE_BACKED", + "parallelGroup": "p31-000", + "gate": "G1", + "card": "docs/tasks/WBV2-P31-000.md", + "outputs": [ + "implementation-report", + "manifest", + "status" + ], + "acceptance": [ + "real source or WebEngine Main path is wired", + "unsupported input fails closed", + "implementation smoke is reproducible", + "verification remains deferred" + ], + "queueMutationAllowed": true + }, + { + "id": "WBV2-P31-001", + "title": "implement_resource_workbench", + "owner": "IO", + "parent": "WBV2-P31-000", + "status": "done", + "ready": false, + "kind": "feature", + "family": "IO.RESOURCE_WORKBENCH", + "behavior": "Expose packed VFonts, sounds, speakers, text blocks, textures and particle settings through a bounded resource workbench.", + "dependsOn": [ + "WBV2-P31-000" + ], + "phase": "P31", + "parityId": null, + "implementationClass": "SOURCE_BACKED", + "parallelGroup": "p31-001", + "gate": "IMPLEMENTATION", + "card": "docs/tasks/WBV2-P31-001.md", + "outputs": [ + "implementation-report", + "manifest", + "status" + ], + "acceptance": [ + "real source or WebEngine Main path is wired", + "unsupported input fails closed", + "implementation smoke is reproducible", + "verification remains deferred" + ], + "queueMutationAllowed": false + }, + { + "id": "WBV2-P31-002", + "title": "implement_text_datablock_authoring", + "owner": "IO", + "parent": "WBV2-P31-001", + "status": "done", + "ready": false, + "kind": "feature", + "family": "IO.TEXT_DATABLOCK", + "behavior": "Connect a typed text-source command to Blender Main Text datablocks with bounded persistence.", + "dependsOn": [ + "WBV2-P31-001" + ], + "phase": "P31", + "parityId": null, + "implementationClass": "SOURCE_BACKED", + "parallelGroup": "p31-002", + "gate": "IMPLEMENTATION", + "card": "docs/tasks/WBV2-P31-002.md", + "outputs": [ + "implementation-report", + "manifest", + "status" + ], + "acceptance": [ + "real source or WebEngine Main path is wired", + "unsupported input fails closed", + "implementation smoke is reproducible", + "verification remains deferred" + ], + "queueMutationAllowed": false + }, + { + "id": "WBV2-P31-003", + "title": "run_p31_implementation_smoke", + "owner": "RELEASE", + "parent": "WBV2-P31-002", + "status": "in_progress", + "ready": true, + "kind": "enabling", + "behavior": "Run the bounded production build smoke after P31 resource implementation.", + "dependsOn": [ + "WBV2-P31-002" + ], + "phase": "P31", + "parityId": null, + "implementationClass": "SOURCE_BACKED", + "parallelGroup": "p31-003", + "gate": "G1", + "card": "docs/tasks/WBV2-P31-003.md", + "outputs": [ + "implementation-report", + "manifest", + "status" + ], + "acceptance": [ + "real source or WebEngine Main path is wired", + "unsupported input fails closed", + "implementation smoke is reproducible", + "verification remains deferred" + ], + "queueMutationAllowed": true + } + ] +} diff --git a/tests/golden/WBV2-P31-002/task-context.json b/tests/golden/WBV2-P31-002/task-context.json new file mode 100644 index 000000000..5fc4e8d1c --- /dev/null +++ b/tests/golden/WBV2-P31-002/task-context.json @@ -0,0 +1,162 @@ +{ + "schemaVersion": 1, + "task": "WBV2-P31-002", + "parentTask": "WBV2-P31-001", + "status": "in_progress", + "goal": "Connect a typed text-source command to Blender Main Text datablocks with bounded persistence.", + "scope": { + "gap": "IO.TEXT_DATABLOCK", + "ownerFamily": "IO", + "implementationClass": "SOURCE_BACKED" + }, + "commands": [ + "node tools/web/check-task-context.mjs --task WBV2-P31-002 --write" + ], + "inputPaths": [], + "inputSelection": { + "schemaVersion": 1, + "limits": { + "maxFiles": 12, + "evidenceBytes": 8192, + "contextRemainingBytes": 3659, + "contextRemainingTokens": 914 + }, + "source": { + "bytes": 6245, + "tokens": 1562 + }, + "selected": [], + "excluded": [ + { + "path": "web/protocol/web-engine.ts", + "bytes": 15041, + "reason": "EVIDENCE_BYTE_BUDGET" + }, + { + "path": "tests/golden/WBV2-P31-002/", + "bytes": null, + "reason": "GENERATED_EVIDENCE_OUTPUT" + }, + { + "path": "docs/status/WBV2-P31-002.md", + "bytes": null, + "reason": "GENERATED_EVIDENCE_OUTPUT" + }, + { + "path": "tests/golden/WBV2-P31-002/manifest.json", + "bytes": null, + "reason": "GENERATED_EVIDENCE_OUTPUT" + } + ], + "totals": { + "files": 0, + "bytes": 0, + "tokens": 0 + } + }, + "exitCriteria": [ + "real source or WebEngine Main path is wired", + "unsupported input fails closed", + "implementation smoke is reproducible", + "verification remains deferred" + ], + "nextTask": "WBV2-P31-003", + "sourceDocuments": { + "queue": "docs/EXECUTION_QUEUE.md", + "taskCard": "docs/tasks/WBV2-P31-002.md", + "taskIndex": "tests/golden/WBV2/task-index.json", + "parentManifest": "tests/golden/WBV2-P31-001/manifest.json", + "parentStatus": "docs/status/WBV2-P31-001.md" + }, + "readPolicy": { + "required": [ + "docs/EXECUTION_QUEUE.md", + "docs/tasks/WBV2-P31-002.md", + "tests/golden/WBV2-P31-001/manifest.json", + "docs/status/WBV2-P31-001.md" + ], + "machineOnly": [ + "tests/golden/WBV2/task-index.json", + "tests/golden/M15-03A/task-catalog.jsonl" + ], + "optionalByNeed": [ + "docs/WEB_BLENDER_MODELER_V1_SCOPE.md", + "任务卡列出的精确协议/生产路径", + "任务卡明确命名的长期计划小节" + ], + "forbiddenByDefault": [ + "完整 CURRENT_EXECUTION_PLAN.md", + "完整 PROJECT_STATUS_AND_NEXT_WORK.md", + "全部 docs/status/*.md", + "完整 parity/WBS 计划", + "README 历史和 test-results/" + ] + }, + "parent": { + "manifest": { + "schemaVersion": 1, + "task": "WBV2-P31-001", + "parentTask": "WBV2-P31-000", + "status": "done", + "nextTask": "WBV2-P31-002", + "artifactCount": 7 + }, + "statusSummary": [ + "# WBV2-P31-001 status", + "- task: `WBV2-P31-001`; parent: `WBV2-P31-000`; status: `done`", + "- source-backed resource/scene family: `IO.RESOURCE_WORKBENCH`; marker: `resource-scene-workbench`", + "- Chromium receipts and completion overlay: `DEFERRED`", + "- inventory unchanged: `6900/6618`, effective `290/6609`", + "- nextTask: `WBV2-P31-002`" + ] + }, + "budgets": { + "queueBytes": 4096, + "taskBytes": 1323, + "parentManifestBytes": 24576, + "parentStatusBytes": 6144, + "evidenceFiles": 12, + "evidenceBytes": 8192, + "contextTokens": 3500, + "contextEnvelopeTokens": 1024, + "taskLines": 38, + "taskTokens": 331 + }, + "size": { + "documents": [ + { + "path": "docs/EXECUTION_QUEUE.md", + "bytes": 2803, + "lines": 51, + "tokens": 701 + }, + { + "path": "docs/tasks/WBV2-P31-002.md", + "bytes": 1323, + "lines": 38, + "tokens": 331 + }, + { + "path": "tests/golden/WBV2-P31-001/manifest.json", + "bytes": 1795, + "lines": 53, + "tokens": 449 + }, + { + "path": "docs/status/WBV2-P31-001.md", + "bytes": 324, + "lines": 8, + "tokens": 81 + } + ], + "sourceTokens": 1562, + "evidenceFiles": 0, + "evidenceBytes": 0, + "evidenceTokens": 0, + "totalTokens": 1562, + "reservedEnvelopeTokens": 1024, + "estimatedContextTokens": 2586, + "serializedContextTokens": 605, + "withinBudget": true + } +} diff --git a/tests/golden/WBV2-P31-003/implementation-report.json b/tests/golden/WBV2-P31-003/implementation-report.json new file mode 100644 index 000000000..778921810 --- /dev/null +++ b/tests/golden/WBV2-P31-003/implementation-report.json @@ -0,0 +1,30 @@ +{ + "schemaVersion": 1, + "task": "WBV2-P31-003", + "operation": "RUN_RESOURCE_SCENE_IMPLEMENTATION_SMOKE", + "status": "PASS", + "family": "P31.IMPLEMENTATION_SMOKE", + "sourceBacked": true, + "implementation": { + "marker": "applyCommand", + "sourcePaths": [ + "web/app/src/workers/web-engine.worker.ts", + "web/app/src/vendor/blender/web_engine.wasm" + ], + "duplicateShimAdded": false + }, + "verification": { + "status": "DEFERRED", + "chromium": false, + "receipts": false, + "completionOverlay": false + }, + "inventory": { + "total": 6900, + "legacyCompleted": 281, + "legacyPending": 6618, + "effectiveCompleted": 290, + "effectivePending": 6609 + }, + "nextTask": "WBV2-P32-000" +} diff --git a/tests/golden/WBV2-P31-003/manifest.json b/tests/golden/WBV2-P31-003/manifest.json new file mode 100644 index 000000000..a4896e334 --- /dev/null +++ b/tests/golden/WBV2-P31-003/manifest.json @@ -0,0 +1,52 @@ +{ + "schemaVersion": 1, + "task": "WBV2-P31-003", + "parentTask": "WBV2-P31-002", + "operation": "RUN_RESOURCE_SCENE_IMPLEMENTATION_SMOKE", + "status": "done", + "enablingTask": false, + "parityStateChange": false, + "runtime": "SOURCE_BACKED_RESOURCE_SCENE_IMPLEMENTATION", + "artifacts": { + "parentManifest": { + "path": "tests/golden/WBV2-P31-002/manifest.json", + "sha256": "d08dcb1bf0646292af0095853dac6d4194a5e76867e72b14e35669b7f7af9abc" + }, + "source1": { + "path": "web/app/src/workers/web-engine.worker.ts", + "sha256": "72242855c47eb33b1f440f3a586f290e074876bda6e5c1369d83444b0cb3e0af" + }, + "source2": { + "path": "web/app/src/vendor/blender/web_engine.wasm", + "sha256": "e04c9c06fa2db509acf210290cfd132acae68597964952869f133d51a8c0d9ff" + }, + "report": { + "path": "tests/golden/WBV2-P31-003/implementation-report.json", + "sha256": "9cae0b50b135c2436fa48e5656be20c738a45b92c85be4c9a4e7287242d164d4" + }, + "status": { + "path": "docs/status/WBV2-P31-003.md", + "sha256": "0e56452fadae174fe741651a85d310128dd930474e4eaf5dbcdd300dc0010656" + }, + "plan": { + "path": "tests/golden/WBV2-P31-003/resource-scene-task-plan.json", + "sha256": "f6305f6161166a75c4759ce532357cef85f0a5586396449803e72b01782479c5" + }, + "taskContext": { + "path": "tests/golden/WBV2-P31-003/task-context.json", + "sha256": "30d53c25a3ac057e6d5beb760287777d56d2f9955af42710a0e148e330f1240f" + } + }, + "assertions": { + "capabilityFamily": "P31.IMPLEMENTATION_SMOKE", + "sourceBacked": true, + "unsupportedFailsClosed": true, + "verificationDeferred": true, + "completionOverlayWritten": false, + "inventoryTotal": 6900, + "effectiveCompleted": 290, + "effectivePending": 6609, + "historicalReproduction": false + }, + "nextTask": "WBV2-P32-000" +} diff --git a/tests/golden/WBV2-P31-003/resource-scene-task-plan.json b/tests/golden/WBV2-P31-003/resource-scene-task-plan.json new file mode 100644 index 000000000..9eb33ffda --- /dev/null +++ b/tests/golden/WBV2-P31-003/resource-scene-task-plan.json @@ -0,0 +1,180 @@ +{ + "schemaVersion": 1, + "planId": "BLENDER_WEB_RESOURCE_SCENE_IMPLEMENTATION_P31", + "status": "ACTIVE_RESOURCE_SCENE_QUEUE", + "authority": "user_authorized_implementation_first_execution", + "executionPointer": "docs/EXECUTION_QUEUE.md", + "runtimePolicy": { + "blenderSource": "blender-5.2.0", + "mainAuthority": "blender_main", + "browserPolicy": "chromium_only_for_later_verification", + "verificationPolicy": "deferred", + "reusePolicy": "source_hash_behavior_hash_and_dedupe_key" + }, + "inventoryPolicy": { + "total": 6900, + "legacyCompleted": 281, + "legacyPending": 6618, + "effectiveCompleted": 290, + "effectivePending": 6609, + "overlayMutation": "forbidden_during_implementation_wave" + }, + "tasks": [ + { + "id": "WBV2-P31-000", + "title": "authorize_resource_scene_workbench", + "owner": "PROGRAM", + "parent": "WBV2-P30-004", + "status": "done", + "ready": false, + "kind": "enabling", + "behavior": "Authorize the next source-backed resource and scene-data implementation wave.", + "dependsOn": [ + "WBV2-P30-004" + ], + "phase": "P31", + "parityId": null, + "implementationClass": "SOURCE_BACKED", + "parallelGroup": "p31-000", + "gate": "G1", + "card": "docs/tasks/WBV2-P31-000.md", + "outputs": [ + "implementation-report", + "manifest", + "status" + ], + "acceptance": [ + "real source or WebEngine Main path is wired", + "unsupported input fails closed", + "implementation smoke is reproducible", + "verification remains deferred" + ], + "queueMutationAllowed": true + }, + { + "id": "WBV2-P31-001", + "title": "implement_resource_workbench", + "owner": "IO", + "parent": "WBV2-P31-000", + "status": "done", + "ready": false, + "kind": "feature", + "family": "IO.RESOURCE_WORKBENCH", + "behavior": "Expose packed VFonts, sounds, speakers, text blocks, textures and particle settings through a bounded resource workbench.", + "dependsOn": [ + "WBV2-P31-000" + ], + "phase": "P31", + "parityId": null, + "implementationClass": "SOURCE_BACKED", + "parallelGroup": "p31-001", + "gate": "IMPLEMENTATION", + "card": "docs/tasks/WBV2-P31-001.md", + "outputs": [ + "implementation-report", + "manifest", + "status" + ], + "acceptance": [ + "real source or WebEngine Main path is wired", + "unsupported input fails closed", + "implementation smoke is reproducible", + "verification remains deferred" + ], + "queueMutationAllowed": false + }, + { + "id": "WBV2-P31-002", + "title": "implement_text_datablock_authoring", + "owner": "IO", + "parent": "WBV2-P31-001", + "status": "done", + "ready": false, + "kind": "feature", + "family": "IO.TEXT_DATABLOCK", + "behavior": "Connect a typed text-source command to Blender Main Text datablocks with bounded persistence.", + "dependsOn": [ + "WBV2-P31-001" + ], + "phase": "P31", + "parityId": null, + "implementationClass": "SOURCE_BACKED", + "parallelGroup": "p31-002", + "gate": "IMPLEMENTATION", + "card": "docs/tasks/WBV2-P31-002.md", + "outputs": [ + "implementation-report", + "manifest", + "status" + ], + "acceptance": [ + "real source or WebEngine Main path is wired", + "unsupported input fails closed", + "implementation smoke is reproducible", + "verification remains deferred" + ], + "queueMutationAllowed": false + }, + { + "id": "WBV2-P31-003", + "title": "run_p31_implementation_smoke", + "owner": "RELEASE", + "parent": "WBV2-P31-002", + "status": "done", + "ready": false, + "kind": "enabling", + "behavior": "Run the bounded production build smoke after P31 resource implementation.", + "dependsOn": [ + "WBV2-P31-002" + ], + "phase": "P31", + "parityId": null, + "implementationClass": "SOURCE_BACKED", + "parallelGroup": "p31-003", + "gate": "G1", + "card": "docs/tasks/WBV2-P31-003.md", + "outputs": [ + "implementation-report", + "manifest", + "status" + ], + "acceptance": [ + "real source or WebEngine Main path is wired", + "unsupported input fails closed", + "implementation smoke is reproducible", + "verification remains deferred" + ], + "queueMutationAllowed": true + }, + { + "id": "WBV2-P32-000", + "phase": "P32", + "title": "authorize_next_implementation_wave", + "kind": "enabling", + "owner": "PROGRAM", + "dependsOn": [ + "WBV2-P31-003" + ], + "parityId": null, + "implementationClass": "SOURCE_BACKED", + "parallelGroup": "p32-000", + "gate": "G1", + "card": "docs/tasks/WBV2-P32-000.md", + "behavior": "Authorize the next source-backed implementation wave.", + "outputs": [ + "implementation-report", + "manifest", + "status" + ], + "acceptance": [ + "real source or WebEngine Main path is wired", + "unsupported input fails closed", + "implementation smoke is reproducible", + "verification remains deferred" + ], + "status": "in_progress", + "ready": true, + "queueMutationAllowed": true + } + ] +} diff --git a/tests/golden/WBV2-P31-003/task-context.json b/tests/golden/WBV2-P31-003/task-context.json new file mode 100644 index 000000000..110b97c54 --- /dev/null +++ b/tests/golden/WBV2-P31-003/task-context.json @@ -0,0 +1,162 @@ +{ + "schemaVersion": 1, + "task": "WBV2-P31-003", + "parentTask": "WBV2-P31-002", + "status": "in_progress", + "goal": "Run the bounded production build smoke after P31 resource implementation.", + "scope": { + "gap": "workflow:run_p31_implementation_smoke", + "ownerFamily": "RELEASE", + "implementationClass": "SOURCE_BACKED" + }, + "commands": [ + "node tools/web/check-task-context.mjs --task WBV2-P31-003 --write" + ], + "inputPaths": [], + "inputSelection": { + "schemaVersion": 1, + "limits": { + "maxFiles": 12, + "evidenceBytes": 8192, + "contextRemainingBytes": 2956, + "contextRemainingTokens": 737 + }, + "source": { + "bytes": 6948, + "tokens": 1739 + }, + "selected": [], + "excluded": [ + { + "path": "web/protocol/web-engine.ts", + "bytes": 15041, + "reason": "EVIDENCE_BYTE_BUDGET" + }, + { + "path": "tests/golden/WBV2-P31-003/", + "bytes": null, + "reason": "GENERATED_EVIDENCE_OUTPUT" + }, + { + "path": "docs/status/WBV2-P31-003.md", + "bytes": null, + "reason": "GENERATED_EVIDENCE_OUTPUT" + }, + { + "path": "tests/golden/WBV2-P31-003/manifest.json", + "bytes": null, + "reason": "GENERATED_EVIDENCE_OUTPUT" + } + ], + "totals": { + "files": 0, + "bytes": 0, + "tokens": 0 + } + }, + "exitCriteria": [ + "real source or WebEngine Main path is wired", + "unsupported input fails closed", + "implementation smoke is reproducible", + "verification remains deferred" + ], + "nextTask": "WBV2-P32-000", + "sourceDocuments": { + "queue": "docs/EXECUTION_QUEUE.md", + "taskCard": "docs/tasks/WBV2-P31-003.md", + "taskIndex": "tests/golden/WBV2/task-index.json", + "parentManifest": "tests/golden/WBV2-P31-002/manifest.json", + "parentStatus": "docs/status/WBV2-P31-002.md" + }, + "readPolicy": { + "required": [ + "docs/EXECUTION_QUEUE.md", + "docs/tasks/WBV2-P31-003.md", + "tests/golden/WBV2-P31-002/manifest.json", + "docs/status/WBV2-P31-002.md" + ], + "machineOnly": [ + "tests/golden/WBV2/task-index.json", + "tests/golden/M15-03A/task-catalog.jsonl" + ], + "optionalByNeed": [ + "docs/WEB_BLENDER_MODELER_V1_SCOPE.md", + "任务卡列出的精确协议/生产路径", + "任务卡明确命名的长期计划小节" + ], + "forbiddenByDefault": [ + "完整 CURRENT_EXECUTION_PLAN.md", + "完整 PROJECT_STATUS_AND_NEXT_WORK.md", + "全部 docs/status/*.md", + "完整 parity/WBS 计划", + "README 历史和 test-results/" + ] + }, + "parent": { + "manifest": { + "schemaVersion": 1, + "task": "WBV2-P31-002", + "parentTask": "WBV2-P31-001", + "status": "done", + "nextTask": "WBV2-P31-003", + "artifactCount": 11 + }, + "statusSummary": [ + "# WBV2-P31-002 status", + "- task: `WBV2-P31-002`; parent: `WBV2-P31-001`; status: `done`", + "- source-backed resource/scene family: `IO.TEXT_DATABLOCK`; marker: `web_engine_blend_main_set_text_source`", + "- Chromium receipts and completion overlay: `DEFERRED`", + "- inventory unchanged: `6900/6618`, effective `290/6609`", + "- nextTask: `WBV2-P31-003`" + ] + }, + "budgets": { + "queueBytes": 4096, + "taskBytes": 1293, + "parentManifestBytes": 24576, + "parentStatusBytes": 6144, + "evidenceFiles": 12, + "evidenceBytes": 8192, + "contextTokens": 3500, + "contextEnvelopeTokens": 1024, + "taskLines": 38, + "taskTokens": 324 + }, + "size": { + "documents": [ + { + "path": "docs/EXECUTION_QUEUE.md", + "bytes": 2803, + "lines": 51, + "tokens": 701 + }, + { + "path": "docs/tasks/WBV2-P31-003.md", + "bytes": 1293, + "lines": 38, + "tokens": 324 + }, + { + "path": "tests/golden/WBV2-P31-002/manifest.json", + "bytes": 2519, + "lines": 69, + "tokens": 630 + }, + { + "path": "docs/status/WBV2-P31-002.md", + "bytes": 333, + "lines": 8, + "tokens": 84 + } + ], + "sourceTokens": 1739, + "evidenceFiles": 0, + "evidenceBytes": 0, + "evidenceTokens": 0, + "totalTokens": 1739, + "reservedEnvelopeTokens": 1024, + "estimatedContextTokens": 2763, + "serializedContextTokens": 607, + "withinBudget": true + } +} diff --git a/tests/golden/WBV2-P32-000/manifest.json b/tests/golden/WBV2-P32-000/manifest.json new file mode 100644 index 000000000..77e620161 --- /dev/null +++ b/tests/golden/WBV2-P32-000/manifest.json @@ -0,0 +1,38 @@ +{ + "schemaVersion": 1, + "task": "WBV2-P32-000", + "parentTask": "WBV2-P31-003", + "operation": "AUTHORIZE_SCENE_CONTEXT_WORKBENCH", + "status": "done", + "enablingTask": true, + "parityStateChange": false, + "runtime": "SOURCE_BACKED_SCENE_CONTEXT_QUEUE", + "artifacts": { + "parentManifest": { + "path": "tests/golden/WBV2-P31-003/manifest.json", + "sha256": "7279cf19524eeec2ffd6a43abed0d48ac311d901953cd855e88dacf4292bcb98" + }, + "plan": { + "path": "tests/golden/WBV2-P32-000/scene-context-task-plan.json", + "sha256": "9ebfc48396562ee59744f77c175256906fd31d4538eaef44b28f0018676039d5" + }, + "report": { + "path": "tests/golden/WBV2-P32-000/scene-context-root-report.json", + "sha256": "4006189330353510b79aa278f48e9b64473a6b965bf85c233f229164b4534a9a" + }, + "status": { + "path": "docs/status/WBV2-P32-000.md", + "sha256": "a319059263e65f7ba2de5cf51338e92f6a203271ef0a60a633c8f28bbf865de0" + } + }, + "assertions": { + "plannedTasks": 4, + "verificationDeferred": true, + "completionOverlayWritten": false, + "inventoryTotal": 6900, + "effectiveCompleted": 290, + "effectivePending": 6609, + "historicalReproduction": false + }, + "nextTask": "WBV2-P32-001" +} diff --git a/tests/golden/WBV2-P32-000/scene-context-root-report.json b/tests/golden/WBV2-P32-000/scene-context-root-report.json new file mode 100644 index 000000000..38a6f47ab --- /dev/null +++ b/tests/golden/WBV2-P32-000/scene-context-root-report.json @@ -0,0 +1,33 @@ +{ + "schemaVersion": 1, + "task": "WBV2-P32-000", + "operation": "AUTHORIZE_SCENE_CONTEXT_WORKBENCH", + "status": "PASS", + "parent": { + "task": "WBV2-P31-003", + "manifest": "tests/golden/WBV2-P31-003/manifest.json", + "manifestSha256": "7279cf19524eeec2ffd6a43abed0d48ac311d901953cd855e88dacf4292bcb98" + }, + "scope": { + "firstTask": "WBV2-P32-001", + "plannedTasks": [ + "WBV2-P32-000", + "WBV2-P32-001", + "WBV2-P32-002", + "WBV2-P32-003" + ] + }, + "verification": { + "status": "DEFERRED", + "chromium": false, + "completionOverlay": false + }, + "inventory": { + "total": 6900, + "legacyCompleted": 281, + "legacyPending": 6618, + "effectiveCompleted": 290, + "effectivePending": 6609 + }, + "nextTask": "WBV2-P32-001" +} diff --git a/tests/golden/WBV2-P32-000/scene-context-task-plan.json b/tests/golden/WBV2-P32-000/scene-context-task-plan.json new file mode 100644 index 000000000..acbdde020 --- /dev/null +++ b/tests/golden/WBV2-P32-000/scene-context-task-plan.json @@ -0,0 +1,144 @@ +{ + "schemaVersion": 1, + "planId": "BLENDER_WEB_SCENE_CONTEXT_IMPLEMENTATION_P32", + "status": "ACTIVE_SCENE_CONTEXT_QUEUE", + "authority": "user_authorized_implementation_first_execution", + "executionPointer": "docs/EXECUTION_QUEUE.md", + "runtimePolicy": { + "blenderSource": "blender-5.2.0", + "mainAuthority": "blender_main", + "browserPolicy": "chromium_only_for_later_verification", + "verificationPolicy": "deferred", + "reusePolicy": "source_hash_behavior_hash_and_dedupe_key" + }, + "inventoryPolicy": { + "total": 6900, + "legacyCompleted": 281, + "legacyPending": 6618, + "effectiveCompleted": 290, + "effectivePending": 6609, + "overlayMutation": "forbidden_during_implementation_wave" + }, + "tasks": [ + { + "id": "WBV2-P32-000", + "phase": "P32", + "title": "authorize_scene_context_workbench", + "kind": "enabling", + "owner": "PROGRAM", + "dependsOn": [ + "WBV2-P31-003" + ], + "parityId": null, + "implementationClass": "SOURCE_BACKED", + "parallelGroup": "p32-000", + "gate": "G1", + "card": "docs/tasks/WBV2-P32-000.md", + "behavior": "Authorize scene context and release status implementation.", + "outputs": [ + "implementation-report", + "manifest", + "status" + ], + "acceptance": [ + "real source or WebEngine Main path is wired", + "unsupported input fails closed", + "implementation smoke is reproducible", + "verification remains deferred" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": true + }, + { + "id": "WBV2-P32-001", + "phase": "P32", + "title": "implement_scene_context_workbench", + "kind": "feature", + "owner": "WORKFLOW", + "dependsOn": [ + "WBV2-P32-000" + ], + "parityId": null, + "implementationClass": "SOURCE_BACKED", + "parallelGroup": "p32-001", + "gate": "IMPLEMENTATION", + "card": "docs/tasks/WBV2-P32-001.md", + "behavior": "Expose real SceneIR collections, libraries, armatures and workflow status in the Properties workbench.", + "outputs": [ + "implementation-report", + "manifest", + "status" + ], + "acceptance": [ + "real source or WebEngine Main path is wired", + "unsupported input fails closed", + "implementation smoke is reproducible", + "verification remains deferred" + ], + "status": "in_progress", + "ready": true, + "queueMutationAllowed": false + }, + { + "id": "WBV2-P32-002", + "phase": "P32", + "title": "implement_release_status_workbench", + "kind": "feature", + "owner": "RELEASE", + "dependsOn": [ + "WBV2-P32-001" + ], + "parityId": null, + "implementationClass": "SOURCE_BACKED", + "parallelGroup": "p32-002", + "gate": "IMPLEMENTATION", + "card": "docs/tasks/WBV2-P32-002.md", + "behavior": "Expose guarded scripting, render routing, server job and release candidate status without local shims.", + "outputs": [ + "implementation-report", + "manifest", + "status" + ], + "acceptance": [ + "real source or WebEngine Main path is wired", + "unsupported input fails closed", + "implementation smoke is reproducible", + "verification remains deferred" + ], + "status": "planned", + "ready": false, + "queueMutationAllowed": false + }, + { + "id": "WBV2-P32-003", + "phase": "P32", + "title": "run_p32_implementation_smoke", + "kind": "enabling", + "owner": "RELEASE", + "dependsOn": [ + "WBV2-P32-002" + ], + "parityId": null, + "implementationClass": "SOURCE_BACKED", + "parallelGroup": "p32-003", + "gate": "IMPLEMENTATION", + "card": "docs/tasks/WBV2-P32-003.md", + "behavior": "Run the bounded production build smoke after scene context implementation.", + "outputs": [ + "implementation-report", + "manifest", + "status" + ], + "acceptance": [ + "real source or WebEngine Main path is wired", + "unsupported input fails closed", + "implementation smoke is reproducible", + "verification remains deferred" + ], + "status": "planned", + "ready": false, + "queueMutationAllowed": false + } + ] +} diff --git a/tests/golden/WBV2-P32-000/task-context.json b/tests/golden/WBV2-P32-000/task-context.json new file mode 100644 index 000000000..64c345dcc --- /dev/null +++ b/tests/golden/WBV2-P32-000/task-context.json @@ -0,0 +1,162 @@ +{ + "schemaVersion": 1, + "task": "WBV2-P32-000", + "parentTask": "WBV2-P31-003", + "status": "done", + "goal": "Authorize scene context and release status implementation.", + "scope": { + "gap": "workflow:authorize_scene_context_workbench", + "ownerFamily": "PROGRAM", + "implementationClass": "SOURCE_BACKED" + }, + "commands": [ + "node tools/web/check-task-context.mjs --task WBV2-P32-000 --write" + ], + "inputPaths": [], + "inputSelection": { + "schemaVersion": 1, + "limits": { + "maxFiles": 12, + "evidenceBytes": 8192, + "contextRemainingBytes": 3638, + "contextRemainingTokens": 908 + }, + "source": { + "bytes": 6266, + "tokens": 1568 + }, + "selected": [], + "excluded": [ + { + "path": "web/protocol/scene-ir.ts", + "bytes": 110285, + "reason": "EVIDENCE_BYTE_BUDGET" + }, + { + "path": "tests/golden/WBV2-P32-000/", + "bytes": null, + "reason": "GENERATED_EVIDENCE_OUTPUT" + }, + { + "path": "docs/status/WBV2-P32-000.md", + "bytes": null, + "reason": "GENERATED_EVIDENCE_OUTPUT" + }, + { + "path": "tests/golden/WBV2-P32-000/manifest.json", + "bytes": null, + "reason": "GENERATED_EVIDENCE_OUTPUT" + } + ], + "totals": { + "files": 0, + "bytes": 0, + "tokens": 0 + } + }, + "exitCriteria": [ + "real source or WebEngine Main path is wired", + "unsupported input fails closed", + "implementation smoke is reproducible", + "verification remains deferred" + ], + "nextTask": "WBV2-P32-001", + "sourceDocuments": { + "queue": "docs/EXECUTION_QUEUE.md", + "taskCard": "docs/tasks/WBV2-P32-000.md", + "taskIndex": "tests/golden/WBV2/task-index.json", + "parentManifest": "tests/golden/WBV2-P31-003/manifest.json", + "parentStatus": "docs/status/WBV2-P31-003.md" + }, + "readPolicy": { + "required": [ + "docs/EXECUTION_QUEUE.md", + "docs/tasks/WBV2-P32-000.md", + "tests/golden/WBV2-P31-003/manifest.json", + "docs/status/WBV2-P31-003.md" + ], + "machineOnly": [ + "tests/golden/WBV2/task-index.json", + "tests/golden/M15-03A/task-catalog.jsonl" + ], + "optionalByNeed": [ + "docs/WEB_BLENDER_MODELER_V1_SCOPE.md", + "任务卡列出的精确协议/生产路径", + "任务卡明确命名的长期计划小节" + ], + "forbiddenByDefault": [ + "完整 CURRENT_EXECUTION_PLAN.md", + "完整 PROJECT_STATUS_AND_NEXT_WORK.md", + "全部 docs/status/*.md", + "完整 parity/WBS 计划", + "README 历史和 test-results/" + ] + }, + "parent": { + "manifest": { + "schemaVersion": 1, + "task": "WBV2-P31-003", + "parentTask": "WBV2-P31-002", + "status": "done", + "nextTask": "WBV2-P32-000", + "artifactCount": 7 + }, + "statusSummary": [ + "# WBV2-P31-003 status", + "- task: `WBV2-P31-003`; parent: `WBV2-P31-002`; status: `done`", + "- source-backed resource/scene family: `P31.IMPLEMENTATION_SMOKE`; marker: `applyCommand`", + "- Chromium receipts and completion overlay: `DEFERRED`", + "- inventory unchanged: `6900/6618`, effective `290/6609`", + "- nextTask: `WBV2-P32-000`" + ] + }, + "budgets": { + "queueBytes": 4096, + "taskBytes": 1307, + "parentManifestBytes": 24576, + "parentStatusBytes": 6144, + "evidenceFiles": 12, + "evidenceBytes": 8192, + "contextTokens": 3500, + "contextEnvelopeTokens": 1024, + "taskLines": 38, + "taskTokens": 327 + }, + "size": { + "documents": [ + { + "path": "docs/EXECUTION_QUEUE.md", + "bytes": 2803, + "lines": 51, + "tokens": 701 + }, + { + "path": "docs/tasks/WBV2-P32-000.md", + "bytes": 1307, + "lines": 38, + "tokens": 327 + }, + { + "path": "tests/golden/WBV2-P31-003/manifest.json", + "bytes": 1841, + "lines": 53, + "tokens": 461 + }, + { + "path": "docs/status/WBV2-P31-003.md", + "bytes": 315, + "lines": 8, + "tokens": 79 + } + ], + "sourceTokens": 1568, + "evidenceFiles": 0, + "evidenceBytes": 0, + "evidenceTokens": 0, + "totalTokens": 1568, + "reservedEnvelopeTokens": 1024, + "estimatedContextTokens": 2592, + "serializedContextTokens": 602, + "withinBudget": true + } +} diff --git a/tests/golden/WBV2-P32-001/implementation-report.json b/tests/golden/WBV2-P32-001/implementation-report.json new file mode 100644 index 000000000..39dc1d67a --- /dev/null +++ b/tests/golden/WBV2-P32-001/implementation-report.json @@ -0,0 +1,30 @@ +{ + "schemaVersion": 1, + "task": "WBV2-P32-001", + "operation": "IMPLEMENT_SCENE_CONTEXT_FAMILY", + "status": "PASS", + "family": "WORKFLOW.SCENE_CONTEXT", + "sourceBacked": true, + "implementation": { + "marker": "scene-context-workbench", + "sourcePaths": [ + "web/app/src/app/App.tsx", + "web/protocol/scene-ir.ts" + ], + "duplicateShimAdded": false + }, + "verification": { + "status": "DEFERRED", + "chromium": false, + "receipts": false, + "completionOverlay": false + }, + "inventory": { + "total": 6900, + "legacyCompleted": 281, + "legacyPending": 6618, + "effectiveCompleted": 290, + "effectivePending": 6609 + }, + "nextTask": "WBV2-P32-002" +} diff --git a/tests/golden/WBV2-P32-001/manifest.json b/tests/golden/WBV2-P32-001/manifest.json new file mode 100644 index 000000000..5b0b04650 --- /dev/null +++ b/tests/golden/WBV2-P32-001/manifest.json @@ -0,0 +1,52 @@ +{ + "schemaVersion": 1, + "task": "WBV2-P32-001", + "parentTask": "WBV2-P32-000", + "operation": "IMPLEMENT_SCENE_CONTEXT_FAMILY", + "status": "done", + "enablingTask": false, + "parityStateChange": false, + "runtime": "SOURCE_BACKED_SCENE_CONTEXT_IMPLEMENTATION", + "artifacts": { + "parentManifest": { + "path": "tests/golden/WBV2-P32-000/manifest.json", + "sha256": "dd6018ab897e23f7a4dd62a3d7836af0475c0b961d29cb7b67c3e5f49f4256ee" + }, + "source1": { + "path": "web/app/src/app/App.tsx", + "sha256": "4c608bb481c1c2da0bb80f010a5636fd1a9b69b412cd231834eba1f24d5da784" + }, + "source2": { + "path": "web/protocol/scene-ir.ts", + "sha256": "7c3582a11cfbab47ebb0dced99034a43591500f70ca2a24c58bd5dc183d977cb" + }, + "report": { + "path": "tests/golden/WBV2-P32-001/implementation-report.json", + "sha256": "fe08e8f7bd449586804631d4c1b4e8f916244c96179abeed01bbff058f30ec07" + }, + "status": { + "path": "docs/status/WBV2-P32-001.md", + "sha256": "95e97781271bc3dbb2d07c583a443b1e21b7bf8c96f0ab8caf2f8a68466f883a" + }, + "plan": { + "path": "tests/golden/WBV2-P32-001/scene-context-task-plan.json", + "sha256": "e76c3bcc63bdaeea9951e10c1c9907fbbbd0eee5bd97dc53869cf915f95d0aa6" + }, + "taskContext": { + "path": "tests/golden/WBV2-P32-001/task-context.json", + "sha256": "5240442f22b808f9390dc15b42be67ba32f957c06872864dde2c405cf4fb5da1" + } + }, + "assertions": { + "capabilityFamily": "WORKFLOW.SCENE_CONTEXT", + "sourceBacked": true, + "unsupportedFailsClosed": true, + "verificationDeferred": true, + "completionOverlayWritten": false, + "inventoryTotal": 6900, + "effectiveCompleted": 290, + "effectivePending": 6609, + "historicalReproduction": false + }, + "nextTask": "WBV2-P32-002" +} diff --git a/tests/golden/WBV2-P32-001/scene-context-task-plan.json b/tests/golden/WBV2-P32-001/scene-context-task-plan.json new file mode 100644 index 000000000..a0117fc08 --- /dev/null +++ b/tests/golden/WBV2-P32-001/scene-context-task-plan.json @@ -0,0 +1,144 @@ +{ + "schemaVersion": 1, + "planId": "BLENDER_WEB_SCENE_CONTEXT_IMPLEMENTATION_P32", + "status": "ACTIVE_SCENE_CONTEXT_QUEUE", + "authority": "user_authorized_implementation_first_execution", + "executionPointer": "docs/EXECUTION_QUEUE.md", + "runtimePolicy": { + "blenderSource": "blender-5.2.0", + "mainAuthority": "blender_main", + "browserPolicy": "chromium_only_for_later_verification", + "verificationPolicy": "deferred", + "reusePolicy": "source_hash_behavior_hash_and_dedupe_key" + }, + "inventoryPolicy": { + "total": 6900, + "legacyCompleted": 281, + "legacyPending": 6618, + "effectiveCompleted": 290, + "effectivePending": 6609, + "overlayMutation": "forbidden_during_implementation_wave" + }, + "tasks": [ + { + "id": "WBV2-P32-000", + "phase": "P32", + "title": "authorize_scene_context_workbench", + "kind": "enabling", + "owner": "PROGRAM", + "dependsOn": [ + "WBV2-P31-003" + ], + "parityId": null, + "implementationClass": "SOURCE_BACKED", + "parallelGroup": "p32-000", + "gate": "G1", + "card": "docs/tasks/WBV2-P32-000.md", + "behavior": "Authorize scene context and release status implementation.", + "outputs": [ + "implementation-report", + "manifest", + "status" + ], + "acceptance": [ + "real source or WebEngine Main path is wired", + "unsupported input fails closed", + "implementation smoke is reproducible", + "verification remains deferred" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": true + }, + { + "id": "WBV2-P32-001", + "phase": "P32", + "title": "implement_scene_context_workbench", + "kind": "feature", + "owner": "WORKFLOW", + "dependsOn": [ + "WBV2-P32-000" + ], + "parityId": null, + "implementationClass": "SOURCE_BACKED", + "parallelGroup": "p32-001", + "gate": "IMPLEMENTATION", + "card": "docs/tasks/WBV2-P32-001.md", + "behavior": "Expose real SceneIR collections, libraries, armatures and workflow status in the Properties workbench.", + "outputs": [ + "implementation-report", + "manifest", + "status" + ], + "acceptance": [ + "real source or WebEngine Main path is wired", + "unsupported input fails closed", + "implementation smoke is reproducible", + "verification remains deferred" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": false + }, + { + "id": "WBV2-P32-002", + "phase": "P32", + "title": "implement_release_status_workbench", + "kind": "feature", + "owner": "RELEASE", + "dependsOn": [ + "WBV2-P32-001" + ], + "parityId": null, + "implementationClass": "SOURCE_BACKED", + "parallelGroup": "p32-002", + "gate": "IMPLEMENTATION", + "card": "docs/tasks/WBV2-P32-002.md", + "behavior": "Expose guarded scripting, render routing, server job and release candidate status without local shims.", + "outputs": [ + "implementation-report", + "manifest", + "status" + ], + "acceptance": [ + "real source or WebEngine Main path is wired", + "unsupported input fails closed", + "implementation smoke is reproducible", + "verification remains deferred" + ], + "status": "in_progress", + "ready": true, + "queueMutationAllowed": false + }, + { + "id": "WBV2-P32-003", + "phase": "P32", + "title": "run_p32_implementation_smoke", + "kind": "enabling", + "owner": "RELEASE", + "dependsOn": [ + "WBV2-P32-002" + ], + "parityId": null, + "implementationClass": "SOURCE_BACKED", + "parallelGroup": "p32-003", + "gate": "IMPLEMENTATION", + "card": "docs/tasks/WBV2-P32-003.md", + "behavior": "Run the bounded production build smoke after scene context implementation.", + "outputs": [ + "implementation-report", + "manifest", + "status" + ], + "acceptance": [ + "real source or WebEngine Main path is wired", + "unsupported input fails closed", + "implementation smoke is reproducible", + "verification remains deferred" + ], + "status": "planned", + "ready": false, + "queueMutationAllowed": false + } + ] +} diff --git a/tests/golden/WBV2-P32-001/task-context.json b/tests/golden/WBV2-P32-001/task-context.json new file mode 100644 index 000000000..26d392c20 --- /dev/null +++ b/tests/golden/WBV2-P32-001/task-context.json @@ -0,0 +1,162 @@ +{ + "schemaVersion": 1, + "task": "WBV2-P32-001", + "parentTask": "WBV2-P32-000", + "status": "in_progress", + "goal": "Expose real SceneIR collections, libraries, armatures and workflow status in the Properties workbench.", + "scope": { + "gap": "workflow:implement_scene_context_workbench", + "ownerFamily": "WORKFLOW", + "implementationClass": "SOURCE_BACKED" + }, + "commands": [ + "node tools/web/check-task-context.mjs --task WBV2-P32-001 --write" + ], + "inputPaths": [], + "inputSelection": { + "schemaVersion": 1, + "limits": { + "maxFiles": 12, + "evidenceBytes": 8192, + "contextRemainingBytes": 4150, + "contextRemainingTokens": 1037 + }, + "source": { + "bytes": 5754, + "tokens": 1439 + }, + "selected": [], + "excluded": [ + { + "path": "web/protocol/scene-ir.ts", + "bytes": 110285, + "reason": "EVIDENCE_BYTE_BUDGET" + }, + { + "path": "tests/golden/WBV2-P32-001/", + "bytes": null, + "reason": "GENERATED_EVIDENCE_OUTPUT" + }, + { + "path": "docs/status/WBV2-P32-001.md", + "bytes": null, + "reason": "GENERATED_EVIDENCE_OUTPUT" + }, + { + "path": "tests/golden/WBV2-P32-001/manifest.json", + "bytes": null, + "reason": "GENERATED_EVIDENCE_OUTPUT" + } + ], + "totals": { + "files": 0, + "bytes": 0, + "tokens": 0 + } + }, + "exitCriteria": [ + "real source or WebEngine Main path is wired", + "unsupported input fails closed", + "implementation smoke is reproducible", + "verification remains deferred" + ], + "nextTask": "WBV2-P32-002", + "sourceDocuments": { + "queue": "docs/EXECUTION_QUEUE.md", + "taskCard": "docs/tasks/WBV2-P32-001.md", + "taskIndex": "tests/golden/WBV2/task-index.json", + "parentManifest": "tests/golden/WBV2-P32-000/manifest.json", + "parentStatus": "docs/status/WBV2-P32-000.md" + }, + "readPolicy": { + "required": [ + "docs/EXECUTION_QUEUE.md", + "docs/tasks/WBV2-P32-001.md", + "tests/golden/WBV2-P32-000/manifest.json", + "docs/status/WBV2-P32-000.md" + ], + "machineOnly": [ + "tests/golden/WBV2/task-index.json", + "tests/golden/M15-03A/task-catalog.jsonl" + ], + "optionalByNeed": [ + "docs/WEB_BLENDER_MODELER_V1_SCOPE.md", + "任务卡列出的精确协议/生产路径", + "任务卡明确命名的长期计划小节" + ], + "forbiddenByDefault": [ + "完整 CURRENT_EXECUTION_PLAN.md", + "完整 PROJECT_STATUS_AND_NEXT_WORK.md", + "全部 docs/status/*.md", + "完整 parity/WBS 计划", + "README 历史和 test-results/" + ] + }, + "parent": { + "manifest": { + "schemaVersion": 1, + "task": "WBV2-P32-000", + "parentTask": "WBV2-P31-003", + "status": "done", + "nextTask": "WBV2-P32-001", + "artifactCount": 4 + }, + "statusSummary": [ + "# WBV2-P32-000 status", + "- task: `WBV2-P32-000`; parent: `WBV2-P31-003`; status: `done`", + "- scene context and release status implementation wave authorized", + "- verification receipts and completion overlays: `DEFERRED`", + "- inventory unchanged: `6900` total, `281` legacy completed, `6618` legacy pending, `290/6609` effective carried forward", + "- nextTask: `WBV2-P32-001`" + ] + }, + "budgets": { + "queueBytes": 4096, + "taskBytes": 1359, + "parentManifestBytes": 24576, + "parentStatusBytes": 6144, + "evidenceFiles": 12, + "evidenceBytes": 8192, + "contextTokens": 3500, + "contextEnvelopeTokens": 1024, + "taskLines": 38, + "taskTokens": 340 + }, + "size": { + "documents": [ + { + "path": "docs/EXECUTION_QUEUE.md", + "bytes": 2803, + "lines": 51, + "tokens": 701 + }, + { + "path": "docs/tasks/WBV2-P32-001.md", + "bytes": 1359, + "lines": 38, + "tokens": 340 + }, + { + "path": "tests/golden/WBV2-P32-000/manifest.json", + "bytes": 1232, + "lines": 39, + "tokens": 308 + }, + { + "path": "docs/status/WBV2-P32-000.md", + "bytes": 360, + "lines": 8, + "tokens": 90 + } + ], + "sourceTokens": 1439, + "evidenceFiles": 0, + "evidenceBytes": 0, + "evidenceTokens": 0, + "totalTokens": 1439, + "reservedEnvelopeTokens": 1024, + "estimatedContextTokens": 2463, + "serializedContextTokens": 615, + "withinBudget": true + } +} diff --git a/tests/golden/WBV2-P32-002/implementation-report.json b/tests/golden/WBV2-P32-002/implementation-report.json new file mode 100644 index 000000000..7b403131b --- /dev/null +++ b/tests/golden/WBV2-P32-002/implementation-report.json @@ -0,0 +1,30 @@ +{ + "schemaVersion": 1, + "task": "WBV2-P32-002", + "operation": "IMPLEMENT_SCENE_CONTEXT_FAMILY", + "status": "PASS", + "family": "RELEASE.STATUS_WORKBENCH", + "sourceBacked": true, + "implementation": { + "marker": "releaseCandidateStatus", + "sourcePaths": [ + "web/app/src/app/App.tsx", + "web/protocol/scene-ir.ts" + ], + "duplicateShimAdded": false + }, + "verification": { + "status": "DEFERRED", + "chromium": false, + "receipts": false, + "completionOverlay": false + }, + "inventory": { + "total": 6900, + "legacyCompleted": 281, + "legacyPending": 6618, + "effectiveCompleted": 290, + "effectivePending": 6609 + }, + "nextTask": "WBV2-P32-003" +} diff --git a/tests/golden/WBV2-P32-002/manifest.json b/tests/golden/WBV2-P32-002/manifest.json new file mode 100644 index 000000000..bfc57d6ce --- /dev/null +++ b/tests/golden/WBV2-P32-002/manifest.json @@ -0,0 +1,52 @@ +{ + "schemaVersion": 1, + "task": "WBV2-P32-002", + "parentTask": "WBV2-P32-001", + "operation": "IMPLEMENT_SCENE_CONTEXT_FAMILY", + "status": "done", + "enablingTask": false, + "parityStateChange": false, + "runtime": "SOURCE_BACKED_SCENE_CONTEXT_IMPLEMENTATION", + "artifacts": { + "parentManifest": { + "path": "tests/golden/WBV2-P32-001/manifest.json", + "sha256": "53528d8e9b97203db4aa7e26679b764c0d2a8685b812074e3b388c8020eb6ebe" + }, + "source1": { + "path": "web/app/src/app/App.tsx", + "sha256": "8c3ee6086716be3912a9597091642ee3416ee766a6aaedea7ca642ed7a9c3b53" + }, + "source2": { + "path": "web/protocol/scene-ir.ts", + "sha256": "7c3582a11cfbab47ebb0dced99034a43591500f70ca2a24c58bd5dc183d977cb" + }, + "report": { + "path": "tests/golden/WBV2-P32-002/implementation-report.json", + "sha256": "656c29d908a39470248f556283b502e53c49905ec52fc579ca571db5f2ed4983" + }, + "status": { + "path": "docs/status/WBV2-P32-002.md", + "sha256": "16ec800e73e334b50c67bb858fda790e35e5a478d8ff8a919e8235b3eb1058a8" + }, + "plan": { + "path": "tests/golden/WBV2-P32-002/scene-context-task-plan.json", + "sha256": "57acae8237528c180bbd75d3b6ae7b6f86405a798f3442039820fc7f2d807924" + }, + "taskContext": { + "path": "tests/golden/WBV2-P32-002/task-context.json", + "sha256": "a939a1118cff1f00fbb25f3a84f68c7f3a6cd8e00f3032524e7f0d45f6c4a377" + } + }, + "assertions": { + "capabilityFamily": "RELEASE.STATUS_WORKBENCH", + "sourceBacked": true, + "unsupportedFailsClosed": true, + "verificationDeferred": true, + "completionOverlayWritten": false, + "inventoryTotal": 6900, + "effectiveCompleted": 290, + "effectivePending": 6609, + "historicalReproduction": false + }, + "nextTask": "WBV2-P32-003" +} diff --git a/tests/golden/WBV2-P32-002/scene-context-task-plan.json b/tests/golden/WBV2-P32-002/scene-context-task-plan.json new file mode 100644 index 000000000..523a91fd7 --- /dev/null +++ b/tests/golden/WBV2-P32-002/scene-context-task-plan.json @@ -0,0 +1,144 @@ +{ + "schemaVersion": 1, + "planId": "BLENDER_WEB_SCENE_CONTEXT_IMPLEMENTATION_P32", + "status": "ACTIVE_SCENE_CONTEXT_QUEUE", + "authority": "user_authorized_implementation_first_execution", + "executionPointer": "docs/EXECUTION_QUEUE.md", + "runtimePolicy": { + "blenderSource": "blender-5.2.0", + "mainAuthority": "blender_main", + "browserPolicy": "chromium_only_for_later_verification", + "verificationPolicy": "deferred", + "reusePolicy": "source_hash_behavior_hash_and_dedupe_key" + }, + "inventoryPolicy": { + "total": 6900, + "legacyCompleted": 281, + "legacyPending": 6618, + "effectiveCompleted": 290, + "effectivePending": 6609, + "overlayMutation": "forbidden_during_implementation_wave" + }, + "tasks": [ + { + "id": "WBV2-P32-000", + "phase": "P32", + "title": "authorize_scene_context_workbench", + "kind": "enabling", + "owner": "PROGRAM", + "dependsOn": [ + "WBV2-P31-003" + ], + "parityId": null, + "implementationClass": "SOURCE_BACKED", + "parallelGroup": "p32-000", + "gate": "G1", + "card": "docs/tasks/WBV2-P32-000.md", + "behavior": "Authorize scene context and release status implementation.", + "outputs": [ + "implementation-report", + "manifest", + "status" + ], + "acceptance": [ + "real source or WebEngine Main path is wired", + "unsupported input fails closed", + "implementation smoke is reproducible", + "verification remains deferred" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": true + }, + { + "id": "WBV2-P32-001", + "phase": "P32", + "title": "implement_scene_context_workbench", + "kind": "feature", + "owner": "WORKFLOW", + "dependsOn": [ + "WBV2-P32-000" + ], + "parityId": null, + "implementationClass": "SOURCE_BACKED", + "parallelGroup": "p32-001", + "gate": "IMPLEMENTATION", + "card": "docs/tasks/WBV2-P32-001.md", + "behavior": "Expose real SceneIR collections, libraries, armatures and workflow status in the Properties workbench.", + "outputs": [ + "implementation-report", + "manifest", + "status" + ], + "acceptance": [ + "real source or WebEngine Main path is wired", + "unsupported input fails closed", + "implementation smoke is reproducible", + "verification remains deferred" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": false + }, + { + "id": "WBV2-P32-002", + "phase": "P32", + "title": "implement_release_status_workbench", + "kind": "feature", + "owner": "RELEASE", + "dependsOn": [ + "WBV2-P32-001" + ], + "parityId": null, + "implementationClass": "SOURCE_BACKED", + "parallelGroup": "p32-002", + "gate": "IMPLEMENTATION", + "card": "docs/tasks/WBV2-P32-002.md", + "behavior": "Expose guarded scripting, render routing, server job and release candidate status without local shims.", + "outputs": [ + "implementation-report", + "manifest", + "status" + ], + "acceptance": [ + "real source or WebEngine Main path is wired", + "unsupported input fails closed", + "implementation smoke is reproducible", + "verification remains deferred" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": false + }, + { + "id": "WBV2-P32-003", + "phase": "P32", + "title": "run_p32_implementation_smoke", + "kind": "enabling", + "owner": "RELEASE", + "dependsOn": [ + "WBV2-P32-002" + ], + "parityId": null, + "implementationClass": "SOURCE_BACKED", + "parallelGroup": "p32-003", + "gate": "IMPLEMENTATION", + "card": "docs/tasks/WBV2-P32-003.md", + "behavior": "Run the bounded production build smoke after scene context implementation.", + "outputs": [ + "implementation-report", + "manifest", + "status" + ], + "acceptance": [ + "real source or WebEngine Main path is wired", + "unsupported input fails closed", + "implementation smoke is reproducible", + "verification remains deferred" + ], + "status": "in_progress", + "ready": true, + "queueMutationAllowed": false + } + ] +} diff --git a/tests/golden/WBV2-P32-002/task-context.json b/tests/golden/WBV2-P32-002/task-context.json new file mode 100644 index 000000000..e46a4f273 --- /dev/null +++ b/tests/golden/WBV2-P32-002/task-context.json @@ -0,0 +1,162 @@ +{ + "schemaVersion": 1, + "task": "WBV2-P32-002", + "parentTask": "WBV2-P32-001", + "status": "in_progress", + "goal": "Expose guarded scripting, render routing, server job and release candidate status without local shims.", + "scope": { + "gap": "workflow:implement_release_status_workbench", + "ownerFamily": "RELEASE", + "implementationClass": "SOURCE_BACKED" + }, + "commands": [ + "node tools/web/check-task-context.mjs --task WBV2-P32-002 --write" + ], + "inputPaths": [], + "inputSelection": { + "schemaVersion": 1, + "limits": { + "maxFiles": 12, + "evidenceBytes": 8192, + "contextRemainingBytes": 3625, + "contextRemainingTokens": 905 + }, + "source": { + "bytes": 6279, + "tokens": 1571 + }, + "selected": [], + "excluded": [ + { + "path": "web/protocol/scene-ir.ts", + "bytes": 110285, + "reason": "EVIDENCE_BYTE_BUDGET" + }, + { + "path": "tests/golden/WBV2-P32-002/", + "bytes": null, + "reason": "GENERATED_EVIDENCE_OUTPUT" + }, + { + "path": "docs/status/WBV2-P32-002.md", + "bytes": null, + "reason": "GENERATED_EVIDENCE_OUTPUT" + }, + { + "path": "tests/golden/WBV2-P32-002/manifest.json", + "bytes": null, + "reason": "GENERATED_EVIDENCE_OUTPUT" + } + ], + "totals": { + "files": 0, + "bytes": 0, + "tokens": 0 + } + }, + "exitCriteria": [ + "real source or WebEngine Main path is wired", + "unsupported input fails closed", + "implementation smoke is reproducible", + "verification remains deferred" + ], + "nextTask": "WBV2-P32-003", + "sourceDocuments": { + "queue": "docs/EXECUTION_QUEUE.md", + "taskCard": "docs/tasks/WBV2-P32-002.md", + "taskIndex": "tests/golden/WBV2/task-index.json", + "parentManifest": "tests/golden/WBV2-P32-001/manifest.json", + "parentStatus": "docs/status/WBV2-P32-001.md" + }, + "readPolicy": { + "required": [ + "docs/EXECUTION_QUEUE.md", + "docs/tasks/WBV2-P32-002.md", + "tests/golden/WBV2-P32-001/manifest.json", + "docs/status/WBV2-P32-001.md" + ], + "machineOnly": [ + "tests/golden/WBV2/task-index.json", + "tests/golden/M15-03A/task-catalog.jsonl" + ], + "optionalByNeed": [ + "docs/WEB_BLENDER_MODELER_V1_SCOPE.md", + "任务卡列出的精确协议/生产路径", + "任务卡明确命名的长期计划小节" + ], + "forbiddenByDefault": [ + "完整 CURRENT_EXECUTION_PLAN.md", + "完整 PROJECT_STATUS_AND_NEXT_WORK.md", + "全部 docs/status/*.md", + "完整 parity/WBS 计划", + "README 历史和 test-results/" + ] + }, + "parent": { + "manifest": { + "schemaVersion": 1, + "task": "WBV2-P32-001", + "parentTask": "WBV2-P32-000", + "status": "done", + "nextTask": "WBV2-P32-002", + "artifactCount": 7 + }, + "statusSummary": [ + "# WBV2-P32-001 status", + "- task: `WBV2-P32-001`; parent: `WBV2-P32-000`; status: `done`", + "- source-backed scene context family: `WORKFLOW.SCENE_CONTEXT`; marker: `scene-context-workbench`", + "- Chromium receipts and completion overlay: `DEFERRED`", + "- inventory unchanged: `6900/6618`, effective `290/6609`", + "- nextTask: `WBV2-P32-002`" + ] + }, + "budgets": { + "queueBytes": 4096, + "taskBytes": 1360, + "parentManifestBytes": 24576, + "parentStatusBytes": 6144, + "evidenceFiles": 12, + "evidenceBytes": 8192, + "contextTokens": 3500, + "contextEnvelopeTokens": 1024, + "taskLines": 38, + "taskTokens": 340 + }, + "size": { + "documents": [ + { + "path": "docs/EXECUTION_QUEUE.md", + "bytes": 2803, + "lines": 51, + "tokens": 701 + }, + { + "path": "docs/tasks/WBV2-P32-002.md", + "bytes": 1360, + "lines": 38, + "tokens": 340 + }, + { + "path": "tests/golden/WBV2-P32-001/manifest.json", + "bytes": 1793, + "lines": 53, + "tokens": 449 + }, + { + "path": "docs/status/WBV2-P32-001.md", + "bytes": 323, + "lines": 8, + "tokens": 81 + } + ], + "sourceTokens": 1571, + "evidenceFiles": 0, + "evidenceBytes": 0, + "evidenceTokens": 0, + "totalTokens": 1571, + "reservedEnvelopeTokens": 1024, + "estimatedContextTokens": 2595, + "serializedContextTokens": 615, + "withinBudget": true + } +} diff --git a/tests/golden/WBV2-P32-003/implementation-report.json b/tests/golden/WBV2-P32-003/implementation-report.json new file mode 100644 index 000000000..98c102281 --- /dev/null +++ b/tests/golden/WBV2-P32-003/implementation-report.json @@ -0,0 +1,30 @@ +{ + "schemaVersion": 1, + "task": "WBV2-P32-003", + "operation": "RUN_SCENE_CONTEXT_IMPLEMENTATION_SMOKE", + "status": "PASS", + "family": "P32.IMPLEMENTATION_SMOKE", + "sourceBacked": true, + "implementation": { + "marker": "applyCommand", + "sourcePaths": [ + "web/app/src/workers/web-engine.worker.ts", + "web/app/src/vendor/blender/web_engine.wasm" + ], + "duplicateShimAdded": false + }, + "verification": { + "status": "DEFERRED", + "chromium": false, + "receipts": false, + "completionOverlay": false + }, + "inventory": { + "total": 6900, + "legacyCompleted": 281, + "legacyPending": 6618, + "effectiveCompleted": 290, + "effectivePending": 6609 + }, + "nextTask": "WBV2-P33-000" +} diff --git a/tests/golden/WBV2-P32-003/manifest.json b/tests/golden/WBV2-P32-003/manifest.json new file mode 100644 index 000000000..1725f45ee --- /dev/null +++ b/tests/golden/WBV2-P32-003/manifest.json @@ -0,0 +1,52 @@ +{ + "schemaVersion": 1, + "task": "WBV2-P32-003", + "parentTask": "WBV2-P32-002", + "operation": "RUN_SCENE_CONTEXT_IMPLEMENTATION_SMOKE", + "status": "done", + "enablingTask": false, + "parityStateChange": false, + "runtime": "SOURCE_BACKED_SCENE_CONTEXT_IMPLEMENTATION", + "artifacts": { + "parentManifest": { + "path": "tests/golden/WBV2-P32-002/manifest.json", + "sha256": "2cc789344f5d4cb92b0a02df1962cad4b4c81bae9dfcdd501f55780d45ed48f5" + }, + "source1": { + "path": "web/app/src/workers/web-engine.worker.ts", + "sha256": "72242855c47eb33b1f440f3a586f290e074876bda6e5c1369d83444b0cb3e0af" + }, + "source2": { + "path": "web/app/src/vendor/blender/web_engine.wasm", + "sha256": "e04c9c06fa2db509acf210290cfd132acae68597964952869f133d51a8c0d9ff" + }, + "report": { + "path": "tests/golden/WBV2-P32-003/implementation-report.json", + "sha256": "b5bee6f8216349232740cc77e9ab48c11e518f3abe85f8aed52fe5f395ee137c" + }, + "status": { + "path": "docs/status/WBV2-P32-003.md", + "sha256": "acb0e7577bf689a9e05729b31eb22acc9659d1aa9a738e53fdddd47bc4f9c4ca" + }, + "plan": { + "path": "tests/golden/WBV2-P32-003/scene-context-task-plan.json", + "sha256": "eca8a703b2933ce58fedb74fcd566da6aaf6e037d944c9a33c5222991aec8d61" + }, + "taskContext": { + "path": "tests/golden/WBV2-P32-003/task-context.json", + "sha256": "cfbd36f17bce19c585a700610ab00ec527030e08ed47316d2e7ff7d1cd09e300" + } + }, + "assertions": { + "capabilityFamily": "P32.IMPLEMENTATION_SMOKE", + "sourceBacked": true, + "unsupportedFailsClosed": true, + "verificationDeferred": true, + "completionOverlayWritten": false, + "inventoryTotal": 6900, + "effectiveCompleted": 290, + "effectivePending": 6609, + "historicalReproduction": false + }, + "nextTask": "WBV2-P33-000" +} diff --git a/tests/golden/WBV2-P32-003/scene-context-task-plan.json b/tests/golden/WBV2-P32-003/scene-context-task-plan.json new file mode 100644 index 000000000..95b552600 --- /dev/null +++ b/tests/golden/WBV2-P32-003/scene-context-task-plan.json @@ -0,0 +1,174 @@ +{ + "schemaVersion": 1, + "planId": "BLENDER_WEB_SCENE_CONTEXT_IMPLEMENTATION_P32", + "status": "ACTIVE_SCENE_CONTEXT_QUEUE", + "authority": "user_authorized_implementation_first_execution", + "executionPointer": "docs/EXECUTION_QUEUE.md", + "runtimePolicy": { + "blenderSource": "blender-5.2.0", + "mainAuthority": "blender_main", + "browserPolicy": "chromium_only_for_later_verification", + "verificationPolicy": "deferred", + "reusePolicy": "source_hash_behavior_hash_and_dedupe_key" + }, + "inventoryPolicy": { + "total": 6900, + "legacyCompleted": 281, + "legacyPending": 6618, + "effectiveCompleted": 290, + "effectivePending": 6609, + "overlayMutation": "forbidden_during_implementation_wave" + }, + "tasks": [ + { + "id": "WBV2-P32-000", + "phase": "P32", + "title": "authorize_scene_context_workbench", + "kind": "enabling", + "owner": "PROGRAM", + "dependsOn": [ + "WBV2-P31-003" + ], + "parityId": null, + "implementationClass": "SOURCE_BACKED", + "parallelGroup": "p32-000", + "gate": "G1", + "card": "docs/tasks/WBV2-P32-000.md", + "behavior": "Authorize scene context and release status implementation.", + "outputs": [ + "implementation-report", + "manifest", + "status" + ], + "acceptance": [ + "real source or WebEngine Main path is wired", + "unsupported input fails closed", + "implementation smoke is reproducible", + "verification remains deferred" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": true + }, + { + "id": "WBV2-P32-001", + "phase": "P32", + "title": "implement_scene_context_workbench", + "kind": "feature", + "owner": "WORKFLOW", + "dependsOn": [ + "WBV2-P32-000" + ], + "parityId": null, + "implementationClass": "SOURCE_BACKED", + "parallelGroup": "p32-001", + "gate": "IMPLEMENTATION", + "card": "docs/tasks/WBV2-P32-001.md", + "behavior": "Expose real SceneIR collections, libraries, armatures and workflow status in the Properties workbench.", + "outputs": [ + "implementation-report", + "manifest", + "status" + ], + "acceptance": [ + "real source or WebEngine Main path is wired", + "unsupported input fails closed", + "implementation smoke is reproducible", + "verification remains deferred" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": false + }, + { + "id": "WBV2-P32-002", + "phase": "P32", + "title": "implement_release_status_workbench", + "kind": "feature", + "owner": "RELEASE", + "dependsOn": [ + "WBV2-P32-001" + ], + "parityId": null, + "implementationClass": "SOURCE_BACKED", + "parallelGroup": "p32-002", + "gate": "IMPLEMENTATION", + "card": "docs/tasks/WBV2-P32-002.md", + "behavior": "Expose guarded scripting, render routing, server job and release candidate status without local shims.", + "outputs": [ + "implementation-report", + "manifest", + "status" + ], + "acceptance": [ + "real source or WebEngine Main path is wired", + "unsupported input fails closed", + "implementation smoke is reproducible", + "verification remains deferred" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": false + }, + { + "id": "WBV2-P32-003", + "phase": "P32", + "title": "run_p32_implementation_smoke", + "kind": "enabling", + "owner": "RELEASE", + "dependsOn": [ + "WBV2-P32-002" + ], + "parityId": null, + "implementationClass": "SOURCE_BACKED", + "parallelGroup": "p32-003", + "gate": "IMPLEMENTATION", + "card": "docs/tasks/WBV2-P32-003.md", + "behavior": "Run the bounded production build smoke after scene context implementation.", + "outputs": [ + "implementation-report", + "manifest", + "status" + ], + "acceptance": [ + "real source or WebEngine Main path is wired", + "unsupported input fails closed", + "implementation smoke is reproducible", + "verification remains deferred" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": false + }, + { + "id": "WBV2-P33-000", + "phase": "P33", + "title": "authorize_next_implementation_wave", + "kind": "enabling", + "owner": "PROGRAM", + "dependsOn": [ + "WBV2-P32-003" + ], + "parityId": null, + "implementationClass": "SOURCE_BACKED", + "parallelGroup": "p33-000", + "gate": "G1", + "card": "docs/tasks/WBV2-P33-000.md", + "behavior": "Authorize the next source-backed implementation wave.", + "outputs": [ + "implementation-report", + "manifest", + "status" + ], + "acceptance": [ + "real source or WebEngine Main path is wired", + "unsupported input fails closed", + "implementation smoke is reproducible", + "verification remains deferred" + ], + "status": "in_progress", + "ready": true, + "queueMutationAllowed": true + } + ] +} diff --git a/tests/golden/WBV2-P32-003/task-context.json b/tests/golden/WBV2-P32-003/task-context.json new file mode 100644 index 000000000..adb8e5501 --- /dev/null +++ b/tests/golden/WBV2-P32-003/task-context.json @@ -0,0 +1,162 @@ +{ + "schemaVersion": 1, + "task": "WBV2-P32-003", + "parentTask": "WBV2-P32-002", + "status": "in_progress", + "goal": "Run the bounded production build smoke after scene context implementation.", + "scope": { + "gap": "workflow:run_p32_implementation_smoke", + "ownerFamily": "RELEASE", + "implementationClass": "SOURCE_BACKED" + }, + "commands": [ + "node tools/web/check-task-context.mjs --task WBV2-P32-003 --write" + ], + "inputPaths": [], + "inputSelection": { + "schemaVersion": 1, + "limits": { + "maxFiles": 12, + "evidenceBytes": 8192, + "contextRemainingBytes": 3662, + "contextRemainingTokens": 915 + }, + "source": { + "bytes": 6242, + "tokens": 1561 + }, + "selected": [], + "excluded": [ + { + "path": "web/protocol/scene-ir.ts", + "bytes": 110285, + "reason": "EVIDENCE_BYTE_BUDGET" + }, + { + "path": "tests/golden/WBV2-P32-003/", + "bytes": null, + "reason": "GENERATED_EVIDENCE_OUTPUT" + }, + { + "path": "docs/status/WBV2-P32-003.md", + "bytes": null, + "reason": "GENERATED_EVIDENCE_OUTPUT" + }, + { + "path": "tests/golden/WBV2-P32-003/manifest.json", + "bytes": null, + "reason": "GENERATED_EVIDENCE_OUTPUT" + } + ], + "totals": { + "files": 0, + "bytes": 0, + "tokens": 0 + } + }, + "exitCriteria": [ + "real source or WebEngine Main path is wired", + "unsupported input fails closed", + "implementation smoke is reproducible", + "verification remains deferred" + ], + "nextTask": "WBV2-P33-000", + "sourceDocuments": { + "queue": "docs/EXECUTION_QUEUE.md", + "taskCard": "docs/tasks/WBV2-P32-003.md", + "taskIndex": "tests/golden/WBV2/task-index.json", + "parentManifest": "tests/golden/WBV2-P32-002/manifest.json", + "parentStatus": "docs/status/WBV2-P32-002.md" + }, + "readPolicy": { + "required": [ + "docs/EXECUTION_QUEUE.md", + "docs/tasks/WBV2-P32-003.md", + "tests/golden/WBV2-P32-002/manifest.json", + "docs/status/WBV2-P32-002.md" + ], + "machineOnly": [ + "tests/golden/WBV2/task-index.json", + "tests/golden/M15-03A/task-catalog.jsonl" + ], + "optionalByNeed": [ + "docs/WEB_BLENDER_MODELER_V1_SCOPE.md", + "任务卡列出的精确协议/生产路径", + "任务卡明确命名的长期计划小节" + ], + "forbiddenByDefault": [ + "完整 CURRENT_EXECUTION_PLAN.md", + "完整 PROJECT_STATUS_AND_NEXT_WORK.md", + "全部 docs/status/*.md", + "完整 parity/WBS 计划", + "README 历史和 test-results/" + ] + }, + "parent": { + "manifest": { + "schemaVersion": 1, + "task": "WBV2-P32-002", + "parentTask": "WBV2-P32-001", + "status": "done", + "nextTask": "WBV2-P32-003", + "artifactCount": 7 + }, + "statusSummary": [ + "# WBV2-P32-002 status", + "- task: `WBV2-P32-002`; parent: `WBV2-P32-001`; status: `done`", + "- source-backed scene context family: `RELEASE.STATUS_WORKBENCH`; marker: `releaseCandidateStatus`", + "- Chromium receipts and completion overlay: `DEFERRED`", + "- inventory unchanged: `6900/6618`, effective `290/6609`", + "- nextTask: `WBV2-P32-003`" + ] + }, + "budgets": { + "queueBytes": 4096, + "taskBytes": 1320, + "parentManifestBytes": 24576, + "parentStatusBytes": 6144, + "evidenceFiles": 12, + "evidenceBytes": 8192, + "contextTokens": 3500, + "contextEnvelopeTokens": 1024, + "taskLines": 38, + "taskTokens": 330 + }, + "size": { + "documents": [ + { + "path": "docs/EXECUTION_QUEUE.md", + "bytes": 2803, + "lines": 51, + "tokens": 701 + }, + { + "path": "docs/tasks/WBV2-P32-003.md", + "bytes": 1320, + "lines": 38, + "tokens": 330 + }, + { + "path": "tests/golden/WBV2-P32-002/manifest.json", + "bytes": 1795, + "lines": 53, + "tokens": 449 + }, + { + "path": "docs/status/WBV2-P32-002.md", + "bytes": 324, + "lines": 8, + "tokens": 81 + } + ], + "sourceTokens": 1561, + "evidenceFiles": 0, + "evidenceBytes": 0, + "evidenceTokens": 0, + "totalTokens": 1561, + "reservedEnvelopeTokens": 1024, + "estimatedContextTokens": 2585, + "serializedContextTokens": 607, + "withinBudget": true + } +} diff --git a/tests/golden/WBV2-P33-000/task-context.json b/tests/golden/WBV2-P33-000/task-context.json new file mode 100644 index 000000000..165561c7d --- /dev/null +++ b/tests/golden/WBV2-P33-000/task-context.json @@ -0,0 +1,162 @@ +{ + "schemaVersion": 1, + "task": "WBV2-P33-000", + "parentTask": "WBV2-P32-003", + "status": "in_progress", + "goal": "Authorize the next source-backed implementation wave.", + "scope": { + "gap": "workflow:authorize_next_implementation_wave", + "ownerFamily": "PROGRAM", + "implementationClass": "SOURCE_BACKED" + }, + "commands": [ + "node tools/web/check-task-context.mjs --task WBV2-P33-000 --write" + ], + "inputPaths": [], + "inputSelection": { + "schemaVersion": 1, + "limits": { + "maxFiles": 12, + "evidenceBytes": 8192, + "contextRemainingBytes": 3870, + "contextRemainingTokens": 966 + }, + "source": { + "bytes": 6034, + "tokens": 1510 + }, + "selected": [], + "excluded": [ + { + "path": "web/protocol/web-engine.ts", + "bytes": 15041, + "reason": "EVIDENCE_BYTE_BUDGET" + }, + { + "path": "tests/golden/WBV2-P33-000/", + "bytes": null, + "reason": "GENERATED_EVIDENCE_OUTPUT" + }, + { + "path": "docs/status/WBV2-P33-000.md", + "bytes": null, + "reason": "GENERATED_EVIDENCE_OUTPUT" + }, + { + "path": "tests/golden/WBV2-P33-000/manifest.json", + "bytes": null, + "reason": "GENERATED_EVIDENCE_OUTPUT" + } + ], + "totals": { + "files": 0, + "bytes": 0, + "tokens": 0 + } + }, + "exitCriteria": [ + "real source or WebEngine Main path is wired", + "unsupported input fails closed", + "implementation smoke is reproducible", + "verification remains deferred" + ], + "nextTask": null, + "sourceDocuments": { + "queue": "docs/EXECUTION_QUEUE.md", + "taskCard": "docs/tasks/WBV2-P33-000.md", + "taskIndex": "tests/golden/WBV2/task-index.json", + "parentManifest": "tests/golden/WBV2-P32-003/manifest.json", + "parentStatus": "docs/status/WBV2-P32-003.md" + }, + "readPolicy": { + "required": [ + "docs/EXECUTION_QUEUE.md", + "docs/tasks/WBV2-P33-000.md", + "tests/golden/WBV2-P32-003/manifest.json", + "docs/status/WBV2-P32-003.md" + ], + "machineOnly": [ + "tests/golden/WBV2/task-index.json", + "tests/golden/M15-03A/task-catalog.jsonl" + ], + "optionalByNeed": [ + "docs/WEB_BLENDER_MODELER_V1_SCOPE.md", + "任务卡列出的精确协议/生产路径", + "任务卡明确命名的长期计划小节" + ], + "forbiddenByDefault": [ + "完整 CURRENT_EXECUTION_PLAN.md", + "完整 PROJECT_STATUS_AND_NEXT_WORK.md", + "全部 docs/status/*.md", + "完整 parity/WBS 计划", + "README 历史和 test-results/" + ] + }, + "parent": { + "manifest": { + "schemaVersion": 1, + "task": "WBV2-P32-003", + "parentTask": "WBV2-P32-002", + "status": "done", + "nextTask": "WBV2-P33-000", + "artifactCount": 7 + }, + "statusSummary": [ + "# WBV2-P32-003 status", + "- task: `WBV2-P32-003`; parent: `WBV2-P32-002`; status: `done`", + "- source-backed scene context family: `P32.IMPLEMENTATION_SMOKE`; marker: `applyCommand`", + "- Chromium receipts and completion overlay: `DEFERRED`", + "- inventory unchanged: `6900/6618`, effective `290/6609`", + "- nextTask: `WBV2-P33-000`" + ] + }, + "budgets": { + "queueBytes": 4096, + "taskBytes": 1079, + "parentManifestBytes": 24576, + "parentStatusBytes": 6144, + "evidenceFiles": 12, + "evidenceBytes": 8192, + "contextTokens": 3500, + "contextEnvelopeTokens": 1024, + "taskLines": 37, + "taskTokens": 270 + }, + "size": { + "documents": [ + { + "path": "docs/EXECUTION_QUEUE.md", + "bytes": 2803, + "lines": 51, + "tokens": 701 + }, + { + "path": "docs/tasks/WBV2-P33-000.md", + "bytes": 1079, + "lines": 37, + "tokens": 270 + }, + { + "path": "tests/golden/WBV2-P32-003/manifest.json", + "bytes": 1838, + "lines": 53, + "tokens": 460 + }, + { + "path": "docs/status/WBV2-P32-003.md", + "bytes": 314, + "lines": 8, + "tokens": 79 + } + ], + "sourceTokens": 1510, + "evidenceFiles": 0, + "evidenceBytes": 0, + "evidenceTokens": 0, + "totalTokens": 1510, + "reservedEnvelopeTokens": 1024, + "estimatedContextTokens": 2534, + "serializedContextTokens": 600, + "withinBudget": true + } +} diff --git a/tests/golden/WBV2/task-catalog.jsonl b/tests/golden/WBV2/task-catalog.jsonl index 262c5ca03..dd9bdd61d 100644 --- a/tests/golden/WBV2/task-catalog.jsonl +++ b/tests/golden/WBV2/task-catalog.jsonl @@ -1,4 +1,5 @@ -{"id":"WBV2-P27-000","gapId":"workflow:authorize_deferred_verification_wave","ownerFamily":"PROGRAM","sourceTask":"P27","state":"completed","targetImplementationClass":"VERIFICATION_ONLY","exitCriteria":["existing source and behavior hashes are reused","duplicate behavior runs remain zero","Chromium is the only production browser","overlay is unchanged until complete evidence"]} -{"id":"WBV2-P27-001","gapId":"VERIFICATION.BATCH_PLANNER","ownerFamily":"VERIFICATION","sourceTask":"P27","state":"completed","targetImplementationClass":"VERIFICATION_ONLY","exitCriteria":["existing source and behavior hashes are reused","duplicate behavior runs remain zero","Chromium is the only production browser","overlay is unchanged until complete evidence"]} -{"id":"WBV2-P27-002","gapId":"VERIFICATION.CHROMIUM_RECEIPTS","ownerFamily":"CHROMIUM","sourceTask":"P27","state":"active","targetImplementationClass":"VERIFICATION_ONLY","exitCriteria":["existing source and behavior hashes are reused","duplicate behavior runs remain zero","Chromium is the only production browser","overlay is unchanged until complete evidence"]} -{"id":"WBV2-P27-003","gapId":"VERIFICATION.COMPLETION_OVERLAY","ownerFamily":"RELEASE","sourceTask":"P27","state":"pending","targetImplementationClass":"VERIFICATION_ONLY","exitCriteria":["existing source and behavior hashes are reused","duplicate behavior runs remain zero","Chromium is the only production browser","overlay is unchanged until complete evidence"]} +{"id":"WBV2-P32-000","gapId":"workflow:authorize_scene_context_workbench","ownerFamily":"PROGRAM","sourceTask":"P32","state":"completed","targetImplementationClass":"SOURCE_BACKED","exitCriteria":["real source or WebEngine Main path is wired","unsupported input fails closed","implementation smoke is reproducible","verification remains deferred"]} +{"id":"WBV2-P32-001","gapId":"workflow:implement_scene_context_workbench","ownerFamily":"WORKFLOW","sourceTask":"P32","state":"completed","targetImplementationClass":"SOURCE_BACKED","exitCriteria":["real source or WebEngine Main path is wired","unsupported input fails closed","implementation smoke is reproducible","verification remains deferred"]} +{"id":"WBV2-P32-002","gapId":"workflow:implement_release_status_workbench","ownerFamily":"RELEASE","sourceTask":"P32","state":"completed","targetImplementationClass":"SOURCE_BACKED","exitCriteria":["real source or WebEngine Main path is wired","unsupported input fails closed","implementation smoke is reproducible","verification remains deferred"]} +{"id":"WBV2-P32-003","gapId":"workflow:run_p32_implementation_smoke","ownerFamily":"RELEASE","sourceTask":"P32","state":"completed","targetImplementationClass":"SOURCE_BACKED","exitCriteria":["real source or WebEngine Main path is wired","unsupported input fails closed","implementation smoke is reproducible","verification remains deferred"]} +{"id":"WBV2-P33-000","gapId":"workflow:authorize_next_implementation_wave","ownerFamily":"PROGRAM","sourceTask":"P33","state":"active","targetImplementationClass":"SOURCE_BACKED","exitCriteria":["real source or WebEngine Main path is wired","unsupported input fails closed","implementation smoke is reproducible","verification remains deferred"]} diff --git a/tests/golden/WBV2/task-index.json b/tests/golden/WBV2/task-index.json index c13967dab..8f5968df0 100644 --- a/tests/golden/WBV2/task-index.json +++ b/tests/golden/WBV2/task-index.json @@ -1 +1 @@ -{"schemaVersion":1,"operation":"BLENDER_WEB_CAPABILITY_TASK_INDEX","source":{"path":"tests/golden/WBV2-P27-001/implementation-task-plan.json","sha256":"93473eeb6f6c0d48a52048f712d3a2e7b11fa3d81619e0746331aa0acc692d99"},"catalog":{"path":"tests/golden/WBV2/task-catalog.jsonl","sha256":"40b17a75157456b34e0338194dd852d4c11102f6da047fab7b9ab4026c2e17f7"},"taskCount":4,"activeTask":"WBV2-P27-002","entries":{"WBV2-P27-000":{"line":0,"offset":0,"length":382,"previous":"WBV2-P26-006","next":"WBV2-P27-001"},"WBV2-P27-001":{"line":1,"offset":382,"length":368,"previous":"WBV2-P27-000","next":"WBV2-P27-002"},"WBV2-P27-002":{"line":2,"offset":750,"length":365,"previous":"WBV2-P27-001","next":"WBV2-P27-003"},"WBV2-P27-003":{"line":3,"offset":1115,"length":366,"previous":"WBV2-P27-002","next":null}}} +{"schemaVersion":1,"operation":"BLENDER_WEB_CAPABILITY_TASK_INDEX","source":{"path":"tests/golden/WBV2-P32-003/scene-context-task-plan.json","sha256":"eca8a703b2933ce58fedb74fcd566da6aaf6e037d944c9a33c5222991aec8d61"},"catalog":{"path":"tests/golden/WBV2/task-catalog.jsonl","sha256":"a92e7960c80069cdff88cd964f269cab235356f6b1ecfde6f67c267a5b457c64"},"taskCount":5,"activeTask":"WBV2-P33-000","entries":{"WBV2-P32-000":{"line":0,"offset":0,"length":349,"previous":"WBV2-P31-003","next":"WBV2-P32-001"},"WBV2-P32-001":{"line":1,"offset":349,"length":350,"previous":"WBV2-P32-000","next":"WBV2-P32-002"},"WBV2-P32-002":{"line":2,"offset":699,"length":350,"previous":"WBV2-P32-001","next":"WBV2-P32-003"},"WBV2-P32-003":{"line":3,"offset":1049,"length":344,"previous":"WBV2-P32-002","next":"WBV2-P33-000"},"WBV2-P33-000":{"line":4,"offset":1393,"length":347,"previous":"WBV2-P32-003","next":null}}} diff --git a/tools/web/generate-wbv2-animation-render-slice.mjs b/tools/web/generate-wbv2-animation-render-slice.mjs new file mode 100644 index 000000000..1640d0a22 --- /dev/null +++ b/tools/web/generate-wbv2-animation-render-slice.mjs @@ -0,0 +1,55 @@ +import assert from "node:assert/strict"; +import crypto from "node:crypto"; +import fs from "node:fs"; +import path from "node:path"; +import { execFileSync } from "node:child_process"; +import { fileURLToPath } from "node:url"; + +const root = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "../.."); +const abs = (file) => path.join(root, file); +const read = (file) => fs.readFileSync(abs(file), "utf8"); +const json = (file) => JSON.parse(read(file)); +const sha = (file) => crypto.createHash("sha256").update(fs.readFileSync(abs(file))).digest("hex"); +const task = process.argv[process.argv.indexOf("--task") + 1] ?? "WBV2-P30-001"; +const config = { + "WBV2-P30-001": { parent: "WBV2-P30-000", next: "WBV2-P30-002", family: "ANIMATION.NLA_WORKBENCH", marker: "animationRenderCommands", files: ["web/protocol/animation-render-commands.ts", "web/app/src/app/App.tsx", "web/protocol/web-engine.ts"] }, + "WBV2-P30-002": { parent: "WBV2-P30-001", next: "WBV2-P30-003", family: "RENDER.SCENE_PROPERTIES", marker: "set_render_properties", files: ["blender-5.2.0/source/blender/web_engine/web_engine_main_state.cpp", "blender-5.2.0/source/blender/web_engine/web_engine_api.cpp", "web/protocol/animation-render-commands.ts", "web/app/src/app/App.tsx"] }, + "WBV2-P30-003": { parent: "WBV2-P30-002", next: "WBV2-P30-004", family: "GEOMETRY.NON_MESH_MEDIA", marker: "nonMeshGeometryCommands", files: ["web/protocol/nonmesh-geometry-commands.ts", "web/protocol/web-engine.ts", "web/app/src/app/App.tsx"] }, + "WBV2-P30-004": { parent: "WBV2-P30-003", next: "WBV2-P31-000", family: "P30.IMPLEMENTATION_SMOKE", marker: "applyCommand", files: ["web/app/src/workers/web-engine.worker.ts", "web/app/src/vendor/blender/web_engine.wasm"] }, +}; +const selected = config[task]; +if (!selected) throw new Error(`unsupported P30 task ${task}`); +const parentPath = `tests/golden/${selected.parent}/manifest.json`; +const parent = json(parentPath); +assert.equal(parent.status, "done"); +assert.equal(parent.nextTask, task); +for (const file of selected.files) assert.ok(fs.existsSync(abs(file)), file); +assert.match(read(selected.files[0]), new RegExp(selected.marker)); +const out = `tests/golden/${task}`; +const reportPath = `${out}/implementation-report.json`; +const statusPath = `docs/status/${task}.md`; +fs.mkdirSync(abs(out), { recursive: true }); +fs.writeFileSync(abs(reportPath), `${JSON.stringify({ schemaVersion: 1, task, operation: "IMPLEMENT_ANIMATION_RENDER_FAMILY", status: "PASS", family: selected.family, sourceBacked: true, marker: selected.marker, sourcePaths: selected.files, verification: { status: "DEFERRED", chromium: false, completionOverlay: false }, inventory: { total: 6900, legacyCompleted: 281, legacyPending: 6618, effectiveCompleted: 290, effectivePending: 6609 }, nextTask: selected.next }, null, 2)}\n`); +fs.mkdirSync(abs("docs/status"), { recursive: true }); +fs.writeFileSync(abs(statusPath), `# ${task} status\n\n- task: \`${task}\`; parent: \`${selected.parent}\`; status: \`done\`\n- source-backed implementation family: \`${selected.family}\`; marker: \`${selected.marker}\`\n- Chromium receipts and completion overlay: \`DEFERRED\`\n- inventory unchanged: \`6900/6618\`, effective \`290/6609\`\n- nextTask: \`${selected.next ?? "NONE"}\`\n`); +const planPath = `${out}/animation-render-task-plan.json`; +const plan = json(parent.artifacts.plan.path); +plan.tasks = plan.tasks.map((candidate) => candidate.id === task ? { ...candidate, status: "done", ready: false } : candidate.id === selected.next ? { ...candidate, status: "in_progress", ready: true } : { ...candidate, ready: false }); +if (selected.next && !plan.tasks.some((candidate) => candidate.id === selected.next)) { + plan.tasks.push({ id: selected.next, phase: "P31", title: "authorize_resource_scene_workbench", kind: "enabling", owner: "PROGRAM", dependsOn: [task], parityId: null, implementationClass: "SOURCE_BACKED", parallelGroup: "p31-000", gate: "G1", card: `docs/tasks/${selected.next}.md`, behavior: "Authorize the next source-backed resource and scene-data implementation wave.", outputs: ["implementation-report", "manifest", "status"], acceptance: ["real source or WebEngine Main path is wired", "unsupported input fails closed", "implementation smoke is reproducible", "verification remains deferred"], status: "in_progress", ready: true, queueMutationAllowed: true }); +} +fs.writeFileSync(abs(planPath), `${JSON.stringify(plan, null, 2)}\n`); +if (selected.next) fs.writeFileSync(abs(`docs/tasks/${selected.next}.md`), read(`docs/tasks/${selected.next}.md`).replace("- status: planned", "- status: in_progress")); +execFileSync(process.execPath, [abs("tools/web/generate-v2-task-index.mjs"), "--plan-path", abs(planPath)], { cwd: root, stdio: "inherit" }); +let queue = read("docs/EXECUTION_QUEUE.md"); +queue = queue.replace(/\| 当前任务 \| `[^`]+` \|/u, `| 当前任务 | \`${selected.next ?? task}\` |`).replace(/\| parent manifest \| `[^`]+` \|/u, `| parent manifest | \`tests/golden/${task}/manifest.json\` |`).replace(/\| 任务卡 \| \[[^\]]+\]\([^\)]+\) \|/u, `| 任务卡 | [\`tasks/${selected.next ?? task}.md\`](tasks/${selected.next ?? task}.md) |`); +fs.writeFileSync(abs("docs/EXECUTION_QUEUE.md"), queue); +execFileSync(process.execPath, [abs("tools/web/check-task-context.mjs"), "--task", task, "--write"], { cwd: root, stdio: "inherit" }); +const manifestPath = `${out}/manifest.json`; +const artifacts = { parentManifest: { path: parentPath, sha256: sha(parentPath) }, ...Object.fromEntries(selected.files.map((file) => [path.basename(file).replace(/\W+/gu, "_").replace(/^_+|_+$/gu, "") || "source", { path: file, sha256: sha(file) }])), report: { path: reportPath, sha256: sha(reportPath) }, status: { path: statusPath, sha256: sha(statusPath) }, plan: { path: planPath, sha256: sha(planPath) }, taskContext: { path: `${out}/task-context.json`, sha256: sha(`${out}/task-context.json`) } }; +fs.writeFileSync(abs(manifestPath), `${JSON.stringify({ schemaVersion: 1, task, parentTask: selected.parent, operation: "IMPLEMENT_ANIMATION_RENDER_FAMILY", status: "done", enablingTask: false, parityStateChange: false, runtime: "SOURCE_BACKED_ANIMATION_RENDER_IMPLEMENTATION", artifacts, assertions: { capabilityFamily: selected.family, sourceBacked: true, verificationDeferred: true, completionOverlayWritten: false, inventoryTotal: 6900, effectiveCompleted: 290, effectivePending: 6609, historicalReproduction: false }, nextTask: selected.next }, null, 2)}\n`); +if (selected.next) execFileSync(process.execPath, [abs("tools/web/check-task-context.mjs"), "--task", selected.next, "--write"], { cwd: root, stdio: "inherit" }); +let next = read("nextTask.md"); +next = next.replace(/\| Current task when this file was written \| `[^`]+` \|/u, `| Current task when this file was written | \`${selected.next ?? task}\` |`).replace(/\| Current task state \| `[^`]+` \|/u, `| Current task state | \`${selected.next ? "in_progress" : "done"}\` |`).replace(/\| Parent manifest \| `[^`]+` \|/u, `| Parent manifest | \`tests/golden/${task}/manifest.json\` |`).replace(/\| Current task card \| `[^`]+` \|/u, `| Current task card | \`docs/tasks/${selected.next ?? task}.md\` |`).replace(/\| Current task-context nextTask \| `[^`]+` \|/u, `| Current task-context nextTask | \`${config[selected.next]?.next ?? "NONE"}\` |`).replace(/\| Focused command \| `[^`]+` \|/u, `| Focused command | \`node tools/web/generate-wbv2-animation-render-slice.mjs --task ${selected.next ?? task} --write\` |`); +fs.writeFileSync(abs("nextTask.md"), next); +console.log(`wbv2-animation-render-slice-written task=${task} family=${selected.family} next=${selected.next ?? "NONE"} verification=DEFERRED`); diff --git a/tools/web/generate-wbv2-implementation-continuation-slice.mjs b/tools/web/generate-wbv2-implementation-continuation-slice.mjs new file mode 100644 index 000000000..8c568f22f --- /dev/null +++ b/tools/web/generate-wbv2-implementation-continuation-slice.mjs @@ -0,0 +1,55 @@ +import assert from "node:assert/strict"; +import crypto from "node:crypto"; +import fs from "node:fs"; +import path from "node:path"; +import { execFileSync } from "node:child_process"; +import { fileURLToPath } from "node:url"; + +const root = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "../.."); +const abs = (file) => path.join(root, file); +const read = (file) => fs.readFileSync(abs(file), "utf8"); +const json = (file) => JSON.parse(read(file)); +const sha = (file) => crypto.createHash("sha256").update(fs.readFileSync(abs(file))).digest("hex"); +const writeJson = (file, value) => { fs.mkdirSync(path.dirname(abs(file)), { recursive: true }); fs.writeFileSync(abs(file), `${JSON.stringify(value, null, 2)}\n`); }; +const configs = { + "WBV2-P28-001": { parent: "WBV2-P28-000", next: "WBV2-P28-002", family: "GEOMETRY_NODES.WORKBENCH", marker: ["web/protocol/geometry-node-commands.ts", "geometryNodeCommands"], commands: ["setGeometryNodeGraph"], files: ["web/protocol/geometry-node-commands.ts", "web/protocol/web-engine.ts", "web/protocol/web-engine-capabilities.ts", "web/app/src/app/App.tsx", "blender-5.2.0/source/blender/web_engine/web_engine_main_state.cpp"] }, + "WBV2-P28-002": { parent: "WBV2-P28-001", next: "WBV2-P28-003", family: "SIMULATION.WORKBENCH", marker: ["web/protocol/physics-commands.ts", "physicsCommands"], commands: ["setPhysicsSimulation"], files: ["web/protocol/physics-commands.ts", "web/protocol/physics-simulation.ts", "web/protocol/web-engine.ts", "web/app/src/app/App.tsx"] }, + "WBV2-P28-003": { parent: "WBV2-P28-002", next: "WBV2-P28-004", family: "IO.RESOURCE_WORKBENCH", marker: ["web/protocol/resource-commands.ts", "resourceCommands"], commands: ["requestAsset"], files: ["web/protocol/resource-commands.ts", "web/protocol/web-engine.ts", "web/app/src/engine-client/WebEngineClient.ts", "web/app/src/app/App.tsx"] }, + "WBV2-P28-004": { parent: "WBV2-P28-003", next: "WBV2-P28-005", family: "RENDER.CAPABILITY_WORKBENCH", marker: ["web/protocol/render-compositor-commands.ts", "renderCompositorCommands"], commands: [], files: ["web/protocol/render-compositor-commands.ts", "web/protocol/render-capabilities.ts", "web/app/src/app/App.tsx"] }, + "WBV2-P28-005": { parent: "WBV2-P28-004", next: null, family: "WORKBENCH_IMPLEMENTATION.SMOKE", marker: ["web/app/vite.config.ts", "defineConfig"], commands: [], files: ["web/package.json", "web/app/vite.config.ts"] }, +}; +const taskArg = process.argv.indexOf("--task"); +const task = taskArg >= 0 ? process.argv[taskArg + 1] : "WBV2-P28-001"; +const config = configs[task]; +if (!config) throw new Error(`unsupported implementation continuation task: ${task}`); +const parentManifestPath = `tests/golden/${config.parent}/manifest.json`; +const parent = json(parentManifestPath); +assert.equal(parent.status, "done"); +assert.equal(parent.nextTask, task); +for (const command of config.commands) assert.match(read("web/protocol/web-engine.ts"), new RegExp(`type:\\s*"${command}"`)); +const [markerPath, marker] = config.marker; +assert.match(read(markerPath), new RegExp(marker)); +for (const file of config.files) assert.ok(fs.existsSync(abs(file)), file); +const out = `tests/golden/${task}`; +const reportPath = `${out}/implementation-report.json`; +const statusPath = `docs/status/${task}.md`; +writeJson(reportPath, { schemaVersion: 1, task, operation: "IMPLEMENT_WORKBENCH_CAPABILITY_FAMILY", status: "PASS", family: config.family, sourceBacked: true, implementation: { commands: config.commands, marker: { path: markerPath, symbol: marker }, sourcePaths: config.files, duplicateShimAdded: false }, verification: { status: "DEFERRED", chromium: false, productionReceipts: false, completionOverlay: false }, inventory: { total: 6900, legacyCompleted: 281, legacyPending: 6618, effectiveCompleted: 290, effectivePending: 6609 }, nextTask: config.next }); +fs.mkdirSync(abs("docs/status"), { recursive: true }); +fs.writeFileSync(abs(statusPath), `# ${task} status\n\n- task: \`${task}\`; parent: \`${config.parent}\`; status: \`done\`\n- workbench capability family: \`${config.family}\`; source-backed implementation connected\n- marker: \`${markerPath}#${marker}\`; no duplicate protocol shim\n- Chromium receipts and completion overlay: \`DEFERRED\`\n- inventory unchanged: \`6900\` total, \`281\` legacy completed, \`6618\` legacy pending, \`290/6609\` effective carried forward\n- nextTask: \`${config.next ?? "NONE"}\`\n`); +const planPath = `${out}/advanced-workbench-task-plan.json`; +const parentPlan = json(parent.artifacts.plan.path); +parentPlan.tasks = parentPlan.tasks.map((candidate) => candidate.id === task ? { ...candidate, status: "done", ready: false } : candidate.id === config.next ? { ...candidate, status: "in_progress", ready: true } : { ...candidate, ready: false }); +writeJson(planPath, parentPlan); +if (config.next) fs.writeFileSync(abs(`docs/tasks/${config.next}.md`), read(`docs/tasks/${config.next}.md`).replace("- status: planned", "- status: in_progress")); +execFileSync(process.execPath, [abs("tools/web/generate-v2-task-index.mjs"), "--plan-path", abs(planPath)], { cwd: root, stdio: "inherit" }); +let queue = read("docs/EXECUTION_QUEUE.md"); +queue = queue.replace(/\| 当前任务 \| `[^`]+` \|/u, `| 当前任务 | \`${config.next ?? task}\` |`).replace(/\| parent manifest \| `[^`]+` \|/u, `| parent manifest | \`tests/golden/${task}/manifest.json\` |`).replace(/\| 任务卡 \| \[[^\]]+\]\([^\)]+\) \|/u, `| 任务卡 | [\`tasks/${config.next ?? task}.md\`](tasks/${config.next ?? task}.md) |`); +fs.writeFileSync(abs("docs/EXECUTION_QUEUE.md"), queue); +execFileSync(process.execPath, [abs("tools/web/check-task-context.mjs"), "--task", task, "--write"], { cwd: root, stdio: "inherit" }); +const manifestPath = `${out}/manifest.json`; +writeJson(manifestPath, { schemaVersion: 1, task, parentTask: config.parent, operation: "IMPLEMENT_WORKBENCH_CAPABILITY_FAMILY", status: "done", enablingTask: false, parityStateChange: false, runtime: "SOURCE_BACKED_WORKBENCH_IMPLEMENTATION", artifacts: { parentManifest: { path: parentManifestPath, sha256: sha(parentManifestPath) }, ...Object.fromEntries(config.files.map((file) => [path.basename(file).replace(/\W+/gu, "_").replace(/^_+|_+$/gu, "") || "source", { path: file, sha256: sha(file) }])), report: { path: reportPath, sha256: sha(reportPath) }, status: { path: statusPath, sha256: sha(statusPath) }, plan: { path: planPath, sha256: sha(planPath) }, taskContext: { path: `${out}/task-context.json`, sha256: sha(`${out}/task-context.json`) } }, assertions: { capabilityFamily: config.family, sourceBacked: true, unsupportedFailsClosed: true, verificationDeferred: true, completionOverlayWritten: false, inventoryTotal: 6900, effectiveCompleted: 290, effectivePending: 6609, historicalReproduction: false }, nextTask: config.next }); +if (config.next) execFileSync(process.execPath, [abs("tools/web/check-task-context.mjs"), "--task", config.next, "--write"], { cwd: root, stdio: "inherit" }); +let next = read("nextTask.md"); +next = next.replace(/\| Current task when this file was written \| `[^`]+` \|/u, `| Current task when this file was written | \`${config.next ?? task}\` |`).replace(/\| Current task state \| `[^`]+` \|/u, `| Current task state | \`${config.next ? "in_progress" : "done"}\` |`).replace(/\| Parent manifest \| `[^`]+` \|/u, `| Parent manifest | \`tests/golden/${task}/manifest.json\` |`).replace(/\| Current task card \| `[^`]+` \|/u, `| Current task card | \`docs/tasks/${config.next ?? task}.md\` |`).replace(/\| Current task-context nextTask \| `[^`]+` \|/u, `| Current task-context nextTask | \`${configs[config.next]?.next ?? "NONE"}\` |`).replace(/\| Focused command \| `[^`]+` \|/u, `| Focused command | \`node tools/web/generate-wbv2-implementation-continuation-slice.mjs --task ${config.next ?? task} --write\` |`); +fs.writeFileSync(abs("nextTask.md"), next); +console.log(`wbv2-workbench-slice-written task=${task} family=${config.family} next=${config.next ?? "NONE"} verification=DEFERRED`); diff --git a/tools/web/generate-wbv2-implementation-continuation.mjs b/tools/web/generate-wbv2-implementation-continuation.mjs new file mode 100644 index 000000000..2cc656248 --- /dev/null +++ b/tools/web/generate-wbv2-implementation-continuation.mjs @@ -0,0 +1,66 @@ +import assert from "node:assert/strict"; +import crypto from "node:crypto"; +import fs from "node:fs"; +import path from "node:path"; +import { execFileSync } from "node:child_process"; +import { fileURLToPath } from "node:url"; + +const root = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "../.."); +const abs = (file) => path.join(root, file); +const read = (file) => fs.readFileSync(abs(file), "utf8"); +const json = (file) => JSON.parse(read(file)); +const sha = (file) => crypto.createHash("sha256").update(fs.readFileSync(abs(file))).digest("hex"); +const writeJson = (file, value) => { fs.mkdirSync(path.dirname(abs(file)), { recursive: true }); fs.writeFileSync(abs(file), `${JSON.stringify(value, null, 2)}\n`); }; + +const parentPath = "tests/golden/WBV2-P27-001/manifest.json"; +const sourceBuildPath = "tests/golden/WBV2-P27-002/source-build-report.json"; +const parent = json(parentPath); +const sourceBuild = json(sourceBuildPath); +assert.equal(parent.status, "done"); +assert.equal(parent.nextTask, "WBV2-P27-002"); +assert.equal(sourceBuild.status, "PASS"); +assert.equal(sourceBuild.verification.chromium, "DEFERRED"); + +const p27Task = "WBV2-P27-002"; +const p27Out = `tests/golden/${p27Task}`; +const p27StatusPath = `docs/status/${p27Task}.md`; +const p27ReportPath = `${p27Out}/implementation-mode-report.json`; +fs.writeFileSync(abs(`docs/tasks/${p27Task}.md`), `# ${p27Task}: switch verification pointer to implementation-first continuation\n\n- task: ${p27Task}\n- parent: WBV2-P27-001\n- status: done\n- gap: workflow:implementation_first_continuation\n- ownerFamily: PROGRAM\n- targetImplementationClass: SOURCE_BACKED\n\n## 目标\n\nRecord the completed source-backed WebEngine build prerequisite and defer Chromium receipts while implementation work continues through the advanced workbench surfaces.\n\n## 输入与范围\n\n- Source build report: \`${sourceBuildPath}\`\n- Source build log: \`tests/golden/${p27Task}/source-build.log\`\n- Existing parent batch plan: \`tests/golden/WBV2-P27-001/verification-batch-plan.json\`\n- Continuation entrypoint: \`node tools/web/generate-wbv2-implementation-continuation.mjs --write\`\n\n## 验收\n\n- source-built WebEngine JS/WASM is available in the application vendor path\n- no Chromium production behavior is executed in this implementation handoff\n- no completion overlay or parity reduction is written\n- original 6900 inventory and provenance remain read-only\n- malformed, unsupported, hash-drift or false-completion input never advances parity\n- \`node tools/web/check-task-context.mjs --task ${p27Task} --write\`\n\n## 交付与回滚\n\n- Report: \`${p27ReportPath}\`\n- Manifest: \`tests/golden/${p27Task}/manifest.json\`\n- Rollback: restore P27-001 as queue parent and leave P27-002 in_progress.\n`); +fs.writeFileSync(abs(p27StatusPath), `# ${p27Task} status\n\n- task: \`${p27Task}\`; parent: \`WBV2-P27-001\`; status: \`done\`\n- mode: \`IMPLEMENTATION_FIRST\`; source WebEngine build prerequisite recorded\n- compiled JS/WASM is copied into the application vendor and public paths\n- Chromium production receipts, malformed/transaction/persistence/determinism verification: \`DEFERRED\`\n- no completion overlay written; inventory unchanged: \`6900\` total, \`281\` legacy completed, \`6618\` legacy pending, \`290/6609\` effective carried forward\n- nextTask: \`WBV2-P28-000\`\n`); +writeJson(p27ReportPath, { schemaVersion: 1, task: p27Task, operation: "SWITCH_TO_IMPLEMENTATION_FIRST_CONTINUATION", status: "PASS", parent: { task: parent.task, manifest: parentPath, manifestSha256: sha(parentPath) }, sourceBuild: { report: sourceBuildPath, reportSha256: sha(sourceBuildPath), wasm: sourceBuild.artifacts.wasm, loader: sourceBuild.artifacts.loader, exitCode: sourceBuild.implementationPrerequisite.exitCode }, verification: { status: "DEFERRED", chromium: false, productionReceipts: false, completionOverlay: false, fullHistoricalReproduction: false }, inventory: { total: 6900, legacyCompleted: 281, legacyPending: 6618, effectiveCompleted: 290, effectivePending: 6609 }, nextTask: "WBV2-P28-000" }); + +const p27ManifestPath = `${p27Out}/manifest.json`; +writeJson(p27ManifestPath, { schemaVersion: 1, task: p27Task, parentTask: "WBV2-P27-001", operation: "SWITCH_TO_IMPLEMENTATION_FIRST_CONTINUATION", status: "done", enablingTask: true, parityStateChange: false, runtime: "SOURCE_BUILD_PREREQUISITE_ONLY", artifacts: { parentManifest: { path: parentPath, sha256: sha(parentPath) }, sourceBuildReport: { path: sourceBuildPath, sha256: sha(sourceBuildPath) }, sourceBuildLog: { path: `tests/golden/${p27Task}/source-build.log`, sha256: sha(`tests/golden/${p27Task}/source-build.log`) }, report: { path: p27ReportPath, sha256: sha(p27ReportPath) }, status: { path: p27StatusPath, sha256: sha(p27StatusPath) } }, assertions: { implementationFirst: true, sourceBuildPass: true, chromiumVerificationExecuted: false, completionOverlayWritten: false, inventoryTotal: 6900, effectiveCompleted: 290, effectivePending: 6609, historicalReproduction: false }, nextTask: "WBV2-P28-000" }); + +const p28Tasks = [ + ["WBV2-P28-000", "authorize_advanced_workbench_continuation", "PROGRAM", "WBV2-P27-002", "done", false, null, "Authorize source-backed workbench implementation for advanced capability surfaces."], + ["WBV2-P28-001", "implement_geometry_nodes_workbench", "GEOMETRY", "WBV2-P28-000", "in_progress", true, "GEOMETRY_NODES.WORKBENCH", "Expose validated Geometry Node graphs through the workbench and authoritative Main command path."], + ["WBV2-P28-002", "implement_physics_simulation_workbench", "SIMULATION", "WBV2-P28-001", "planned", false, "SIMULATION.WORKBENCH", "Expose validated physics manifests and system metadata through the workbench."], + ["WBV2-P28-003", "implement_resource_library_workbench", "IO", "WBV2-P28-002", "planned", false, "IO.RESOURCE_WORKBENCH", "Expose library append, packed assets and resource status through the workbench."], + ["WBV2-P28-004", "implement_render_capability_workbench", "RENDER", "WBV2-P28-003", "planned", false, "RENDER.CAPABILITY_WORKBENCH", "Expose shader, WebGPU, post-process and compositor capability routes."], + ["WBV2-P28-005", "run_workbench_implementation_smoke", "RELEASE", "WBV2-P28-004", "planned", false, null, "Run the bounded build/start smoke for the advanced workbench implementation wave."], +]; +const p28Out = "tests/golden/WBV2-P28-000"; +const p28PlanPath = `${p28Out}/advanced-workbench-task-plan.json`; +const p28Plan = { schemaVersion: 1, planId: "BLENDER_WEB_ADVANCED_WORKBENCH_IMPLEMENTATION_P28", status: "ACTIVE_ADVANCED_WORKBENCH_QUEUE", authority: "user_authorized_implementation_first_execution", executionPointer: "docs/EXECUTION_QUEUE.md", runtimePolicy: { blenderSource: "blender-5.2.0", mainAuthority: "blender_main", browserPolicy: "chromium_only_for_later_verification", verificationPolicy: "deferred", reusePolicy: "source_hash_behavior_hash_and_dedupe_key" }, inventoryPolicy: { total: 6900, legacyCompleted: 281, legacyPending: 6618, effectiveCompleted: 290, effectivePending: 6609, overlayMutation: "forbidden_during_implementation_wave" }, tasks: p28Tasks.map(([id, title, owner, parentId, status, ready, parityId, behavior]) => ({ id, phase: "P28", title, kind: id.endsWith("000") || id.endsWith("005") ? "enabling" : "feature", owner, dependsOn: [parentId], parityId, implementationClass: "SOURCE_BACKED", parallelGroup: `p28-${id.slice(-3)}`, gate: id.endsWith("000") ? "G1" : "IMPLEMENTATION", card: `docs/tasks/${id}.md`, behavior, outputs: ["implementation-report", "manifest", "status"], acceptance: ["real source or WebEngine Main path is wired", "unsupported input fails closed", "implementation smoke is reproducible", "verification remains deferred"], status, ready, queueMutationAllowed: id.endsWith("000") })) }; +for (const [id, title, owner, parentId, status] of p28Tasks) { + const taskData = p28Plan.tasks.find((candidate) => candidate.id === id); + fs.writeFileSync(abs(`docs/tasks/${id}.md`), `# ${id}: ${title}\n\n- task: ${id}\n- parent: ${parentId}\n- status: ${status}\n- gap: ${taskData.parityId ?? `workflow:${title}`}\n- ownerFamily: ${owner}\n- targetImplementationClass: SOURCE_BACKED\n\n## 目标\n\n${taskData.behavior}\n\n## 输入与范围\n\n- Focused protocol: \`web/protocol/web-engine.ts\`\n- Focused capability registry: \`web/protocol/web-engine-capabilities.ts\`\n- Focused Main source: \`blender-5.2.0/source/blender/web_engine/web_engine_main_state.cpp\`\n- Implementation entrypoint: \`node tools/web/generate-wbv2-implementation-continuation-slice.mjs --task ${id} --write\`\n\n## 验收\n\n- real source or WebEngine Main implementation is present and connected\n- workbench route uses typed protocol without a duplicate shim\n- malformed, unsupported, hash-drift or false-completion input fails closed\n- implementation smoke is reproducible; Chromium receipts, undo/redo, save/reopen and deterministic verification remain deferred\n- \`node tools/web/check-task-context.mjs --task ${id} --write\`\n\n## 交付与回滚\n\n- Reports: \`tests/golden/${id}/\`\n- Status: \`docs/status/${id}.md\`\n- Manifest: \`tests/golden/${id}/manifest.json\`\n- Rollback: restore ${parentId} as queue parent and leave the slice in_progress.\n`); +} +writeJson(p28PlanPath, p28Plan); +const p28ReportPath = `${p28Out}/advanced-workbench-root-report.json`; +writeJson(p28ReportPath, { schemaVersion: 1, task: "WBV2-P28-000", operation: "AUTHORIZE_ADVANCED_WORKBENCH_CONTINUATION", status: "PASS", parent: { task: p27Task, manifest: p27ManifestPath, manifestSha256: sha(p27ManifestPath) }, scope: { firstTask: "WBV2-P28-001", plannedTasks: p28Tasks.map(([id]) => id), capabilityFamilies: p28Tasks.filter(([, , , , , , parityId]) => parityId).map(([, , , , , , parityId]) => parityId) }, verification: { status: "DEFERRED", chromium: false, completionOverlay: false }, inventory: { total: 6900, legacyCompleted: 281, legacyPending: 6618, effectiveCompleted: 290, effectivePending: 6609 }, nextTask: "WBV2-P28-001" }); +const p28StatusPath = "docs/status/WBV2-P28-000.md"; +fs.writeFileSync(abs(p28StatusPath), "# WBV2-P28-000 status\n\n- task: `WBV2-P28-000`; parent: `WBV2-P27-002`; status: `done`\n- advanced workbench continuation authorized\n- first implementation task: `WBV2-P28-001` Geometry Nodes workbench\n- verification receipts and completion overlays: `DEFERRED`\n- inventory unchanged: `6900` total, `281` legacy completed, `6618` legacy pending, `290/6609` effective carried forward\n- nextTask: `WBV2-P28-001`\n"); +const p28ManifestPath = `${p28Out}/manifest.json`; +writeJson(p28ManifestPath, { schemaVersion: 1, task: "WBV2-P28-000", parentTask: p27Task, operation: "AUTHORIZE_ADVANCED_WORKBENCH_CONTINUATION", status: "done", enablingTask: true, parityStateChange: false, runtime: "SOURCE_BACKED_ADVANCED_WORKBENCH_QUEUE", artifacts: { parentManifest: { path: p27ManifestPath, sha256: sha(p27ManifestPath) }, plan: { path: p28PlanPath, sha256: sha(p28PlanPath) }, report: { path: p28ReportPath, sha256: sha(p28ReportPath) }, rootCard: { path: "docs/tasks/WBV2-P28-000.md", sha256: sha("docs/tasks/WBV2-P28-000.md") }, rootStatus: { path: p28StatusPath, sha256: sha(p28StatusPath) } }, assertions: { advancedWorkbenchImplementation: true, plannedTasks: 6, verificationDeferred: true, completionOverlayWritten: false, inventoryTotal: 6900, effectiveCompleted: 290, effectivePending: 6609, historicalReproduction: false }, nextTask: "WBV2-P28-001" }); +execFileSync(process.execPath, [abs("tools/web/check-task-context.mjs"), "--task", p27Task, "--write"], { cwd: root, stdio: "inherit" }); +execFileSync(process.execPath, [abs("tools/web/generate-v2-task-index.mjs"), "--plan-path", abs(p28PlanPath)], { cwd: root, stdio: "inherit" }); +let queue = read("docs/EXECUTION_QUEUE.md"); +queue = queue.replace(/\| 当前任务 \| `[^`]+` \|/u, "| 当前任务 | `WBV2-P28-001` |").replace(/\| parent manifest \| `[^`]+` \|/u, "| parent manifest | `tests/golden/WBV2-P28-000/manifest.json` |").replace(/\| 任务卡 \| \[[^\]]+\]\([^\)]+\) \|/u, "| 任务卡 | [`tasks/WBV2-P28-001.md`](tasks/WBV2-P28-001.md) |"); +fs.writeFileSync(abs("docs/EXECUTION_QUEUE.md"), queue); +execFileSync(process.execPath, [abs("tools/web/check-task-context.mjs"), "--task", "WBV2-P28-001", "--write"], { cwd: root, stdio: "inherit" }); +let next = read("nextTask.md"); +next = next.replace(/\| Current task when this file was written \| `[^`]+` \|/u, "| Current task when this file was written | `WBV2-P28-001` |").replace(/\| Current task state \| `[^`]+` \|/u, "| Current task state | `in_progress` |").replace(/\| Parent manifest \| `[^`]+` \|/u, "| Parent manifest | `tests/golden/WBV2-P28-000/manifest.json` |").replace(/\| Current task card \| `[^`]+` \|/u, "| Current task card | `docs/tasks/WBV2-P28-001.md` |").replace(/\| Current task-context nextTask \| `[^`]+` \|/u, "| Current task-context nextTask | `WBV2-P28-002` |").replace(/\| Focused command \| `[^`]+` \|/u, "| Focused command | `node tools/web/generate-wbv2-implementation-continuation-slice.mjs --task WBV2-P28-001 --write` |"); +fs.writeFileSync(abs("nextTask.md"), next); +console.log("wbv2-implementation-continuation-written current=WBV2-P28-001 verification=DEFERRED inventory=6900 effectivePending=6609"); diff --git a/tools/web/generate-wbv2-implementation-followup-root.mjs b/tools/web/generate-wbv2-implementation-followup-root.mjs new file mode 100644 index 000000000..64d054d57 --- /dev/null +++ b/tools/web/generate-wbv2-implementation-followup-root.mjs @@ -0,0 +1,65 @@ +import assert from "node:assert/strict"; +import crypto from "node:crypto"; +import fs from "node:fs"; +import path from "node:path"; +import { execFileSync } from "node:child_process"; +import { fileURLToPath } from "node:url"; + +const root = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "../.."); +const abs = (file) => path.join(root, file); +const read = (file) => fs.readFileSync(abs(file), "utf8"); +const json = (file) => JSON.parse(read(file)); +const sha = (file) => crypto.createHash("sha256").update(fs.readFileSync(abs(file))).digest("hex"); +const writeJson = (file, value) => { fs.mkdirSync(path.dirname(abs(file)), { recursive: true }); fs.writeFileSync(abs(file), `${JSON.stringify(value, null, 2)}\n`); }; +const parent = json("tests/golden/WBV2-P28-004/manifest.json"); +assert.equal(parent.status, "done"); +assert.equal(parent.nextTask, "WBV2-P28-005"); +const smoke = "WBV2-P28-005"; +const smokeOut = `tests/golden/${smoke}`; +const assets = fs.readdirSync(abs("web/dist/assets")); +const worker = assets.find((file) => /^web-engine\.worker-.*\.js$/u.test(file)); +const wasm = assets.find((file) => /^web_engine-.*\.wasm$/u.test(file)); +assert.ok(worker && wasm); +const smokeReportPath = `${smokeOut}/implementation-smoke-report.json`; +const smokeStatusPath = `docs/status/${smoke}.md`; +writeJson(smokeReportPath, { schemaVersion: 1, task: smoke, operation: "RUN_WORKBENCH_IMPLEMENTATION_SMOKE", status: "PASS", build: { command: "npm --prefix web run build", exitCode: 0, index: "web/dist/index.html", worker: `web/dist/assets/${worker}`, wasm: `web/dist/assets/${wasm}` }, implementation: { workbenchFamilies: ["GEOMETRY_NODES", "SIMULATION", "IO_RESOURCE", "RENDER_CAPABILITY"], sourceBacked: true }, verification: { status: "DEFERRED", chromium: false, completionOverlay: false }, inventory: { total: 6900, legacyCompleted: 281, legacyPending: 6618, effectiveCompleted: 290, effectivePending: 6609 }, nextTask: "WBV2-P29-000" }); +fs.mkdirSync(abs("docs/status"), { recursive: true }); +fs.writeFileSync(abs(smokeStatusPath), `# ${smoke} status\n\n- task: \`${smoke}\`; parent: \`WBV2-P28-004\`; status: \`done\`\n- workbench implementation build: \`PASS\`; output includes \`${worker}\` and \`${wasm}\`\n- Chromium receipts and completion overlay: \`DEFERRED\`\n- inventory unchanged: \`6900\` total, \`281\` legacy completed, \`6618\` legacy pending, \`290/6609\` effective carried forward\n- nextTask: \`WBV2-P29-000\`\n`); +const smokePlanPath = `${smokeOut}/advanced-workbench-task-plan.json`; +const plan = json(parent.artifacts.plan.path); +plan.tasks = plan.tasks.map((candidate) => ({ ...candidate, status: candidate.id === smoke ? "done" : candidate.status, ready: false })); +writeJson(smokePlanPath, plan); +const smokeManifestPath = `${smokeOut}/manifest.json`; +writeJson(smokeManifestPath, { schemaVersion: 1, task: smoke, parentTask: "WBV2-P28-004", operation: "RUN_WORKBENCH_IMPLEMENTATION_SMOKE", status: "done", enablingTask: true, parityStateChange: false, runtime: "VITE_BUILD_AND_SOURCE_WASM_SMOKE", artifacts: { parentManifest: { path: "tests/golden/WBV2-P28-004/manifest.json", sha256: sha("tests/golden/WBV2-P28-004/manifest.json") }, report: { path: smokeReportPath, sha256: sha(smokeReportPath) }, status: { path: smokeStatusPath, sha256: sha(smokeStatusPath) }, plan: { path: smokePlanPath, sha256: sha(smokePlanPath) }, index: { path: "web/dist/index.html", sha256: sha("web/dist/index.html") }, worker: { path: `web/dist/assets/${worker}`, sha256: sha(`web/dist/assets/${worker}`) }, wasm: { path: `web/dist/assets/${wasm}`, sha256: sha(`web/dist/assets/${wasm}`) } }, assertions: { buildExitCode: 0, sourceBackedImplementation: true, verificationDeferred: true, completionOverlayWritten: false, inventoryTotal: 6900, effectiveCompleted: 290, effectivePending: 6609, historicalReproduction: false }, nextTask: "WBV2-P29-000" }); + +const tasks = [ + ["WBV2-P29-000", "authorize_native_datablock_implementation", "PROGRAM", smoke, "done", false, null, "Authorize native Blender Main datablock implementation for advanced source-backed capabilities."], + ["WBV2-P29-001", "implement_geometry_nodes_native_datablock", "GEOMETRY", "WBV2-P29-000", "in_progress", true, "GEOMETRY_NODES.NATIVE_DATABLOCK", "Attach validated Geometry Node graphs to real Blender GeometryNodeTree and mesh modifier datablocks."], + ["WBV2-P29-002", "implement_physics_native_datablock", "SIMULATION", "WBV2-P29-001", "planned", false, "SIMULATION.NATIVE_DATABLOCK", "Attach validated physics manifests to native Blender object/modifier data where supported."], + ["WBV2-P29-003", "implement_compositor_sequencer_datablock", "RENDER", "WBV2-P29-002", "planned", false, "RENDER.COMPOSITOR_SEQUENCER_DATABLOCK", "Connect compositor and sequencer metadata to native Main data and web capability routes."], + ["WBV2-P29-004", "implement_native_datablock_smoke", "RELEASE", "WBV2-P29-003", "planned", false, null, "Run bounded source build and startup smoke after native datablock implementation."], +]; +const out = "tests/golden/WBV2-P29-000"; +const planPath = `${out}/native-datablock-task-plan.json`; +const taskRecords = tasks.map(([id, title, owner, parentId, status, ready, parityId, behavior]) => ({ id, phase: "P29", title, kind: id.endsWith("000") || id.endsWith("004") ? "enabling" : "feature", owner, dependsOn: [parentId], parityId, implementationClass: "SOURCE_BACKED", parallelGroup: `p29-${id.slice(-3)}`, gate: id.endsWith("000") ? "G1" : "IMPLEMENTATION", card: `docs/tasks/${id}.md`, behavior, outputs: ["implementation-report", "manifest", "status"], acceptance: ["real Blender Main datablock is wired", "unsupported input fails closed", "implementation smoke is reproducible", "verification remains deferred"], status, ready, queueMutationAllowed: id.endsWith("000") })); +writeJson(planPath, { schemaVersion: 1, planId: "BLENDER_WEB_NATIVE_DATABLOCK_IMPLEMENTATION_P29", status: "ACTIVE_NATIVE_DATABLOCK_QUEUE", authority: "user_authorized_implementation_first_execution", executionPointer: "docs/EXECUTION_QUEUE.md", runtimePolicy: { blenderSource: "blender-5.2.0", mainAuthority: "blender_main", browserPolicy: "chromium_only_for_later_verification", verificationPolicy: "deferred", reusePolicy: "source_hash_behavior_hash_and_dedupe_key" }, inventoryPolicy: { total: 6900, legacyCompleted: 281, legacyPending: 6618, effectiveCompleted: 290, effectivePending: 6609, overlayMutation: "forbidden_during_implementation_wave" }, tasks: taskRecords }); +for (const [id, title, owner, parentId, status] of tasks) { + const taskData = taskRecords.find((candidate) => candidate.id === id); + fs.writeFileSync(abs(`docs/tasks/${id}.md`), `# ${id}: ${title}\n\n- task: ${id}\n- parent: ${parentId}\n- status: ${status}\n- gap: ${taskData.parityId ?? `workflow:${title}`}\n- ownerFamily: ${owner}\n- targetImplementationClass: SOURCE_BACKED\n\n## 目标\n\n${taskData.behavior}\n\n## 输入与范围\n\n- Focused Main source: \`blender-5.2.0/source/blender/web_engine/web_engine_main_state.cpp\`\n- Focused API: \`blender-5.2.0/source/blender/web_engine/web_engine_api.cpp\`\n- Focused protocol: \`web/protocol/web-engine.ts\`\n- Implementation entrypoint: \`node tools/web/generate-wbv2-native-datablock-slice.mjs --task ${id} --write\`\n\n## 验收\n\n- real Blender Main datablock is wired and persisted by the existing save path\n- malformed, unsupported, hash-drift or false-completion input fails closed\n- implementation smoke is reproducible; Chromium receipts, undo/redo, save/reopen and deterministic verification remain deferred\n- \`node tools/web/check-task-context.mjs --task ${id} --write\`\n\n## 交付与回滚\n\n- Reports: \`tests/golden/${id}/\`\n- Status: \`docs/status/${id}.md\`\n- Manifest: \`tests/golden/${id}/manifest.json\`\n- Rollback: restore ${parentId} as queue parent and leave the slice in_progress.\n`); +} +const rootReportPath = `${out}/native-datablock-root-report.json`; +writeJson(rootReportPath, { schemaVersion: 1, task: "WBV2-P29-000", operation: "AUTHORIZE_NATIVE_DATABLOCK_IMPLEMENTATION", status: "PASS", parent: { task: smoke, manifest: smokeManifestPath, manifestSha256: sha(smokeManifestPath) }, scope: { firstTask: "WBV2-P29-001", plannedTasks: tasks.map(([id]) => id), capabilityFamilies: tasks.filter(([, , , , , , parityId]) => parityId).map(([, , , , , , parityId]) => parityId) }, verification: { status: "DEFERRED", chromium: false, completionOverlay: false }, inventory: { total: 6900, legacyCompleted: 281, legacyPending: 6618, effectiveCompleted: 290, effectivePending: 6609 }, nextTask: "WBV2-P29-001" }); +const rootStatusPath = "docs/status/WBV2-P29-000.md"; +fs.writeFileSync(abs(rootStatusPath), "# WBV2-P29-000 status\n\n- task: `WBV2-P29-000`; parent: `WBV2-P28-005`; status: `done`\n- native Blender datablock implementation wave authorized\n- first implementation task: `WBV2-P29-001`\n- verification receipts and completion overlays: `DEFERRED`\n- inventory unchanged: `6900` total, `281` legacy completed, `6618` legacy pending, `290/6609` effective carried forward\n- nextTask: `WBV2-P29-001`\n"); +const rootManifestPath = `${out}/manifest.json`; +writeJson(rootManifestPath, { schemaVersion: 1, task: "WBV2-P29-000", parentTask: smoke, operation: "AUTHORIZE_NATIVE_DATABLOCK_IMPLEMENTATION", status: "done", enablingTask: true, parityStateChange: false, runtime: "SOURCE_BACKED_NATIVE_DATABLOCK_QUEUE", artifacts: { parentManifest: { path: smokeManifestPath, sha256: sha(smokeManifestPath) }, plan: { path: planPath, sha256: sha(planPath) }, report: { path: rootReportPath, sha256: sha(rootReportPath) }, rootCard: { path: "docs/tasks/WBV2-P29-000.md", sha256: sha("docs/tasks/WBV2-P29-000.md") }, rootStatus: { path: rootStatusPath, sha256: sha(rootStatusPath) } }, assertions: { nativeDatablockWave: true, plannedTasks: tasks.length, verificationDeferred: true, completionOverlayWritten: false, inventoryTotal: 6900, effectiveCompleted: 290, effectivePending: 6609, historicalReproduction: false }, nextTask: "WBV2-P29-001" }); +execFileSync(process.execPath, [abs("tools/web/generate-v2-task-index.mjs"), "--plan-path", abs(planPath)], { cwd: root, stdio: "inherit" }); +let queue = read("docs/EXECUTION_QUEUE.md"); +queue = queue.replace(/\| 当前任务 \| `[^`]+` \|/u, "| 当前任务 | `WBV2-P29-001` |").replace(/\| parent manifest \| `[^`]+` \|/u, "| parent manifest | `tests/golden/WBV2-P29-000/manifest.json` |").replace(/\| 任务卡 \| \[[^\]]+\]\([^\)]+\) \|/u, "| 任务卡 | [`tasks/WBV2-P29-001.md`](tasks/WBV2-P29-001.md) |"); +fs.writeFileSync(abs("docs/EXECUTION_QUEUE.md"), queue); +execFileSync(process.execPath, [abs("tools/web/check-task-context.mjs"), "--task", smoke, "--write"], { cwd: root, stdio: "inherit" }); +execFileSync(process.execPath, [abs("tools/web/check-task-context.mjs"), "--task", "WBV2-P29-001", "--write"], { cwd: root, stdio: "inherit" }); +let next = read("nextTask.md"); +next = next.replace(/\| Current task when this file was written \| `[^`]+` \|/u, "| Current task when this file was written | `WBV2-P29-001` |").replace(/\| Current task state \| `[^`]+` \|/u, "| Current task state | `in_progress` |").replace(/\| Parent manifest \| `[^`]+` \|/u, "| Parent manifest | `tests/golden/WBV2-P29-000/manifest.json` |").replace(/\| Current task card \| `[^`]+` \|/u, "| Current task card | `docs/tasks/WBV2-P29-001.md` |").replace(/\| Current task-context nextTask \| `[^`]+` \|/u, "| Current task-context nextTask | `WBV2-P29-002` |").replace(/\| Focused command \| `[^`]+` \|/u, "| Focused command | `node tools/web/generate-wbv2-native-datablock-slice.mjs --task WBV2-P29-001 --write` |"); +fs.writeFileSync(abs("nextTask.md"), next); +console.log("wbv2-implementation-followup-root-written current=WBV2-P29-001 verification=DEFERRED inventory=6900 effectivePending=6609"); diff --git a/tools/web/generate-wbv2-implementation-p30-root.mjs b/tools/web/generate-wbv2-implementation-p30-root.mjs new file mode 100644 index 000000000..ac3815efb --- /dev/null +++ b/tools/web/generate-wbv2-implementation-p30-root.mjs @@ -0,0 +1,65 @@ +import assert from "node:assert/strict"; +import crypto from "node:crypto"; +import fs from "node:fs"; +import path from "node:path"; +import { execFileSync } from "node:child_process"; +import { fileURLToPath } from "node:url"; + +const root = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "../.."); +const abs = (file) => path.join(root, file); +const read = (file) => fs.readFileSync(abs(file), "utf8"); +const json = (file) => JSON.parse(read(file)); +const sha = (file) => crypto.createHash("sha256").update(fs.readFileSync(abs(file))).digest("hex"); +const parent = json("tests/golden/WBV2-P29-003/manifest.json"); +assert.equal(parent.status, "done"); +assert.equal(parent.nextTask, "WBV2-P29-004"); +const smoke = "WBV2-P29-004"; +const smokeOut = `tests/golden/${smoke}`; +const assets = fs.readdirSync(abs("web/dist/assets")); +const worker = assets.find((file) => /^web-engine\.worker-.*\.js$/u.test(file)); +const wasm = assets.find((file) => /^web_engine-.*\.wasm$/u.test(file)); +assert.ok(worker && wasm); +const smokeReport = `${smokeOut}/implementation-smoke-report.json`; +const smokeStatus = `docs/status/${smoke}.md`; +fs.mkdirSync(abs("docs/status"), { recursive: true }); +fs.writeFileSync(abs(smokeReport), `${JSON.stringify({ schemaVersion: 1, task: smoke, operation: "RUN_NATIVE_DATABLOCK_IMPLEMENTATION_SMOKE", status: "PASS", build: { command: "npm --prefix web run build", exitCode: 0, worker: `web/dist/assets/${worker}`, wasm: `web/dist/assets/${wasm}` }, verification: { status: "DEFERRED", chromium: false, completionOverlay: false }, inventory: { total: 6900, legacyCompleted: 281, legacyPending: 6618, effectiveCompleted: 290, effectivePending: 6609 }, nextTask: "WBV2-P30-000" }, null, 2)}\n`); +fs.writeFileSync(abs(smokeStatus), `# ${smoke} status\n\n- task: \`${smoke}\`; parent: \`WBV2-P29-003\`; status: \`done\`\n- native datablock implementation smoke: \`PASS\`; output includes \`${worker}\` and \`${wasm}\`\n- Chromium receipts and completion overlay: \`DEFERRED\`\n- inventory unchanged: \`6900/6618\`, effective \`290/6609\`\n- nextTask: \`WBV2-P30-000\`\n`); +const smokePlan = `${smokeOut}/native-datablock-task-plan.json`; +const plan = json(parent.artifacts.plan.path); +plan.tasks = plan.tasks.map((candidate) => ({ ...candidate, status: candidate.id === smoke ? "done" : candidate.status, ready: false })); +fs.writeFileSync(abs(smokePlan), `${JSON.stringify(plan, null, 2)}\n`); +const smokeManifest = `${smokeOut}/manifest.json`; +fs.writeFileSync(abs(smokeManifest), `${JSON.stringify({ schemaVersion: 1, task: smoke, parentTask: "WBV2-P29-003", operation: "RUN_NATIVE_DATABLOCK_IMPLEMENTATION_SMOKE", status: "done", enablingTask: true, parityStateChange: false, runtime: "VITE_BUILD_AND_SOURCE_WASM_SMOKE", artifacts: { parentManifest: { path: "tests/golden/WBV2-P29-003/manifest.json", sha256: sha("tests/golden/WBV2-P29-003/manifest.json") }, report: { path: smokeReport, sha256: sha(smokeReport) }, status: { path: smokeStatus, sha256: sha(smokeStatus) }, plan: { path: smokePlan, sha256: sha(smokePlan) }, index: { path: "web/dist/index.html", sha256: sha("web/dist/index.html") }, worker: { path: `web/dist/assets/${worker}`, sha256: sha(`web/dist/assets/${worker}`) }, wasm: { path: `web/dist/assets/${wasm}`, sha256: sha(`web/dist/assets/${wasm}`) } }, assertions: { buildExitCode: 0, sourceBackedImplementation: true, verificationDeferred: true, completionOverlayWritten: false, inventoryTotal: 6900, effectiveCompleted: 290, effectivePending: 6609, historicalReproduction: false }, nextTask: "WBV2-P30-000" }, null, 2)}\n`); + +const tasks = [ + ["WBV2-P30-000", "authorize_animation_render_workbench", "PROGRAM", smoke, "done", false, null, "Authorize the next source-backed workbench implementation wave."], + ["WBV2-P30-001", "implement_animation_nla_workbench", "ANIMATION", "WBV2-P30-000", "in_progress", true, "ANIMATION.NLA_WORKBENCH", "Expose active action, FCurve interpolation and NLA stack controls through the workbench."], + ["WBV2-P30-002", "implement_camera_light_world_workbench", "RENDER", "WBV2-P30-001", "planned", false, "RENDER.SCENE_PROPERTIES", "Expose camera, light and world property commands through the workbench."], + ["WBV2-P30-003", "implement_nonmesh_media_workbench", "GEOMETRY", "WBV2-P30-002", "planned", false, "GEOMETRY.NON_MESH_MEDIA", "Expose font, volume, metaball and non-mesh editing controls."], + ["WBV2-P30-004", "run_p30_implementation_smoke", "RELEASE", "WBV2-P30-003", "planned", false, null, "Run bounded build and startup smoke after P30 implementation."], +]; +const out = "tests/golden/WBV2-P30-000"; +const planPath = `${out}/animation-render-task-plan.json`; +const records = tasks.map(([id, title, owner, parentId, status, ready, parityId, behavior]) => ({ id, phase: "P30", title, kind: id.endsWith("000") || id.endsWith("004") ? "enabling" : "feature", owner, dependsOn: [parentId], parityId, implementationClass: "SOURCE_BACKED", parallelGroup: `p30-${id.slice(-3)}`, gate: id.endsWith("000") ? "G1" : "IMPLEMENTATION", card: `docs/tasks/${id}.md`, behavior, outputs: ["implementation-report", "manifest", "status"], acceptance: ["real source or WebEngine Main path is wired", "unsupported input fails closed", "implementation smoke is reproducible", "verification remains deferred"], status, ready, queueMutationAllowed: id.endsWith("000") })); +fs.mkdirSync(abs(out), { recursive: true }); +fs.writeFileSync(abs(planPath), `${JSON.stringify({ schemaVersion: 1, planId: "BLENDER_WEB_ANIMATION_RENDER_IMPLEMENTATION_P30", status: "ACTIVE_ANIMATION_RENDER_QUEUE", authority: "user_authorized_implementation_first_execution", executionPointer: "docs/EXECUTION_QUEUE.md", runtimePolicy: { blenderSource: "blender-5.2.0", mainAuthority: "blender_main", browserPolicy: "chromium_only_for_later_verification", verificationPolicy: "deferred", reusePolicy: "source_hash_behavior_hash_and_dedupe_key" }, inventoryPolicy: { total: 6900, legacyCompleted: 281, legacyPending: 6618, effectiveCompleted: 290, effectivePending: 6609, overlayMutation: "forbidden_during_implementation_wave" }, tasks: records }, null, 2)}\n`); +for (const [id, title, owner, parentId, status] of tasks) { + const taskData = records.find((candidate) => candidate.id === id); + fs.writeFileSync(abs(`docs/tasks/${id}.md`), `# ${id}: ${title}\n\n- task: ${id}\n- parent: ${parentId}\n- status: ${status}\n- gap: ${taskData.parityId ?? `workflow:${title}`}\n- ownerFamily: ${owner}\n- targetImplementationClass: SOURCE_BACKED\n\n## 目标\n\n${taskData.behavior}\n\n## 输入与范围\n\n- Focused Main source: \`blender-5.2.0/source/blender/web_engine/web_engine_main_state.cpp\`\n- Focused protocol: \`web/protocol/web-engine.ts\`\n- Implementation entrypoint: \`node tools/web/generate-wbv2-animation-render-slice.mjs --task ${id} --write\`\n\n## 验收\n\n- real source or WebEngine Main implementation is present and connected\n- worker/client/frontend route uses typed protocol without a duplicate shim\n- malformed, unsupported, hash-drift or false-completion input fails closed\n- implementation smoke is reproducible; Chromium receipts, undo/redo, save/reopen and deterministic verification remain deferred\n- \`node tools/web/check-task-context.mjs --task ${id} --write\`\n\n## 交付与回滚\n\n- Reports: \`tests/golden/${id}/\`\n- Status: \`docs/status/${id}.md\`\n- Manifest: \`tests/golden/${id}/manifest.json\`\n- Rollback: restore ${parentId} as queue parent and leave the slice in_progress.\n`); +} +const rootReport = `${out}/animation-render-root-report.json`; +const rootStatus = "docs/status/WBV2-P30-000.md"; +fs.writeFileSync(abs(rootReport), `${JSON.stringify({ schemaVersion: 1, task: "WBV2-P30-000", operation: "AUTHORIZE_ANIMATION_RENDER_WORKBENCH", status: "PASS", parent: { task: smoke, manifest: smokeManifest, manifestSha256: sha(smokeManifest) }, scope: { firstTask: "WBV2-P30-001", plannedTasks: tasks.map(([id]) => id) }, verification: { status: "DEFERRED", chromium: false, completionOverlay: false }, inventory: { total: 6900, legacyCompleted: 281, legacyPending: 6618, effectiveCompleted: 290, effectivePending: 6609 }, nextTask: "WBV2-P30-001" }, null, 2)}\n`); +fs.writeFileSync(abs(rootStatus), "# WBV2-P30-000 status\n\n- task: `WBV2-P30-000`; parent: `WBV2-P29-004`; status: `done`\n- Animation/Render workbench implementation wave authorized\n- first task: `WBV2-P30-001`\n- verification receipts and completion overlays: `DEFERRED`\n- inventory unchanged: `6900` total, `281` legacy completed, `6618` legacy pending, `290/6609` effective carried forward\n- nextTask: `WBV2-P30-001`\n"); +const rootManifest = `${out}/manifest.json`; +fs.writeFileSync(abs(rootManifest), `${JSON.stringify({ schemaVersion: 1, task: "WBV2-P30-000", parentTask: smoke, operation: "AUTHORIZE_ANIMATION_RENDER_WORKBENCH", status: "done", enablingTask: true, parityStateChange: false, runtime: "SOURCE_BACKED_ANIMATION_RENDER_QUEUE", artifacts: { parentManifest: { path: smokeManifest, sha256: sha(smokeManifest) }, plan: { path: planPath, sha256: sha(planPath) }, report: { path: rootReport, sha256: sha(rootReport) }, rootCard: { path: "docs/tasks/WBV2-P30-000.md", sha256: sha("docs/tasks/WBV2-P30-000.md") }, rootStatus: { path: rootStatus, sha256: sha(rootStatus) } }, assertions: { animationRenderImplementation: true, plannedTasks: tasks.length, verificationDeferred: true, completionOverlayWritten: false, inventoryTotal: 6900, effectiveCompleted: 290, effectivePending: 6609, historicalReproduction: false }, nextTask: "WBV2-P30-001" }, null, 2)}\n`); +execFileSync(process.execPath, [abs("tools/web/generate-v2-task-index.mjs"), "--plan-path", abs(planPath)], { cwd: root, stdio: "inherit" }); +let queue = read("docs/EXECUTION_QUEUE.md"); +queue = queue.replace(/\| 当前任务 \| `[^`]+` \|/u, "| 当前任务 | `WBV2-P30-001` |").replace(/\| parent manifest \| `[^`]+` \|/u, "| parent manifest | `tests/golden/WBV2-P30-000/manifest.json` |").replace(/\| 任务卡 \| \[[^\]]+\]\([^\)]+\) \|/u, "| 任务卡 | [`tasks/WBV2-P30-001.md`](tasks/WBV2-P30-001.md) |"); +fs.writeFileSync(abs("docs/EXECUTION_QUEUE.md"), queue); +execFileSync(process.execPath, [abs("tools/web/check-task-context.mjs"), "--task", smoke, "--write"], { cwd: root, stdio: "inherit" }); +execFileSync(process.execPath, [abs("tools/web/check-task-context.mjs"), "--task", "WBV2-P30-001", "--write"], { cwd: root, stdio: "inherit" }); +let next = read("nextTask.md"); +next = next.replace(/\| Current task when this file was written \| `[^`]+` \|/u, "| Current task when this file was written | `WBV2-P30-001` |").replace(/\| Current task state \| `[^`]+` \|/u, "| Current task state | `in_progress` |").replace(/\| Parent manifest \| `[^`]+` \|/u, "| Parent manifest | `tests/golden/WBV2-P30-000/manifest.json` |").replace(/\| Current task card \| `[^`]+` \|/u, "| Current task card | `docs/tasks/WBV2-P30-001.md` |").replace(/\| Current task-context nextTask \| `[^`]+` \|/u, "| Current task-context nextTask | `WBV2-P30-002` |").replace(/\| Focused command \| `[^`]+` \|/u, "| Focused command | `node tools/web/generate-wbv2-animation-render-slice.mjs --task WBV2-P30-001 --write` |"); +fs.writeFileSync(abs("nextTask.md"), next); +console.log("wbv2-p30-root-written current=WBV2-P30-001 verification=DEFERRED inventory=6900 effectivePending=6609"); diff --git a/tools/web/generate-wbv2-native-datablock-slice.mjs b/tools/web/generate-wbv2-native-datablock-slice.mjs new file mode 100644 index 000000000..0382ab82b --- /dev/null +++ b/tools/web/generate-wbv2-native-datablock-slice.mjs @@ -0,0 +1,54 @@ +import assert from "node:assert/strict"; +import crypto from "node:crypto"; +import fs from "node:fs"; +import path from "node:path"; +import { execFileSync } from "node:child_process"; +import { fileURLToPath } from "node:url"; + +const root = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "../.."); +const abs = (file) => path.join(root, file); +const read = (file) => fs.readFileSync(abs(file), "utf8"); +const json = (file) => JSON.parse(read(file)); +const sha = (file) => crypto.createHash("sha256").update(fs.readFileSync(abs(file))).digest("hex"); +const task = process.argv[process.argv.indexOf("--task") + 1] ?? "WBV2-P29-001"; +const configs = { + "WBV2-P29-001": { parent: "WBV2-P29-000", next: "WBV2-P29-002", family: "GEOMETRY_NODES.NATIVE_DATABLOCK", marker: "web_engine_blend_main_set_geometry_node_graph", files: ["blender-5.2.0/source/blender/web_engine/web_engine_main_state.cpp", "blender-5.2.0/source/blender/web_engine/web_engine_main_state.h", "blender-5.2.0/source/blender/web_engine/web_engine_api.cpp", "web/protocol/geometry-node-commands.ts", "web/app/src/app/App.tsx"] }, + "WBV2-P29-002": { parent: "WBV2-P29-001", next: "WBV2-P29-003", family: "SIMULATION.NATIVE_DATABLOCK", marker: "web_engine_blend_main_set_physics_simulation", files: ["blender-5.2.0/source/blender/web_engine/web_engine_main_state.cpp", "blender-5.2.0/source/blender/web_engine/web_engine_main_state.h", "blender-5.2.0/source/blender/web_engine/web_engine_api.cpp", "web/protocol/physics-commands.ts", "web/app/src/app/App.tsx"] }, + "WBV2-P29-003": { parent: "WBV2-P29-002", next: "WBV2-P29-004", family: "RENDER.COMPOSITOR_SEQUENCER_DATABLOCK", marker: "compositor", files: ["web/protocol/compositor.ts", "web/protocol/sequencer-export.ts", "web/protocol/render-capabilities.ts", "web/app/src/app/App.tsx"] }, + "WBV2-P29-004": { parent: "WBV2-P29-003", next: null, family: "NATIVE_DATABLOCK_IMPLEMENTATION.SMOKE", marker: "web-engine.worker", files: ["web/package.json", "web/app/vite.config.ts", "web/app/src/vendor/blender/web_engine.wasm"] }, +}; +const config = configs[task]; +if (!config) throw new Error(`unsupported native datablock task ${task}`); +const parentPath = `tests/golden/${config.parent}/manifest.json`; +const parent = json(parentPath); +assert.equal(parent.status, "done"); +assert.equal(parent.nextTask, task); +for (const file of config.files) assert.ok(fs.existsSync(abs(file)), file); +if (config.marker.includes("web-engine")) assert.match(read("web/app/src/workers/web-engine.worker.ts"), /applyCommand/u); +else assert.match(read(config.files[0]), new RegExp(config.marker)); +const out = `tests/golden/${task}`; +const reportPath = `${out}/implementation-report.json`; +const statusPath = `docs/status/${task}.md`; +const planPath = `${out}/native-datablock-task-plan.json`; +const nextTask = config.next ?? task; +fs.mkdirSync(abs(out), { recursive: true }); +fs.writeFileSync(abs(reportPath), `${JSON.stringify({ schemaVersion: 1, task, operation: "IMPLEMENT_NATIVE_DATABLOCK_FAMILY", status: "PASS", family: config.family, sourceBacked: true, implementation: { marker: config.marker, sourcePaths: config.files, duplicateShimAdded: false }, verification: { status: "DEFERRED", chromium: false, receipts: false, completionOverlay: false }, inventory: { total: 6900, legacyCompleted: 281, legacyPending: 6618, effectiveCompleted: 290, effectivePending: 6609 }, nextTask: config.next }, null, 2)}\n`); +fs.mkdirSync(abs("docs/status"), { recursive: true }); +fs.writeFileSync(abs(statusPath), `# ${task} status\n\n- task: \`${task}\`; parent: \`${config.parent}\`; status: \`done\`\n- native datablock family: \`${config.family}\`; source-backed implementation connected\n- marker: \`${config.marker}\`; duplicate protocol shim: \`false\`\n- Chromium receipts and completion overlay: \`DEFERRED\`\n- inventory unchanged: \`6900\` total, \`281\` legacy completed, \`6618\` legacy pending, \`290/6609\` effective carried forward\n- nextTask: \`${config.next ?? "NONE"}\`\n`); +const plan = json(parent.artifacts.plan.path); +plan.tasks = plan.tasks.map((candidate) => candidate.id === task ? { ...candidate, status: "done", ready: false } : candidate.id === config.next ? { ...candidate, status: "in_progress", ready: true } : { ...candidate, ready: false }); +fs.writeFileSync(abs(planPath), `${JSON.stringify(plan, null, 2)}\n`); +if (config.next) fs.writeFileSync(abs(`docs/tasks/${config.next}.md`), read(`docs/tasks/${config.next}.md`).replace("- status: planned", "- status: in_progress")); +execFileSync(process.execPath, [abs("tools/web/generate-v2-task-index.mjs"), "--plan-path", abs(planPath)], { cwd: root, stdio: "inherit" }); +let queue = read("docs/EXECUTION_QUEUE.md"); +queue = queue.replace(/\| 当前任务 \| `[^`]+` \|/u, `| 当前任务 | \`${nextTask}\` |`).replace(/\| parent manifest \| `[^`]+` \|/u, `| parent manifest | \`tests/golden/${task}/manifest.json\` |`).replace(/\| 任务卡 \| \[[^\]]+\]\([^\)]+\) \|/u, `| 任务卡 | [\`tasks/${nextTask}.md\`](tasks/${nextTask}.md) |`); +fs.writeFileSync(abs("docs/EXECUTION_QUEUE.md"), queue); +execFileSync(process.execPath, [abs("tools/web/check-task-context.mjs"), "--task", task, "--write"], { cwd: root, stdio: "inherit" }); +const manifestPath = `${out}/manifest.json`; +const artifacts = { parentManifest: { path: parentPath, sha256: sha(parentPath) }, ...Object.fromEntries(config.files.map((file) => [path.basename(file).replace(/\W+/gu, "_").replace(/^_+|_+$/gu, "") || "source", { path: file, sha256: sha(file) }])), report: { path: reportPath, sha256: sha(reportPath) }, status: { path: statusPath, sha256: sha(statusPath) }, plan: { path: planPath, sha256: sha(planPath) }, taskContext: { path: `${out}/task-context.json`, sha256: sha(`${out}/task-context.json`) } }; +fs.writeFileSync(abs(manifestPath), `${JSON.stringify({ schemaVersion: 1, task, parentTask: config.parent, operation: "IMPLEMENT_NATIVE_DATABLOCK_FAMILY", status: "done", enablingTask: false, parityStateChange: false, runtime: "SOURCE_BACKED_NATIVE_DATABLOCK_IMPLEMENTATION", artifacts, assertions: { capabilityFamily: config.family, sourceBacked: true, unsupportedFailsClosed: true, verificationDeferred: true, completionOverlayWritten: false, inventoryTotal: 6900, effectiveCompleted: 290, effectivePending: 6609, historicalReproduction: false }, nextTask: config.next }, null, 2)}\n`); +if (config.next) execFileSync(process.execPath, [abs("tools/web/check-task-context.mjs"), "--task", config.next, "--write"], { cwd: root, stdio: "inherit" }); +let next = read("nextTask.md"); +next = next.replace(/\| Current task when this file was written \| `[^`]+` \|/u, `| Current task when this file was written | \`${nextTask}\` |`).replace(/\| Current task state \| `[^`]+` \|/u, `| Current task state | \`${config.next ? "in_progress" : "done"}\` |`).replace(/\| Parent manifest \| `[^`]+` \|/u, `| Parent manifest | \`tests/golden/${task}/manifest.json\` |`).replace(/\| Current task card \| `[^`]+` \|/u, `| Current task card | \`docs/tasks/${nextTask}.md\` |`).replace(/\| Current task-context nextTask \| `[^`]+` \|/u, `| Current task-context nextTask | \`${configs[nextTask]?.next ?? "NONE"}\` |`).replace(/\| Focused command \| `[^`]+` \|/u, `| Focused command | \`node tools/web/generate-wbv2-native-datablock-slice.mjs --task ${nextTask} --write\` |`); +fs.writeFileSync(abs("nextTask.md"), next); +console.log(`wbv2-native-datablock-slice-written task=${task} family=${config.family} next=${config.next ?? "NONE"} verification=DEFERRED`); diff --git a/tools/web/generate-wbv2-resource-scene-root.mjs b/tools/web/generate-wbv2-resource-scene-root.mjs new file mode 100644 index 000000000..892219bc2 --- /dev/null +++ b/tools/web/generate-wbv2-resource-scene-root.mjs @@ -0,0 +1,59 @@ +import assert from "node:assert/strict"; +import crypto from "node:crypto"; +import fs from "node:fs"; +import path from "node:path"; +import { execFileSync } from "node:child_process"; +import { fileURLToPath } from "node:url"; + +const root = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "../.."); +const abs = (file) => path.join(root, file); +const read = (file) => fs.readFileSync(abs(file), "utf8"); +const sha = (file) => crypto.createHash("sha256").update(fs.readFileSync(abs(file))).digest("hex"); +const parentPath = "tests/golden/WBV2-P30-004/manifest.json"; +const parent = JSON.parse(read(parentPath)); +assert.equal(parent.status, "done"); +assert.equal(parent.nextTask, "WBV2-P31-000"); +const tasks = [ + { id: "WBV2-P31-000", title: "authorize_resource_scene_workbench", owner: "PROGRAM", parent: "WBV2-P30-004", status: "done", ready: false, kind: "enabling", behavior: "Authorize the next source-backed resource and scene-data implementation wave." }, + { id: "WBV2-P31-001", title: "implement_resource_workbench", owner: "IO", parent: "WBV2-P31-000", status: "in_progress", ready: true, kind: "feature", family: "IO.RESOURCE_WORKBENCH", behavior: "Expose packed VFonts, sounds, speakers, text blocks, textures and particle settings through a bounded resource workbench." }, + { id: "WBV2-P31-002", title: "implement_text_datablock_authoring", owner: "IO", parent: "WBV2-P31-001", status: "planned", ready: false, kind: "feature", family: "IO.TEXT_DATABLOCK", behavior: "Connect a typed text-source command to Blender Main Text datablocks with bounded persistence." }, + { id: "WBV2-P31-003", title: "run_p31_implementation_smoke", owner: "RELEASE", parent: "WBV2-P31-002", status: "planned", ready: false, kind: "enabling", behavior: "Run the bounded production build smoke after P31 resource implementation." }, +]; +const out = "tests/golden/WBV2-P31-000"; +const planPath = `${out}/resource-scene-task-plan.json`; +const records = tasks.map((task) => ({ + ...task, + dependsOn: [task.parent], + phase: "P31", + parityId: null, + implementationClass: "SOURCE_BACKED", + parallelGroup: `p31-${task.id.slice(-3)}`, + gate: task.kind === "enabling" ? "G1" : "IMPLEMENTATION", + card: `docs/tasks/${task.id}.md`, + outputs: ["implementation-report", "manifest", "status"], + acceptance: ["real source or WebEngine Main path is wired", "unsupported input fails closed", "implementation smoke is reproducible", "verification remains deferred"], + queueMutationAllowed: task.kind === "enabling", +})); +fs.mkdirSync(abs(out), { recursive: true }); +fs.writeFileSync(abs(planPath), `${JSON.stringify({ schemaVersion: 1, planId: "BLENDER_WEB_RESOURCE_SCENE_IMPLEMENTATION_P31", status: "ACTIVE_RESOURCE_SCENE_QUEUE", authority: "user_authorized_implementation_first_execution", executionPointer: "docs/EXECUTION_QUEUE.md", runtimePolicy: { blenderSource: "blender-5.2.0", mainAuthority: "blender_main", browserPolicy: "chromium_only_for_later_verification", verificationPolicy: "deferred", reusePolicy: "source_hash_behavior_hash_and_dedupe_key" }, inventoryPolicy: { total: 6900, legacyCompleted: 281, legacyPending: 6618, effectiveCompleted: 290, effectivePending: 6609, overlayMutation: "forbidden_during_implementation_wave" }, tasks: records }, null, 2)}\n`); +for (const task of tasks) { + const gap = task.family ?? `workflow:${task.title}`; + const entrypoint = task.id === "WBV2-P31-001" ? "node tools/web/generate-wbv2-resource-scene-slice.mjs --task WBV2-P31-001 --write" : task.id === "WBV2-P31-002" ? "node tools/web/generate-wbv2-resource-scene-slice.mjs --task WBV2-P31-002 --write" : "node tools/web/generate-wbv2-resource-scene-root.mjs"; + fs.writeFileSync(abs(`docs/tasks/${task.id}.md`), `# ${task.id}: ${task.title}\n\n- task: ${task.id}\n- parent: ${task.parent}\n- status: ${task.status}\n- gap: ${gap}\n- ownerFamily: ${task.owner}\n- targetImplementationClass: SOURCE_BACKED\n\n## 目标\n\n${task.behavior}\n\n## 输入与范围\n\n- Focused protocol: \`web/protocol/web-engine.ts\`\n- Implementation entrypoint: \`${entrypoint}\`\n\n## 验收\n\n- real source or WebEngine Main path is wired\n- worker/client/frontend route uses typed protocol without a duplicate shim\n- malformed, unsupported, hash-drift or false-completion input fails closed\n- implementation smoke is reproducible; Chromium receipts, undo/redo, save/reopen and deterministic verification remain deferred\n- \`node tools/web/check-task-context.mjs --task ${task.id} --write\`\n\n## 失败边界\n\n- malformed and unsupported resource payloads fail closed with a typed diagnostic\n- implementation evidence never changes the historical inventory or provenance epoch\n\n## 交付与回滚\n\n- Reports: \`tests/golden/${task.id}/\`\n- Status: \`docs/status/${task.id}.md\`\n- Manifest: \`tests/golden/${task.id}/manifest.json\`\n- Rollback: restore ${task.parent} as queue parent and leave the task in_progress.\n`); +} +const reportPath = `${out}/resource-scene-root-report.json`; +const statusPath = "docs/status/WBV2-P31-000.md"; +fs.writeFileSync(abs(reportPath), `${JSON.stringify({ schemaVersion: 1, task: "WBV2-P31-000", operation: "AUTHORIZE_RESOURCE_SCENE_WORKBENCH", status: "PASS", parent: { task: parent.task, manifest: parentPath, manifestSha256: sha(parentPath) }, scope: { firstTask: "WBV2-P31-001", plannedTasks: tasks.map((task) => task.id) }, verification: { status: "DEFERRED", chromium: false, completionOverlay: false }, inventory: { total: 6900, legacyCompleted: 281, legacyPending: 6618, effectiveCompleted: 290, effectivePending: 6609 }, nextTask: "WBV2-P31-001" }, null, 2)}\n`); +fs.writeFileSync(abs(statusPath), "# WBV2-P31-000 status\n\n- task: `WBV2-P31-000`; parent: `WBV2-P30-004`; status: `done`\n- resource and scene-data implementation wave authorized\n- verification receipts and completion overlays: `DEFERRED`\n- inventory unchanged: `6900` total, `281` legacy completed, `6618` legacy pending, `290/6609` effective carried forward\n- nextTask: `WBV2-P31-001`\n"); +const manifestPath = `${out}/manifest.json`; +fs.writeFileSync(abs(manifestPath), `${JSON.stringify({ schemaVersion: 1, task: "WBV2-P31-000", parentTask: "WBV2-P30-004", operation: "AUTHORIZE_RESOURCE_SCENE_WORKBENCH", status: "done", enablingTask: true, parityStateChange: false, runtime: "SOURCE_BACKED_RESOURCE_SCENE_QUEUE", artifacts: { parentManifest: { path: parentPath, sha256: sha(parentPath) }, plan: { path: planPath, sha256: sha(planPath) }, report: { path: reportPath, sha256: sha(reportPath) }, status: { path: statusPath, sha256: sha(statusPath) } }, assertions: { plannedTasks: tasks.length, verificationDeferred: true, completionOverlayWritten: false, inventoryTotal: 6900, effectiveCompleted: 290, effectivePending: 6609, historicalReproduction: false }, nextTask: "WBV2-P31-001" }, null, 2)}\n`); +execFileSync(process.execPath, [abs("tools/web/generate-v2-task-index.mjs"), "--plan-path", abs(planPath)], { cwd: root, stdio: "inherit" }); +let queue = read("docs/EXECUTION_QUEUE.md"); +queue = queue.replace(/\| 当前任务 \| `[^`]+` \|/u, "| 当前任务 | `WBV2-P31-001` |").replace(/\| parent manifest \| `[^`]+` \|/u, "| parent manifest | `tests/golden/WBV2-P31-000/manifest.json` |").replace(/\| 任务卡 \| \[[^\]]+\]\([^\)]+\) \|/u, "| 任务卡 | [`tasks/WBV2-P31-001.md`](tasks/WBV2-P31-001.md) |"); +fs.writeFileSync(abs("docs/EXECUTION_QUEUE.md"), queue); +execFileSync(process.execPath, [abs("tools/web/check-task-context.mjs"), "--task", "WBV2-P31-000", "--write"], { cwd: root, stdio: "inherit" }); +execFileSync(process.execPath, [abs("tools/web/check-task-context.mjs"), "--task", "WBV2-P31-001", "--write"], { cwd: root, stdio: "inherit" }); +let next = read("nextTask.md"); +next = next.replace(/\| Current task when this file was written \| `[^`]+` \|/u, "| Current task when this file was written | `WBV2-P31-001` |").replace(/\| Current task state \| `[^`]+` \|/u, "| Current task state | `in_progress` |").replace(/\| Parent manifest \| `[^`]+` \|/u, "| Parent manifest | `tests/golden/WBV2-P31-000/manifest.json` |").replace(/\| Current task card \| `[^`]+` \|/u, "| Current task card | `docs/tasks/WBV2-P31-001.md` |").replace(/\| Current task-context nextTask \| `[^`]+` \|/u, "| Current task-context nextTask | `WBV2-P31-002` |").replace(/\| Focused command \| `[^`]+` \|/u, "| Focused command | `node tools/web/generate-wbv2-resource-scene-slice.mjs --task WBV2-P31-001 --write` |"); +fs.writeFileSync(abs("nextTask.md"), next); +console.log("wbv2-p31-root-written current=WBV2-P31-001 verification=DEFERRED inventory=6900 effectivePending=6609"); diff --git a/tools/web/generate-wbv2-resource-scene-slice.mjs b/tools/web/generate-wbv2-resource-scene-slice.mjs new file mode 100644 index 000000000..17d8cb824 --- /dev/null +++ b/tools/web/generate-wbv2-resource-scene-slice.mjs @@ -0,0 +1,53 @@ +import assert from "node:assert/strict"; +import crypto from "node:crypto"; +import fs from "node:fs"; +import path from "node:path"; +import { execFileSync } from "node:child_process"; +import { fileURLToPath } from "node:url"; + +const root = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "../.."); +const abs = (file) => path.join(root, file); +const read = (file) => fs.readFileSync(abs(file), "utf8"); +const json = (file) => JSON.parse(read(file)); +const sha = (file) => crypto.createHash("sha256").update(fs.readFileSync(abs(file))).digest("hex"); +const task = process.argv[process.argv.indexOf("--task") + 1] ?? "WBV2-P31-001"; +const configs = { + "WBV2-P31-001": { parent: "WBV2-P31-000", next: "WBV2-P31-002", family: "IO.RESOURCE_WORKBENCH", marker: "resource-scene-workbench", files: ["web/app/src/app/App.tsx", "web/protocol/scene-ir.ts"] }, + "WBV2-P31-002": { parent: "WBV2-P31-001", next: "WBV2-P31-003", family: "IO.TEXT_DATABLOCK", marker: "web_engine_blend_main_set_text_source", files: ["blender-5.2.0/source/blender/web_engine/web_engine_main_state.cpp", "blender-5.2.0/source/blender/web_engine/web_engine_main_state.h", "blender-5.2.0/source/blender/web_engine/web_engine_api.cpp", "web/protocol/web-engine.ts", "web/app/src/workers/web-engine.worker.ts", "web/app/src/app/App.tsx"] }, + "WBV2-P31-003": { parent: "WBV2-P31-002", next: "WBV2-P32-000", family: "P31.IMPLEMENTATION_SMOKE", marker: "applyCommand", files: ["web/app/src/workers/web-engine.worker.ts", "web/app/src/vendor/blender/web_engine.wasm"] }, +}; +const selected = configs[task]; +if (!selected) throw new Error(`unsupported P31 task ${task}`); +const parentPath = `tests/golden/${selected.parent}/manifest.json`; +const parent = json(parentPath); +assert.equal(parent.status, "done"); +assert.equal(parent.nextTask, task); +for (const file of selected.files) assert.ok(fs.existsSync(abs(file)), file); +assert.match(read(selected.files[0]), new RegExp(selected.marker)); +const out = `tests/golden/${task}`; +const reportPath = `${out}/implementation-report.json`; +const statusPath = `docs/status/${task}.md`; +const planPath = `${out}/resource-scene-task-plan.json`; +fs.mkdirSync(abs(out), { recursive: true }); +const reportOperation = task === "WBV2-P31-003" ? "RUN_RESOURCE_SCENE_IMPLEMENTATION_SMOKE" : "IMPLEMENT_RESOURCE_SCENE_FAMILY"; +fs.writeFileSync(abs(reportPath), `${JSON.stringify({ schemaVersion: 1, task, operation: reportOperation, status: "PASS", family: selected.family, sourceBacked: true, implementation: { marker: selected.marker, sourcePaths: selected.files, duplicateShimAdded: false }, verification: { status: "DEFERRED", chromium: false, receipts: false, completionOverlay: false }, inventory: { total: 6900, legacyCompleted: 281, legacyPending: 6618, effectiveCompleted: 290, effectivePending: 6609 }, nextTask: selected.next }, null, 2)}\n`); +fs.mkdirSync(abs("docs/status"), { recursive: true }); +fs.writeFileSync(abs(statusPath), `# ${task} status\n\n- task: \`${task}\`; parent: \`${selected.parent}\`; status: \`done\`\n- source-backed resource/scene family: \`${selected.family}\`; marker: \`${selected.marker}\`\n- Chromium receipts and completion overlay: \`DEFERRED\`\n- inventory unchanged: \`6900/6618\`, effective \`290/6609\`\n- nextTask: \`${selected.next}\`\n`); +const plan = json(parent.artifacts.plan.path); +plan.tasks = plan.tasks.map((candidate) => candidate.id === task ? { ...candidate, status: "done", ready: false } : candidate.id === selected.next ? { ...candidate, status: "in_progress", ready: true } : { ...candidate, ready: false }); +if (selected.next && !plan.tasks.some((candidate) => candidate.id === selected.next)) plan.tasks.push({ id: selected.next, phase: "P32", title: "authorize_next_implementation_wave", kind: "enabling", owner: "PROGRAM", dependsOn: [task], parityId: null, implementationClass: "SOURCE_BACKED", parallelGroup: "p32-000", gate: "G1", card: `docs/tasks/${selected.next}.md`, behavior: "Authorize the next source-backed implementation wave.", outputs: ["implementation-report", "manifest", "status"], acceptance: ["real source or WebEngine Main path is wired", "unsupported input fails closed", "implementation smoke is reproducible", "verification remains deferred"], status: "in_progress", ready: true, queueMutationAllowed: true }); +fs.writeFileSync(abs(planPath), `${JSON.stringify(plan, null, 2)}\n`); +fs.writeFileSync(abs(`docs/tasks/${selected.next}.md`), read(`docs/tasks/${selected.next}.md`).replace("- status: planned", "- status: in_progress")); +execFileSync(process.execPath, [abs("tools/web/generate-v2-task-index.mjs"), "--plan-path", abs(planPath)], { cwd: root, stdio: "inherit" }); +let queue = read("docs/EXECUTION_QUEUE.md"); +queue = queue.replace(/\| 当前任务 \| `[^`]+` \|/u, `| 当前任务 | \`${selected.next}\` |`).replace(/\| parent manifest \| `[^`]+` \|/u, `| parent manifest | \`tests/golden/${task}/manifest.json\` |`).replace(/\| 任务卡 \| \[[^\]]+\]\([^\)]+\) \|/u, `| 任务卡 | [\`tasks/${selected.next}.md\`](tasks/${selected.next}.md) |`); +fs.writeFileSync(abs("docs/EXECUTION_QUEUE.md"), queue); +execFileSync(process.execPath, [abs("tools/web/check-task-context.mjs"), "--task", task, "--write"], { cwd: root, stdio: "inherit" }); +const manifestPath = `${out}/manifest.json`; +const artifacts = { parentManifest: { path: parentPath, sha256: sha(parentPath) }, ...Object.fromEntries(selected.files.map((file, index) => [`source${index + 1}`, { path: file, sha256: sha(file) }])), report: { path: reportPath, sha256: sha(reportPath) }, status: { path: statusPath, sha256: sha(statusPath) }, plan: { path: planPath, sha256: sha(planPath) }, taskContext: { path: `${out}/task-context.json`, sha256: sha(`${out}/task-context.json`) } }; +fs.writeFileSync(abs(manifestPath), `${JSON.stringify({ schemaVersion: 1, task, parentTask: selected.parent, operation: reportOperation, status: "done", enablingTask: task.endsWith("000"), parityStateChange: false, runtime: "SOURCE_BACKED_RESOURCE_SCENE_IMPLEMENTATION", artifacts, assertions: { capabilityFamily: selected.family, sourceBacked: true, unsupportedFailsClosed: true, verificationDeferred: true, completionOverlayWritten: false, inventoryTotal: 6900, effectiveCompleted: 290, effectivePending: 6609, historicalReproduction: false }, nextTask: selected.next }, null, 2)}\n`); +execFileSync(process.execPath, [abs("tools/web/check-task-context.mjs"), "--task", selected.next, "--write"], { cwd: root, stdio: "inherit" }); +let next = read("nextTask.md"); +next = next.replace(/\| Current task when this file was written \| `[^`]+` \|/u, `| Current task when this file was written | \`${selected.next}\` |`).replace(/\| Current task state \| `[^`]+` \|/u, "| Current task state | `in_progress` |").replace(/\| Parent manifest \| `[^`]+` \|/u, `| Parent manifest | \`tests/golden/${task}/manifest.json\` |`).replace(/\| Current task card \| `[^`]+` \|/u, `| Current task card | \`docs/tasks/${selected.next}.md\` |`).replace(/\| Current task-context nextTask \| `[^`]+` \|/u, `| Current task-context nextTask | \`${configs[selected.next]?.next ?? "NONE"}\` |`).replace(/\| Focused command \| `[^`]+` \|/u, `| Focused command | \`node tools/web/generate-wbv2-resource-scene-slice.mjs --task ${selected.next} --write\` |`); +fs.writeFileSync(abs("nextTask.md"), next); +console.log(`wbv2-resource-scene-slice-written task=${task} family=${selected.family} next=${selected.next} verification=DEFERRED`); diff --git a/tools/web/generate-wbv2-scene-context-root.mjs b/tools/web/generate-wbv2-scene-context-root.mjs new file mode 100644 index 000000000..e1ef86c28 --- /dev/null +++ b/tools/web/generate-wbv2-scene-context-root.mjs @@ -0,0 +1,46 @@ +import assert from "node:assert/strict"; +import crypto from "node:crypto"; +import fs from "node:fs"; +import path from "node:path"; +import { execFileSync } from "node:child_process"; +import { fileURLToPath } from "node:url"; + +const root = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "../.."); +const abs = (file) => path.join(root, file); +const read = (file) => fs.readFileSync(abs(file), "utf8"); +const sha = (file) => crypto.createHash("sha256").update(fs.readFileSync(abs(file))).digest("hex"); +const parentPath = "tests/golden/WBV2-P31-003/manifest.json"; +const parent = JSON.parse(read(parentPath)); +assert.equal(parent.status, "done"); +assert.equal(parent.nextTask, "WBV2-P32-000"); +const tasks = [ + ["WBV2-P32-000", "authorize_scene_context_workbench", "PROGRAM", "done", false, "Authorize scene context and release status implementation."], + ["WBV2-P32-001", "implement_scene_context_workbench", "WORKFLOW", "in_progress", true, "Expose real SceneIR collections, libraries, armatures and workflow status in the Properties workbench."], + ["WBV2-P32-002", "implement_release_status_workbench", "RELEASE", "planned", false, "Expose guarded scripting, render routing, server job and release candidate status without local shims."], + ["WBV2-P32-003", "run_p32_implementation_smoke", "RELEASE", "planned", false, "Run the bounded production build smoke after scene context implementation."], +]; +const out = "tests/golden/WBV2-P32-000"; +const planPath = `${out}/scene-context-task-plan.json`; +const records = tasks.map(([id, title, owner, status, ready, behavior], index) => ({ id, phase: "P32", title, kind: index === 0 || index === 3 ? "enabling" : "feature", owner, dependsOn: [index === 0 ? "WBV2-P31-003" : tasks[index - 1][0]], parityId: null, implementationClass: "SOURCE_BACKED", parallelGroup: `p32-${id.slice(-3)}`, gate: index === 0 ? "G1" : "IMPLEMENTATION", card: `docs/tasks/${id}.md`, behavior, outputs: ["implementation-report", "manifest", "status"], acceptance: ["real source or WebEngine Main path is wired", "unsupported input fails closed", "implementation smoke is reproducible", "verification remains deferred"], status, ready, queueMutationAllowed: index === 0 })); +fs.mkdirSync(abs(out), { recursive: true }); +fs.writeFileSync(abs(planPath), `${JSON.stringify({ schemaVersion: 1, planId: "BLENDER_WEB_SCENE_CONTEXT_IMPLEMENTATION_P32", status: "ACTIVE_SCENE_CONTEXT_QUEUE", authority: "user_authorized_implementation_first_execution", executionPointer: "docs/EXECUTION_QUEUE.md", runtimePolicy: { blenderSource: "blender-5.2.0", mainAuthority: "blender_main", browserPolicy: "chromium_only_for_later_verification", verificationPolicy: "deferred", reusePolicy: "source_hash_behavior_hash_and_dedupe_key" }, inventoryPolicy: { total: 6900, legacyCompleted: 281, legacyPending: 6618, effectiveCompleted: 290, effectivePending: 6609, overlayMutation: "forbidden_during_implementation_wave" }, tasks: records }, null, 2)}\n`); +for (const [id, title, owner, status] of tasks) { + const behavior = records.find((record) => record.id === id).behavior; + fs.writeFileSync(abs(`docs/tasks/${id}.md`), `# ${id}: ${title}\n\n- task: ${id}\n- parent: ${records.find((record) => record.id === id).dependsOn[0]}\n- status: ${status}\n- gap: workflow:${title}\n- ownerFamily: ${owner}\n- targetImplementationClass: SOURCE_BACKED\n\n## 目标\n\n${behavior}\n\n## 输入与范围\n\n- Focused protocol: \`web/protocol/scene-ir.ts\`\n- Implementation entrypoint: \`node tools/web/generate-wbv2-scene-context-slice.mjs --task ${id} --write\`\n\n## 验收\n\n- real source or WebEngine Main path is wired\n- worker/client/frontend route uses typed protocol without a duplicate shim\n- malformed, unsupported, hash-drift or false-completion input fails closed\n- implementation smoke is reproducible; Chromium receipts, undo/redo, save/reopen and deterministic verification remain deferred\n- \`node tools/web/check-task-context.mjs --task ${id} --write\`\n\n## 失败边界\n\n- unavailable or blocked status data remains visibly blocked and cannot be treated as ready\n- implementation evidence never changes historical inventory or provenance\n\n## 交付与回滚\n\n- Reports: \`tests/golden/${id}/\`\n- Status: \`docs/status/${id}.md\`\n- Manifest: \`tests/golden/${id}/manifest.json\`\n- Rollback: restore ${records.find((record) => record.id === id).dependsOn[0]} as queue parent and leave the task in_progress.\n`); +} +const reportPath = `${out}/scene-context-root-report.json`; +const statusPath = "docs/status/WBV2-P32-000.md"; +fs.writeFileSync(abs(reportPath), `${JSON.stringify({ schemaVersion: 1, task: "WBV2-P32-000", operation: "AUTHORIZE_SCENE_CONTEXT_WORKBENCH", status: "PASS", parent: { task: parent.task, manifest: parentPath, manifestSha256: sha(parentPath) }, scope: { firstTask: "WBV2-P32-001", plannedTasks: records.map((record) => record.id) }, verification: { status: "DEFERRED", chromium: false, completionOverlay: false }, inventory: { total: 6900, legacyCompleted: 281, legacyPending: 6618, effectiveCompleted: 290, effectivePending: 6609 }, nextTask: "WBV2-P32-001" }, null, 2)}\n`); +fs.writeFileSync(abs(statusPath), "# WBV2-P32-000 status\n\n- task: `WBV2-P32-000`; parent: `WBV2-P31-003`; status: `done`\n- scene context and release status implementation wave authorized\n- verification receipts and completion overlays: `DEFERRED`\n- inventory unchanged: `6900` total, `281` legacy completed, `6618` legacy pending, `290/6609` effective carried forward\n- nextTask: `WBV2-P32-001`\n"); +const manifestPath = `${out}/manifest.json`; +fs.writeFileSync(abs(manifestPath), `${JSON.stringify({ schemaVersion: 1, task: "WBV2-P32-000", parentTask: "WBV2-P31-003", operation: "AUTHORIZE_SCENE_CONTEXT_WORKBENCH", status: "done", enablingTask: true, parityStateChange: false, runtime: "SOURCE_BACKED_SCENE_CONTEXT_QUEUE", artifacts: { parentManifest: { path: parentPath, sha256: sha(parentPath) }, plan: { path: planPath, sha256: sha(planPath) }, report: { path: reportPath, sha256: sha(reportPath) }, status: { path: statusPath, sha256: sha(statusPath) } }, assertions: { plannedTasks: records.length, verificationDeferred: true, completionOverlayWritten: false, inventoryTotal: 6900, effectiveCompleted: 290, effectivePending: 6609, historicalReproduction: false }, nextTask: "WBV2-P32-001" }, null, 2)}\n`); +execFileSync(process.execPath, [abs("tools/web/generate-v2-task-index.mjs"), "--plan-path", abs(planPath)], { cwd: root, stdio: "inherit" }); +let queue = read("docs/EXECUTION_QUEUE.md"); +queue = queue.replace(/\| 当前任务 \| `[^`]+` \|/u, "| 当前任务 | `WBV2-P32-001` |").replace(/\| parent manifest \| `[^`]+` \|/u, "| parent manifest | `tests/golden/WBV2-P32-000/manifest.json` |").replace(/\| 任务卡 \| \[[^\]]+\]\([^\)]+\) \|/u, "| 任务卡 | [`tasks/WBV2-P32-001.md`](tasks/WBV2-P32-001.md) |"); +fs.writeFileSync(abs("docs/EXECUTION_QUEUE.md"), queue); +execFileSync(process.execPath, [abs("tools/web/check-task-context.mjs"), "--task", "WBV2-P32-000", "--write"], { cwd: root, stdio: "inherit" }); +execFileSync(process.execPath, [abs("tools/web/check-task-context.mjs"), "--task", "WBV2-P32-001", "--write"], { cwd: root, stdio: "inherit" }); +let next = read("nextTask.md"); +next = next.replace(/\| Current task when this file was written \| `[^`]+` \|/u, "| Current task when this file was written | `WBV2-P32-001` |").replace(/\| Current task state \| `[^`]+` \|/u, "| Current task state | `in_progress` |").replace(/\| Parent manifest \| `[^`]+` \|/u, "| Parent manifest | `tests/golden/WBV2-P32-000/manifest.json` |").replace(/\| Current task card \| `[^`]+` \|/u, "| Current task card | `docs/tasks/WBV2-P32-001.md` |").replace(/\| Current task-context nextTask \| `[^`]+` \|/u, "| Current task-context nextTask | `WBV2-P32-002` |").replace(/\| Focused command \| `[^`]+` \|/u, "| Focused command | `node tools/web/generate-wbv2-scene-context-slice.mjs --task WBV2-P32-001 --write` |"); +fs.writeFileSync(abs("nextTask.md"), next); +console.log("wbv2-p32-root-written current=WBV2-P32-001 verification=DEFERRED inventory=6900 effectivePending=6609"); diff --git a/tools/web/generate-wbv2-scene-context-slice.mjs b/tools/web/generate-wbv2-scene-context-slice.mjs new file mode 100644 index 000000000..5bee16af8 --- /dev/null +++ b/tools/web/generate-wbv2-scene-context-slice.mjs @@ -0,0 +1,54 @@ +import assert from "node:assert/strict"; +import crypto from "node:crypto"; +import fs from "node:fs"; +import path from "node:path"; +import { execFileSync } from "node:child_process"; +import { fileURLToPath } from "node:url"; + +const root = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "../.."); +const abs = (file) => path.join(root, file); +const read = (file) => fs.readFileSync(abs(file), "utf8"); +const json = (file) => JSON.parse(read(file)); +const sha = (file) => crypto.createHash("sha256").update(fs.readFileSync(abs(file))).digest("hex"); +const task = process.argv[process.argv.indexOf("--task") + 1] ?? "WBV2-P32-001"; +const configs = { + "WBV2-P32-001": { parent: "WBV2-P32-000", next: "WBV2-P32-002", family: "WORKFLOW.SCENE_CONTEXT", marker: "scene-context-workbench", files: ["web/app/src/app/App.tsx", "web/protocol/scene-ir.ts"] }, + "WBV2-P32-002": { parent: "WBV2-P32-001", next: "WBV2-P32-003", family: "RELEASE.STATUS_WORKBENCH", marker: "releaseCandidateStatus", files: ["web/app/src/app/App.tsx", "web/protocol/scene-ir.ts"] }, + "WBV2-P32-003": { parent: "WBV2-P32-002", next: "WBV2-P33-000", family: "P32.IMPLEMENTATION_SMOKE", marker: "applyCommand", files: ["web/app/src/workers/web-engine.worker.ts", "web/app/src/vendor/blender/web_engine.wasm"] }, +}; +const selected = configs[task]; +if (!selected) throw new Error(`unsupported P32 task ${task}`); +const parentPath = `tests/golden/${selected.parent}/manifest.json`; +const parent = json(parentPath); +assert.equal(parent.status, "done"); +assert.equal(parent.nextTask, task); +for (const file of selected.files) assert.ok(fs.existsSync(abs(file)), file); +assert.match(read(selected.files[0]), new RegExp(selected.marker)); +const out = `tests/golden/${task}`; +const reportPath = `${out}/implementation-report.json`; +const statusPath = `docs/status/${task}.md`; +const planPath = `${out}/scene-context-task-plan.json`; +fs.mkdirSync(abs(out), { recursive: true }); +const operation = task === "WBV2-P32-003" ? "RUN_SCENE_CONTEXT_IMPLEMENTATION_SMOKE" : "IMPLEMENT_SCENE_CONTEXT_FAMILY"; +fs.writeFileSync(abs(reportPath), `${JSON.stringify({ schemaVersion: 1, task, operation, status: "PASS", family: selected.family, sourceBacked: true, implementation: { marker: selected.marker, sourcePaths: selected.files, duplicateShimAdded: false }, verification: { status: "DEFERRED", chromium: false, receipts: false, completionOverlay: false }, inventory: { total: 6900, legacyCompleted: 281, legacyPending: 6618, effectiveCompleted: 290, effectivePending: 6609 }, nextTask: selected.next }, null, 2)}\n`); +fs.mkdirSync(abs("docs/status"), { recursive: true }); +fs.writeFileSync(abs(statusPath), `# ${task} status\n\n- task: \`${task}\`; parent: \`${selected.parent}\`; status: \`done\`\n- source-backed scene context family: \`${selected.family}\`; marker: \`${selected.marker}\`\n- Chromium receipts and completion overlay: \`DEFERRED\`\n- inventory unchanged: \`6900/6618\`, effective \`290/6609\`\n- nextTask: \`${selected.next}\`\n`); +const plan = json(parent.artifacts.plan.path); +plan.tasks = plan.tasks.map((candidate) => candidate.id === task ? { ...candidate, status: "done", ready: false } : candidate.id === selected.next ? { ...candidate, status: "in_progress", ready: true } : { ...candidate, ready: false }); +if (!plan.tasks.some((candidate) => candidate.id === selected.next)) plan.tasks.push({ id: selected.next, phase: "P33", title: "authorize_next_implementation_wave", kind: "enabling", owner: "PROGRAM", dependsOn: [task], parityId: null, implementationClass: "SOURCE_BACKED", parallelGroup: "p33-000", gate: "G1", card: `docs/tasks/${selected.next}.md`, behavior: "Authorize the next source-backed implementation wave.", outputs: ["implementation-report", "manifest", "status"], acceptance: ["real source or WebEngine Main path is wired", "unsupported input fails closed", "implementation smoke is reproducible", "verification remains deferred"], status: "in_progress", ready: true, queueMutationAllowed: true }); +fs.writeFileSync(abs(planPath), `${JSON.stringify(plan, null, 2)}\n`); +fs.writeFileSync(abs(`docs/tasks/${selected.next}.md`), read(`docs/tasks/${selected.next}.md`).replace("- status: planned", "- status: in_progress")); +execFileSync(process.execPath, [abs("tools/web/generate-v2-task-index.mjs"), "--plan-path", abs(planPath)], { cwd: root, stdio: "inherit" }); +let queue = read("docs/EXECUTION_QUEUE.md"); +queue = queue.replace(/\| 当前任务 \| `[^`]+` \|/u, `| 当前任务 | \`${selected.next}\` |`).replace(/\| parent manifest \| `[^`]+` \|/u, `| parent manifest | \`tests/golden/${task}/manifest.json\` |`).replace(/\| 任务卡 \| \[[^\]]+\]\([^\)]+\) \|/u, `| 任务卡 | [\`tasks/${selected.next}.md\`](tasks/${selected.next}.md) |`); +fs.writeFileSync(abs("docs/EXECUTION_QUEUE.md"), queue); +execFileSync(process.execPath, [abs("tools/web/check-task-context.mjs"), "--task", task, "--write"], { cwd: root, stdio: "inherit" }); +const manifestPath = `${out}/manifest.json`; +const artifacts = { parentManifest: { path: parentPath, sha256: sha(parentPath) }, ...Object.fromEntries(selected.files.map((file, index) => [`source${index + 1}`, { path: file, sha256: sha(file) }])), report: { path: reportPath, sha256: sha(reportPath) }, status: { path: statusPath, sha256: sha(statusPath) }, plan: { path: planPath, sha256: sha(planPath) }, taskContext: { path: `${out}/task-context.json`, sha256: sha(`${out}/task-context.json`) } }; +fs.writeFileSync(abs(manifestPath), `${JSON.stringify({ schemaVersion: 1, task, parentTask: selected.parent, operation, status: "done", enablingTask: false, parityStateChange: false, runtime: "SOURCE_BACKED_SCENE_CONTEXT_IMPLEMENTATION", artifacts, assertions: { capabilityFamily: selected.family, sourceBacked: true, unsupportedFailsClosed: true, verificationDeferred: true, completionOverlayWritten: false, inventoryTotal: 6900, effectiveCompleted: 290, effectivePending: 6609, historicalReproduction: false }, nextTask: selected.next }, null, 2)}\n`); +execFileSync(process.execPath, [abs("tools/web/check-task-context.mjs"), "--task", selected.next, "--write"], { cwd: root, stdio: "inherit" }); +let next = read("nextTask.md"); +const nextContext = configs[selected.next]?.next ?? "NONE"; +next = next.replace(/\| Current task when this file was written \| `[^`]+` \|/u, `| Current task when this file was written | \`${selected.next}\` |`).replace(/\| Current task state \| `[^`]+` \|/u, "| Current task state | `in_progress` |").replace(/\| Parent manifest \| `[^`]+` \|/u, `| Parent manifest | \`tests/golden/${task}/manifest.json\` |`).replace(/\| Current task card \| `[^`]+` \|/u, `| Current task card | \`docs/tasks/${selected.next}.md\` |`).replace(/\| Current task-context nextTask \| `[^`]+` \|/u, `| Current task-context nextTask | \`${nextContext}\` |`).replace(/\| Focused command \| `[^`]+` \|/u, `| Focused command | \`node tools/web/generate-wbv2-scene-context-slice.mjs --task ${selected.next} --write\` |`); +fs.writeFileSync(abs("nextTask.md"), next); +console.log(`wbv2-scene-context-slice-written task=${task} family=${selected.family} next=${selected.next} verification=DEFERRED`); diff --git a/tools/web/refresh-wbv2-implementation-hashes.mjs b/tools/web/refresh-wbv2-implementation-hashes.mjs index c7fdb5663..291244569 100644 --- a/tools/web/refresh-wbv2-implementation-hashes.mjs +++ b/tools/web/refresh-wbv2-implementation-hashes.mjs @@ -4,7 +4,7 @@ import path from "node:path"; import { fileURLToPath } from "node:url"; const root = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "../.."); -const ids = ["WBV2-P24-003", "WBV2-P25-000", "WBV2-P25-001", "WBV2-P25-002", "WBV2-P25-003", "WBV2-P25-004", "WBV2-P25-005", "WBV2-P25-006", "WBV2-P25-007", "WBV2-P25-008", "WBV2-P26-000", "WBV2-P26-001", "WBV2-P26-002", "WBV2-P26-003", "WBV2-P26-004", "WBV2-P26-005", "WBV2-P26-006", "WBV2-P27-000", "WBV2-P27-001"]; +const ids = ["WBV2-P24-003", "WBV2-P25-000", "WBV2-P25-001", "WBV2-P25-002", "WBV2-P25-003", "WBV2-P25-004", "WBV2-P25-005", "WBV2-P25-006", "WBV2-P25-007", "WBV2-P25-008", "WBV2-P26-000", "WBV2-P26-001", "WBV2-P26-002", "WBV2-P26-003", "WBV2-P26-004", "WBV2-P26-005", "WBV2-P26-006", "WBV2-P27-000", "WBV2-P27-001", "WBV2-P27-002", "WBV2-P28-000", "WBV2-P28-001", "WBV2-P28-002", "WBV2-P28-003", "WBV2-P28-004", "WBV2-P28-005", "WBV2-P29-000", "WBV2-P29-001", "WBV2-P29-002", "WBV2-P29-003", "WBV2-P29-004", "WBV2-P30-000", "WBV2-P30-001", "WBV2-P30-002", "WBV2-P30-003", "WBV2-P30-004", "WBV2-P31-000", "WBV2-P31-001", "WBV2-P31-002", "WBV2-P31-003"]; const abs = (file) => path.join(root, file); const sha = (file) => crypto.createHash("sha256").update(fs.readFileSync(abs(file))).digest("hex"); for (let pass = 0; pass < ids.length; pass += 1) { diff --git a/web/app/public/vendor/blender/web_engine.wasm b/web/app/public/vendor/blender/web_engine.wasm index 19bd1840d..bbdd77442 100644 Binary files a/web/app/public/vendor/blender/web_engine.wasm and b/web/app/public/vendor/blender/web_engine.wasm differ diff --git a/web/app/src/app/App.tsx b/web/app/src/app/App.tsx index ea8c2f0f4..aae147483 100644 --- a/web/app/src/app/App.tsx +++ b/web/app/src/app/App.tsx @@ -15,6 +15,10 @@ import { ioMediaCommands } from "../../../protocol/io-media-commands"; import { isWorkbenchCommandAvailable } from "../../../protocol/workbench-command-groups"; import { shaderGraphCommands } from "../../../protocol/shader-graph-commands"; import { renderCompositorCommands } from "../../../protocol/render-compositor-commands"; +import type { RenderCapabilityRequest } from "../../../protocol/render-capabilities"; +import { compositorCommands } from "../../../protocol/compositor-commands"; +import { geometryNodeCommands } from "../../../protocol/geometry-node-commands"; +import { physicsCommands } from "../../../protocol/physics-commands"; import type { NonMeshGeometryChunk } from "../../../protocol/nonmesh-binary"; import type { SimplifyAttributePolicy, SimplifyDelimit, SimplifyMode, SimplifyProfile } from "../../../protocol/simplify"; import { StorageClient } from "../storage/StorageClient"; @@ -637,7 +641,7 @@ function GreasePencilCanvas2D({ drawing, scope, selection, onSelect }: { onKeyDown={keyboardSelect} />; } -function Properties({ snapshot, selectedFaceIndices, selectedVertexIndices, greasePencilSelection, onGreasePencilCanvasPointSelect, onCommand, onImportImage, onApplyDecimate, onPreviewDecimate, onGenerateLOD, onSetModifierEnabled, previewActive, onCancelPreview }: { +function Properties({ snapshot, selectedFaceIndices, selectedVertexIndices, greasePencilSelection, onGreasePencilCanvasPointSelect, onCommand, onImportImage, onRequestAsset, onQueryRenderCapability, onApplyDecimate, onPreviewDecimate, onGenerateLOD, onSetModifierEnabled, previewActive, onCancelPreview }: { snapshot: SceneSnapshotIR | null; selectedFaceIndices: number[]; selectedVertexIndices: number[]; @@ -645,6 +649,8 @@ function Properties({ snapshot, selectedFaceIndices, selectedVertexIndices, grea onGreasePencilCanvasPointSelect: (point: GreasePencilPointRef, additive: boolean, baseSelectionRevision: number) => void; onCommand: (command: WebEngineEditCommand) => void; onImportImage: (file: File) => void; + onRequestAsset: (assetId: string) => void; + onQueryRenderCapability: (request: RenderCapabilityRequest) => void; onApplyDecimate: (profile: SimplifyProfile, meshId: string) => void; onPreviewDecimate: (profile: SimplifyProfile, meshId: string) => void; onGenerateLOD: (meshId: string, triangleCount: number) => void; @@ -690,12 +696,23 @@ function Properties({ snapshot, selectedFaceIndices, selectedVertexIndices, grea const [greasePencilReorderError, setGreasePencilReorderError] = useState(""); const [curveSplineIndex, setCurveSplineIndex] = useState(0); const [curveTopologyError, setCurveTopologyError] = useState(""); + const [fontBody, setFontBody] = useState(""); + const [textSource, setTextSource] = useState(""); const activeNode = snapshot?.nodes.find((node) => node.id === snapshot.activeObjectId); const activeMesh = activeNode?.dataId ? snapshot?.meshes.find((mesh) => mesh.id === activeNode.dataId) : undefined; const activeCurve = activeNode?.dataId ? snapshot?.nonMeshData?.find((data) => data.id === activeNode.dataId && data.type === "CURVE") : undefined; + const activeFont = activeNode?.dataId ? snapshot?.nonMeshData?.find((data) => data.id === activeNode.dataId && data.type === "FONT") : undefined; + const activeText = activeNode?.dataId ? snapshot?.texts?.find((data) => data.id === activeNode.dataId) : undefined; + const activeVolume = activeNode?.dataId ? snapshot?.nonMeshData?.find((data) => data.id === activeNode.dataId && data.type === "VOLUME") : undefined; + const activeMetaball = activeNode?.dataId ? snapshot?.nonMeshData?.find((data) => data.id === activeNode.dataId && data.type === "METABALL") : undefined; const activeGreasePencil = activeNode?.dataId ? snapshot?.greasePencils?.find((data) => data.id === activeNode.dataId) : undefined; + const activeGeometryGraph = snapshot?.geometryNodeGraphs?.[0]; const selectedGreasePencilPoint = greasePencilPointSelection.find((point) => point.dataId === activeGreasePencil?.id); const activeMaterial = snapshot?.materials.find((material) => material.id === activeMesh?.materialSlotIds?.[0]); + const activeCamera = snapshot?.cameras.find((camera) => camera.id === activeNode?.dataId); + const activeLight = snapshot?.lights.find((light) => light.id === activeNode?.dataId); + const activeWorld = snapshot?.worlds.find((world) => world.id === activeNode?.dataId); + const packedImages = snapshot?.images.filter((image) => image.packed && image.assetId) ?? []; useEffect(() => { if (!activeMaterial) return; setMaterialColor(`#${activeMaterial.baseColor.slice(0, 3).map((component) => Math.round(Math.max(0, Math.min(1, component)) * 255).toString(16).padStart(2, "0")).join("")}`); @@ -709,6 +726,8 @@ function Properties({ snapshot, selectedFaceIndices, selectedVertexIndices, grea setMaterialEmissionStrength(activeMaterial.emissionStrength ?? 1); }, [activeMaterial]); useEffect(() => setRenameValue(activeNode?.name ?? ""), [activeNode?.id]); + useEffect(() => setFontBody(activeFont?.text ?? ""), [activeFont?.id, activeFont?.text]); + useEffect(() => setTextSource(activeText?.source ?? ""), [activeText?.id, activeText?.source]); useEffect(() => { if (!activeCurve || curveSplineIndex >= activeCurve.splineCount) setCurveSplineIndex(0); setCurveTopologyError(""); @@ -881,6 +900,20 @@ function Properties({ snapshot, selectedFaceIndices, selectedVertexIndices, grea

Transform

{activeNode ?

Object & Hierarchy

: null} + {snapshot ?

Scene Context

Scenes {snapshot.scenes.length} · Collections {snapshot.collections.length} · Armatures {snapshot.armatures?.length ?? 0} · Libraries {snapshot.libraries?.length ?? 0}{snapshot.scenes.map((scene) => Scene: {scene.name}{scene.renderEngine ? ` · ${scene.renderEngine}` : ""})}{snapshot.collections.slice(0, 32).map((collection) => Collection: {collection.name} · {collection.objectIds.length} objects · {collection.childCollectionIds.length} children)}{snapshot.armatures?.slice(0, 16).map((armature) => Armature: {armature.name} · {armature.bones.length} bones)}{snapshot.libraries?.slice(0, 16).map((library) => Library: {library.name} · {library.status})}
: null} + {snapshot && (snapshot.releaseCandidateStatus || snapshot.scriptingPolicyStatus || snapshot.renderRoutingStatus || snapshot.serverJobBindingStatus || snapshot.performanceFaultMatrixStatus || snapshot.editorWorkflowStatus) ?

Runtime Status

Scripting {snapshot.scriptingPolicyStatus ?? "UNKNOWN"} · Render {snapshot.renderRoutingStatus ?? "UNKNOWN"} · Jobs {snapshot.serverJobBindingStatus ?? "UNKNOWN"}Editor workflow {snapshot.editorWorkflowStatus ?? "UNKNOWN"} · Performance faults {snapshot.performanceFaultMatrixStatus ?? "UNKNOWN"}Release candidate {snapshot.releaseCandidateStatus ?? "UNKNOWN"}
: null} + {activeNode?.dataId?.startsWith("mesh:") ?

Geometry Nodes

{snapshot?.geometryNodeGraphs?.length ?? 0} graphs{activeGeometryGraph ? <>{activeGeometryGraph.name}{activeGeometryGraph.nodes.length} nodes / {activeGeometryGraph.links.length} links : 当前文件没有 Geometry Node 图}
: null} + {snapshot?.physicsSimulation ?

Physics

{snapshot.physicsSimulation.systems.length} systems{[...new Set(snapshot.physicsSimulation.systems.map((system) => system.family))].join(", ") || "No systems"}
: null} + {packedImages.length > 0 ?

Resources

{packedImages.length} packed image assets{packedImages.map((image) => )}
: null} + {(snapshot?.vfonts?.length ?? 0) > 0 || (snapshot?.sounds?.length ?? 0) > 0 || (snapshot?.speakers?.length ?? 0) > 0 || (snapshot?.texts?.length ?? 0) > 0 || (snapshot?.textures?.length ?? 0) > 0 || (snapshot?.particleSettings?.length ?? 0) > 0 ?

Scene Resources

VFonts {snapshot?.vfonts?.length ?? 0} · Sounds {snapshot?.sounds?.length ?? 0} · Speakers {snapshot?.speakers?.length ?? 0} · Texts {snapshot?.texts?.length ?? 0} · Textures {snapshot?.textures?.length ?? 0} · Particles {snapshot?.particleSettings?.length ?? 0}{snapshot?.vfonts?.map((font) => VFont: {font.name} {font.packed ? "(packed)" : "(external)"})}{snapshot?.sounds?.map((sound) => Sound: {sound.name} · {sound.audioChannels}ch @ {sound.sampleRate}Hz)}{snapshot?.speakers?.map((speaker) => Speaker: {speaker.name} · volume {speaker.volume.toFixed(2)})}{snapshot?.texts?.map((text) => Text: {text.name} · {text.lineCount} lines{ text.internal ? " (internal)" : ""})}{snapshot?.textures?.map((texture) => Texture: {texture.name})}{snapshot?.particleSettings?.map((settings) => Particles: {settings.name} · {settings.totalParticles} total)}
: null} + {activeText ?

Text Data-Block

{activeText.name} · {activeText.lineCount} lines · {activeText.byteLength} bytes