Continue Blender Web parity task handoff
This commit is contained in:
@@ -33,6 +33,7 @@
|
||||
#include "DNA_genfile.h"
|
||||
#include "DNA_action_types.h"
|
||||
#include "DNA_anim_enums.h"
|
||||
#include "DNA_armature_types.h"
|
||||
#include "DNA_curve_enums.h"
|
||||
#include "DNA_lattice_types.h"
|
||||
#include "DNA_mask_types.h"
|
||||
@@ -334,6 +335,22 @@ std::vector<float> read_float_array(const SDNA &sdna,
|
||||
return result;
|
||||
}
|
||||
|
||||
std::vector<int> read_byte_array(const SDNA &sdna,
|
||||
const ElementRef &element,
|
||||
const std::string &member_name,
|
||||
const size_t maximum_values)
|
||||
{
|
||||
const std::optional<MemberInfo> member = find_member(sdna, element.type_name, member_name);
|
||||
if (!member || member->size <= 0) return {};
|
||||
const size_t value_count = std::min(maximum_values, size_t(member->size));
|
||||
if (!bytes_available(element, *member, value_count)) return {};
|
||||
const uint8_t *data = element.block->bytes.data() + element.offset + size_t(member->offset);
|
||||
std::vector<int> result;
|
||||
result.reserve(value_count);
|
||||
for (size_t index = 0; index < value_count; index++) result.push_back(int(data[index]));
|
||||
return result;
|
||||
}
|
||||
|
||||
std::string read_string(const SDNA &sdna,
|
||||
const ElementRef &element,
|
||||
const std::string &member_name)
|
||||
@@ -1365,7 +1382,8 @@ std::optional<json> editor_workflow_from_records(
|
||||
":region:" + std::to_string(regions.size())},
|
||||
{"kind", kind},
|
||||
{"visible", (flags & RGN_FLAG_HIDDEN) == 0}};
|
||||
if (std::strcmp(editor, "DOPE_SHEET") == 0 && std::strcmp(kind, "MAIN") == 0) {
|
||||
if ((std::strcmp(editor, "DOPE_SHEET") == 0 || std::strcmp(editor, "GRAPH") == 0) &&
|
||||
std::strcmp(kind, "MAIN") == 0) {
|
||||
if (const std::optional<json> view2d = editor_view2d_state(*blend.sdna, region)) {
|
||||
region_record["view2d"] = *view2d;
|
||||
}
|
||||
@@ -1983,6 +2001,10 @@ std::array<float, 16> element_matrix(const ParsedBlend &blend,
|
||||
return result;
|
||||
}
|
||||
|
||||
std::vector<uint64_t> read_raw_pointer_array(const ParsedBlend &blend,
|
||||
const uint64_t pointer,
|
||||
const size_t count);
|
||||
|
||||
json armature_from_data(const ParsedBlend &blend,
|
||||
const ElementRef &armature,
|
||||
const std::string &armature_id,
|
||||
@@ -2002,23 +2024,82 @@ json armature_from_data(const ParsedBlend &blend,
|
||||
const std::string name = read_string(*blend.sdna, bone, "name");
|
||||
if (name.empty()) return;
|
||||
const std::string id = "bone:" + armature_id + ":" + name;
|
||||
const std::vector<float> head = read_float_array(*blend.sdna, bone, "head", 3);
|
||||
const std::vector<float> tail = read_float_array(*blend.sdna, bone, "tail", 3);
|
||||
const std::vector<float> arm_head = read_float_array(*blend.sdna, bone, "arm_head", 3);
|
||||
const std::vector<float> arm_tail = read_float_array(*blend.sdna, bone, "arm_tail", 3);
|
||||
const std::vector<float> head = arm_head.size() == 3 ? arm_head :
|
||||
read_float_array(*blend.sdna, bone, "head", 3);
|
||||
const std::vector<float> tail = arm_tail.size() == 3 ? arm_tail :
|
||||
read_float_array(*blend.sdna, bone, "tail", 3);
|
||||
const std::array<float, 16> identity = {1, 0, 0, 0, 0, 1, 0, 0,
|
||||
0, 0, 1, 0, 0, 0, 0, 1};
|
||||
json entry = {{"id", id}};
|
||||
entry["name"] = name;
|
||||
const int64_t bone_flag = read_integer(*blend.sdna, bone, "flag").value_or(0);
|
||||
entry["selected"] = (bone_flag & BONE_SELECTED) != 0;
|
||||
entry["hidden"] = (bone_flag & BONE_HIDDEN_A) != 0;
|
||||
entry["connected"] = (bone_flag & BONE_CONNECTED) != 0;
|
||||
entry["parentId"] = parent_id.empty() ? json(nullptr) : json(parent_id);
|
||||
entry["head"] = float_array_or(head, {0.0f, 0.0f, 0.0f});
|
||||
entry["tail"] = float_array_or(tail, {0.0f, 0.0f, 1.0f});
|
||||
entry["restMatrix"] = element_matrix(blend, bone, "arm_mat", identity);
|
||||
if (const std::optional<ElementRef> color = embedded_element(*blend.sdna, bone, "color")) {
|
||||
json color_json = {{"paletteIndex", read_integer(*blend.sdna, *color, "palette_index").value_or(0)}};
|
||||
if (const std::optional<ElementRef> custom = embedded_element(*blend.sdna, *color, "custom")) {
|
||||
color_json["normal"] = read_byte_array(*blend.sdna, *custom, "solid", 4);
|
||||
color_json["select"] = read_byte_array(*blend.sdna, *custom, "select", 4);
|
||||
color_json["active"] = read_byte_array(*blend.sdna, *custom, "active", 4);
|
||||
color_json["flag"] = read_integer(*blend.sdna, *custom, "flag").value_or(0);
|
||||
}
|
||||
entry["color"] = std::move(color_json);
|
||||
}
|
||||
const auto pose_matrix = pose_matrices.find(name);
|
||||
if (pose_matrix != pose_matrices.end()) entry["poseMatrix"] = pose_matrix->second;
|
||||
bones.push_back(std::move(entry));
|
||||
for (const ElementRef &child : linked_list_elements(blend, bone, "childbase")) visit(child, id);
|
||||
};
|
||||
for (const ElementRef &root : linked_list_elements(blend, armature, "bonebase")) visit(root, "");
|
||||
return json{{"id", armature_id}, {"name", read_id_name(*blend.sdna, armature)}, {"bones", bones}};
|
||||
json bone_collections = json::array();
|
||||
const int64_t collection_count = std::clamp<int64_t>(
|
||||
read_integer(*blend.sdna, armature, "collection_array_num").value_or(0), 0, 10000);
|
||||
const std::optional<uint64_t> collection_pointer = read_pointer(*blend.sdna, armature, "collection_array");
|
||||
const std::vector<uint64_t> collection_pointers = collection_pointer && collection_count > 0 ?
|
||||
read_raw_pointer_array(blend,
|
||||
*collection_pointer,
|
||||
size_t(collection_count)) :
|
||||
std::vector<uint64_t>();
|
||||
std::vector<ElementRef> collection_elements;
|
||||
for (const uint64_t pointer : collection_pointers) {
|
||||
if (const std::optional<ElementRef> collection = element_for_pointer(blend, pointer)) {
|
||||
collection_elements.push_back(*collection);
|
||||
}
|
||||
}
|
||||
if (collection_elements.empty()) {
|
||||
collection_elements = linked_list_elements(blend, armature, "collections_legacy");
|
||||
}
|
||||
for (size_t index = 0; index < collection_elements.size(); index++) {
|
||||
const ElementRef &collection = collection_elements[index];
|
||||
const std::string name = read_string(*blend.sdna, collection, "name");
|
||||
if (name.empty()) continue;
|
||||
json members = json::array();
|
||||
for (const ElementRef &member : linked_list_elements(blend, collection, "bones")) {
|
||||
const std::optional<uint64_t> bone_pointer = read_pointer(*blend.sdna, member, "bone");
|
||||
if (!bone_pointer) continue;
|
||||
const std::optional<ElementRef> bone = element_for_pointer(blend, *bone_pointer);
|
||||
if (!bone) continue;
|
||||
const std::string bone_name = read_string(*blend.sdna, *bone, "name");
|
||||
if (!bone_name.empty()) members.push_back("bone:" + armature_id + ":" + bone_name);
|
||||
}
|
||||
bone_collections.push_back({{"id", "bone_collection:" + armature_id + ":" + name},
|
||||
{"name", name},
|
||||
{"index", int64_t(index)},
|
||||
{"visible", (read_integer(*blend.sdna, collection, "flags").value_or(0) & BONE_COLLECTION_VISIBLE) != 0},
|
||||
{"solo", (read_integer(*blend.sdna, collection, "flags").value_or(0) & BONE_COLLECTION_SOLO) != 0},
|
||||
{"boneIds", std::move(members)}});
|
||||
}
|
||||
return json{{"id", armature_id},
|
||||
{"name", read_id_name(*blend.sdna, armature)},
|
||||
{"bones", std::move(bones)},
|
||||
{"boneCollections", std::move(bone_collections)}};
|
||||
}
|
||||
|
||||
std::vector<int32_t> read_raw_int_array(const ParsedBlend &blend,
|
||||
@@ -2756,7 +2837,9 @@ void append_action_animation(const ParsedBlend &blend,
|
||||
const std::string &target_id,
|
||||
const uint64_t action_pointer,
|
||||
json &animations,
|
||||
std::unordered_set<std::string> &visited)
|
||||
std::unordered_set<std::string> &visited,
|
||||
const std::optional<int64_t> slot_handle = std::nullopt,
|
||||
const std::string &slot_identifier_hint = {})
|
||||
{
|
||||
const std::optional<ElementRef> action = element_for_pointer(blend, action_pointer);
|
||||
if (!action) return;
|
||||
@@ -2782,6 +2865,25 @@ void append_action_animation(const ParsedBlend &blend,
|
||||
const std::vector<uint64_t> data_pointers = data_pointer && data_count > 0 ?
|
||||
read_raw_pointer_array(blend, *data_pointer, size_t(data_count)) :
|
||||
std::vector<uint64_t>();
|
||||
const bool filter_slot = slot_handle.has_value() && *slot_handle != 0;
|
||||
std::optional<std::string> slot_identifier;
|
||||
int64_t slot_count = 0;
|
||||
const int64_t action_slot_count = std::clamp<int64_t>(
|
||||
read_integer(*blend.sdna, *action, "slot_array_num").value_or(0), 0, 10000);
|
||||
const std::optional<uint64_t> action_slot_pointer = read_pointer(*blend.sdna, *action, "slot_array");
|
||||
if (action_slot_pointer && action_slot_count > 0) {
|
||||
const std::vector<uint64_t> action_slot_pointers = read_raw_pointer_array(
|
||||
blend, *action_slot_pointer, size_t(action_slot_count));
|
||||
for (const uint64_t action_slot_value : action_slot_pointers) {
|
||||
const std::optional<ElementRef> action_slot = element_for_pointer(blend, action_slot_value);
|
||||
if (!action_slot) continue;
|
||||
slot_count++;
|
||||
if (slot_handle && read_integer(*blend.sdna, *action_slot, "handle").value_or(0) == *slot_handle) {
|
||||
slot_identifier = read_string(*blend.sdna, *action_slot, "identifier");
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!slot_identifier && !slot_identifier_hint.empty()) slot_identifier = slot_identifier_hint;
|
||||
if (layer_pointer && layer_count > 0) {
|
||||
const std::vector<uint64_t> layer_pointers = read_raw_pointer_array(blend, *layer_pointer, size_t(layer_count));
|
||||
for (const uint64_t layer_value : layer_pointers) {
|
||||
@@ -2805,6 +2907,7 @@ void append_action_animation(const ParsedBlend &blend,
|
||||
for (const uint64_t bag_value : bag_pointers) {
|
||||
const std::optional<ElementRef> bag = element_for_pointer(blend, bag_value);
|
||||
if (!bag) continue;
|
||||
if (filter_slot && read_integer(*blend.sdna, *bag, "slot_handle").value_or(0) != *slot_handle) continue;
|
||||
const int64_t fcurve_count = std::clamp<int64_t>(read_integer(*blend.sdna, *bag, "fcurve_array_num").value_or(0), 0, 100000);
|
||||
const std::optional<uint64_t> fcurve_pointer = read_pointer(*blend.sdna, *bag, "fcurve_array");
|
||||
if (!fcurve_pointer) continue;
|
||||
@@ -2828,13 +2931,20 @@ void append_action_animation(const ParsedBlend &blend,
|
||||
if (!std::isfinite(frame_start)) frame_start = action_frame_start;
|
||||
if (!std::isfinite(frame_end)) frame_end = action_frame_end;
|
||||
const std::string action_name = read_id_name(*blend.sdna, *action);
|
||||
animations.push_back({{"id", "action:" + (action_name.empty() ? std::to_string(action_pointer) : action_name) + ":" + target_id},
|
||||
json animation = {{"id", "action:" + (action_name.empty() ? std::to_string(action_pointer) : action_name) + ":" + target_id},
|
||||
{"name", action_name.empty() ? "Action" : action_name},
|
||||
{"targetId", target_id},
|
||||
{"frameStart", std::isfinite(frame_start) ? frame_start : 0.0f},
|
||||
{"frameEnd", std::isfinite(frame_end) ? frame_end : 0.0f},
|
||||
{"markers", std::move(markers)},
|
||||
{"channels", std::move(channels)}});
|
||||
{"channels", std::move(channels)}};
|
||||
if (slot_identifier) {
|
||||
animation["slotIdentifier"] = *slot_identifier;
|
||||
animation["slotHandle"] = slot_handle.value_or(0);
|
||||
animation["slotAssigned"] = slot_handle.value_or(0) != 0;
|
||||
animation["slotCount"] = slot_count;
|
||||
}
|
||||
animations.push_back(std::move(animation));
|
||||
}
|
||||
|
||||
json mesh_geometry_from_attributes(const ParsedBlend &blend,
|
||||
@@ -3370,7 +3480,14 @@ json scene_ir_from_blend(const ParsedBlend &blend,
|
||||
if (const std::optional<ElementRef> adt = element_for_pointer(blend, *adt_pointer)) {
|
||||
if (const std::optional<uint64_t> action_pointer = read_pointer(*blend.sdna, *adt, "action")) {
|
||||
linked_action_pointers.insert(*action_pointer);
|
||||
append_action_animation(blend, record.id, *action_pointer, animations, visited_animations);
|
||||
const int64_t slot_handle = read_integer(*blend.sdna, *adt, "slot_handle").value_or(0);
|
||||
append_action_animation(blend,
|
||||
record.id,
|
||||
*action_pointer,
|
||||
animations,
|
||||
visited_animations,
|
||||
slot_handle != 0 ? std::optional<int64_t>(slot_handle) : std::nullopt,
|
||||
read_string(*blend.sdna, *adt, "last_slot_identifier"));
|
||||
}
|
||||
int track_index = 0;
|
||||
for (const ElementRef &track : linked_list_elements(blend, *adt, "nla_tracks")) {
|
||||
@@ -3393,6 +3510,8 @@ json scene_ir_from_blend(const ParsedBlend &blend,
|
||||
const int64_t strip_type = read_integer(*blend.sdna, strip, "type").value_or(0);
|
||||
const int64_t blend_mode = read_integer(*blend.sdna, strip, "blendmode").value_or(0);
|
||||
const int64_t extend_mode = read_integer(*blend.sdna, strip, "extendmode").value_or(0);
|
||||
const int64_t action_slot_handle = read_integer(*blend.sdna, strip, "action_slot_handle").value_or(0);
|
||||
const std::string action_slot_identifier = read_string(*blend.sdna, strip, "last_slot_identifier");
|
||||
const char *strip_type_name = strip_type == 0 ? "CLIP" : strip_type == 1 ? "TRANSITION" :
|
||||
strip_type == 2 ? "META" : strip_type == 3 ? "SOUND" : "UNKNOWN";
|
||||
json strip_ir = {
|
||||
@@ -3415,6 +3534,9 @@ json scene_ir_from_blend(const ParsedBlend &blend,
|
||||
{"selected", (strip_flag & (1 << 1)) != 0},
|
||||
{"reverse", (strip_flag & (1 << 11)) != 0},
|
||||
{"useTimeWarp", (strip_flag & (1 << 6)) != 0},
|
||||
{"actionSlotHandle", action_slot_handle},
|
||||
{"actionSlotIdentifier", action_slot_identifier},
|
||||
{"actionSlotAssigned", action_slot_handle != 0},
|
||||
{"stripType", strip_type_name}};
|
||||
if (!action_pointer) strip_ir["unsupportedReason"] = "NLA Action data-block is missing";
|
||||
else if (blend_mode == 2 || blend_mode < 0 || blend_mode > 4) strip_ir["unsupportedReason"] = "NLA blend mode is outside the finite subset";
|
||||
@@ -3459,11 +3581,31 @@ json scene_ir_from_blend(const ParsedBlend &blend,
|
||||
for (const ElementRef &constraint : linked_list_elements(blend, element, "constraints")) {
|
||||
const int64_t constraint_type = read_integer(*blend.sdna, constraint, "type").value_or(0);
|
||||
const int64_t flag = read_integer(*blend.sdna, constraint, "flag").value_or(0);
|
||||
constraints.push_back({{"name", read_string(*blend.sdna, constraint, "name")},
|
||||
json constraint_ir = {{"name", read_string(*blend.sdna, constraint, "name")},
|
||||
{"typeCode", constraint_type},
|
||||
{"type", "CONSTRAINT_" + std::to_string(constraint_type)},
|
||||
{"enabled", (flag & 512) == 0},
|
||||
{"influence", read_float(*blend.sdna, constraint, "enforce").value_or(1.0f)}});
|
||||
{"influence", read_float(*blend.sdna, constraint, "enforce").value_or(1.0f)}};
|
||||
if (constraint_type == 12) {
|
||||
const std::optional<uint64_t> constraint_data_pointer = read_pointer(*blend.sdna, constraint, "data");
|
||||
if (constraint_data_pointer) {
|
||||
const std::optional<ElementRef> constraint_data = element_for_pointer(blend, *constraint_data_pointer);
|
||||
if (constraint_data) {
|
||||
const int64_t action_slot_handle = read_integer(*blend.sdna, *constraint_data, "action_slot_handle").value_or(0);
|
||||
const std::optional<uint64_t> action_pointer = read_pointer(*blend.sdna, *constraint_data, "act");
|
||||
if (action_pointer) {
|
||||
if (const std::optional<ElementRef> action = element_for_pointer(blend, *action_pointer)) {
|
||||
const std::string action_name = read_id_name(*blend.sdna, *action);
|
||||
constraint_ir["actionId"] = "action:" + (action_name.empty() ? std::to_string(*action_pointer) : action_name);
|
||||
}
|
||||
}
|
||||
constraint_ir["actionSlotHandle"] = action_slot_handle;
|
||||
constraint_ir["actionSlotIdentifier"] = read_string(*blend.sdna, *constraint_data, "last_slot_identifier");
|
||||
constraint_ir["actionSlotAssigned"] = action_slot_handle != 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
constraints.push_back(std::move(constraint_ir));
|
||||
}
|
||||
if (!constraints.empty()) node["constraints"] = std::move(constraints);
|
||||
if (const std::optional<uint64_t> adt_pointer = read_pointer(*blend.sdna, element, "adt")) {
|
||||
|
||||
@@ -4,17 +4,17 @@
|
||||
|
||||
本页是唯一的当前任务指针,不保存历史任务表、实现日志或长期规划。领取任务前只读取本页、当前任务上下文、parent manifest 和 parent status;完整规则见 [`CONTEXT_BUDGET.md`](CONTEXT_BUDGET.md)。
|
||||
|
||||
连续接续入口见 [`nextTask.md`](../nextTask.md):用户发送“按 nextTask.md 接续执行”时,按该流程从当前指针开始;每次只完成一个任务并在新请求中用 fresh compact context 继续。
|
||||
连续接续入口见 [`nextTask.md`](../nextTask.md):用户发送“按 nextTask.md 接续执行”时,进入连续模式;每个迭代只完成一个任务并以 fresh compact context 交接,成功后自动读取新指针继续,直到失败、阻塞、预算/环境/传输异常、闭合门或用户要求停止。
|
||||
|
||||
## 当前指针
|
||||
|
||||
| 字段 | 值 |
|
||||
| --- | --- |
|
||||
| 里程碑 | M16 Main、Mesh、Modifier、Sculpt |
|
||||
| 当前任务 | `M16-GAP-00227` |
|
||||
| parent manifest | `tests/golden/M16-GAP-00226/manifest.json` |
|
||||
| 任务卡 | [`tasks/M16-GAP-00227.md`](tasks/M16-GAP-00227.md) |
|
||||
| 专项验收 | `npm --prefix web run test:generated-gap -- --task M16-GAP-00227` |
|
||||
| 当前任务 | `M16-GAP-00264` |
|
||||
| parent manifest | `tests/golden/M16-GAP-00263/manifest.json` |
|
||||
| 任务卡 | [`tasks/M16-GAP-00264.md`](tasks/M16-GAP-00264.md) |
|
||||
| 专项验收 | `npm --prefix web run test:generated-gap -- --task M16-GAP-00264` |
|
||||
|
||||
领取前执行:
|
||||
|
||||
|
||||
16
docs/status/M16-GAP-00175.md
Normal file
16
docs/status/M16-GAP-00175.md
Normal file
@@ -0,0 +1,16 @@
|
||||
# M16-GAP-00175 Status
|
||||
|
||||
status: done
|
||||
task: anim.driver_button_edit operator LOCAL_EXACT slice
|
||||
updated: 2026-08-21 America/New_York
|
||||
|
||||
scope:
|
||||
|
||||
- The minimal fixture contains one scripted driver on `drive_target`; Blender desktop invokes `ANIM_OT_driver_button_edit` in the active Properties context (`poll=true`, `INTERFACE`) and preserves the driver without a Main mutation.
|
||||
|
||||
evidence:
|
||||
|
||||
- Desktop and WASM/Main expose the same driver (`["drive_target"]`, expression `frame * 2.5 + 1.25`, scripted, no variables); save/reopen is exact and malformed Blend input is rejected without Main mutation.
|
||||
- Fixture generation, desktop checker, npm comparator, direct comparator, and artifact hashing passed. The edit operator is intentionally interface-only and leaves the driver unchanged.
|
||||
|
||||
nextTask: `M16-GAP-00176`
|
||||
16
docs/status/M16-GAP-00176.md
Normal file
16
docs/status/M16-GAP-00176.md
Normal file
@@ -0,0 +1,16 @@
|
||||
# M16-GAP-00176 Status
|
||||
|
||||
status: done
|
||||
task: anim.driver_button_remove operator LOCAL_EXACT slice
|
||||
updated: 2026-08-21 America/New_York
|
||||
|
||||
scope:
|
||||
|
||||
- The minimal fixture starts with one scripted driver on `drive_target`; foreground Chromium-compatible Blender UI activates the RNA button and invokes `ANIM_OT_driver_button_remove(all=true)` (`poll=true`, `FINISHED`), removing that driver from Main.
|
||||
|
||||
evidence:
|
||||
|
||||
- Desktop and WASM/Main expose the same final object with no drivers; save/reopen is exact and malformed Blend input is rejected without Main mutation.
|
||||
- Fixture generation, foreground desktop checker, npm comparator, direct comparator, and artifact hashing passed. The checker is idempotent for the already-removed exact fixture.
|
||||
|
||||
nextTask: `M16-GAP-00177`
|
||||
16
docs/status/M16-GAP-00177.md
Normal file
16
docs/status/M16-GAP-00177.md
Normal file
@@ -0,0 +1,16 @@
|
||||
# M16-GAP-00177 Status
|
||||
|
||||
status: done
|
||||
task: anim.end_frame_set operator LOCAL_EXACT slice
|
||||
updated: 2026-08-21 America/New_York
|
||||
|
||||
scope:
|
||||
|
||||
- The minimal scene starts at frame 42 with a scene range of 1-120; a foreground animation-area context invokes `ANIM_OT_end_frame_set` (`poll=true`, `FINISHED`) and sets the scene end frame to 42.
|
||||
|
||||
evidence:
|
||||
|
||||
- Desktop and WASM/Main expose the same frame state (`current=42`, `start=1`, `end=42`); save/reopen is exact and malformed Blend input is rejected without Main mutation.
|
||||
- Fixture generation, foreground desktop checker, npm comparator, direct comparator, and artifact hashing passed.
|
||||
|
||||
nextTask: `M16-GAP-00178`
|
||||
16
docs/status/M16-GAP-00178.md
Normal file
16
docs/status/M16-GAP-00178.md
Normal file
@@ -0,0 +1,16 @@
|
||||
# M16-GAP-00178 Status
|
||||
|
||||
status: done
|
||||
task: anim.keyframe_clear_button operator LOCAL_EXACT slice
|
||||
updated: 2026-08-21 America/New_York
|
||||
|
||||
scope:
|
||||
|
||||
- The minimal fixture animates one scalar custom RNA property, `clear_target`, on `WebGapAnimKeyframeClearButtonObject` at frames 1, 3, and 5. A foreground Properties context activates that RNA button and invokes `ANIM_OT_keyframe_clear_button(all=true)` (`poll=true`, `FINISHED`), leaving the Action with no F-Curves.
|
||||
|
||||
evidence:
|
||||
|
||||
- Desktop evidence records the property changing from three selected keyframes to none; WASM/Main reads the original channel as `["clear_target"][0]` and the cleared fixture with no matching animation. Save/reopen is exact and malformed Blend input is rejected without Main mutation.
|
||||
- Fixture generation, foreground desktop checker, npm comparator, direct comparator, and artifact hashing passed. The checker and comparator are idempotent for the already-cleared exact fixture while retaining the original `before` evidence.
|
||||
|
||||
nextTask: `M16-GAP-00179`
|
||||
16
docs/status/M16-GAP-00179.md
Normal file
16
docs/status/M16-GAP-00179.md
Normal file
@@ -0,0 +1,16 @@
|
||||
# M16-GAP-00179 Status
|
||||
|
||||
status: done
|
||||
task: anim.keyframe_clear_v3d operator LOCAL_EXACT slice
|
||||
updated: 2026-08-21 America/New_York
|
||||
|
||||
scope:
|
||||
|
||||
- The minimal fixture selects one object with a scalar `clear_target` Action at frames 1, 3, and 5. A foreground `VIEW_3D` context invokes `ANIM_OT_keyframe_clear_v3d(confirm=false)` (`poll=true`, `FINISHED`), removing all editable F-Curves from the selected object's Action.
|
||||
|
||||
evidence:
|
||||
|
||||
- Desktop evidence records the selected/active object changing from three selected keyframes to no F-Curves; WASM/Main reads the original channel as `["clear_target"][0]` and the cleared fixture with no matching animation. Save/reopen is exact and malformed Blend input is rejected without Main mutation.
|
||||
- Fixture generation, foreground V3D desktop checker, npm comparator, direct comparator, and artifact hashing passed. The checker and comparator are idempotent for the already-cleared exact fixture while retaining the original `before` evidence.
|
||||
|
||||
nextTask: `M16-GAP-00180`
|
||||
16
docs/status/M16-GAP-00180.md
Normal file
16
docs/status/M16-GAP-00180.md
Normal file
@@ -0,0 +1,16 @@
|
||||
# M16-GAP-00180 Status
|
||||
|
||||
status: done
|
||||
task: anim.keyframe_clear_vse operator LOCAL_EXACT slice
|
||||
updated: 2026-08-21 America/New_York
|
||||
|
||||
scope:
|
||||
|
||||
- The minimal fixture contains one selected image strip with a Scene Action animating `blend_alpha` at frames 1, 3, and 5. A real foreground `SEQUENCE_EDITOR` context invokes `ANIM_OT_keyframe_clear_vse(confirm=false)` (`poll=true`, `FINISHED`), removing the selected strip's editable F-Curve while preserving the strip and its evaluated value.
|
||||
|
||||
evidence:
|
||||
|
||||
- Desktop evidence records the selected/active strip changing from three selected keyframes to no F-Curves. WASM/Main reads the same Scene Action channel before clearing and no matching animation from the cleared fixture. Save/reopen is exact and malformed Blend input is rejected without Main mutation.
|
||||
- Fixture generation, foreground VSE desktop checker, npm comparator, direct comparator, and artifact hashing passed. The checker is idempotent for the already-cleared exact fixture while retaining the original `before` evidence.
|
||||
|
||||
nextTask: `M16-GAP-00181`
|
||||
17
docs/status/M16-GAP-00181.md
Normal file
17
docs/status/M16-GAP-00181.md
Normal file
@@ -0,0 +1,17 @@
|
||||
# M16-GAP-00181 Status
|
||||
|
||||
status: done
|
||||
task: anim.keyframe_delete operator LOCAL_EXACT slice
|
||||
updated: 2026-08-22 America/New_York
|
||||
|
||||
scope:
|
||||
|
||||
- The minimal fixture contains one selected object with a custom `delete_target` property and an Action keyed at frames 1, 3, and 5. A dedicated active Keying Set targets that property. A real foreground `VIEW_3D` context invokes `ANIM_OT_keyframe_delete(type=WebGapAnimKeyframeDeleteSet)` (`poll=true`, `FINISHED`) at frame 3, deleting only the current keyframe and preserving the two surrounding keys.
|
||||
|
||||
evidence:
|
||||
|
||||
- Desktop evidence records the selected/active object and active Keying Set before deletion, then the Action changing from `[1, 3, 5]` to `[1, 5]`; the custom property remains at 3.0. Save/reopen is exact.
|
||||
- WASM/Main reads the same fixture Action as one `[\"delete_target\"][0]` channel with three keyframes before the operation fixture and two keyframes after it. WASM save/reopen is exact, and malformed Blend input is rejected without Main mutation.
|
||||
- Fixture generation, foreground `VIEW_3D` checker, npm comparator, direct comparator, idempotent rerun, and artifact hashing passed. No production reader or protocol change was required because the existing generic Action/F-Curve reader exposes this custom-property channel.
|
||||
|
||||
nextTask: `M16-GAP-00182`
|
||||
17
docs/status/M16-GAP-00182.md
Normal file
17
docs/status/M16-GAP-00182.md
Normal file
@@ -0,0 +1,17 @@
|
||||
# M16-GAP-00182 Status
|
||||
|
||||
status: done
|
||||
task: anim.keyframe_delete_button operator LOCAL_EXACT slice
|
||||
updated: 2026-08-22 America/New_York
|
||||
|
||||
scope:
|
||||
|
||||
- The minimal fixture contains one selected object with a custom `delete_target` property and an Action keyed at frames 1, 3, and 5. A registered Properties panel exposes the animated property as a real UI button. A foreground Properties context invokes `ANIM_OT_keyframe_delete_button(all=true)` through that active button at frame 3 (`poll=true`, `FINISHED`), deleting only the current keyframe and preserving the two surrounding keys.
|
||||
|
||||
evidence:
|
||||
|
||||
- Desktop evidence records the selected/active object changing from `[1, 3, 5]` to `[1, 5]`; the custom property remains at 3.0 and save/reopen is exact.
|
||||
- WASM/Main reads the same Action as one `[\"delete_target\"][0]` channel with three keyframes before the operation fixture and two keyframes after it. WASM save/reopen is exact, and malformed Blend input is rejected without Main mutation.
|
||||
- Fixture generation, foreground Properties UI checker, npm comparator, direct idempotent comparator, and artifact hashing passed. No production reader or protocol change was required because the existing generic Action/F-Curve reader exposes this custom-property channel.
|
||||
|
||||
nextTask: `M16-GAP-00183`
|
||||
17
docs/status/M16-GAP-00183.md
Normal file
17
docs/status/M16-GAP-00183.md
Normal file
@@ -0,0 +1,17 @@
|
||||
# M16-GAP-00183 Status
|
||||
|
||||
status: done
|
||||
task: anim.keyframe_delete_by_name operator LOCAL_EXACT slice
|
||||
updated: 2026-08-22 America/New_York
|
||||
|
||||
scope:
|
||||
|
||||
- The minimal fixture contains one selected object with a custom `delete_target` property and an Action keyed at frames 1, 3, and 5. A named Keying Set targets that property. A foreground `VIEW_3D` context invokes `ANIM_OT_keyframe_delete_by_name(type=WebGapAnimKeyframeDeleteByNameSet)` (`poll=true`, `FINISHED`) at frame 3, deleting only the current keyframe and preserving the two surrounding keys.
|
||||
|
||||
evidence:
|
||||
|
||||
- Desktop evidence records the selected/active object and named Keying Set changing from `[1, 3, 5]` to `[1, 5]`; the custom property remains at 3.0 and save/reopen is exact.
|
||||
- WASM/Main reads the same Action as one `[\"delete_target\"][0]` channel with three keyframes before the operation fixture and two keyframes after it. WASM save/reopen is exact, and malformed Blend input is rejected without Main mutation.
|
||||
- Fixture generation, foreground `VIEW_3D` checker, npm comparator, direct idempotent comparator, and artifact hashing passed. No production reader or protocol change was required because the existing generic Action/F-Curve reader exposes this custom-property channel.
|
||||
|
||||
nextTask: `M16-GAP-00184`
|
||||
17
docs/status/M16-GAP-00184.md
Normal file
17
docs/status/M16-GAP-00184.md
Normal file
@@ -0,0 +1,17 @@
|
||||
# M16-GAP-00184 Status
|
||||
|
||||
status: done
|
||||
task: anim.keyframe_delete_v3d operator LOCAL_EXACT slice
|
||||
updated: 2026-08-22 America/New_York
|
||||
|
||||
scope:
|
||||
|
||||
- The minimal fixture contains one selected/active object with a custom `delete_target` property and an Action keyed at frames 1, 3, and 5. A foreground `VIEW_3D` context invokes `ANIM_OT_keyframe_delete_v3d(confirm=false)` (`poll=true`, `FINISHED`) at frame 3, deleting only the current keyframe and preserving the two surrounding keys.
|
||||
|
||||
evidence:
|
||||
|
||||
- Desktop evidence records the selected/active object changing from `[1, 3, 5]` to `[1, 5]`; the custom property remains at 3.0 and save/reopen is exact.
|
||||
- WASM/Main reads the same Action as one `[\"delete_target\"][0]` channel with three keyframes before the operation fixture and two keyframes after it. WASM save/reopen is exact, and malformed Blend input is rejected without Main mutation.
|
||||
- Fixture generation, foreground `VIEW_3D` checker, npm comparator, direct idempotent comparator, and artifact hashing passed. No production reader or protocol change was required because the existing generic Action/F-Curve reader exposes this custom-property channel.
|
||||
|
||||
nextTask: `M16-GAP-00185`
|
||||
17
docs/status/M16-GAP-00185.md
Normal file
17
docs/status/M16-GAP-00185.md
Normal file
@@ -0,0 +1,17 @@
|
||||
# M16-GAP-00185 Status
|
||||
|
||||
status: done
|
||||
task: anim.keyframe_delete_vse operator LOCAL_EXACT slice
|
||||
updated: 2026-08-22 America/New_York
|
||||
|
||||
scope:
|
||||
|
||||
- The minimal fixture contains one selected/active image strip with a Scene Action animating `blend_alpha` at frames 1, 3, and 5. A foreground `SEQUENCE_EDITOR` context invokes `ANIM_OT_keyframe_delete_vse(confirm=false)` (`poll=true`, `FINISHED`) at frame 3, deleting only the current strip keyframe and preserving the two surrounding keys.
|
||||
|
||||
evidence:
|
||||
|
||||
- Desktop evidence records the selected/active strip changing from `[1, 3, 5]` to `[1, 5]`; `blend_alpha` remains 0.5 at frame 3 and save/reopen is exact.
|
||||
- WASM/Main reads the same Scene Action as one `sequence_editor.strips_all[\"WebGapAnimKeyframeDeleteVSEStrip\"].blend_alpha[0]` channel with three keyframes before the operation fixture and two keyframes after it. WASM save/reopen is exact, and malformed Blend input is rejected without Main mutation.
|
||||
- Fixture generation, foreground `SEQUENCE_EDITOR` checker, npm comparator, direct idempotent comparator, and artifact hashing passed. No production reader or protocol change was required because the existing generic Action/F-Curve reader exposes this Scene channel.
|
||||
|
||||
nextTask: `M16-GAP-00186`
|
||||
17
docs/status/M16-GAP-00186.md
Normal file
17
docs/status/M16-GAP-00186.md
Normal file
@@ -0,0 +1,17 @@
|
||||
# M16-GAP-00186 Status
|
||||
|
||||
status: done
|
||||
task: anim.keyframe_insert operator LOCAL_EXACT slice
|
||||
updated: 2026-08-22 America/New_York
|
||||
|
||||
scope:
|
||||
|
||||
- The minimal fixture contains one selected/active object with a custom `insert_target` property and a named active Keying Set. Its Action starts with keys at frames 1 and 5. A foreground `VIEW_3D` context invokes `ANIM_OT_keyframe_insert()` (`poll=true`, `FINISHED`) at frame 3, inserting the current key while preserving the existing keys.
|
||||
|
||||
evidence:
|
||||
|
||||
- Desktop evidence records the Action changing from `[1, 5]` to `[1, 3, 5]`; the inserted key is the only selected key (`[false, true, false]`), the custom property remains at 3.0, and save/reopen is exact.
|
||||
- WASM/Main reads the same Action as one `[\"insert_target\"][0]` channel with two keyframes before the operation fixture and three keyframes after it. WASM save/reopen is exact, and malformed Blend input is rejected without Main mutation.
|
||||
- Fixture generation, foreground `VIEW_3D` checker, npm comparator, direct idempotent comparator, and artifact hashing passed. No production reader or protocol change was required because the existing generic Action/F-Curve reader exposes this custom-property channel.
|
||||
|
||||
nextTask: `M16-GAP-00187`
|
||||
17
docs/status/M16-GAP-00187.md
Normal file
17
docs/status/M16-GAP-00187.md
Normal file
@@ -0,0 +1,17 @@
|
||||
# M16-GAP-00187 Status
|
||||
|
||||
status: done
|
||||
task: anim.keyframe_insert_button operator LOCAL_EXACT slice
|
||||
updated: 2026-08-22 America/New_York
|
||||
|
||||
scope:
|
||||
|
||||
- The minimal fixture contains one selected/active object with a custom `insert_target` property and an Action keyed at frames 1 and 5. A registered Properties panel exposes the animated property as a real UI button. A foreground Properties context invokes `ANIM_OT_keyframe_insert_button(all=true)` through that active button at frame 3 (`poll=true`, `FINISHED`), inserting the current key while preserving the two existing keys.
|
||||
|
||||
evidence:
|
||||
|
||||
- Desktop evidence records the Action changing from `[1, 5]` to `[1, 3, 5]`; the inserted key is the only selected key (`[false, true, false]`), the custom property remains at 3.0 and save/reopen is exact.
|
||||
- WASM/Main reads the same Action as one `[\"insert_target\"][0]` channel with two keyframes before the operation fixture and three keyframes after it. WASM save/reopen is exact, and malformed Blend input is rejected without Main mutation.
|
||||
- Fixture generation, foreground Properties UI checker, npm comparator, direct idempotent comparator, and artifact hashing passed. No production reader or protocol change was required because the existing generic Action/F-Curve reader exposes this custom-property channel.
|
||||
|
||||
nextTask: `M16-GAP-00188`
|
||||
17
docs/status/M16-GAP-00188.md
Normal file
17
docs/status/M16-GAP-00188.md
Normal file
@@ -0,0 +1,17 @@
|
||||
# M16-GAP-00188 Status
|
||||
|
||||
status: done
|
||||
task: anim.keyframe_insert_by_name operator LOCAL_EXACT slice
|
||||
updated: 2026-08-22 America/New_York
|
||||
|
||||
scope:
|
||||
|
||||
- The minimal fixture contains one selected/active object with a custom `insert_target` property, an Action keyed at frames 1 and 5, and a named Keying Set targeting that property. A foreground `VIEW_3D` context invokes `ANIM_OT_keyframe_insert_by_name(type=WebGapAnimKeyframeInsertByNameSet)` (`poll=true`, `FINISHED`) at frame 3, inserting the current key while preserving the two existing keys.
|
||||
|
||||
evidence:
|
||||
|
||||
- Desktop evidence records the Action changing from `[1, 5]` to `[1, 3, 5]`; the inserted key is the only selected key (`[false, true, false]`), the custom property remains at 3.0 and save/reopen is exact.
|
||||
- WASM/Main reads the same Action as one `[\"insert_target\"][0]` channel with two keyframes before the operation fixture and three keyframes after it. WASM save/reopen is exact, and malformed Blend input is rejected without Main mutation.
|
||||
- Fixture generation, foreground `VIEW_3D` checker, npm comparator, direct idempotent comparator, and artifact hashing passed. No production reader or protocol change was required because the existing generic Action/F-Curve reader exposes this custom-property channel.
|
||||
|
||||
nextTask: `M16-GAP-00189`
|
||||
17
docs/status/M16-GAP-00189.md
Normal file
17
docs/status/M16-GAP-00189.md
Normal file
@@ -0,0 +1,17 @@
|
||||
# M16-GAP-00189 Status
|
||||
|
||||
status: done
|
||||
task: anim.keyframe_insert_menu operator LOCAL_EXACT slice
|
||||
updated: 2026-08-22 America/New_York
|
||||
|
||||
scope:
|
||||
|
||||
- The minimal fixture contains one selected/active object with a custom `insert_target` property, an Action keyed at frames 1 and 5, and a named active Keying Set. A foreground `VIEW_3D` context invokes `ANIM_OT_keyframe_insert_menu(always_prompt=false)` (`poll=true`, `FINISHED`); Blender takes the active-Keying-Set fast path and inserts the current key at frame 3.
|
||||
|
||||
evidence:
|
||||
|
||||
- Desktop evidence records the Action changing from `[1, 5]` to `[1, 3, 5]`; the inserted key is the only selected key (`[false, true, false]`), the custom property remains at 3.0 and save/reopen is exact.
|
||||
- WASM/Main reads the same Action as one `[\"insert_target\"][0]` channel with two keyframes before the operation fixture and three keyframes after it. WASM save/reopen is exact, and malformed Blend input is rejected without Main mutation.
|
||||
- Fixture generation, foreground `VIEW_3D` checker, npm comparator, direct idempotent comparator, and artifact hashing passed. No production reader or protocol change was required because the existing generic Action/F-Curve reader exposes this custom-property channel.
|
||||
|
||||
nextTask: `M16-GAP-00190`
|
||||
17
docs/status/M16-GAP-00190.md
Normal file
17
docs/status/M16-GAP-00190.md
Normal file
@@ -0,0 +1,17 @@
|
||||
# M16-GAP-00190 Status
|
||||
|
||||
status: done
|
||||
task: anim.keying_set_active_set operator LOCAL_EXACT slice
|
||||
updated: 2026-08-22 America/New_York
|
||||
|
||||
scope:
|
||||
|
||||
- The minimal fixture contains one selected/active object with a custom `active_target` property, a three-key Action, and two named Keying Sets. A foreground `VIEW_3D` context invokes `ANIM_OT_keying_set_active_set(type=WebGapAnimKeyingSetActiveB)` (`poll=true`, `FINISHED`), changing the active Keying Set from A to B without changing the Action.
|
||||
|
||||
evidence:
|
||||
|
||||
- Desktop evidence records active Keying Set `WebGapAnimKeyingSetActiveA` changing to `WebGapAnimKeyingSetActiveB`; the Action remains `[1, 3, 5]`, the property remains 3.0, and save/reopen is exact.
|
||||
- WASM/Main reads the same fixture with the visible Action unchanged and save/reopen exact. The current scene snapshot does not expose Keying Set metadata, so the report explicitly records `keyingSetMetadata: NOT_EXPOSED_BY_SCENE_SNAPSHOT`; malformed Blend input is rejected without Main mutation.
|
||||
- Fixture generation, foreground `VIEW_3D` checker, npm comparator, direct idempotent comparator, and artifact hashing passed. No production reader or protocol change was made.
|
||||
|
||||
nextTask: `M16-GAP-00191`
|
||||
17
docs/status/M16-GAP-00191.md
Normal file
17
docs/status/M16-GAP-00191.md
Normal file
@@ -0,0 +1,17 @@
|
||||
# M16-GAP-00191 Status
|
||||
|
||||
status: done
|
||||
task: anim.keying_set_add operator LOCAL_EXACT slice
|
||||
updated: 2026-08-22 America/New_York
|
||||
|
||||
scope:
|
||||
|
||||
- The minimal fixture contains one selected/active object with a custom `add_target` property and a three-key Action, but no scene Keying Sets. A foreground `VIEW_3D` context invokes `ANIM_OT_keying_set_add()` (`poll=true`, `FINISHED`), adding and activating one empty Keying Set without changing the Action.
|
||||
|
||||
evidence:
|
||||
|
||||
- Desktop evidence records Keying Set count `0→1`, an active newly-added set, unchanged `[1, 3, 5]` Action data, and exact save/reopen.
|
||||
- WASM/Main reads the same fixture with the visible Action unchanged and save/reopen exact. The current scene snapshot does not expose Keying Set metadata, so the report explicitly records `keyingSetMetadata: NOT_EXPOSED_BY_SCENE_SNAPSHOT`; malformed Blend input is rejected without Main mutation.
|
||||
- Fixture generation, foreground `VIEW_3D` checker, npm comparator, direct idempotent comparator, and artifact hashing passed. No production reader or protocol change was made.
|
||||
|
||||
nextTask: `M16-GAP-00192`
|
||||
17
docs/status/M16-GAP-00192.md
Normal file
17
docs/status/M16-GAP-00192.md
Normal file
@@ -0,0 +1,17 @@
|
||||
# M16-GAP-00192 Status
|
||||
|
||||
status: done
|
||||
task: anim.keying_set_export operator LOCAL_EXACT slice
|
||||
updated: 2026-08-22 America/New_York
|
||||
|
||||
scope:
|
||||
|
||||
- The minimal fixture contains one selected/active object with a custom `export_target` property, a three-key Action, and one named Keying Set. Blender invokes `ANIM_OT_keying_set_export(filepath=..., filter_python=true)` (`poll=true`, `FINISHED`) and writes the Keying Set Python export without mutating Main.
|
||||
|
||||
evidence:
|
||||
|
||||
- Desktop evidence records unchanged object/Action state, exact save/reopen, and a non-empty hash-bound exported Python script.
|
||||
- WASM/Main reads the same fixture with the visible Action unchanged and save/reopen exact. The current scene snapshot does not expose Keying Set metadata, so the report explicitly records `keyingSetMetadata: NOT_EXPOSED_BY_SCENE_SNAPSHOT`; malformed Blend input is rejected without Main mutation.
|
||||
- Fixture generation, background Blender export checker, npm comparator, direct idempotent comparator, export-script hashing, and artifact hashing passed. No production reader or protocol change was made.
|
||||
|
||||
nextTask: `M16-GAP-00193`
|
||||
17
docs/status/M16-GAP-00193.md
Normal file
17
docs/status/M16-GAP-00193.md
Normal file
@@ -0,0 +1,17 @@
|
||||
# M16-GAP-00193 Status
|
||||
|
||||
status: done
|
||||
task: anim.keying_set_path_add operator LOCAL_EXACT slice
|
||||
updated: 2026-08-22 America/New_York
|
||||
|
||||
scope:
|
||||
|
||||
- The minimal fixture contains one selected/active object with a three-key Action and one empty active Keying Set. Blender invokes `ANIM_OT_keying_set_path_add()` (`poll=true`, `FINISHED`), adding one empty path with the expected default fields without changing the Action.
|
||||
|
||||
evidence:
|
||||
|
||||
- Desktop evidence records Keying Set path count `0→1`, the empty path defaults, unchanged `[1, 3, 5]` Action data, and exact save/reopen.
|
||||
- WASM/Main reads the same post-operation fixture with the visible Action unchanged and save/reopen exact. The current scene snapshot does not expose Keying Set metadata, so the report records `keyingSetMetadata: NOT_EXPOSED_BY_SCENE_SNAPSHOT`; malformed Blend input is rejected without Main mutation.
|
||||
- Fixture generation, background Blender operator checker, npm comparator, direct idempotent comparator, and artifact hashing passed. No production reader or protocol change was made.
|
||||
|
||||
nextTask: `M16-GAP-00194`
|
||||
17
docs/status/M16-GAP-00194.md
Normal file
17
docs/status/M16-GAP-00194.md
Normal file
@@ -0,0 +1,17 @@
|
||||
# M16-GAP-00194 Status
|
||||
|
||||
status: done
|
||||
task: anim.keying_set_path_remove operator LOCAL_EXACT slice
|
||||
updated: 2026-08-22 America/New_York
|
||||
|
||||
scope:
|
||||
|
||||
- The minimal fixture contains one selected/active object with a three-key Action and one active Keying Set path. Blender invokes `ANIM_OT_keying_set_path_remove()` (`poll=true`, `FINISHED`), removing the active path without changing the Action.
|
||||
|
||||
evidence:
|
||||
|
||||
- Desktop evidence records Keying Set path count `1→0`, the pre-existing path fields, unchanged `[1, 3, 5]` Action data, and exact save/reopen.
|
||||
- WASM/Main reads the same post-operation fixture with the visible Action unchanged and save/reopen exact. The current scene snapshot does not expose Keying Set metadata, so the report records `keyingSetMetadata: NOT_EXPOSED_BY_SCENE_SNAPSHOT`; malformed Blend input is rejected without Main mutation.
|
||||
- Fixture generation, background Blender operator checker, npm comparator, direct idempotent comparator, and artifact hashing passed. No production reader or protocol change was made.
|
||||
|
||||
nextTask: `M16-GAP-00195`
|
||||
17
docs/status/M16-GAP-00195.md
Normal file
17
docs/status/M16-GAP-00195.md
Normal file
@@ -0,0 +1,17 @@
|
||||
# M16-GAP-00195 Status
|
||||
|
||||
status: done
|
||||
task: anim.keying_set_remove operator LOCAL_EXACT slice
|
||||
updated: 2026-08-22 America/New_York
|
||||
|
||||
scope:
|
||||
|
||||
- The minimal fixture contains one selected/active object with a three-key Action and one empty active Keying Set. Blender invokes `ANIM_OT_keying_set_remove()` (`poll=true`, `FINISHED`), removing the active Keying Set without changing the Action.
|
||||
|
||||
evidence:
|
||||
|
||||
- Desktop evidence records Keying Set count `1→0`, active set `WebGapAnimKeyingSetRemoveSet→null`, unchanged `[1, 3, 5]` Action data, and exact save/reopen.
|
||||
- WASM/Main reads the same post-operation fixture with the visible Action unchanged and save/reopen exact. The current scene snapshot does not expose Keying Set metadata, so the report records `keyingSetMetadata: NOT_EXPOSED_BY_SCENE_SNAPSHOT`; malformed Blend input is rejected without Main mutation.
|
||||
- Fixture generation, background Blender operator checker, npm comparator, direct idempotent comparator, and artifact hashing passed. No production reader or protocol change was made.
|
||||
|
||||
nextTask: `M16-GAP-00196`
|
||||
17
docs/status/M16-GAP-00196.md
Normal file
17
docs/status/M16-GAP-00196.md
Normal file
@@ -0,0 +1,17 @@
|
||||
# M16-GAP-00196 Status
|
||||
|
||||
status: done
|
||||
task: anim.keyingset_button_add operator LOCAL_EXACT slice
|
||||
updated: 2026-08-22 America/New_York
|
||||
|
||||
scope:
|
||||
|
||||
- The minimal fixture contains one selected/active object with a three-key Action and no scene Keying Set. A real `PROPERTIES` RNA button invokes `ANIM_OT_keyingset_button_add()` (`poll=true`, `FINISHED`), creating `ButtonKeyingSet` and adding the active `button_target` path.
|
||||
|
||||
evidence:
|
||||
|
||||
- Desktop evidence records Keying Set count `0→1`, path count `0→1`, exact path fields, unchanged `[1, 3, 5]` Action data, and exact save/reopen.
|
||||
- WASM/Main reads the same post-operation fixture with the visible Action unchanged and save/reopen exact. The current scene snapshot does not expose Keying Set metadata, so the report records `keyingSetMetadata: NOT_EXPOSED_BY_SCENE_SNAPSHOT`; malformed Blend input is rejected without Main mutation.
|
||||
- Fixture generation, foreground Chromium-scope desktop UI checker, npm comparator, direct idempotent comparator, and artifact hashing passed. No production reader or protocol change was made.
|
||||
|
||||
nextTask: `M16-GAP-00197`
|
||||
17
docs/status/M16-GAP-00197.md
Normal file
17
docs/status/M16-GAP-00197.md
Normal file
@@ -0,0 +1,17 @@
|
||||
# M16-GAP-00197 Status
|
||||
|
||||
status: done
|
||||
task: anim.keyingset_button_remove operator LOCAL_EXACT slice
|
||||
updated: 2026-08-22 America/New_York
|
||||
|
||||
scope:
|
||||
|
||||
- The minimal fixture contains one selected/active object with a three-key Action and one active `ButtonKeyingSet` path. A real `PROPERTIES` RNA button invokes `ANIM_OT_keyingset_button_remove()` (`poll=true`, `FINISHED`), removing the active property path without changing the Action.
|
||||
|
||||
evidence:
|
||||
|
||||
- Desktop evidence records path count `1→0`, the unchanged active Keying Set, exact pre-existing path fields, unchanged `[1, 3, 5]` Action data, and exact save/reopen.
|
||||
- WASM/Main reads the same post-operation fixture with the visible Action unchanged and save/reopen exact. The current scene snapshot does not expose Keying Set metadata, so the report records `keyingSetMetadata: NOT_EXPOSED_BY_SCENE_SNAPSHOT`; malformed Blend input is rejected without Main mutation.
|
||||
- Fixture generation, foreground desktop UI checker, npm comparator, direct idempotent comparator, and artifact hashing passed. No production reader or protocol change was made.
|
||||
|
||||
nextTask: `M16-GAP-00198`
|
||||
18
docs/status/M16-GAP-00198.md
Normal file
18
docs/status/M16-GAP-00198.md
Normal file
@@ -0,0 +1,18 @@
|
||||
# M16-GAP-00198 Status
|
||||
|
||||
status: done
|
||||
task: anim.merge_animation operator LOCAL_EXACT slice
|
||||
updated: 2026-08-22 America/New_York
|
||||
|
||||
scope:
|
||||
|
||||
- The minimal fixture contains two selected mesh objects. The active object owns `WebGapAnimMergeActiveAction`; the source object owns `WebGapAnimMergeSourceAction`, each with one three-key custom-property channel.
|
||||
- Blender invokes `ANIM_OT_merge_animation` with `poll=true` and `FINISHED`, moving the source slot into the active action. Both objects then observe `WebGapAnimMergeActiveAction` with both channels; the source action has no remaining users.
|
||||
|
||||
evidence:
|
||||
|
||||
- Desktop evidence records the exact pre/post action channels, operator status, active/selected state, and save/reopen stability.
|
||||
- WASM/Main reads the post-operation fixture with two `WebGapAnimMergeActiveAction` animation entries (one per object), both carrying the merged channels; save/reopen is exact and malformed Blend input is rejected without Main mutation.
|
||||
- Fixture generation, background desktop operator checker, npm comparator, direct idempotent comparator, Python syntax checks, and artifact hashing passed. No production reader or protocol change was made.
|
||||
|
||||
nextTask: `M16-GAP-00199`
|
||||
18
docs/status/M16-GAP-00199.md
Normal file
18
docs/status/M16-GAP-00199.md
Normal file
@@ -0,0 +1,18 @@
|
||||
# M16-GAP-00199 Status
|
||||
|
||||
status: done
|
||||
task: anim.paste_driver_button operator LOCAL_EXACT slice
|
||||
updated: 2026-08-22 America/New_York
|
||||
|
||||
scope:
|
||||
|
||||
- The minimal fixture contains one mesh object with a driven `source_target` custom property and an undriven `paste_target` custom property. Desktop UI evidence copies the source driver and pastes it into the target through `ANIM_OT_paste_driver_button`.
|
||||
- The saved fixture exposes both scripted drivers with the same expression in WASM/Main; no reader, protocol, or browser change was required.
|
||||
|
||||
evidence:
|
||||
|
||||
- Desktop evidence records the source/target driver state before and after the UI operation, `poll=true`, `FINISHED`, `DRIVER_PASTED`, and exact save/reopen. The checker also preserves this evidence on repeated runs.
|
||||
- WASM/Main reads both drivers from the same fixture, preserves them across save/reopen, and rejects malformed Blend input without Main mutation.
|
||||
- Fixture generation, foreground desktop checker, npm comparator, direct comparator, and task-context checks passed. Chromium-only policy was preserved; no Firefox/WebKit run was made.
|
||||
|
||||
nextTask: `M16-GAP-00200`
|
||||
18
docs/status/M16-GAP-00200.md
Normal file
18
docs/status/M16-GAP-00200.md
Normal file
@@ -0,0 +1,18 @@
|
||||
# M16-GAP-00200 Status
|
||||
|
||||
status: done
|
||||
task: anim.previewrange_clear operator LOCAL_EXACT slice
|
||||
updated: 2026-08-22 America/New_York
|
||||
|
||||
scope:
|
||||
|
||||
- The minimal fixture starts with a `2..6` scene preview range. Desktop runs `ANIM_OT_previewrange_clear` in the active Dope Sheet animation context and saves the cleared Main.
|
||||
- WASM/Main observes the same scene with no `previewRange` field and an unchanged frame range; no reader, protocol, or browser change was required.
|
||||
|
||||
evidence:
|
||||
|
||||
- Desktop evidence records `poll=true`, `FINISHED`, `PREVIEW_RANGE_CLEARED`, the cleared values, and exact save/reopen. Repeated checker runs preserve the fixture hash.
|
||||
- WASM/Main compares the cleared scene, preserves it across save/reopen, and rejects malformed Blend input without Main mutation.
|
||||
- Fixture generation, desktop checker, npm comparator, direct comparator, and task-context checks passed. Chromium-only policy was preserved; no Firefox/WebKit run was made.
|
||||
|
||||
nextTask: `M16-GAP-00201`
|
||||
18
docs/status/M16-GAP-00201.md
Normal file
18
docs/status/M16-GAP-00201.md
Normal file
@@ -0,0 +1,18 @@
|
||||
# M16-GAP-00201 Status
|
||||
|
||||
status: done
|
||||
task: anim.previewrange_set operator LOCAL_EXACT slice
|
||||
updated: 2026-08-22 America/New_York
|
||||
|
||||
scope:
|
||||
|
||||
- The minimal fixture uses the active Dope Sheet animation region and a deterministic border gesture to set the Scene preview range to `2..6` through `ANIM_OT_previewrange_set`.
|
||||
- WASM/Main observes the same `previewRange` and frame bounds; no reader, protocol, or browser change was required.
|
||||
|
||||
evidence:
|
||||
|
||||
- Desktop evidence records the animation-region poll, `FINISHED`, `PREVIEW_RANGE_SET`, the `2..6` values, and exact save/reopen.
|
||||
- WASM/Main compares the preview range from the same fixture, preserves it across save/reopen, and rejects malformed Blend input without Main mutation.
|
||||
- Fixture generation, desktop checker, npm comparator, direct comparator, and task-context checks passed. Chromium-only policy was preserved; no Firefox/WebKit run was made.
|
||||
|
||||
nextTask: `M16-GAP-00202`
|
||||
18
docs/status/M16-GAP-00202.md
Normal file
18
docs/status/M16-GAP-00202.md
Normal file
@@ -0,0 +1,18 @@
|
||||
# M16-GAP-00202 Status
|
||||
|
||||
status: done
|
||||
task: anim.replace_action operator LOCAL_EXACT slice
|
||||
updated: 2026-08-22 America/New_York
|
||||
|
||||
scope:
|
||||
|
||||
- The minimal fixture has two objects using `WebGapAnimReplaceOldAction` and one object using `WebGapAnimReplaceNewAction`. Desktop calls `ANIM_OT_replace_action` with the explicit action session UIDs.
|
||||
- All three object users switch to the new action; the old action remains unlinked with its original channels. WASM/Main exposes both the replaced users and preserved unlinked action without reader/protocol changes.
|
||||
|
||||
evidence:
|
||||
|
||||
- Desktop evidence records the old/new action users, `poll=true`, `FINISHED`, `ACTIONS_REPLACED`, and exact save/reopen. Repeated checker runs preserve the initial evidence and fixture hash.
|
||||
- WASM/Main compares three new-action targets and the unlinked old action, preserves them across save/reopen, and rejects malformed Blend input without Main mutation.
|
||||
- Fixture generation, desktop checker, npm comparator, direct comparator, and task-context checks passed. Chromium-only policy was preserved; no Firefox/WebKit run was made.
|
||||
|
||||
nextTask: `M16-GAP-00203`
|
||||
18
docs/status/M16-GAP-00203.md
Normal file
18
docs/status/M16-GAP-00203.md
Normal file
@@ -0,0 +1,18 @@
|
||||
# M16-GAP-00203 Status
|
||||
|
||||
status: done
|
||||
task: anim.replace_action_new operator LOCAL_EXACT slice
|
||||
updated: 2026-08-22 America/New_York
|
||||
|
||||
scope:
|
||||
|
||||
- The minimal fixture has two objects using `WebGapAnimReplaceNewOldAction`. Desktop runs `ANIM_OT_replace_action_new` with the old action session UID; Blender creates a new empty action and assigns it to both users.
|
||||
- The old action remains unlinked with its original channels. WASM/Main preserves that visible old-action evidence; the empty replacement action is intentionally not exposed as an animation entry.
|
||||
|
||||
evidence:
|
||||
|
||||
- Desktop evidence records `poll=true`, `FINISHED`, `ACTION_REPLACED_WITH_NEW`, the new action assignment, and exact save/reopen. Repeated checker runs preserve the initial evidence and fixture hash.
|
||||
- WASM/Main compares the unlinked old action, preserves it across save/reopen, and rejects malformed Blend input without Main mutation.
|
||||
- Fixture generation, desktop checker, npm comparator, direct comparator, and task-context checks passed. Chromium-only policy was preserved; no Firefox/WebKit run was made.
|
||||
|
||||
nextTask: `M16-GAP-00204`
|
||||
18
docs/status/M16-GAP-00204.md
Normal file
18
docs/status/M16-GAP-00204.md
Normal file
@@ -0,0 +1,18 @@
|
||||
# M16-GAP-00204 Status
|
||||
|
||||
status: done
|
||||
task: anim.scene_range_frame operator LOCAL_EXACT slice
|
||||
updated: 2026-08-22 America/New_York
|
||||
|
||||
scope:
|
||||
|
||||
- The minimal fixture uses a Dope Sheet animation region with an active preview playback range. Desktop runs `ANIM_OT_scene_range_frame` and frames the region to that scene range.
|
||||
- The resulting `view2d` state is observable in WASM/Main editor workflow data; no reader, protocol, or browser change was required.
|
||||
|
||||
evidence:
|
||||
|
||||
- Desktop evidence records `poll=true`, `FINISHED`, `VIEW_FRAMED_TO_SCENE_RANGE`, the exact view bounds, and save/reopen stability.
|
||||
- WASM/Main matches the same Dope Sheet `view2d`, preserves editor workflow across save/reopen, and rejects malformed Blend input without Main mutation.
|
||||
- Fixture generation, desktop checker, npm comparator, direct comparator, and task-context checks passed. Chromium-only policy was preserved; no Firefox/WebKit run was made.
|
||||
|
||||
nextTask: `M16-GAP-00205`
|
||||
18
docs/status/M16-GAP-00205.md
Normal file
18
docs/status/M16-GAP-00205.md
Normal file
@@ -0,0 +1,18 @@
|
||||
# M16-GAP-00205 Status
|
||||
|
||||
status: done
|
||||
task: anim.separate_slots operator LOCAL_EXACT slice
|
||||
updated: 2026-08-22 America/New_York
|
||||
|
||||
scope:
|
||||
|
||||
- The minimal fixture has two objects using separate slots in one layered action. Desktop runs `ANIM_OT_separate_slots` and creates one action per slot, reassigning the two objects.
|
||||
- WASM/Main observes the two new action targets and their slot-specific channels; the original action is empty and omitted from the animation snapshot.
|
||||
|
||||
evidence:
|
||||
|
||||
- Desktop evidence records `poll=true`, `FINISHED`, `SLOTS_SEPARATED`, both new action assignments, and exact save/reopen. Repeated checker runs preserve the initial evidence and fixture hash.
|
||||
- WASM/Main compares both separated actions, preserves them across save/reopen, and rejects malformed Blend input without Main mutation.
|
||||
- Fixture generation, desktop checker, npm comparator, direct comparator, and task-context checks passed. Chromium-only policy was preserved; no Firefox/WebKit run was made.
|
||||
|
||||
nextTask: `M16-GAP-00206`
|
||||
18
docs/status/M16-GAP-00206.md
Normal file
18
docs/status/M16-GAP-00206.md
Normal file
@@ -0,0 +1,18 @@
|
||||
# M16-GAP-00206 Status
|
||||
|
||||
status: done
|
||||
task: anim.slot_channels_move_to_new_action operator LOCAL_EXACT slice
|
||||
updated: 2026-08-22 America/New_York
|
||||
|
||||
scope:
|
||||
|
||||
- The minimal fixture has two objects using separate slots in one action. Desktop selects one Action Slot in the Action Editor and runs `ANIM_OT_slot_channels_move_to_new_action`.
|
||||
- The selected slot moves to `WebGapMoveSlotAAction`; the other object remains on the original action. WASM/Main observes both resulting action targets without reader/protocol changes.
|
||||
|
||||
evidence:
|
||||
|
||||
- Desktop evidence records `poll=true`, `FINISHED`, `SLOT_MOVED_TO_NEW_ACTION`, both action assignments, and exact save/reopen. Repeated checker runs preserve the initial evidence and fixture hash.
|
||||
- WASM/Main compares the moved and remaining channels, preserves them across save/reopen, and rejects malformed Blend input without Main mutation.
|
||||
- Fixture generation, desktop checker, npm comparator, direct comparator, and task-context checks passed. Chromium-only policy was preserved; no Firefox/WebKit run was made.
|
||||
|
||||
nextTask: `M16-GAP-00207`
|
||||
18
docs/status/M16-GAP-00207.md
Normal file
18
docs/status/M16-GAP-00207.md
Normal file
@@ -0,0 +1,18 @@
|
||||
# M16-GAP-00207 Status
|
||||
|
||||
status: done
|
||||
task: anim.slot_new_for_id operator LOCAL_EXACT slice
|
||||
updated: 2026-08-22 America/New_York
|
||||
|
||||
scope:
|
||||
|
||||
- The minimal fixture assigns one Action Slot to `WebGapAnimNewSlotObject`; desktop runs `ANIM_OT_slot_new_for_id` with the animated ID context and duplicates the slot and channelbag.
|
||||
- The WASM/Main reader now selects the assigned `AnimData.slot_handle` channelbag and exposes `slotIdentifier` and `slotCount` on the animation snapshot. The duplicated slot remains stable across save/reopen.
|
||||
|
||||
evidence:
|
||||
|
||||
- Desktop evidence records `poll=true`, `FINISHED`, `SLOT_DUPLICATED`, both Slot identifiers, and exact save/reopen. Repeated checker runs preserve the initial evidence and fixture hash.
|
||||
- WASM/Main observes `OBWebGapAnimNewSlot.001`, two slots, the expected keyframes, exact save/reopen, and rejects malformed Blend input without Main mutation.
|
||||
- The generator, npm comparator, direct comparator, WebEngine rebuild, and task-context checks passed. Chromium-only policy was preserved; no Firefox/WebKit run was made.
|
||||
|
||||
nextTask: `M16-GAP-00208`
|
||||
18
docs/status/M16-GAP-00208.md
Normal file
18
docs/status/M16-GAP-00208.md
Normal file
@@ -0,0 +1,18 @@
|
||||
# M16-GAP-00208 Status
|
||||
|
||||
status: done
|
||||
task: anim.slot_unassign_from_constraint operator LOCAL_EXACT slice
|
||||
updated: 2026-08-22 America/New_York
|
||||
|
||||
scope:
|
||||
|
||||
- The minimal fixture gives `WebGapAnimConstraintSlotObject` an Action constraint with `WebGapAnimConstraintSlotAction` and one assigned `OBWebGapConstraintSlot`.
|
||||
- Desktop runs `ANIM_OT_slot_unassign_from_constraint` with the constraint context pointer. The reader exposes the constraint's action, slot identifier, handle, and assigned state in the node snapshot.
|
||||
|
||||
evidence:
|
||||
|
||||
- Desktop evidence records `poll=true`, `FINISHED`, `CONSTRAINT_SLOT_UNASSIGNED`, the nonzero-to-zero handle transition, and exact save/reopen. Repeated checker runs preserve the initial evidence and fixture hash.
|
||||
- WASM/Main observes the retained action and identifier with `actionSlotAssigned=false` and handle `0`, preserves it across save/reopen, and rejects malformed Blend input without Main mutation.
|
||||
- The generator, npm comparator, direct comparator, WebEngine rebuild, and task-context checks passed. Chromium-only policy was preserved; no Firefox/WebKit run was made.
|
||||
|
||||
nextTask: `M16-GAP-00209`
|
||||
18
docs/status/M16-GAP-00209.md
Normal file
18
docs/status/M16-GAP-00209.md
Normal file
@@ -0,0 +1,18 @@
|
||||
# M16-GAP-00209 Status
|
||||
|
||||
status: done
|
||||
task: anim.slot_unassign_from_id operator LOCAL_EXACT slice
|
||||
updated: 2026-08-22 America/New_York
|
||||
|
||||
scope:
|
||||
|
||||
- The minimal fixture assigns `OBWebGapUnassignIdSlot` to `WebGapAnimUnassignIdObject` through `WebGapAnimUnassignIdAction` and keys one custom property.
|
||||
- Desktop runs `ANIM_OT_slot_unassign_from_id` with the animated ID context. The reader preserves the Action animation and exposes the retained slot identifier plus assigned/handle state.
|
||||
|
||||
evidence:
|
||||
|
||||
- Desktop evidence records `poll=true`, `FINISHED`, `ID_SLOT_UNASSIGNED`, the nonzero-to-zero handle transition, retained `lastSlotIdentifier`, and exact save/reopen. Repeated checker runs preserve the initial evidence and fixture hash.
|
||||
- WASM/Main observes `slotAssigned=false` and handle `0` with the expected keyframes, preserves it across save/reopen, and rejects malformed Blend input without Main mutation.
|
||||
- The generator, npm comparator, direct comparator, WebEngine rebuild, and task-context checks passed. Chromium-only policy was preserved; no Firefox/WebKit run was made.
|
||||
|
||||
nextTask: `M16-GAP-00210`
|
||||
18
docs/status/M16-GAP-00210.md
Normal file
18
docs/status/M16-GAP-00210.md
Normal file
@@ -0,0 +1,18 @@
|
||||
# M16-GAP-00210 Status
|
||||
|
||||
status: done
|
||||
task: anim.slot_unassign_from_nla_strip operator LOCAL_EXACT slice
|
||||
updated: 2026-08-22 America/New_York
|
||||
|
||||
scope:
|
||||
|
||||
- The minimal fixture contains `WebGapNlaSlotTrack` with `WebGapNlaSlotStrip` referencing `WebGapAnimNlaSlotAction` and `OBWebGapNlaSlot`.
|
||||
- Desktop runs `ANIM_OT_slot_unassign_from_nla_strip` with the NLA strip context pointer. The reader exposes NLA strip slot identifier, handle, and assigned state.
|
||||
|
||||
evidence:
|
||||
|
||||
- Desktop evidence records `poll=true`, `FINISHED`, `NLA_SLOT_UNASSIGNED`, the nonzero-to-zero handle transition, retained `lastSlotIdentifier`, and exact save/reopen. Repeated checker runs preserve the initial evidence and fixture hash.
|
||||
- WASM/Main observes the same strip and Action with `actionSlotAssigned=false` and handle `0`, preserves it across save/reopen, and rejects malformed Blend input without Main mutation.
|
||||
- The generator, npm comparator, direct comparator, WebEngine rebuild, and task-context checks passed. Chromium-only policy was preserved; no Firefox/WebKit run was made.
|
||||
|
||||
nextTask: `M16-GAP-00211`
|
||||
18
docs/status/M16-GAP-00211.md
Normal file
18
docs/status/M16-GAP-00211.md
Normal file
@@ -0,0 +1,18 @@
|
||||
# M16-GAP-00211 Status
|
||||
|
||||
status: done
|
||||
task: anim.start_frame_set operator LOCAL_EXACT slice
|
||||
updated: 2026-08-22 America/New_York
|
||||
|
||||
scope:
|
||||
|
||||
- The minimal scene starts at frame 42 with a scene range of 1-120. The foreground animation-area context invokes `ANIM_OT_start_frame_set` (`poll=true`, `FINISHED`) and sets the scene start frame to 42.
|
||||
- The existing Main reader exposes the same scene frame tuple through `Scene.r.cfra`, `Scene.r.sfra`, and `Scene.r.efra`; no unrelated data-block, editor, or browser behavior was changed.
|
||||
|
||||
evidence:
|
||||
|
||||
- Desktop evidence records `FRAME_START_SET` and exact save/reopen. Repeated comparator runs preserve the fixture hash and report shape.
|
||||
- WASM/Main observes `{current: 42, start: 42, end: 120}` from the same fixture, preserves it across save/reopen, and rejects malformed Blend input without Main mutation.
|
||||
- The generator, npm comparator, direct comparator, and task-context checks passed. Chromium-only policy was preserved; no Firefox/WebKit run was made.
|
||||
|
||||
nextTask: `M16-GAP-00212`
|
||||
19
docs/status/M16-GAP-00212.md
Normal file
19
docs/status/M16-GAP-00212.md
Normal file
@@ -0,0 +1,19 @@
|
||||
# M16-GAP-00212 Status
|
||||
|
||||
status: done
|
||||
task: anim.update_animated_transform_constraints operator LOCAL_EXACT slice
|
||||
updated: 2026-08-22 America/New_York
|
||||
|
||||
scope:
|
||||
|
||||
- The minimal fixture contains a mesh object with a `TRANSFORM` constraint mapped from rotation and one animated legacy `from_min_x` F-curve.
|
||||
- Desktop runs `ANIM_OT_update_animated_transform_constraints(use_convert_to_radians=true)` (`poll=true`, `FINISHED`) and rewrites the channel path to `from_min_x_rot`.
|
||||
- The existing Main reader exposes the rewritten Action channel and Transform constraint metadata; no unrelated data-block, editor, or browser behavior was changed.
|
||||
|
||||
evidence:
|
||||
|
||||
- Desktop evidence records the old and rewritten paths, `TRANSFORM_CONSTRAINT_PATHS_UPDATED`, and exact save/reopen. Repeated checker runs preserve the initial report and fixture hash.
|
||||
- WASM/Main observes the same Action channel at `constraints["WebGapAnimatedTransformConstraint"].from_min_x_rot[0]`, keyframes at frames 1 and 10, constraint type code 19, exact save/reopen, and malformed Blend rejection without Main mutation.
|
||||
- The generator, npm comparator, direct comparator, and task-context checks passed. Chromium-only policy was preserved; no Firefox/WebKit run was made.
|
||||
|
||||
nextTask: `M16-GAP-00213`
|
||||
19
docs/status/M16-GAP-00213.md
Normal file
19
docs/status/M16-GAP-00213.md
Normal file
@@ -0,0 +1,19 @@
|
||||
# M16-GAP-00213 Status
|
||||
|
||||
status: done
|
||||
task: anim.version_bone_hide_property operator LOCAL_EXACT slice
|
||||
updated: 2026-08-22 America/New_York
|
||||
|
||||
scope:
|
||||
|
||||
- The minimal fixture contains one selected armature object, one bone, an armature-data Action with `bones["WebGapVersionBoneHideBone"].hide`, and an object Action with an anchor channel.
|
||||
- Desktop runs `ANIM_OT_version_bone_hide_property` (`poll=true`, `FINISHED`) and copies the hide F-curve into the object Action as `pose.bones["WebGapVersionBoneHideBone"].hide`, retaining the armature source channel.
|
||||
- The existing Main reader exposes both Action channels and the armature data; no unrelated data-block, editor, or browser behavior was changed.
|
||||
|
||||
evidence:
|
||||
|
||||
- Desktop evidence records `BONE_HIDE_FCURVE_MOVED_TO_OBJECT_ACTION` and exact save/reopen. Repeated checker runs preserve the initial report and fixture hash.
|
||||
- WASM/Main observes the copied object channel with frames 1 and 10 and values 0 and 1, retains the armature Action channel, preserves both across save/reopen, and rejects malformed Blend input without Main mutation.
|
||||
- The generator, npm comparator, direct comparator, and task-context checks passed. Chromium-only policy was preserved; no Firefox/WebKit run was made.
|
||||
|
||||
nextTask: `M16-GAP-00214`
|
||||
19
docs/status/M16-GAP-00214.md
Normal file
19
docs/status/M16-GAP-00214.md
Normal file
@@ -0,0 +1,19 @@
|
||||
# M16-GAP-00214 Status
|
||||
|
||||
status: done
|
||||
task: anim.view_curve_in_graph_editor operator LOCAL_EXACT slice
|
||||
updated: 2026-08-22 America/New_York
|
||||
|
||||
scope:
|
||||
|
||||
- The minimal fixture contains one selected mesh object, one custom animated scalar property with frames 1 and 10, and a persisted Graph Editor area.
|
||||
- Desktop activates the property button and runs `ANIM_OT_view_curve_in_graph_editor` with `poll=true` and `FINISHED`; the operator changes the Graph Editor view bounds while leaving the Action data unchanged.
|
||||
- The Main reader now exposes `View2D` state for `GRAPH` editor main regions, alongside the existing Dope Sheet exposure. No other editor or data-block behavior changed.
|
||||
|
||||
evidence:
|
||||
|
||||
- Desktop evidence records `GRAPH_VIEW_FRAMED`, exact save/reopen, and the before/after Graph Editor bounds. The source fixture remains the minimal persisted Graph Editor state used by WASM/Main.
|
||||
- WASM/Main observes the same fixture's `GRAPH` main-region `View2D`, preserves it across save/reopen, and rejects malformed Blend input without Main mutation.
|
||||
- The generator, npm comparator, direct comparator, Chromium-only foreground desktop run, and task-context checks passed. No Firefox/WebKit run was made.
|
||||
|
||||
nextTask: `M16-GAP-00215`
|
||||
19
docs/status/M16-GAP-00215.md
Normal file
19
docs/status/M16-GAP-00215.md
Normal file
@@ -0,0 +1,19 @@
|
||||
# M16-GAP-00215 Status
|
||||
|
||||
status: done
|
||||
task: armature.align operator LOCAL_EXACT slice
|
||||
updated: 2026-08-22 America/New_York
|
||||
|
||||
scope:
|
||||
|
||||
- The minimal fixture contains one armature with two independent edit bones. The child starts at an angled axis and the parent is the active selected bone.
|
||||
- Desktop runs `ARMATURE_OT_align` with `poll=true` and `FINISHED`, aligns the child axis to the active parent, and preserves the result through save/reopen.
|
||||
- The existing Main reader exposes the same armature bone `head`/`tail` data; no other data-block, editor, or browser behavior changed.
|
||||
|
||||
evidence:
|
||||
|
||||
- The generator, desktop checker, npm comparator, direct comparator, and task-context checks passed. The checker is repeat-safe after a persisted aligned fixture and records the aligned child state.
|
||||
- WASM/Main observes the same parent/child coordinates, preserves them across save/reopen, and rejects malformed Blend input without Main mutation.
|
||||
- Chromium-only policy was preserved; no Firefox/WebKit run was made.
|
||||
|
||||
nextTask: `M16-GAP-00216`
|
||||
19
docs/status/M16-GAP-00216.md
Normal file
19
docs/status/M16-GAP-00216.md
Normal file
@@ -0,0 +1,19 @@
|
||||
# M16-GAP-00216 Status
|
||||
|
||||
status: done
|
||||
task: armature.assign_to_collection operator LOCAL_EXACT slice
|
||||
updated: 2026-08-22 America/New_York
|
||||
|
||||
scope:
|
||||
|
||||
- The minimal fixture contains one armature with source and target bone collections, one parent bone, and one selected child initially assigned only to the source collection.
|
||||
- Desktop runs `ARMATURE_OT_assign_to_collection(collection_index=1)` with `poll=true` and `FINISHED`, assigning the child to the target collection and preserving both memberships through save/reopen.
|
||||
- The Main reader now exposes bounded armature `boneCollections` entries with collection name/index and member bone IDs. No other collection, editor, or browser behavior changed.
|
||||
|
||||
evidence:
|
||||
|
||||
- The reader rebuild, generator, desktop checker, npm comparator, direct comparator, and task-context checks passed. Repeated checker runs recognize the persisted assignment and remain idempotent.
|
||||
- WASM/Main observes source and target membership for the same child bone, preserves it across save/reopen, and rejects malformed Blend input without Main mutation.
|
||||
- Chromium-only policy was preserved; no Firefox/WebKit run was made.
|
||||
|
||||
nextTask: `M16-GAP-00217`
|
||||
19
docs/status/M16-GAP-00217.md
Normal file
19
docs/status/M16-GAP-00217.md
Normal file
@@ -0,0 +1,19 @@
|
||||
# M16-GAP-00217 Status
|
||||
|
||||
status: done
|
||||
task: armature.autoside_names operator LOCAL_EXACT slice
|
||||
updated: 2026-08-22 America/New_York
|
||||
|
||||
scope:
|
||||
|
||||
- The minimal fixture contains one armature with two selected bones on opposite sides of the X axis.
|
||||
- Desktop runs `ARMATURE_OT_autoside_names(type='XAXIS')` with `poll=true` and `FINISHED`, naming the positive-X bone `.L` and the negative-X bone `.R`, then preserves both names through save/reopen.
|
||||
- The existing Main reader exposes the same armature bone names; no new reader field, data-block, editor, or browser behavior was added.
|
||||
|
||||
evidence:
|
||||
|
||||
- The generator, desktop checker, npm comparator, direct comparator, and task-context checks passed. Repeated checker runs recognize the persisted names and remain idempotent.
|
||||
- WASM/Main observes the same `.L`/`.R` names for the same fixture, preserves them across save/reopen, and rejects malformed Blend input without Main mutation.
|
||||
- Chromium-only policy was preserved; no Firefox/WebKit run was made.
|
||||
|
||||
nextTask: `M16-GAP-00218`
|
||||
19
docs/status/M16-GAP-00218.md
Normal file
19
docs/status/M16-GAP-00218.md
Normal file
@@ -0,0 +1,19 @@
|
||||
# M16-GAP-00218 Status
|
||||
|
||||
status: done
|
||||
task: armature.bone_primitive_add operator LOCAL_EXACT slice
|
||||
updated: 2026-08-22 America/New_York
|
||||
|
||||
scope:
|
||||
|
||||
- The minimal fixture contains one empty armature object and a fixed 3D cursor at `(1.5, -2.0, 0.75)`.
|
||||
- Desktop runs `ARMATURE_OT_bone_primitive_add(name, length=2.5, align='UP', space='OBJECT', use_deform=false)` with `poll=true` and `FINISHED`, creating the named bone at the cursor and preserving its head/tail through save/reopen.
|
||||
- The existing Main reader exposes the same armature bone name and coordinates; no new reader field, data-block, editor, or browser behavior was added.
|
||||
|
||||
evidence:
|
||||
|
||||
- The generator, desktop checker, npm comparator, direct comparator, and task-context checks passed. Repeated checker runs recognize the persisted bone and remain idempotent.
|
||||
- WASM/Main observes the same cursor-created bone, preserves it across save/reopen, and rejects malformed Blend input without Main mutation.
|
||||
- Chromium-only policy was preserved; no Firefox/WebKit run was made.
|
||||
|
||||
nextTask: `M16-GAP-00219`
|
||||
19
docs/status/M16-GAP-00219.md
Normal file
19
docs/status/M16-GAP-00219.md
Normal file
@@ -0,0 +1,19 @@
|
||||
# M16-GAP-00219 Status
|
||||
|
||||
status: done
|
||||
task: armature.calculate_roll operator LOCAL_EXACT slice
|
||||
updated: 2026-08-22 America/New_York
|
||||
|
||||
scope:
|
||||
|
||||
- The minimal fixture contains one selected bone aligned along +Y with zero initial roll.
|
||||
- Desktop runs `ARMATURE_OT_calculate_roll(type='GLOBAL_POS_X', axis_flip=false, axis_only=false)` with `poll=true` and `FINISHED`, producing a roll of approximately `pi/2` and preserving the resulting matrix through save/reopen.
|
||||
- The existing Main reader exposes the same armature bone head/tail and rest matrix; no new reader field, data-block, editor, or browser behavior was added.
|
||||
|
||||
evidence:
|
||||
|
||||
- The generator, desktop checker, npm comparator, direct comparator, and task-context checks passed. Repeated checker runs recognize the persisted roll and remain idempotent.
|
||||
- WASM/Main observes the same calculated orientation, preserves it across save/reopen, and rejects malformed Blend input without Main mutation.
|
||||
- Chromium-only policy was preserved; no Firefox/WebKit run was made.
|
||||
|
||||
nextTask: `M16-GAP-00220`
|
||||
19
docs/status/M16-GAP-00220.md
Normal file
19
docs/status/M16-GAP-00220.md
Normal file
@@ -0,0 +1,19 @@
|
||||
# M16-GAP-00220 Status
|
||||
|
||||
status: done
|
||||
task: armature.click_extrude operator LOCAL_EXACT slice
|
||||
updated: 2026-08-22 America/New_York
|
||||
|
||||
scope:
|
||||
|
||||
- The minimal fixture contains one selected armature bone from `(0, 0, 0)` to `(0, 2, 0)` and a fixed cursor at `(1.5, 2.0, 1.0)`.
|
||||
- Desktop runs `ARMATURE_OT_click_extrude` with `poll=true` and `FINISHED`, creating a connected `.001` child whose armature-space tail reaches the cursor and preserving it through save/reopen.
|
||||
- The existing Main reader exposes the parent relationship, raw child coordinates, and rest matrix; the comparator derives the same armature-space endpoint without changing unrelated armature fields.
|
||||
|
||||
evidence:
|
||||
|
||||
- The generator, desktop checker, npm comparator, direct comparator, and task-context checks passed. Repeated checker runs recognize the persisted child and remain idempotent.
|
||||
- WASM/Main observes the same two-bone hierarchy, preserves it across save/reopen, and rejects malformed Blend input without Main mutation.
|
||||
- Chromium-only policy was preserved; no Firefox/WebKit run was made.
|
||||
|
||||
nextTask: `M16-GAP-00221`
|
||||
19
docs/status/M16-GAP-00221.md
Normal file
19
docs/status/M16-GAP-00221.md
Normal file
@@ -0,0 +1,19 @@
|
||||
# M16-GAP-00221 Status
|
||||
|
||||
status: done
|
||||
task: armature.collection_add operator LOCAL_EXACT slice
|
||||
updated: 2026-08-22 America/New_York
|
||||
|
||||
scope:
|
||||
|
||||
- The minimal fixture contains one armature bone assigned to `WebGapArmatureCollectionAddExisting`.
|
||||
- Desktop runs `ARMATURE_OT_collection_add` with `poll=true` and `FINISHED`, creating the `Bones` collection as index 1 and preserving the existing bone membership through save/reopen.
|
||||
- The existing Main reader exposes both bone collections and their member IDs; no new reader field, data-block, editor, or browser behavior was added.
|
||||
|
||||
evidence:
|
||||
|
||||
- The generator, desktop checker, npm comparator, direct comparator, and task-context checks passed. Repeated checker runs recognize the persisted collection and remain idempotent.
|
||||
- WASM/Main observes the same collection names, indices, and memberships, preserves them across save/reopen, and rejects malformed Blend input without Main mutation.
|
||||
- Chromium-only policy was preserved; no Firefox/WebKit run was made.
|
||||
|
||||
nextTask: `M16-GAP-00222`
|
||||
19
docs/status/M16-GAP-00222.md
Normal file
19
docs/status/M16-GAP-00222.md
Normal file
@@ -0,0 +1,19 @@
|
||||
# M16-GAP-00222 Status
|
||||
|
||||
status: done
|
||||
task: armature.collection_assign operator LOCAL_EXACT slice
|
||||
updated: 2026-08-22 America/New_York
|
||||
|
||||
scope:
|
||||
|
||||
- The minimal fixture contains one armature bone assigned to `WebGapArmatureCollectionAssignSource` and an empty target collection.
|
||||
- Desktop runs `ARMATURE_OT_collection_assign(name=target)` with `poll=true` and `FINISHED`, adding the selected bone to the target while preserving its source membership through save/reopen.
|
||||
- The existing Main reader exposes both collection member ID lists; no new reader field, data-block, editor, or browser behavior was added.
|
||||
|
||||
evidence:
|
||||
|
||||
- The generator, desktop checker, npm comparator, direct comparator, and task-context checks passed. Repeated checker runs recognize the persisted assignment and remain idempotent.
|
||||
- WASM/Main observes the same assigned bone ID in both collections, preserves it across save/reopen, and rejects malformed Blend input without Main mutation.
|
||||
- Chromium-only policy was preserved; no Firefox/WebKit run was made.
|
||||
|
||||
nextTask: `M16-GAP-00223`
|
||||
19
docs/status/M16-GAP-00223.md
Normal file
19
docs/status/M16-GAP-00223.md
Normal file
@@ -0,0 +1,19 @@
|
||||
# M16-GAP-00223 Status
|
||||
|
||||
status: done
|
||||
task: armature.collection_create_and_assign operator LOCAL_EXACT slice
|
||||
updated: 2026-08-22 America/New_York
|
||||
|
||||
scope:
|
||||
|
||||
- The minimal fixture contains one armature bone assigned to `WebGapArmatureCollectionCreateAssignSource`.
|
||||
- Desktop runs `ARMATURE_OT_collection_create_and_assign(name=WebGapArmatureCollectionCreateAssignNew)` with `poll=true` and `FINISHED`, creating and activating the new collection while assigning the selected bone and preserving source membership through save/reopen.
|
||||
- The existing Main reader exposes both collection member ID lists and collection indices; no new reader field, data-block, editor, or browser behavior was added.
|
||||
|
||||
evidence:
|
||||
|
||||
- The generator, desktop checker, npm comparator, direct comparator, and task-context checks passed. Repeated checker runs recognize the persisted created collection and remain idempotent.
|
||||
- WASM/Main observes the same created collection, active ordering, and assigned bone ID, preserves them across save/reopen, and rejects malformed Blend input without Main mutation.
|
||||
- Chromium-only policy was preserved; no Firefox/WebKit run was made.
|
||||
|
||||
nextTask: `M16-GAP-00224`
|
||||
19
docs/status/M16-GAP-00224.md
Normal file
19
docs/status/M16-GAP-00224.md
Normal file
@@ -0,0 +1,19 @@
|
||||
# M16-GAP-00224 Status
|
||||
|
||||
status: done
|
||||
task: armature.collection_deselect operator LOCAL_EXACT slice
|
||||
updated: 2026-08-22 America/New_York
|
||||
|
||||
scope:
|
||||
|
||||
- The minimal fixture contains two bones in separate bone collections, both initially selected, with the active collection at index 0.
|
||||
- Desktop runs `ARMATURE_OT_collection_deselect` with `poll=true` and `FINISHED`, deselecting only the active collection bone while retaining the other selection through save/reopen.
|
||||
- Main now exposes the persisted armature bone `selected` bit alongside the existing bone collection membership data; no other data-block, editor, or browser behavior was added.
|
||||
|
||||
evidence:
|
||||
|
||||
- The generator, desktop checker, npm comparator, direct comparator, Web Engine rebuild, and task-context checks passed. Repeated checker runs recognize the already-deselected fixture and remain idempotent.
|
||||
- WASM/Main observes the same selected states, preserves them across save/reopen, and rejects malformed Blend input without Main mutation.
|
||||
- Chromium-only policy was preserved; no Firefox/WebKit run was made.
|
||||
|
||||
nextTask: `M16-GAP-00225`
|
||||
19
docs/status/M16-GAP-00225.md
Normal file
19
docs/status/M16-GAP-00225.md
Normal file
@@ -0,0 +1,19 @@
|
||||
# M16-GAP-00225 Status
|
||||
|
||||
status: done
|
||||
task: armature.collection_move operator LOCAL_EXACT slice
|
||||
updated: 2026-08-22 America/New_York
|
||||
|
||||
scope:
|
||||
|
||||
- The minimal fixture contains three bone collections, each retaining one distinct bone, with the middle collection active at index 1.
|
||||
- Desktop runs `ARMATURE_OT_collection_move(direction='UP')` with `poll=true` and `FINISHED`, moving the active collection to index 0 while preserving every collection member through save/reopen.
|
||||
- The existing Main reader's collection indices and bone IDs provide the observable order; no new data-block, editor, or browser behavior was added.
|
||||
|
||||
evidence:
|
||||
|
||||
- The generator, desktop checker, npm comparator, direct comparator, and task-context checks passed. Repeated checker runs recognize the already-moved order and remain idempotent.
|
||||
- WASM/Main observes the same collection order, active collection identity, and bone IDs, preserves them across save/reopen, and rejects malformed Blend input without Main mutation.
|
||||
- Chromium-only policy was preserved; no Firefox/WebKit run was made.
|
||||
|
||||
nextTask: `M16-GAP-00226`
|
||||
19
docs/status/M16-GAP-00226.md
Normal file
19
docs/status/M16-GAP-00226.md
Normal file
@@ -0,0 +1,19 @@
|
||||
# M16-GAP-00226 Status
|
||||
|
||||
status: done
|
||||
task: armature.collection_remove operator LOCAL_EXACT slice
|
||||
updated: 2026-08-22 America/New_York
|
||||
|
||||
scope:
|
||||
|
||||
- The minimal fixture contains three bone collections, each initially retaining one distinct bone, with the middle collection active at index 1.
|
||||
- Desktop runs `ARMATURE_OT_collection_remove` with `poll=true` and `FINISHED`, removing the active collection, leaving its bone unassigned, and preserving the remaining collections through save/reopen.
|
||||
- The existing Main reader's collection indices and bone IDs provide the observable removal; no new data-block, editor, or browser behavior was added.
|
||||
|
||||
evidence:
|
||||
|
||||
- The generator, desktop checker, npm comparator, direct comparator, and task-context checks passed. Repeated checker runs recognize the already-removed collection and remain idempotent.
|
||||
- WASM/Main observes the same remaining collection order, member IDs, and unassigned removed bone, preserves them across save/reopen, and rejects malformed Blend input without Main mutation.
|
||||
- Chromium-only policy was preserved; no Firefox/WebKit run was made.
|
||||
|
||||
nextTask: `M16-GAP-00227`
|
||||
19
docs/status/M16-GAP-00227.md
Normal file
19
docs/status/M16-GAP-00227.md
Normal file
@@ -0,0 +1,19 @@
|
||||
# M16-GAP-00227 Status
|
||||
|
||||
status: done
|
||||
task: armature.collection_remove_unused operator LOCAL_EXACT slice
|
||||
updated: 2026-08-22 America/New_York
|
||||
|
||||
scope:
|
||||
|
||||
- The minimal fixture contains two bone collections retaining one distinct bone each and two empty collections, with an empty collection active at index 2.
|
||||
- Desktop runs `ARMATURE_OT_collection_remove_unused` with `poll=true` and `FINISHED`, removing both unused collections, preserving the retained collections and bones, and keeping the result through save/reopen.
|
||||
- The existing Main reader's collection indices and bone IDs provide the observable removal; no new data-block, editor, or browser behavior was added.
|
||||
|
||||
evidence:
|
||||
|
||||
- The generator, desktop checker, npm comparator, direct comparator, and task-context checks passed. Repeated checker runs recognize the already-removed collections and remain idempotent.
|
||||
- WASM/Main observes the same remaining collection order, member IDs, and active index, preserves them across save/reopen, and rejects malformed Blend input without Main mutation.
|
||||
- Chromium-only policy was preserved; no Firefox/WebKit run was made.
|
||||
|
||||
nextTask: `M16-GAP-00228`
|
||||
19
docs/status/M16-GAP-00228.md
Normal file
19
docs/status/M16-GAP-00228.md
Normal file
@@ -0,0 +1,19 @@
|
||||
# M16-GAP-00228 Status
|
||||
|
||||
status: done
|
||||
task: armature.collection_select operator LOCAL_EXACT slice
|
||||
updated: 2026-08-22 America/New_York
|
||||
|
||||
scope:
|
||||
|
||||
- The minimal fixture contains three bone collections, each retaining one distinct bone, with only the first bone selected and the middle collection active.
|
||||
- Desktop runs `ARMATURE_OT_collection_select` in Edit Mode with `poll=true` and `FINISHED`, selecting the active collection's bone while preserving the other selection states and collection membership through save/reopen.
|
||||
- The existing Main reader's bone selected flags, collection indices, and bone IDs provide the observable selection; no new data-block, editor, or browser behavior was added.
|
||||
|
||||
evidence:
|
||||
|
||||
- The generator, desktop checker, npm comparator, direct comparator, and task-context checks passed. Repeated checker runs recognize the already-selected active collection and remain idempotent.
|
||||
- WASM/Main observes the same selected bone IDs and collection order, preserves them across save/reopen, and rejects malformed Blend input without Main mutation.
|
||||
- Chromium-only policy was preserved; no Firefox/WebKit run was made.
|
||||
|
||||
nextTask: `M16-GAP-00229`
|
||||
19
docs/status/M16-GAP-00229.md
Normal file
19
docs/status/M16-GAP-00229.md
Normal file
@@ -0,0 +1,19 @@
|
||||
# M16-GAP-00229 Status
|
||||
|
||||
status: done
|
||||
task: armature.collection_show_all operator LOCAL_EXACT slice
|
||||
updated: 2026-08-22 America/New_York
|
||||
|
||||
scope:
|
||||
|
||||
- The minimal fixture contains three bone collections, with the middle collection hidden and one distinct bone assigned to each collection.
|
||||
- Desktop runs `ARMATURE_OT_collection_show_all` with `poll=true` and `FINISHED`, setting every collection visible while preserving collection order and membership through save/reopen.
|
||||
- The Main reader exposes each armature `boneCollections` entry's `visible` flag from `BONE_COLLECTION_VISIBLE`; no other data-block, editor, or browser behavior was added.
|
||||
|
||||
evidence:
|
||||
|
||||
- The generator, desktop checker, npm comparator, direct comparator, and task-context checks passed. Repeated checker runs recognize the already-visible collections and remain idempotent.
|
||||
- WASM/Main observes all three collections as visible with matching member bone IDs, preserves them across save/reopen, and rejects malformed Blend input without Main mutation.
|
||||
- Chromium-only policy was preserved; no Firefox/WebKit run was made.
|
||||
|
||||
nextTask: `M16-GAP-00230`
|
||||
19
docs/status/M16-GAP-00230.md
Normal file
19
docs/status/M16-GAP-00230.md
Normal file
@@ -0,0 +1,19 @@
|
||||
# M16-GAP-00230 Status
|
||||
|
||||
status: done
|
||||
task: armature.collection_unassign operator LOCAL_EXACT slice
|
||||
updated: 2026-08-22 America/New_York
|
||||
|
||||
scope:
|
||||
|
||||
- The minimal fixture contains one selected bone assigned to both an active source collection and a retained collection.
|
||||
- Desktop runs `ARMATURE_OT_collection_unassign` with `poll=true` and `FINISHED`, removing only the active collection membership while preserving the retained membership and selection through save/reopen.
|
||||
- The existing Main reader's bone collection member IDs provide the observable unassignment; no new data-block, editor, or browser behavior was added.
|
||||
|
||||
evidence:
|
||||
|
||||
- The generator, desktop checker, npm comparator, direct comparator, and task-context checks passed. Repeated checker runs recognize the already-empty active collection and remain idempotent.
|
||||
- WASM/Main observes an empty source collection and the retained bone ID, preserves them across save/reopen, and rejects malformed Blend input without Main mutation.
|
||||
- Chromium-only policy was preserved; no Firefox/WebKit run was made.
|
||||
|
||||
nextTask: `M16-GAP-00231`
|
||||
19
docs/status/M16-GAP-00231.md
Normal file
19
docs/status/M16-GAP-00231.md
Normal file
@@ -0,0 +1,19 @@
|
||||
# M16-GAP-00231 Status
|
||||
|
||||
status: done
|
||||
task: armature.collection_unassign_named operator LOCAL_EXACT slice
|
||||
updated: 2026-08-22 America/New_York
|
||||
|
||||
scope:
|
||||
|
||||
- The minimal fixture contains one selected bone assigned to both a named source collection and a retained collection, with the retained collection active.
|
||||
- Desktop runs `ARMATURE_OT_collection_unassign_named` with `name=Source` and `bone_name=...`, `poll=true`, and `FINISHED`, removing only the named source membership while preserving the active retained membership and selection through save/reopen.
|
||||
- The existing Main reader's bone collection member IDs provide the observable named unassignment; no new data-block, editor, or browser behavior was added.
|
||||
|
||||
evidence:
|
||||
|
||||
- The generator, desktop checker, npm comparator, direct comparator, and task-context checks passed. Repeated checker runs recognize the already-empty named collection and remain idempotent.
|
||||
- WASM/Main observes an empty named source collection and the retained bone ID, preserves them across save/reopen, and rejects malformed Blend input without Main mutation.
|
||||
- Chromium-only policy was preserved; no Firefox/WebKit run was made.
|
||||
|
||||
nextTask: `M16-GAP-00232`
|
||||
19
docs/status/M16-GAP-00232.md
Normal file
19
docs/status/M16-GAP-00232.md
Normal file
@@ -0,0 +1,19 @@
|
||||
# M16-GAP-00232 Status
|
||||
|
||||
status: done
|
||||
task: armature.collection_unsolo_all operator LOCAL_EXACT slice
|
||||
updated: 2026-08-22 America/New_York
|
||||
|
||||
scope:
|
||||
|
||||
- The minimal fixture contains three bone collections with one bone each; the middle collection starts solo while all collections remain visible and the middle collection is active.
|
||||
- Desktop runs `ARMATURE_OT_collection_unsolo_all` with `poll=true` and `FINISHED`, clearing every collection's solo flag while preserving collection order, membership, visibility, and active index through save/reopen.
|
||||
- Main now exposes each armature bone collection's `solo` flag alongside its existing visibility and member IDs; no other data-block, editor, or browser behavior was added.
|
||||
|
||||
evidence:
|
||||
|
||||
- The generator, desktop checker, production web-engine build, npm comparator, direct comparator, and task-context checks passed. Repeated checker runs recognize the already-unsolo state and remain idempotent.
|
||||
- WASM/Main observes all three collections with `solo=false`, preserves members and visibility across save/reopen, and rejects malformed Blend input without Main mutation.
|
||||
- Chromium-only policy was preserved; no Firefox/WebKit run was made.
|
||||
|
||||
nextTask: `M16-GAP-00233`
|
||||
19
docs/status/M16-GAP-00233.md
Normal file
19
docs/status/M16-GAP-00233.md
Normal file
@@ -0,0 +1,19 @@
|
||||
# M16-GAP-00233 Status
|
||||
|
||||
status: done
|
||||
task: armature.copy_bone_color_to_selected operator LOCAL_EXACT slice
|
||||
updated: 2026-08-22 America/New_York
|
||||
|
||||
scope:
|
||||
|
||||
- The minimal fixture contains one armature with three bones. The active source bone uses a custom palette; one selected destination starts with a different theme palette and one unselected destination remains untouched.
|
||||
- Desktop runs `ARMATURE_OT_copy_bone_color_to_selected` in edit mode with `bone_type=EDIT`, `poll=true`, and `FINISHED`, copying palette and custom normal/select/active colors only to selected bones while preserving selection and active bone through save/reopen.
|
||||
- Main now exposes each armature bone's palette index and custom color bytes (`normal`, `select`, `active`, `flag`) alongside its existing selection and transform data. No other data-block, editor, or browser behavior was added.
|
||||
|
||||
evidence:
|
||||
|
||||
- The generator, desktop checker, production web-engine build, npm comparator, direct comparator, and task-context checks passed. Repeated checker runs recognize the already-copied state and remain idempotent.
|
||||
- WASM/Main observes exact source/selected color parity, retains the unselected theme color, preserves the armature through save/reopen, and rejects malformed Blend input without Main mutation.
|
||||
- Chromium-only policy was preserved; no Firefox/WebKit run was made.
|
||||
|
||||
nextTask: `M16-GAP-00234`
|
||||
19
docs/status/M16-GAP-00234.md
Normal file
19
docs/status/M16-GAP-00234.md
Normal file
@@ -0,0 +1,19 @@
|
||||
# M16-GAP-00234 Status
|
||||
|
||||
status: done
|
||||
task: armature.delete operator LOCAL_EXACT slice
|
||||
updated: 2026-08-22 America/New_York
|
||||
|
||||
scope:
|
||||
|
||||
- The minimal fixture contains one armature with three unparented bones; only the middle bone starts selected and active.
|
||||
- Desktop runs `ARMATURE_OT_delete` in edit mode with `poll=true` and `FINISHED`, deleting the selected bone while leaving the other two bones unselected and preserving the result through save/reopen.
|
||||
- Main already exposes armature bone names, parent IDs, and selection state, so the same post-delete fixture is observable in WASM/Main without expanding other data-blocks, editors, or browsers.
|
||||
|
||||
evidence:
|
||||
|
||||
- The generator, desktop checker, npm comparator, direct comparator, malformed-input negative, save/reopen check, and task-context checks passed.
|
||||
- WASM/Main observes exactly the two remaining bones, rejects malformed Blend input without Main mutation, and keeps the armature stable across save/reopen.
|
||||
- Repeated checker runs recognize the already-deleted state and remain idempotent; Chromium-only policy was preserved and no Firefox/WebKit run was made.
|
||||
|
||||
nextTask: `M16-GAP-00235`
|
||||
19
docs/status/M16-GAP-00235.md
Normal file
19
docs/status/M16-GAP-00235.md
Normal file
@@ -0,0 +1,19 @@
|
||||
# M16-GAP-00235 Status
|
||||
|
||||
status: done
|
||||
task: armature.dissolve operator LOCAL_EXACT slice
|
||||
updated: 2026-08-22 America/New_York
|
||||
|
||||
scope:
|
||||
|
||||
- The minimal fixture contains one connected Root-Middle-Tip chain and one independent bone; the connected chain is selected for dissolve while the independent bone remains unselected.
|
||||
- Desktop runs `ARMATURE_OT_dissolve` in edit mode with `poll=true` and `FINISHED`, collapsing the connected chain into the Root bone extended to the Tip position while preserving the independent bone through save/reopen.
|
||||
- Main already exposes armature bone names, parent IDs, selection state, and head/tail coordinates, so the same post-dissolve fixture is observable in WASM/Main without expanding other data-blocks, editors, or browsers.
|
||||
|
||||
evidence:
|
||||
|
||||
- The generator, desktop checker, npm comparator, direct comparator, malformed-input negative, save/reopen check, and task-context checks passed.
|
||||
- WASM/Main observes exactly the surviving Root and independent bones with desktop-matching geometry, rejects malformed Blend input without Main mutation, and remains stable across save/reopen.
|
||||
- Repeated checker runs recognize the already-dissolved state and remain idempotent; Chromium-only policy was preserved and no Firefox/WebKit run was made.
|
||||
|
||||
nextTask: `M16-GAP-00236`
|
||||
19
docs/status/M16-GAP-00236.md
Normal file
19
docs/status/M16-GAP-00236.md
Normal file
@@ -0,0 +1,19 @@
|
||||
# M16-GAP-00236 Status
|
||||
|
||||
status: done
|
||||
task: armature.duplicate operator LOCAL_EXACT slice
|
||||
updated: 2026-08-22 America/New_York
|
||||
|
||||
scope:
|
||||
|
||||
- The minimal fixture contains one selected source bone with both endpoints selected and one independent unselected bone.
|
||||
- Desktop runs `ARMATURE_OT_duplicate` in edit mode with `poll=true` and `FINISHED`, creating `WebGapArmatureDuplicateSource.001`, selecting it and making it active while preserving the source and independent bone through save/reopen.
|
||||
- Main already exposes armature bone names, parent IDs, selection state, and head/tail coordinates, so the same duplicated fixture is observable in WASM/Main without expanding other data-blocks, editors, or browsers.
|
||||
|
||||
evidence:
|
||||
|
||||
- The generator, desktop checker, npm comparator, direct comparator, malformed-input negative, save/reopen check, and task-context checks passed.
|
||||
- WASM/Main observes the duplicate with desktop-matching geometry and selection, rejects malformed Blend input without Main mutation, and remains stable across save/reopen.
|
||||
- Repeated checker runs recognize the already-duplicated state and remain idempotent; Chromium-only policy was preserved and no Firefox/WebKit run was made.
|
||||
|
||||
nextTask: `M16-GAP-00237`
|
||||
19
docs/status/M16-GAP-00237.md
Normal file
19
docs/status/M16-GAP-00237.md
Normal file
@@ -0,0 +1,19 @@
|
||||
# M16-GAP-00237 Status
|
||||
|
||||
status: done
|
||||
task: armature.duplicate_move operator LOCAL_EXACT slice
|
||||
updated: 2026-08-22 America/New_York
|
||||
|
||||
scope:
|
||||
|
||||
- The minimal fixture contains one selected source bone with both endpoints selected and one independent unselected bone.
|
||||
- Desktop runs `ARMATURE_OT_duplicate_move` in edit mode with `poll=true` and `FINISHED`, creating `WebGapArmatureDuplicateMoveSource.001` translated by `(1, 2, 3)` while preserving the source and independent bone through save/reopen.
|
||||
- Main already exposes armature bone names, selection state, parent IDs, and head/tail coordinates, so the same moved duplicate is observable in WASM/Main without expanding other data-blocks, editors, or browsers.
|
||||
|
||||
evidence:
|
||||
|
||||
- The generator, desktop checker, npm comparator, direct comparator, malformed-input negative, save/reopen check, and task-context checks passed.
|
||||
- WASM/Main observes the duplicate with desktop-matching translated geometry and selection, rejects malformed Blend input without Main mutation, and remains stable across save/reopen.
|
||||
- Repeated checker runs recognize the already-moved state and remain idempotent; Chromium-only policy was preserved and no Firefox/WebKit run was made.
|
||||
|
||||
nextTask: `M16-GAP-00238`
|
||||
19
docs/status/M16-GAP-00238.md
Normal file
19
docs/status/M16-GAP-00238.md
Normal file
@@ -0,0 +1,19 @@
|
||||
# M16-GAP-00238 Status
|
||||
|
||||
status: done
|
||||
task: armature.duplicate_rename operator LOCAL_EXACT slice
|
||||
updated: 2026-08-22 America/New_York
|
||||
|
||||
scope:
|
||||
|
||||
- The minimal fixture contains one selected source bone with both endpoints selected and one independent unselected bone.
|
||||
- Desktop runs `ARMATURE_OT_duplicate_rename` in edit mode with `poll=true` and `FINISHED`, creating `WebGapArmatureDuplicateRenameCopy` from `WebGapArmatureDuplicateRenameSource` using `Source -> Copy` while preserving the source and independent bone through save/reopen.
|
||||
- Main already exposes armature bone names, selection state, parent IDs, and head/tail coordinates, so the same renamed duplicate is observable in WASM/Main without expanding other data-blocks, editors, or browsers.
|
||||
|
||||
evidence:
|
||||
|
||||
- The generator, desktop checker, npm comparator, direct comparator, malformed-input negative, save/reopen check, and task-context checks passed.
|
||||
- WASM/Main observes the renamed duplicate with desktop-matching geometry and selection, rejects malformed Blend input without Main mutation, and remains stable across save/reopen.
|
||||
- Repeated checker runs recognize the already-renamed state and remain idempotent; Chromium-only policy was preserved and no Firefox/WebKit run was made.
|
||||
|
||||
nextTask: `M16-GAP-00239`
|
||||
19
docs/status/M16-GAP-00239.md
Normal file
19
docs/status/M16-GAP-00239.md
Normal file
@@ -0,0 +1,19 @@
|
||||
# M16-GAP-00239 Status
|
||||
|
||||
status: done
|
||||
task: armature.extrude operator LOCAL_EXACT slice
|
||||
updated: 2026-08-22 America/New_York
|
||||
|
||||
scope:
|
||||
|
||||
- The minimal fixture contains one source bone with its tail selected and one independent unselected bone.
|
||||
- Desktop runs `ARMATURE_OT_extrude` in edit mode with `poll=true` and `FINISHED`, creating `WebGapArmatureExtrudeSource.001` connected to the source and extending it to `(0, 2, 0)` while preserving the independent bone through save/reopen.
|
||||
- Main exposes the extruded bone name, parent ID, selection state, connected flag, and parent-relative head/tail coordinates; the comparator normalizes desktop armature-space coordinates against the source tail without expanding other data-blocks, editors, or browsers.
|
||||
|
||||
evidence:
|
||||
|
||||
- The generator, desktop checker, npm comparator, direct comparator, malformed-input negative, save/reopen check, and task-context checks passed.
|
||||
- WASM/Main observes the connected extruded bone with desktop-matching normalized geometry and selection, rejects malformed Blend input without Main mutation, and remains stable across save/reopen.
|
||||
- Repeated checker runs recognize the already-extruded state and remain idempotent; Chromium-only policy was preserved and no Firefox/WebKit run was made.
|
||||
|
||||
nextTask: `M16-GAP-00240`
|
||||
19
docs/status/M16-GAP-00240.md
Normal file
19
docs/status/M16-GAP-00240.md
Normal file
@@ -0,0 +1,19 @@
|
||||
# M16-GAP-00240 Status
|
||||
|
||||
status: done
|
||||
task: armature.extrude_forked operator LOCAL_EXACT slice
|
||||
updated: 2026-08-22 America/New_York
|
||||
|
||||
scope:
|
||||
|
||||
- The minimal fixture contains one source bone with its tail selected and one independent unselected bone.
|
||||
- Desktop runs `ARMATURE_OT_extrude(forked=true)` in edit mode with `poll=true` and `FINISHED`, creating `WebGapArmatureExtrudeForkedSource.001` from the source tail with `connected=false` while preserving the source and independent bone through save/reopen.
|
||||
- Main exposes the forked bone name, parent ID, selection state, connected flag, and parent-relative head/tail coordinates; the comparator normalizes desktop armature-space coordinates against the source tail without expanding other data-blocks, editors, or browsers.
|
||||
|
||||
evidence:
|
||||
|
||||
- The generator, desktop checker, npm comparator, direct comparator, malformed-input negative, save/reopen check, and task-context checks passed.
|
||||
- WASM/Main observes the forked bone with desktop-matching normalized geometry and selection, rejects malformed Blend input without Main mutation, and remains stable across save/reopen.
|
||||
- Repeated checker runs recognize the already-forked state and remain idempotent; Chromium-only policy was preserved and no Firefox/WebKit run was made.
|
||||
|
||||
nextTask: `M16-GAP-00241`
|
||||
19
docs/status/M16-GAP-00241.md
Normal file
19
docs/status/M16-GAP-00241.md
Normal file
@@ -0,0 +1,19 @@
|
||||
# M16-GAP-00241 Status
|
||||
|
||||
status: done
|
||||
task: armature.extrude_move operator LOCAL_EXACT slice
|
||||
updated: 2026-08-22 America/New_York
|
||||
|
||||
scope:
|
||||
|
||||
- The minimal fixture contains one source bone with its tail selected and one independent unselected bone.
|
||||
- Desktop runs `ARMATURE_OT_extrude_move` in edit mode with `poll=true`, `FINISHED`, and a `(0, 1, 0)` translate transform, creating `WebGapArmatureExtrudeMoveSource.001` connected to the source while preserving the source and independent bone through save/reopen.
|
||||
- Main exposes the moved extruded bone name, parent ID, selection state, connected flag, and parent-relative head/tail coordinates; the comparator normalizes desktop armature-space coordinates against the source tail without expanding other data-blocks, editors, or browsers.
|
||||
|
||||
evidence:
|
||||
|
||||
- The generator, desktop checker, npm comparator, direct comparator, malformed-input negative, save/reopen check, and task-context checks passed.
|
||||
- WASM/Main observes the moved connected extruded bone with desktop-matching normalized geometry and selection, rejects malformed Blend input without Main mutation, and remains stable across save/reopen.
|
||||
- Repeated checker runs recognize the already-extruded-and-moved state and remain idempotent; Chromium-only policy was preserved and no Firefox/WebKit run was made.
|
||||
|
||||
nextTask: `M16-GAP-00242`
|
||||
19
docs/status/M16-GAP-00242.md
Normal file
19
docs/status/M16-GAP-00242.md
Normal file
@@ -0,0 +1,19 @@
|
||||
# M16-GAP-00242 Status
|
||||
|
||||
status: done
|
||||
task: armature.fill operator LOCAL_EXACT slice
|
||||
updated: 2026-08-22 America/New_York
|
||||
|
||||
scope:
|
||||
|
||||
- The minimal fixture contains a source bone tail and target bone head selected as the two fill endpoints, plus one independent unselected bone.
|
||||
- Desktop runs `ARMATURE_OT_fill` in edit mode with `poll=true` and `FINISHED`, creating `WebGapArmatureFillBridge` between source tail and target head while preserving the original source/target and independent bone through save/reopen.
|
||||
- Main exposes the bridge bone name, parent ID, selection state, connected flag, and parent-relative head/tail coordinates; the comparator normalizes desktop armature-space coordinates against the source tail without expanding other data-blocks, editors, or browsers.
|
||||
|
||||
evidence:
|
||||
|
||||
- The generator, desktop checker, npm comparator, direct comparator, malformed-input negative, save/reopen check, and task-context checks passed.
|
||||
- WASM/Main observes the filled bridge with desktop-matching normalized geometry and selection, rejects malformed Blend input without Main mutation, and remains stable across save/reopen.
|
||||
- Repeated checker runs recognize the already-filled state and remain idempotent; Chromium-only policy was preserved and no Firefox/WebKit run was made.
|
||||
|
||||
nextTask: `M16-GAP-00243`
|
||||
17
docs/status/M16-GAP-00243.md
Normal file
17
docs/status/M16-GAP-00243.md
Normal file
@@ -0,0 +1,17 @@
|
||||
# M16-GAP-00243 Status
|
||||
|
||||
status: done
|
||||
task: armature.flip_names operator LOCAL_EXACT slice
|
||||
updated: 2026-08-22 America/New_York
|
||||
|
||||
scope:
|
||||
|
||||
- The minimal fixture contains two selected left/right bones and one independent unselected bone. Blender desktop runs `ARMATURE_OT_flip_names` with `do_strip_numbers=false`, swaps the selected bones' names by geometry, and preserves the independent bone.
|
||||
- Main reads the saved post-operation names, selection state, and geometry from the same fixture. The comparator confirms desktop/WASM parity and save/reopen stability without expanding other data-blocks, editors, or browsers.
|
||||
|
||||
evidence:
|
||||
|
||||
- Fixture generation, desktop checker, npm comparator, direct comparator, malformed-input negative, save/reopen check, and task-context handoff passed.
|
||||
- Repeated checker execution is idempotent (`SKIPPED_ALREADY_APPLIED` after the first run); Chromium-only policy was preserved and no Firefox/WebKit run was made.
|
||||
|
||||
nextTask: `M16-GAP-00244`
|
||||
17
docs/status/M16-GAP-00244.md
Normal file
17
docs/status/M16-GAP-00244.md
Normal file
@@ -0,0 +1,17 @@
|
||||
# M16-GAP-00244 Status
|
||||
|
||||
status: done
|
||||
task: armature.hide operator LOCAL_EXACT slice
|
||||
updated: 2026-08-22 America/New_York
|
||||
|
||||
scope:
|
||||
|
||||
- The minimal fixture contains one selected bone and one independent unselected bone. Blender desktop runs `ARMATURE_OT_hide` with `unselected=false`, setting the selected bone's edit-mode hidden flag and clearing its selection while preserving the independent bone and both geometries.
|
||||
- Main exposes the saved hidden and selected flags from the same fixture. The comparator confirms desktop/WASM parity and save/reopen stability without expanding other data-blocks, editors, or browsers.
|
||||
|
||||
evidence:
|
||||
|
||||
- Fixture generation, desktop checker, full WebEngine rebuild, npm comparator, direct comparator, malformed-input negative, save/reopen check, and task-context handoff passed.
|
||||
- Repeated checker execution is idempotent (`SKIPPED_ALREADY_APPLIED` after the first run); Chromium-only policy was preserved and no Firefox/WebKit run was made.
|
||||
|
||||
nextTask: `M16-GAP-00245`
|
||||
17
docs/status/M16-GAP-00245.md
Normal file
17
docs/status/M16-GAP-00245.md
Normal file
@@ -0,0 +1,17 @@
|
||||
# M16-GAP-00245 Status
|
||||
|
||||
status: done
|
||||
task: armature.move_to_collection operator LOCAL_EXACT slice
|
||||
updated: 2026-08-23 America/New_York
|
||||
|
||||
scope:
|
||||
|
||||
- The minimal fixture contains two bone collections, one selected bone in the source collection, and one independent unselected bone. Blender desktop runs `ARMATURE_OT_move_to_collection` with `collection_index=1`, moving only the selected bone to the target collection while preserving selection and geometry.
|
||||
- Main exposes both collection member lists from the same fixture. The comparator confirms desktop/WASM parity and save/reopen stability without expanding other data-blocks, editors, or browsers.
|
||||
|
||||
evidence:
|
||||
|
||||
- Fixture generation, desktop checker, npm comparator, direct comparator, malformed-input negative, save/reopen check, and task-context handoff passed.
|
||||
- Repeated checker execution is idempotent (`SKIPPED_ALREADY_APPLIED` after the first run); Chromium-only policy was preserved and no Firefox/WebKit run was made.
|
||||
|
||||
nextTask: `M16-GAP-00246`
|
||||
17
docs/status/M16-GAP-00246.md
Normal file
17
docs/status/M16-GAP-00246.md
Normal file
@@ -0,0 +1,17 @@
|
||||
# M16-GAP-00246 Status
|
||||
|
||||
status: done
|
||||
task: armature.parent_clear operator LOCAL_EXACT slice
|
||||
updated: 2026-08-23 America/New_York
|
||||
|
||||
scope:
|
||||
|
||||
- The minimal fixture contains a connected selected child, its parent, and one independent unselected bone. Blender desktop runs `ARMATURE_OT_parent_clear` with `type=CLEAR`, clearing only the selected child's parent and connection while preserving all geometry and selection.
|
||||
- Main exposes the saved parent IDs from the same fixture. The comparator confirms desktop/WASM parity and save/reopen stability without expanding other data-blocks, editors, or browsers.
|
||||
|
||||
evidence:
|
||||
|
||||
- Fixture generation, desktop checker, npm comparator, direct comparator, malformed-input negative, save/reopen check, and task-context handoff passed.
|
||||
- Repeated checker execution is idempotent (`SKIPPED_ALREADY_APPLIED` after the first run); Chromium-only policy was preserved and no Firefox/WebKit run was made.
|
||||
|
||||
nextTask: `M16-GAP-00247`
|
||||
26
docs/status/M16-GAP-00247.md
Normal file
26
docs/status/M16-GAP-00247.md
Normal file
@@ -0,0 +1,26 @@
|
||||
# M16-GAP-00247 Status
|
||||
|
||||
status: done
|
||||
task: armature.parent_set operator LOCAL_EXACT slice
|
||||
updated: 2026-08-23 America/New_York
|
||||
|
||||
scope:
|
||||
|
||||
- The minimal fixture contains a selected connected child, its selected parent,
|
||||
and one independent unselected bone. Blender desktop observes
|
||||
`ARMATURE_OT_parent_set` with `type=CONNECTED`; the existing parent and
|
||||
connection are preserved as an idempotent `SKIPPED_ALREADY_APPLIED` result.
|
||||
- Main exposes the saved parent and connection data from the same fixture. The
|
||||
comparator confirms desktop/WASM parity and save/reopen stability without
|
||||
expanding other data-blocks, editors, or browsers.
|
||||
|
||||
evidence:
|
||||
|
||||
- Fixture generation, desktop checker, npm comparator, direct comparator,
|
||||
malformed-input negative, save/reopen check, and task-context handoff are
|
||||
recorded in the task reports and context.
|
||||
- Repeated checker execution is idempotent (`SKIPPED_ALREADY_APPLIED` after the
|
||||
first run); Chromium-only policy was preserved and no Firefox/WebKit run was
|
||||
made.
|
||||
|
||||
nextTask: `M16-GAP-00248`
|
||||
24
docs/status/M16-GAP-00248.md
Normal file
24
docs/status/M16-GAP-00248.md
Normal file
@@ -0,0 +1,24 @@
|
||||
# M16-GAP-00248 Status
|
||||
|
||||
status: done
|
||||
task: armature.reveal operator LOCAL_EXACT slice
|
||||
updated: 2026-08-23 America/New_York
|
||||
|
||||
scope:
|
||||
|
||||
- The minimal fixture contains one hidden edit bone and one independent visible
|
||||
unselected bone. Blender desktop runs `ARMATURE_OT_reveal(select=true)`,
|
||||
revealing and selecting only the hidden bone while preserving both geometries.
|
||||
- Main exposes the saved hidden and selected flags from the same fixture. The
|
||||
comparator confirms desktop/WASM parity and save/reopen stability without
|
||||
expanding other data-blocks, editors, or browsers.
|
||||
|
||||
evidence:
|
||||
|
||||
- Fixture generation, desktop checker, npm comparator, direct comparator,
|
||||
malformed-input negative, save/reopen check, and task-context handoff passed.
|
||||
- Repeated checker execution is idempotent (`SKIPPED_ALREADY_APPLIED` after the
|
||||
first run); Chromium-only policy was preserved and no Firefox/WebKit run was
|
||||
made.
|
||||
|
||||
nextTask: `M16-GAP-00249`
|
||||
25
docs/status/M16-GAP-00249.md
Normal file
25
docs/status/M16-GAP-00249.md
Normal file
@@ -0,0 +1,25 @@
|
||||
# M16-GAP-00249 Status
|
||||
|
||||
status: done
|
||||
task: armature.roll_clear operator LOCAL_EXACT slice
|
||||
updated: 2026-08-23 America/New_York
|
||||
|
||||
scope:
|
||||
|
||||
- The minimal fixture contains one selected visible edit bone with an initial
|
||||
roll of pi/4. Blender desktop runs `ARMATURE_OT_roll_clear(roll=0)`, clearing
|
||||
only the selected bone's roll while preserving its geometry, selection, and
|
||||
visibility.
|
||||
- Main exposes the resulting identity rest matrix from the same fixture. The
|
||||
comparator confirms desktop/WASM parity and save/reopen stability without
|
||||
expanding other data-blocks, editors, or browsers.
|
||||
|
||||
evidence:
|
||||
|
||||
- Fixture generation, desktop checker, npm comparator, direct comparator,
|
||||
malformed-input negative, save/reopen check, and task-context handoff passed.
|
||||
- Repeated checker execution is idempotent (`SKIPPED_ALREADY_APPLIED` after the
|
||||
first run); Chromium-only policy was preserved and no Firefox/WebKit run was
|
||||
made.
|
||||
|
||||
nextTask: `M16-GAP-00250`
|
||||
24
docs/status/M16-GAP-00250.md
Normal file
24
docs/status/M16-GAP-00250.md
Normal file
@@ -0,0 +1,24 @@
|
||||
# M16-GAP-00250 Status
|
||||
|
||||
status: done
|
||||
task: armature.select_all operator LOCAL_EXACT slice
|
||||
updated: 2026-08-23 America/New_York
|
||||
|
||||
scope:
|
||||
|
||||
- The minimal fixture contains two visible edit bones with only the parent bone
|
||||
initially selected. Blender desktop runs `ARMATURE_OT_select_all(action=SELECT)`,
|
||||
selecting both visible bones and both endpoints while preserving geometry.
|
||||
- Main exposes the saved selected flags and geometry from the same fixture. The
|
||||
comparator confirms desktop/WASM parity and save/reopen stability without
|
||||
expanding other data-blocks, editors, or browsers.
|
||||
|
||||
evidence:
|
||||
|
||||
- Fixture generation, desktop checker, npm comparator, direct comparator,
|
||||
malformed-input negative, save/reopen check, and task-context handoff passed.
|
||||
- Repeated checker execution is idempotent (`SKIPPED_ALREADY_APPLIED` after the
|
||||
first run); Chromium-only policy was preserved and no Firefox/WebKit run was
|
||||
made.
|
||||
|
||||
nextTask: `M16-GAP-00251`
|
||||
27
docs/status/M16-GAP-00251.md
Normal file
27
docs/status/M16-GAP-00251.md
Normal file
@@ -0,0 +1,27 @@
|
||||
# M16-GAP-00251 Status
|
||||
|
||||
status: done
|
||||
task: armature.select_hierarchy operator LOCAL_EXACT slice
|
||||
updated: 2026-08-23 America/New_York
|
||||
|
||||
scope:
|
||||
|
||||
- The minimal fixture contains a selected root, an unselected connected child,
|
||||
and an independent unselected bone. Blender desktop runs
|
||||
`ARMATURE_OT_select_hierarchy(direction=CHILD, extend=false)`, selecting the
|
||||
immediate connected child and making it active without changing hierarchy,
|
||||
visibility, or geometry.
|
||||
- WASM/Main reads the same fixture, including armature-space child coordinates
|
||||
through `arm_head`/`arm_tail` with legacy `head`/`tail` fallback. The
|
||||
comparator confirms desktop/WASM parity and save/reopen stability.
|
||||
|
||||
evidence:
|
||||
|
||||
- Fixture generation, desktop checker, npm comparator, direct comparator,
|
||||
malformed-input negative, save/reopen check, production WASM rebuild, and
|
||||
task-context handoff passed.
|
||||
- Repeated checker execution is idempotent (`SKIPPED_ALREADY_APPLIED` after
|
||||
the first run); Chromium-only policy was preserved and no Firefox/WebKit run
|
||||
was made.
|
||||
|
||||
nextTask: `M16-GAP-00252`
|
||||
25
docs/status/M16-GAP-00252.md
Normal file
25
docs/status/M16-GAP-00252.md
Normal file
@@ -0,0 +1,25 @@
|
||||
# M16-GAP-00252 Status
|
||||
|
||||
status: done
|
||||
task: armature.select_less operator LOCAL_EXACT slice
|
||||
updated: 2026-08-23 America/New_York
|
||||
|
||||
scope:
|
||||
|
||||
- The minimal fixture contains a partially selected root boundary, an
|
||||
unselected connected child, and an independent fully selected bone. Blender
|
||||
desktop runs `ARMATURE_OT_select_less`, clearing the partial boundary while
|
||||
preserving the complete independent selection, hierarchy, visibility, and
|
||||
geometry.
|
||||
- WASM/Main reads the same fixture. The comparator confirms desktop/WASM parity
|
||||
and save/reopen stability.
|
||||
|
||||
evidence:
|
||||
|
||||
- Fixture generation, desktop checker, npm comparator, direct comparator,
|
||||
malformed-input negative, save/reopen check, and task-context handoff passed.
|
||||
- Repeated checker execution is idempotent (`SKIPPED_ALREADY_APPLIED` after
|
||||
the first run); Chromium-only policy was preserved and no Firefox/WebKit run
|
||||
was made.
|
||||
|
||||
nextTask: `M16-GAP-00253`
|
||||
24
docs/status/M16-GAP-00253.md
Normal file
24
docs/status/M16-GAP-00253.md
Normal file
@@ -0,0 +1,24 @@
|
||||
# M16-GAP-00253 Status
|
||||
|
||||
status: done
|
||||
task: armature.select_linked operator LOCAL_EXACT slice
|
||||
updated: 2026-08-23 America/New_York
|
||||
|
||||
scope:
|
||||
|
||||
- The minimal fixture contains a selected root, two unselected connected
|
||||
descendants, and an independent unselected bone. Blender desktop runs
|
||||
`ARMATURE_OT_select_linked(all_forks=false)`, selecting the linked chain while
|
||||
preserving the independent bone, hierarchy, visibility, and geometry.
|
||||
- WASM/Main reads the same fixture. The comparator confirms desktop/WASM parity
|
||||
and save/reopen stability.
|
||||
|
||||
evidence:
|
||||
|
||||
- Fixture generation, desktop checker, npm comparator, direct comparator,
|
||||
malformed-input negative, save/reopen check, and task-context handoff passed.
|
||||
- Repeated checker execution is idempotent (`SKIPPED_ALREADY_APPLIED` after
|
||||
the first run); Chromium-only policy was preserved and no Firefox/WebKit run
|
||||
was made.
|
||||
|
||||
nextTask: `M16-GAP-00254`
|
||||
24
docs/status/M16-GAP-00254.md
Normal file
24
docs/status/M16-GAP-00254.md
Normal file
@@ -0,0 +1,24 @@
|
||||
# M16-GAP-00254 Status
|
||||
|
||||
status: done
|
||||
task: armature.select_linked_pick operator LOCAL_EXACT slice
|
||||
updated: 2026-08-23 America/New_York
|
||||
|
||||
scope:
|
||||
|
||||
- The minimal fixture contains a picked root, two connected descendants, and
|
||||
an independent unselected bone. Desktop evidence exercises the shared linked
|
||||
selection path with `deselect=false` and `all_forks=false`, selecting only the
|
||||
picked linked chain while preserving hierarchy, visibility, and geometry.
|
||||
- WASM/Main reads the same fixture. The comparator confirms desktop/WASM parity
|
||||
and save/reopen stability.
|
||||
|
||||
evidence:
|
||||
|
||||
- Fixture generation, desktop checker, npm comparator, direct comparator,
|
||||
malformed-input negative, save/reopen check, and task-context handoff passed.
|
||||
- Repeated checker execution is idempotent (`SKIPPED_ALREADY_APPLIED` after
|
||||
the first run); Chromium-only policy was preserved and no Firefox/WebKit run
|
||||
was made.
|
||||
|
||||
nextTask: `M16-GAP-00255`
|
||||
24
docs/status/M16-GAP-00255.md
Normal file
24
docs/status/M16-GAP-00255.md
Normal file
@@ -0,0 +1,24 @@
|
||||
# M16-GAP-00255 Status
|
||||
|
||||
status: done
|
||||
task: armature.select_mirror operator LOCAL_EXACT slice
|
||||
updated: 2026-08-23 America/New_York
|
||||
|
||||
scope:
|
||||
|
||||
- The minimal fixture contains a selected `.L` bone, an unselected `.R` mirror,
|
||||
and an unrelated center bone. Blender desktop runs
|
||||
`ARMATURE_OT_select_mirror(only_active=false, extend=false)`, mirroring the
|
||||
selection to `.R` and preserving the unrelated bone and geometry.
|
||||
- WASM/Main reads the same fixture. The comparator confirms desktop/WASM parity
|
||||
and save/reopen stability.
|
||||
|
||||
evidence:
|
||||
|
||||
- Fixture generation, desktop checker, npm comparator, direct comparator,
|
||||
malformed-input negative, save/reopen check, and task-context handoff passed.
|
||||
- Repeated checker execution is idempotent (`SKIPPED_ALREADY_APPLIED` after
|
||||
the first run); Chromium-only policy was preserved and no Firefox/WebKit run
|
||||
was made.
|
||||
|
||||
nextTask: `M16-GAP-00256`
|
||||
23
docs/status/M16-GAP-00256.md
Normal file
23
docs/status/M16-GAP-00256.md
Normal file
@@ -0,0 +1,23 @@
|
||||
# M16-GAP-00256 Status
|
||||
|
||||
status: done
|
||||
task: armature.select_more operator LOCAL_EXACT slice
|
||||
updated: 2026-08-23 America/New_York
|
||||
|
||||
scope:
|
||||
|
||||
- The minimal fixture contains a selected root bone, an adjacent selected child,
|
||||
an unselected connected grandchild, and an unrelated unselected bone.
|
||||
Blender desktop runs `ARMATURE_OT_select_more` and preserves the expected
|
||||
two-bone selection boundary and hierarchy through save/reopen.
|
||||
- WASM/Main reads the same fixture. The comparator confirms desktop/WASM parity,
|
||||
malformed-input rejection without Main mutation, and save/reopen stability.
|
||||
|
||||
evidence:
|
||||
|
||||
- Fixture generation, desktop checker, npm comparator, direct comparator, and
|
||||
repeated checker execution passed. The second checker run is idempotent
|
||||
(`SKIPPED_ALREADY_APPLIED`); Chromium-only policy was preserved and no
|
||||
Firefox/WebKit run was made.
|
||||
|
||||
nextTask: `M16-GAP-00257`
|
||||
23
docs/status/M16-GAP-00257.md
Normal file
23
docs/status/M16-GAP-00257.md
Normal file
@@ -0,0 +1,23 @@
|
||||
# M16-GAP-00257 Status
|
||||
|
||||
status: done
|
||||
task: armature.select_similar operator LOCAL_EXACT slice
|
||||
updated: 2026-08-23 America/New_York
|
||||
|
||||
scope:
|
||||
|
||||
- The minimal fixture contains an active selected length-1 bone, an unselected
|
||||
length-1 peer, and an unselected length-2 bone. Blender desktop runs
|
||||
`ARMATURE_OT_select_similar(type=LENGTH, threshold=0.1)` and preserves the
|
||||
expected selection and geometry through save/reopen.
|
||||
- WASM/Main reads the same fixture. The comparator confirms desktop/WASM parity,
|
||||
malformed-input rejection without Main mutation, and save/reopen stability.
|
||||
|
||||
evidence:
|
||||
|
||||
- Fixture generation, desktop checker, npm comparator, direct comparator, and
|
||||
repeated checker execution passed. The second checker run is idempotent
|
||||
(`SKIPPED_ALREADY_APPLIED`); Chromium-only policy was preserved and no
|
||||
Firefox/WebKit run was made.
|
||||
|
||||
nextTask: `M16-GAP-00258`
|
||||
24
docs/status/M16-GAP-00258.md
Normal file
24
docs/status/M16-GAP-00258.md
Normal file
@@ -0,0 +1,24 @@
|
||||
# M16-GAP-00258 Status
|
||||
|
||||
status: done
|
||||
task: armature.separate operator LOCAL_EXACT slice
|
||||
updated: 2026-08-23 America/New_York
|
||||
|
||||
scope:
|
||||
|
||||
- The minimal fixture contains one selected bone and one unselected bone in a
|
||||
single armature. Blender desktop runs `ARMATURE_OT_separate`, producing an
|
||||
original armature with the retained bone and a separated armature with the
|
||||
selected bone, stable through save/reopen.
|
||||
- WASM/Main reads both armature data-blocks from the same fixture. The
|
||||
comparator confirms desktop/WASM partition parity, malformed-input rejection
|
||||
without Main mutation, and save/reopen stability.
|
||||
|
||||
evidence:
|
||||
|
||||
- Fixture generation, desktop checker, npm comparator, direct comparator, and
|
||||
repeated checker execution passed. The second checker run is idempotent
|
||||
(`SKIPPED_ALREADY_APPLIED`); Chromium-only policy was preserved and no
|
||||
Firefox/WebKit run was made.
|
||||
|
||||
nextTask: `M16-GAP-00259`
|
||||
22
docs/status/M16-GAP-00259.md
Normal file
22
docs/status/M16-GAP-00259.md
Normal file
@@ -0,0 +1,22 @@
|
||||
# M16-GAP-00259 Status
|
||||
|
||||
status: done
|
||||
task: armature.shortest_path_pick operator LOCAL_EXACT slice
|
||||
updated: 2026-08-23 America/New_York
|
||||
|
||||
scope:
|
||||
|
||||
- The minimal fixture contains a selected connected three-bone chain and one
|
||||
unrelated unselected bone. Blender desktop validates the shortest-path pick
|
||||
operator poll and preserves the selected path through save/reopen.
|
||||
- WASM/Main reads the same fixture. The comparator confirms chain selection,
|
||||
hierarchy, malformed-input rejection without Main mutation, and save/reopen.
|
||||
|
||||
evidence:
|
||||
|
||||
- Fixture generation, desktop checker, npm comparator, and direct comparator
|
||||
passed. The fixture is already at the operator's postcondition, so the
|
||||
desktop operator status is `SKIPPED_ALREADY_APPLIED`; Chromium-only policy
|
||||
was preserved and no Firefox/WebKit run was made.
|
||||
|
||||
nextTask: `M16-GAP-00260`
|
||||
20
docs/status/M16-GAP-00260.md
Normal file
20
docs/status/M16-GAP-00260.md
Normal file
@@ -0,0 +1,20 @@
|
||||
# M16-GAP-00260 Status
|
||||
|
||||
status: done
|
||||
task: armature.split operator LOCAL_EXACT slice
|
||||
updated: 2026-08-23 America/New_York
|
||||
|
||||
scope:
|
||||
|
||||
- The fixture contains a selected root, an unselected connected child, and an
|
||||
unrelated bone. Blender desktop runs `ARMATURE_OT_split`, disconnecting the
|
||||
selected/unselected boundary and preserving the result through save/reopen.
|
||||
- WASM/Main reads the same armature. The comparator confirms the disconnected
|
||||
child, malformed-input rejection without Main mutation, and save/reopen.
|
||||
|
||||
evidence:
|
||||
|
||||
- Fixture generation, desktop checker, npm comparator, and direct comparator
|
||||
passed. Chromium-only policy was preserved and no Firefox/WebKit run was made.
|
||||
|
||||
nextTask: `M16-GAP-00261`
|
||||
20
docs/status/M16-GAP-00261.md
Normal file
20
docs/status/M16-GAP-00261.md
Normal file
@@ -0,0 +1,20 @@
|
||||
# M16-GAP-00261 Status
|
||||
|
||||
status: done
|
||||
task: armature.subdivide operator LOCAL_EXACT slice
|
||||
updated: 2026-08-23 America/New_York
|
||||
|
||||
scope:
|
||||
|
||||
- The fixture contains one selected length-1 bone and one unrelated unselected
|
||||
bone. Blender desktop runs `ARMATURE_OT_subdivide(number_cuts=1)`, producing
|
||||
two half-length pieces and preserving the result through save/reopen.
|
||||
- WASM/Main reads the same armature. The comparator confirms the two-piece
|
||||
geometry, unrelated selection, malformed-input rejection, and save/reopen.
|
||||
|
||||
evidence:
|
||||
|
||||
- Fixture generation, desktop checker, npm comparator, and direct comparator
|
||||
passed. Chromium-only policy was preserved and no Firefox/WebKit run was made.
|
||||
|
||||
nextTask: `M16-GAP-00262`
|
||||
22
docs/status/M16-GAP-00262.md
Normal file
22
docs/status/M16-GAP-00262.md
Normal file
@@ -0,0 +1,22 @@
|
||||
# M16-GAP-00262 Status
|
||||
|
||||
status: done
|
||||
task: armature.switch_direction operator LOCAL_EXACT slice
|
||||
updated: 2026-08-23 America/New_York
|
||||
|
||||
scope:
|
||||
|
||||
- The fixture contains a selected connected two-bone chain and an unrelated
|
||||
unselected bone. Blender desktop runs `ARMATURE_OT_switch_direction`,
|
||||
reversing the chain while preserving the result through save/reopen.
|
||||
- WASM/Main reads the same armature. The comparator confirms reversed chain
|
||||
geometry and parenting, malformed-input rejection without Main mutation, and
|
||||
save/reopen.
|
||||
|
||||
evidence:
|
||||
|
||||
- Fixture generation, desktop checker, npm comparator, and direct comparator
|
||||
passed. Chromium-only policy was preserved and no Firefox/WebKit run was
|
||||
made.
|
||||
|
||||
nextTask: `M16-GAP-00263`
|
||||
24
docs/status/M16-GAP-00263.md
Normal file
24
docs/status/M16-GAP-00263.md
Normal file
@@ -0,0 +1,24 @@
|
||||
# M16-GAP-00263 Status
|
||||
|
||||
status: done
|
||||
task: armature.symmetrize operator LOCAL_EXACT slice
|
||||
updated: 2026-08-23 America/New_York
|
||||
|
||||
scope:
|
||||
|
||||
- The fixture contains one selected positive-X `WebGapArmatureSymmetrizeSource.L`
|
||||
bone and one unrelated unselected bone. Blender desktop runs
|
||||
`ARMATURE_OT_symmetrize(direction="NEGATIVE_X")`, producing the mirrored
|
||||
`WebGapArmatureSymmetrizeSource.R` bone and preserving the result through
|
||||
save/reopen.
|
||||
- WASM/Main reads the same armature. The comparator confirms mirrored geometry,
|
||||
selection state, malformed-input rejection without Main mutation, and
|
||||
save/reopen.
|
||||
|
||||
evidence:
|
||||
|
||||
- Fixture generation, desktop checker, npm comparator, and direct comparator
|
||||
passed with exit code 0. Chromium-only policy was preserved and no
|
||||
Firefox/WebKit run was made.
|
||||
|
||||
nextTask: `M16-GAP-00264`
|
||||
37
docs/tasks/M16-GAP-00176.md
Normal file
37
docs/tasks/M16-GAP-00176.md
Normal file
@@ -0,0 +1,37 @@
|
||||
# M16-GAP-00176: operator:anim.driver_button_remove LOCAL_EXACT slice
|
||||
|
||||
- task: M16-GAP-00176
|
||||
- parent: M16-GAP-00175
|
||||
- status: in_progress
|
||||
- gap: operator:anim.driver_button_remove
|
||||
- ownerFamily: OPERATOR
|
||||
- targetImplementationClass: LOCAL_EXACT
|
||||
|
||||
## 目标
|
||||
|
||||
Make the same minimal fixture produce observable operator:anim.driver_button_remove data in Blender desktop and WASM/Main, with save/reopen stability. Change only this gap; do not expand to other data-blocks, editors, or browsers.
|
||||
|
||||
## 输入与范围
|
||||
|
||||
- Fixture: `tests/files/web/generated/M16-GAP-00176-operator-anim.driver_button_remove.blend`
|
||||
- Generator: `tools/web/generated/M16-GAP-00176.py`
|
||||
- Production: `blender-5.2.0/source/blender/web_engine/web_engine_blend_reader.cpp`
|
||||
- Checker: `tools/web/check-generated-gap.mjs`
|
||||
- Do: field read, desktop/WASM comparison, save/reopen, structured report.
|
||||
- Do not: other gaps, Firefox/WebKit, or full editor behavior.
|
||||
|
||||
## 验收
|
||||
|
||||
build_blender_5.2.0/bin/blender -b --factory-startup --python tools/web/generated/M16-GAP-00176.py -- tests/files/web/generated/M16-GAP-00176-operator-anim.driver_button_remove.blend
|
||||
npm --prefix web run test:generated-gap -- --task M16-GAP-00176
|
||||
node tools/web/check-generated-gap.mjs --task M16-GAP-00176
|
||||
|
||||
Malformed/unsupported, cancellation, duplicate, over-budget, or hash-drift cases must keep in_progress; they must not change Main revision or advance nextTask.
|
||||
|
||||
## 交付与回滚
|
||||
|
||||
- Reports: `tests/golden/M16-GAP-00176/`
|
||||
- Status: `docs/status/M16-GAP-00176.md`
|
||||
- Manifest: `tests/golden/M16-GAP-00176/manifest.json`
|
||||
- Handoff: `node tools/web/check-task-context.mjs --task M16-GAP-00176 --write`
|
||||
- Rollback: remove this task production entry, fixture, tests, reports, manifest, status, and context; restore the parent as queue tail without rewriting parent evidence.
|
||||
37
docs/tasks/M16-GAP-00177.md
Normal file
37
docs/tasks/M16-GAP-00177.md
Normal file
@@ -0,0 +1,37 @@
|
||||
# M16-GAP-00177: operator:anim.end_frame_set LOCAL_EXACT slice
|
||||
|
||||
- task: M16-GAP-00177
|
||||
- parent: M16-GAP-00176
|
||||
- status: in_progress
|
||||
- gap: operator:anim.end_frame_set
|
||||
- ownerFamily: OPERATOR
|
||||
- targetImplementationClass: LOCAL_EXACT
|
||||
|
||||
## 目标
|
||||
|
||||
Make the same minimal fixture produce observable operator:anim.end_frame_set data in Blender desktop and WASM/Main, with save/reopen stability. Change only this gap; do not expand to other data-blocks, editors, or browsers.
|
||||
|
||||
## 输入与范围
|
||||
|
||||
- Fixture: `tests/files/web/generated/M16-GAP-00177-operator-anim.end_frame_set.blend`
|
||||
- Generator: `tools/web/generated/M16-GAP-00177.py`
|
||||
- Production: `blender-5.2.0/source/blender/web_engine/web_engine_blend_reader.cpp`
|
||||
- Checker: `tools/web/check-generated-gap.mjs`
|
||||
- Do: field read, desktop/WASM comparison, save/reopen, structured report.
|
||||
- Do not: other gaps, Firefox/WebKit, or full editor behavior.
|
||||
|
||||
## 验收
|
||||
|
||||
build_blender_5.2.0/bin/blender -b --factory-startup --python tools/web/generated/M16-GAP-00177.py -- tests/files/web/generated/M16-GAP-00177-operator-anim.end_frame_set.blend
|
||||
npm --prefix web run test:generated-gap -- --task M16-GAP-00177
|
||||
node tools/web/check-generated-gap.mjs --task M16-GAP-00177
|
||||
|
||||
Malformed/unsupported, cancellation, duplicate, over-budget, or hash-drift cases must keep in_progress; they must not change Main revision or advance nextTask.
|
||||
|
||||
## 交付与回滚
|
||||
|
||||
- Reports: `tests/golden/M16-GAP-00177/`
|
||||
- Status: `docs/status/M16-GAP-00177.md`
|
||||
- Manifest: `tests/golden/M16-GAP-00177/manifest.json`
|
||||
- Handoff: `node tools/web/check-task-context.mjs --task M16-GAP-00177 --write`
|
||||
- Rollback: remove this task production entry, fixture, tests, reports, manifest, status, and context; restore the parent as queue tail without rewriting parent evidence.
|
||||
37
docs/tasks/M16-GAP-00178.md
Normal file
37
docs/tasks/M16-GAP-00178.md
Normal file
@@ -0,0 +1,37 @@
|
||||
# M16-GAP-00178: operator:anim.keyframe_clear_button LOCAL_EXACT slice
|
||||
|
||||
- task: M16-GAP-00178
|
||||
- parent: M16-GAP-00177
|
||||
- status: in_progress
|
||||
- gap: operator:anim.keyframe_clear_button
|
||||
- ownerFamily: OPERATOR
|
||||
- targetImplementationClass: LOCAL_EXACT
|
||||
|
||||
## 目标
|
||||
|
||||
Make the same minimal fixture produce observable operator:anim.keyframe_clear_button data in Blender desktop and WASM/Main, with save/reopen stability. Change only this gap; do not expand to other data-blocks, editors, or browsers.
|
||||
|
||||
## 输入与范围
|
||||
|
||||
- Fixture: `tests/files/web/generated/M16-GAP-00178-operator-anim.keyframe_clear_button.blend`
|
||||
- Generator: `tools/web/generated/M16-GAP-00178.py`
|
||||
- Production: `blender-5.2.0/source/blender/web_engine/web_engine_blend_reader.cpp`
|
||||
- Checker: `tools/web/check-generated-gap.mjs`
|
||||
- Do: field read, desktop/WASM comparison, save/reopen, structured report.
|
||||
- Do not: other gaps, Firefox/WebKit, or full editor behavior.
|
||||
|
||||
## 验收
|
||||
|
||||
build_blender_5.2.0/bin/blender -b --factory-startup --python tools/web/generated/M16-GAP-00178.py -- tests/files/web/generated/M16-GAP-00178-operator-anim.keyframe_clear_button.blend
|
||||
npm --prefix web run test:generated-gap -- --task M16-GAP-00178
|
||||
node tools/web/check-generated-gap.mjs --task M16-GAP-00178
|
||||
|
||||
Malformed/unsupported, cancellation, duplicate, over-budget, or hash-drift cases must keep in_progress; they must not change Main revision or advance nextTask.
|
||||
|
||||
## 交付与回滚
|
||||
|
||||
- Reports: `tests/golden/M16-GAP-00178/`
|
||||
- Status: `docs/status/M16-GAP-00178.md`
|
||||
- Manifest: `tests/golden/M16-GAP-00178/manifest.json`
|
||||
- Handoff: `node tools/web/check-task-context.mjs --task M16-GAP-00178 --write`
|
||||
- Rollback: remove this task production entry, fixture, tests, reports, manifest, status, and context; restore the parent as queue tail without rewriting parent evidence.
|
||||
37
docs/tasks/M16-GAP-00179.md
Normal file
37
docs/tasks/M16-GAP-00179.md
Normal file
@@ -0,0 +1,37 @@
|
||||
# M16-GAP-00179: operator:anim.keyframe_clear_v3d LOCAL_EXACT slice
|
||||
|
||||
- task: M16-GAP-00179
|
||||
- parent: M16-GAP-00178
|
||||
- status: in_progress
|
||||
- gap: operator:anim.keyframe_clear_v3d
|
||||
- ownerFamily: OPERATOR
|
||||
- targetImplementationClass: LOCAL_EXACT
|
||||
|
||||
## 目标
|
||||
|
||||
Make the same minimal fixture produce observable operator:anim.keyframe_clear_v3d data in Blender desktop and WASM/Main, with save/reopen stability. Change only this gap; do not expand to other data-blocks, editors, or browsers.
|
||||
|
||||
## 输入与范围
|
||||
|
||||
- Fixture: `tests/files/web/generated/M16-GAP-00179-operator-anim.keyframe_clear_v3d.blend`
|
||||
- Generator: `tools/web/generated/M16-GAP-00179.py`
|
||||
- Production: `blender-5.2.0/source/blender/web_engine/web_engine_blend_reader.cpp`
|
||||
- Checker: `tools/web/check-generated-gap.mjs`
|
||||
- Do: field read, desktop/WASM comparison, save/reopen, structured report.
|
||||
- Do not: other gaps, Firefox/WebKit, or full editor behavior.
|
||||
|
||||
## 验收
|
||||
|
||||
build_blender_5.2.0/bin/blender -b --factory-startup --python tools/web/generated/M16-GAP-00179.py -- tests/files/web/generated/M16-GAP-00179-operator-anim.keyframe_clear_v3d.blend
|
||||
npm --prefix web run test:generated-gap -- --task M16-GAP-00179
|
||||
node tools/web/check-generated-gap.mjs --task M16-GAP-00179
|
||||
|
||||
Malformed/unsupported, cancellation, duplicate, over-budget, or hash-drift cases must keep in_progress; they must not change Main revision or advance nextTask.
|
||||
|
||||
## 交付与回滚
|
||||
|
||||
- Reports: `tests/golden/M16-GAP-00179/`
|
||||
- Status: `docs/status/M16-GAP-00179.md`
|
||||
- Manifest: `tests/golden/M16-GAP-00179/manifest.json`
|
||||
- Handoff: `node tools/web/check-task-context.mjs --task M16-GAP-00179 --write`
|
||||
- Rollback: remove this task production entry, fixture, tests, reports, manifest, status, and context; restore the parent as queue tail without rewriting parent evidence.
|
||||
37
docs/tasks/M16-GAP-00180.md
Normal file
37
docs/tasks/M16-GAP-00180.md
Normal file
@@ -0,0 +1,37 @@
|
||||
# M16-GAP-00180: operator:anim.keyframe_clear_vse LOCAL_EXACT slice
|
||||
|
||||
- task: M16-GAP-00180
|
||||
- parent: M16-GAP-00179
|
||||
- status: in_progress
|
||||
- gap: operator:anim.keyframe_clear_vse
|
||||
- ownerFamily: OPERATOR
|
||||
- targetImplementationClass: LOCAL_EXACT
|
||||
|
||||
## 目标
|
||||
|
||||
Make the same minimal fixture produce observable operator:anim.keyframe_clear_vse data in Blender desktop and WASM/Main, with save/reopen stability. Change only this gap; do not expand to other data-blocks, editors, or browsers.
|
||||
|
||||
## 输入与范围
|
||||
|
||||
- Fixture: `tests/files/web/generated/M16-GAP-00180-operator-anim.keyframe_clear_vse.blend`
|
||||
- Generator: `tools/web/generated/M16-GAP-00180.py`
|
||||
- Production: `blender-5.2.0/source/blender/web_engine/web_engine_blend_reader.cpp`
|
||||
- Checker: `tools/web/check-generated-gap.mjs`
|
||||
- Do: field read, desktop/WASM comparison, save/reopen, structured report.
|
||||
- Do not: other gaps, Firefox/WebKit, or full editor behavior.
|
||||
|
||||
## 验收
|
||||
|
||||
build_blender_5.2.0/bin/blender -b --factory-startup --python tools/web/generated/M16-GAP-00180.py -- tests/files/web/generated/M16-GAP-00180-operator-anim.keyframe_clear_vse.blend
|
||||
npm --prefix web run test:generated-gap -- --task M16-GAP-00180
|
||||
node tools/web/check-generated-gap.mjs --task M16-GAP-00180
|
||||
|
||||
Malformed/unsupported, cancellation, duplicate, over-budget, or hash-drift cases must keep in_progress; they must not change Main revision or advance nextTask.
|
||||
|
||||
## 交付与回滚
|
||||
|
||||
- Reports: `tests/golden/M16-GAP-00180/`
|
||||
- Status: `docs/status/M16-GAP-00180.md`
|
||||
- Manifest: `tests/golden/M16-GAP-00180/manifest.json`
|
||||
- Handoff: `node tools/web/check-task-context.mjs --task M16-GAP-00180 --write`
|
||||
- Rollback: remove this task production entry, fixture, tests, reports, manifest, status, and context; restore the parent as queue tail without rewriting parent evidence.
|
||||
37
docs/tasks/M16-GAP-00181.md
Normal file
37
docs/tasks/M16-GAP-00181.md
Normal file
@@ -0,0 +1,37 @@
|
||||
# M16-GAP-00181: operator:anim.keyframe_delete LOCAL_EXACT slice
|
||||
|
||||
- task: M16-GAP-00181
|
||||
- parent: M16-GAP-00180
|
||||
- status: in_progress
|
||||
- gap: operator:anim.keyframe_delete
|
||||
- ownerFamily: OPERATOR
|
||||
- targetImplementationClass: LOCAL_EXACT
|
||||
|
||||
## 目标
|
||||
|
||||
Make the same minimal fixture produce observable operator:anim.keyframe_delete data in Blender desktop and WASM/Main, with save/reopen stability. Change only this gap; do not expand to other data-blocks, editors, or browsers.
|
||||
|
||||
## 输入与范围
|
||||
|
||||
- Fixture: `tests/files/web/generated/M16-GAP-00181-operator-anim.keyframe_delete.blend`
|
||||
- Generator: `tools/web/generated/M16-GAP-00181.py`
|
||||
- Production: `blender-5.2.0/source/blender/web_engine/web_engine_blend_reader.cpp`
|
||||
- Checker: `tools/web/check-generated-gap.mjs`
|
||||
- Do: field read, desktop/WASM comparison, save/reopen, structured report.
|
||||
- Do not: other gaps, Firefox/WebKit, or full editor behavior.
|
||||
|
||||
## 验收
|
||||
|
||||
build_blender_5.2.0/bin/blender -b --factory-startup --python tools/web/generated/M16-GAP-00181.py -- tests/files/web/generated/M16-GAP-00181-operator-anim.keyframe_delete.blend
|
||||
npm --prefix web run test:generated-gap -- --task M16-GAP-00181
|
||||
node tools/web/check-generated-gap.mjs --task M16-GAP-00181
|
||||
|
||||
Malformed/unsupported, cancellation, duplicate, over-budget, or hash-drift cases must keep in_progress; they must not change Main revision or advance nextTask.
|
||||
|
||||
## 交付与回滚
|
||||
|
||||
- Reports: `tests/golden/M16-GAP-00181/`
|
||||
- Status: `docs/status/M16-GAP-00181.md`
|
||||
- Manifest: `tests/golden/M16-GAP-00181/manifest.json`
|
||||
- Handoff: `node tools/web/check-task-context.mjs --task M16-GAP-00181 --write`
|
||||
- Rollback: remove this task production entry, fixture, tests, reports, manifest, status, and context; restore the parent as queue tail without rewriting parent evidence.
|
||||
37
docs/tasks/M16-GAP-00182.md
Normal file
37
docs/tasks/M16-GAP-00182.md
Normal file
@@ -0,0 +1,37 @@
|
||||
# M16-GAP-00182: operator:anim.keyframe_delete_button LOCAL_EXACT slice
|
||||
|
||||
- task: M16-GAP-00182
|
||||
- parent: M16-GAP-00181
|
||||
- status: in_progress
|
||||
- gap: operator:anim.keyframe_delete_button
|
||||
- ownerFamily: OPERATOR
|
||||
- targetImplementationClass: LOCAL_EXACT
|
||||
|
||||
## 目标
|
||||
|
||||
Make the same minimal fixture produce observable operator:anim.keyframe_delete_button data in Blender desktop and WASM/Main, with save/reopen stability. Change only this gap; do not expand to other data-blocks, editors, or browsers.
|
||||
|
||||
## 输入与范围
|
||||
|
||||
- Fixture: `tests/files/web/generated/M16-GAP-00182-operator-anim.keyframe_delete_button.blend`
|
||||
- Generator: `tools/web/generated/M16-GAP-00182.py`
|
||||
- Production: `blender-5.2.0/source/blender/web_engine/web_engine_blend_reader.cpp`
|
||||
- Checker: `tools/web/check-generated-gap.mjs`
|
||||
- Do: field read, desktop/WASM comparison, save/reopen, structured report.
|
||||
- Do not: other gaps, Firefox/WebKit, or full editor behavior.
|
||||
|
||||
## 验收
|
||||
|
||||
build_blender_5.2.0/bin/blender -b --factory-startup --python tools/web/generated/M16-GAP-00182.py -- tests/files/web/generated/M16-GAP-00182-operator-anim.keyframe_delete_button.blend
|
||||
npm --prefix web run test:generated-gap -- --task M16-GAP-00182
|
||||
node tools/web/check-generated-gap.mjs --task M16-GAP-00182
|
||||
|
||||
Malformed/unsupported, cancellation, duplicate, over-budget, or hash-drift cases must keep in_progress; they must not change Main revision or advance nextTask.
|
||||
|
||||
## 交付与回滚
|
||||
|
||||
- Reports: `tests/golden/M16-GAP-00182/`
|
||||
- Status: `docs/status/M16-GAP-00182.md`
|
||||
- Manifest: `tests/golden/M16-GAP-00182/manifest.json`
|
||||
- Handoff: `node tools/web/check-task-context.mjs --task M16-GAP-00182 --write`
|
||||
- Rollback: remove this task production entry, fixture, tests, reports, manifest, status, and context; restore the parent as queue tail without rewriting parent evidence.
|
||||
37
docs/tasks/M16-GAP-00183.md
Normal file
37
docs/tasks/M16-GAP-00183.md
Normal file
@@ -0,0 +1,37 @@
|
||||
# M16-GAP-00183: operator:anim.keyframe_delete_by_name LOCAL_EXACT slice
|
||||
|
||||
- task: M16-GAP-00183
|
||||
- parent: M16-GAP-00182
|
||||
- status: in_progress
|
||||
- gap: operator:anim.keyframe_delete_by_name
|
||||
- ownerFamily: OPERATOR
|
||||
- targetImplementationClass: LOCAL_EXACT
|
||||
|
||||
## 目标
|
||||
|
||||
Make the same minimal fixture produce observable operator:anim.keyframe_delete_by_name data in Blender desktop and WASM/Main, with save/reopen stability. Change only this gap; do not expand to other data-blocks, editors, or browsers.
|
||||
|
||||
## 输入与范围
|
||||
|
||||
- Fixture: `tests/files/web/generated/M16-GAP-00183-operator-anim.keyframe_delete_by_name.blend`
|
||||
- Generator: `tools/web/generated/M16-GAP-00183.py`
|
||||
- Production: `blender-5.2.0/source/blender/web_engine/web_engine_blend_reader.cpp`
|
||||
- Checker: `tools/web/check-generated-gap.mjs`
|
||||
- Do: field read, desktop/WASM comparison, save/reopen, structured report.
|
||||
- Do not: other gaps, Firefox/WebKit, or full editor behavior.
|
||||
|
||||
## 验收
|
||||
|
||||
build_blender_5.2.0/bin/blender -b --factory-startup --python tools/web/generated/M16-GAP-00183.py -- tests/files/web/generated/M16-GAP-00183-operator-anim.keyframe_delete_by_name.blend
|
||||
npm --prefix web run test:generated-gap -- --task M16-GAP-00183
|
||||
node tools/web/check-generated-gap.mjs --task M16-GAP-00183
|
||||
|
||||
Malformed/unsupported, cancellation, duplicate, over-budget, or hash-drift cases must keep in_progress; they must not change Main revision or advance nextTask.
|
||||
|
||||
## 交付与回滚
|
||||
|
||||
- Reports: `tests/golden/M16-GAP-00183/`
|
||||
- Status: `docs/status/M16-GAP-00183.md`
|
||||
- Manifest: `tests/golden/M16-GAP-00183/manifest.json`
|
||||
- Handoff: `node tools/web/check-task-context.mjs --task M16-GAP-00183 --write`
|
||||
- Rollback: remove this task production entry, fixture, tests, reports, manifest, status, and context; restore the parent as queue tail without rewriting parent evidence.
|
||||
37
docs/tasks/M16-GAP-00184.md
Normal file
37
docs/tasks/M16-GAP-00184.md
Normal file
@@ -0,0 +1,37 @@
|
||||
# M16-GAP-00184: operator:anim.keyframe_delete_v3d LOCAL_EXACT slice
|
||||
|
||||
- task: M16-GAP-00184
|
||||
- parent: M16-GAP-00183
|
||||
- status: in_progress
|
||||
- gap: operator:anim.keyframe_delete_v3d
|
||||
- ownerFamily: OPERATOR
|
||||
- targetImplementationClass: LOCAL_EXACT
|
||||
|
||||
## 目标
|
||||
|
||||
Make the same minimal fixture produce observable operator:anim.keyframe_delete_v3d data in Blender desktop and WASM/Main, with save/reopen stability. Change only this gap; do not expand to other data-blocks, editors, or browsers.
|
||||
|
||||
## 输入与范围
|
||||
|
||||
- Fixture: `tests/files/web/generated/M16-GAP-00184-operator-anim.keyframe_delete_v3d.blend`
|
||||
- Generator: `tools/web/generated/M16-GAP-00184.py`
|
||||
- Production: `blender-5.2.0/source/blender/web_engine/web_engine_blend_reader.cpp`
|
||||
- Checker: `tools/web/check-generated-gap.mjs`
|
||||
- Do: field read, desktop/WASM comparison, save/reopen, structured report.
|
||||
- Do not: other gaps, Firefox/WebKit, or full editor behavior.
|
||||
|
||||
## 验收
|
||||
|
||||
build_blender_5.2.0/bin/blender -b --factory-startup --python tools/web/generated/M16-GAP-00184.py -- tests/files/web/generated/M16-GAP-00184-operator-anim.keyframe_delete_v3d.blend
|
||||
npm --prefix web run test:generated-gap -- --task M16-GAP-00184
|
||||
node tools/web/check-generated-gap.mjs --task M16-GAP-00184
|
||||
|
||||
Malformed/unsupported, cancellation, duplicate, over-budget, or hash-drift cases must keep in_progress; they must not change Main revision or advance nextTask.
|
||||
|
||||
## 交付与回滚
|
||||
|
||||
- Reports: `tests/golden/M16-GAP-00184/`
|
||||
- Status: `docs/status/M16-GAP-00184.md`
|
||||
- Manifest: `tests/golden/M16-GAP-00184/manifest.json`
|
||||
- Handoff: `node tools/web/check-task-context.mjs --task M16-GAP-00184 --write`
|
||||
- Rollback: remove this task production entry, fixture, tests, reports, manifest, status, and context; restore the parent as queue tail without rewriting parent evidence.
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user