fix(web): keep unattended source batch authorization productive
Some checks failed
M6 deployable RC / quick (push) Has been cancelled
M6 deployable RC / chromium (push) Has been cancelled
M6 deployable RC / release (push) Has been cancelled

This commit is contained in:
mes123456
2026-09-05 17:51:14 +08:00
parent 1086d4b68a
commit 88ccb03e9a
12 changed files with 63437 additions and 514 deletions

View File

@@ -15,9 +15,9 @@
| 字段 | 值 |
| --- | --- |
| 里程碑 | WBV2 capability workflow |
| 当前任务 | `WBV2-P1291-001` |
| parent manifest | `tests/golden/WBV2-P1291-000/manifest.json` |
| 任务卡 | [`tasks/WBV2-P1291-001.md`](tasks/WBV2-P1291-001.md) |
| 当前任务 | `WBV2-P1292-001` |
| parent manifest | `tests/golden/WBV2-P1292-000/manifest.json` |
| 任务卡 | [`tasks/WBV2-P1292-001.md`](tasks/WBV2-P1292-001.md) |
| 专项验收 | `node tools/web/check-execution-control-plane.mjs` |
| legacy coverage checkpoint | `M16-GAP-00282` |
| legacy coverage parent | `tests/golden/M16-GAP-00281/manifest.json` |

View File

@@ -0,0 +1,7 @@
# WBV2-P1292-000 status
- task: `WBV2-P1292-000`; parent: `WBV2-P1291-001`; status: `done`
- taskClass: `QUEUE_ENABLEMENT`; no modifier-family parity completion claimed
- source-backed batch authorized: `OBJECT_DUPLICATE_MACRO_BATCH` (1 units)
- dynamic inventory: `3745` units; verified `1025`; unverified `2720`; bound delta `0`
- nextTask: `WBV2-P1292-001`

View File

@@ -0,0 +1,35 @@
# WBV2-P1292-000: authorize module batch
- task: WBV2-P1292-000
- parent: WBV2-P1291-001
- status: done
- gap: capability:OBJECT_DUPLICATE_MACRO_BATCH
- ownerFamily: OBJECT
- targetImplementationClass: QUEUE_ONLY
- batchId: WBV2-P1292-001:OBJECT_DUPLICATE_MACRO_BATCH:811c939e205ecafd
- selectedRecordIds: ["operator-macro:ACTION_OT_duplicate_move"]
- commandBudget: max=48; read/exploration max=16
- Implementation entrypoint: `python3 my-tools/authorize_next_wbv2_task.py --write`
## 目标
授权一个共享 Blender Main/WASM/Chromium 功能批次:OBJECT_DUPLICATE_MACRO_BATCH,共 1 个源码/RNA 单元。
## 输入与范围
- Blender source: `blender-5.2.0/source/blender`
- Fixtures/test: `tests/files/web/basic_scene.blend`, `web/tests/e2e/wbv2-object-duplicate-production.spec.ts`
## 验收
- prior evidence and dynamic inventory remain hash-bound and immutable
- one shared function chain validates the complete selected batch
- missing source, unsupported data, hash drift or false completion remains blocked
- `node tools/web/check-task-context.mjs --task WBV2-P1292-000 --write`
## 交付与回滚
- Manifest: `tests/golden/WBV2-P1292-000/manifest.json`
- Status: `docs/status/WBV2-P1292-000.md`
- Rollback: restore WBV2-P1291-001 as queue parent.

View File

@@ -0,0 +1,48 @@
# WBV2-P1292-001: verify ACTION_OT_duplicate_move through existing native gate
- task: WBV2-P1292-001
- parent: WBV2-P1292-000
- status: in_progress
- gap: capability:OBJECT_DUPLICATE_MACRO_BATCH
- ownerFamily: OBJECT
- targetImplementationClass: LOCAL_EXACT
- batchId: WBV2-P1292-001:OBJECT_DUPLICATE_MACRO_BATCH:811c939e205ecafd
- selectedRecordIds: ["operator-macro:ACTION_OT_duplicate_move"]
- commandBudget: max=48; read/exploration max=16
- Implementation entrypoint: `node tools/web/run-wbv2-module-task.mjs --task WBV2-P1292-001 --write`
## 目标
以一个共享 Blender Main reader、WASM build、Worker 路由和 Chromium receipt 批量验证 ACTION_OT_duplicate_move 的真实 modifier/RNA 元数据。
## 输入与范围
- Blender modifier sources: `blender-5.2.0/source/blender/modifiers/intern/`
- RNA source: `blender-5.2.0/source/blender/makesrna/intern/rna_modifier.cc`
- Native reader: `blender-5.2.0/source/blender/web_engine/web_engine_blend_reader.cpp`
- Fixtures: `tests/files/web/basic_scene.blend`
- Chromium test: `web/tests/e2e/wbv2-object-duplicate-production.spec.ts`
- Selected modifier units: `modifier-source:ACTION_OT_duplicate_move`
- Selected RNA units: none (source-only dependency batch)
## 验收
- one shared Main/WASM/Worker/Chromium chain observes every selected type
- malformed input is rejected without Main mutation
- save/reopen and deterministic second read are exact
- only Chromium is used; JS simulation and per-API duplicate workers are forbidden
- each selected source unit receives an explicit hash-bound coverage binding
- `node tools/web/check-task-context.mjs --task WBV2-P1292-001 --write`
## 失败边界
- any missing source, unsupported type, hash drift, malformed data or non-exact recovery keeps the batch `in_progress`/`blocked`
- partial batch success never claims the omitted family; historical inventory remains read-only
## 交付与回滚
- Receipt: `tests/golden/WBV2-P1292-001/module-receipt.json`
- Aggregate production evidence: `tests/golden/WBV2-P1292-001/modifier-reader-batch-production.json`
- Manifest: `tests/golden/WBV2-P1292-001/manifest.json`
- Status: `docs/status/WBV2-P1292-001.md`
- Rollback: restore WBV2-P1292-000 as queue parent without rewriting prior evidence.

View File

@@ -782,6 +782,7 @@ def discover_existing_evidence_batch(inventory: dict) -> dict | None:
unresolved = {unit["id"]: unit for unit in inventory.get("units", []) if isinstance(unit, dict) and unit.get("coverageStatus") != "VERIFIED"}
if not unresolved:
return None
operation_tests = (
("FCURVE", "web/tests/e2e/wbv2-fcurve-modifier-production.spec.ts"),
("LINE_STYLE", "web/tests/e2e/wbv2-line-style-reader-production.spec.ts"),
@@ -826,6 +827,61 @@ def discover_existing_evidence_batch(inventory: dict) -> dict | None:
}
def auto_operator_macro_batch(inventory: dict) -> dict | None:
"""Select a source-backed operator/macro batch from an existing native gate.
The dynamic inventory contains many Blender UI macro identifiers whose
executable behavior is represented by a smaller set of already-proven
native commands. Keep this bridge explicit and bounded: it only maps
identifiers to gates that already exercise the corresponding mutation,
uses one unit per batch, and never changes coverage until Chromium emits
an exact receipt for that selected source record.
"""
units = [
unit for unit in inventory.get("units", [])
if isinstance(unit, dict)
and unit.get("coverageStatus") != "VERIFIED"
and unit.get("kind") in {"operator", "operator-macro"}
and isinstance(unit.get("identifier"), str)
]
if not units:
return None
gates = (
("duplicate_move", "OBJECT_DUPLICATE_MACRO_BATCH", "OBJECT", "tests/files/web/basic_scene.blend", "web/tests/e2e/wbv2-object-duplicate-production.spec.ts", "object-duplicate-production.json", None),
("extrude_", "MESH_EXTRUDE_MACRO_BATCH", "MESH", "tests/files/web/generated/WBV2-P2-003-MESH.EDIT_CORE.blend", "web/tests/e2e/wbv2-mesh-topology-production.spec.ts", "mesh-topology-production.json", "EXTRUDE"),
("loopcut", "MESH_LOOPCUT_MACRO_BATCH", "MESH", "tests/files/web/generated/WBV2-P2-003-MESH.EDIT_CORE.blend", "web/tests/e2e/wbv2-mesh-topology-production.spec.ts", "mesh-topology-production.json", "LOOP_CUT"),
("dissolve", "MESH_DISSOLVE_MACRO_BATCH", "MESH", "tests/files/web/generated/WBV2-P2-003-MESH.EDIT_CORE.blend", "web/tests/e2e/wbv2-mesh-topology-production.spec.ts", "mesh-topology-production.json", "DISSOLVE"),
("merge", "MESH_MERGE_MACRO_BATCH", "MESH", "tests/files/web/generated/WBV2-P2-003-MESH.EDIT_CORE.blend", "web/tests/e2e/wbv2-mesh-topology-production.spec.ts", "mesh-topology-production.json", "MERGE"),
)
for marker, module_id, owner, fixture, test, production_name, operation in gates:
if not (ROOT / fixture).is_file() or not (ROOT / test).is_file():
continue
selected = next((unit for unit in units if marker in unit["identifier"].lower()), None)
if not selected:
continue
return {
"moduleId": module_id,
"title": f"verify {selected['identifier']} through existing native gate",
"owner": owner,
"identifiers": [selected["identifier"]],
"rna": [],
"fixture": fixture,
"test": test,
"production": f"tests/golden/{{task}}/{production_name}",
"types": [],
"batchOperation": operation,
"units": [selected],
"candidateUnits": [selected],
"adaptiveKey": f"{module_id}:LOCAL_EXACT:{owner}",
"adaptiveHistory": [],
"adaptiveCurrentSize": 1,
"adaptiveNextSize": 1,
"adaptiveMinSize": 1,
"adaptiveMaxSize": 1,
}
return None
def pending_summary(inventory: dict) -> dict:
pending = [unit for unit in inventory.get("units", []) if isinstance(unit, dict) and unit.get("coverageStatus") != "VERIFIED"]
by_kind: dict[str, int] = {}
@@ -1083,6 +1139,9 @@ def select_batch(inventory: dict) -> dict:
"adaptiveMinSize": 1,
"adaptiveMaxSize": 1,
}
macro = auto_operator_macro_batch(inventory)
if macro:
return macro
summary = pending_summary(inventory)
write_planner_status({
"status": "waiting_for_exact_evidence",

View File

@@ -0,0 +1,46 @@
{
"schemaVersion": 1,
"task": "WBV2-P1292-000",
"parentTask": "WBV2-P1291-001",
"operation": "AUTHORIZE_SOURCE_BACKED_MODULE_BATCH",
"status": "done",
"enablingTask": true,
"parityStateChange": false,
"runtime": "MODULE_EXECUTION_QUEUE_BRIDGE",
"batchId": "WBV2-P1292-001:OBJECT_DUPLICATE_MACRO_BATCH:811c939e205ecafd",
"selectedRecordIds": [
"operator-macro:ACTION_OT_duplicate_move"
],
"artifacts": {
"parentManifest": {
"path": "tests/golden/WBV2-P1291-001/manifest.json",
"sha256": "27336871286dc6069f00ff594f03d7340bcde5be8e029f52c9499294865da103"
},
"plan": {
"path": "tests/golden/WBV2-P1292-000/module-execution-plan.json",
"sha256": "f6dc32301e35e8246d1f05ceb9b92e078eee0ea8817bc8b14efe1cb6d259ef18"
},
"report": {
"path": "tests/golden/WBV2-P1292-000/successor-authorization-report.json",
"sha256": "ef68f7c846f85ecc1cf03215fc7ca6b3abcbf159030e9be8361665203ed18d4b"
},
"status": {
"path": "docs/status/WBV2-P1292-000.md",
"sha256": "b4948b69bf4400aaf89944152e3c0edced7451270772b0e2c7afa81de8e7c2ec"
}
},
"assertions": {
"sourceBackedSuccessor": true,
"moduleId": "OBJECT_DUPLICATE_MACRO_BATCH",
"batchSize": 1,
"inventoryTotal": 6900,
"effectiveCompleted": 290,
"effectivePending": 6609,
"dynamicUnitCount": 3745,
"dynamicVerifiedUnits": 1025,
"dynamicUnverifiedUnits": 2720,
"boundUnitDelta": 0,
"fullHistoricalReproduction": false
},
"nextTask": "WBV2-P1292-001"
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,41 @@
{
"schemaVersion": 1,
"task": "WBV2-P1292-000",
"operation": "AUTHORIZE_SOURCE_BACKED_MODULE_BATCH",
"taskClass": "QUEUE_ENABLEMENT",
"status": "PASS",
"parent": {
"task": "WBV2-P1291-001",
"manifest": "tests/golden/WBV2-P1291-001/manifest.json",
"manifestSha256": "27336871286dc6069f00ff594f03d7340bcde5be8e029f52c9499294865da103"
},
"batchId": "WBV2-P1292-001:OBJECT_DUPLICATE_MACRO_BATCH:811c939e205ecafd",
"selectedRecordIds": [
"operator-macro:ACTION_OT_duplicate_move"
],
"module": {
"moduleId": "OBJECT_DUPLICATE_MACRO_BATCH",
"task": "WBV2-P1292-001",
"batchSize": 1,
"candidateBatchSize": 1,
"sourceUnits": [
"operator-macro:ACTION_OT_duplicate_move"
],
"sourceBacked": true
},
"inventory": {
"unitCount": 3745,
"verifiedUnits": 1025,
"unverifiedUnits": 2720,
"sourceTreeSha256": "600cb3dd441f09d9655b740735fbf8fa49ad6c14d308c68d59a29f9c338e4202",
"boundUnitDelta": 0
},
"efficiency": {
"existingBindingsReused": 0,
"selectionPolicy": "all-candidate-units-then-unresolved-only",
"adaptiveKey": "OBJECT_DUPLICATE_MACRO_BATCH:LOCAL_EXACT:OBJECT",
"adaptiveHistory": [],
"adaptiveNextSize": 1
},
"nextTask": "WBV2-P1292-001"
}

View File

@@ -0,0 +1,217 @@
{
"schemaVersion": 1,
"task": "WBV2-P1292-001",
"parentTask": "WBV2-P1292-000",
"status": "in_progress",
"goal": "以一个共享 Blender Main reader、WASM build、Worker 路由和 Chromium receipt 批量验证 ACTION_OT_duplicate_move 的真实 modifier/RNA 元数据。",
"scope": {
"gap": "capability:OBJECT_DUPLICATE_MACRO_BATCH",
"ownerFamily": "OBJECT",
"implementationClass": "LOCAL_EXACT"
},
"commands": [
"node tools/web/check-task-context.mjs --task WBV2-P1292-001 --write"
],
"inputPaths": [],
"inputMetadata": {
"docs/EXECUTION_QUEUE.md": {
"path": "docs/EXECUTION_QUEUE.md",
"exists": true,
"bytes": 4030,
"mtime_ns": "1788601687755262851",
"sha256": "19ccfb1e1acd53ba030267d0b026e623405fb45e4d5a393c4532846bde8f8d28"
},
"docs/tasks/WBV2-P1292-001.md": {
"path": "docs/tasks/WBV2-P1292-001.md",
"exists": true,
"bytes": 2263,
"mtime_ns": "1788601687728523112",
"sha256": "c905cf7682f53d18c38763c48d167531ebb3f06567a03a9b865644f172afe7a3"
},
"tests/golden/WBV2-P1292-000/manifest.json": {
"path": "tests/golden/WBV2-P1292-000/manifest.json",
"exists": true,
"bytes": 1537,
"mtime_ns": "1788601687729533628",
"sha256": "c537067685baa98047f80926434d6ff2a93642d7b316a9944475d57328e27fa3"
},
"docs/status/WBV2-P1292-000.md": {
"path": "docs/status/WBV2-P1292-000.md",
"exists": true,
"bytes": 361,
"mtime_ns": "1788601687728681932",
"sha256": "b4948b69bf4400aaf89944152e3c0edced7451270772b0e2c7afa81de8e7c2ec"
}
},
"inputSelection": {
"schemaVersion": 1,
"limits": {
"maxFiles": 12,
"evidenceBytes": 8192,
"contextRemainingBytes": 1713,
"contextRemainingTokens": 426
},
"source": {
"bytes": 8191,
"tokens": 2050
},
"selected": [],
"excluded": [
{
"path": "blender-5.2.0/source/blender/modifiers/intern/",
"bytes": 10155,
"reason": "EVIDENCE_BYTE_BUDGET"
},
{
"path": "blender-5.2.0/source/blender/makesrna/intern/rna_modifier.cc",
"bytes": 521651,
"reason": "EVIDENCE_BYTE_BUDGET"
},
{
"path": "blender-5.2.0/source/blender/web_engine/web_engine_blend_reader.cpp",
"bytes": 314614,
"reason": "EVIDENCE_BYTE_BUDGET"
},
{
"path": "tests/files/web/basic_scene.blend",
"bytes": 95608,
"reason": "EVIDENCE_BYTE_BUDGET"
},
{
"path": "web/tests/e2e/wbv2-object-duplicate-production.spec.ts",
"bytes": 4089,
"reason": "CONTEXT_REMAINING_SPACE"
},
{
"path": "tests/golden/WBV2-P1292-001/module-receipt.json",
"bytes": null,
"reason": "MISSING_PATH"
},
{
"path": "tests/golden/WBV2-P1292-001/modifier-reader-batch-production.json",
"bytes": null,
"reason": "MISSING_PATH"
},
{
"path": "tests/golden/WBV2-P1292-001/manifest.json",
"bytes": null,
"reason": "GENERATED_EVIDENCE_OUTPUT"
},
{
"path": "docs/status/WBV2-P1292-001.md",
"bytes": null,
"reason": "GENERATED_EVIDENCE_OUTPUT"
}
],
"totals": {
"files": 0,
"bytes": 0,
"tokens": 0
}
},
"exitCriteria": [
"source and protocol hashes are bound",
"every selected Main reader type is proven",
"negative no-mutation and recovery are proven",
"Chromium and save/reopen evidence are exact"
],
"nextTask": null,
"sourceDocuments": {
"queue": "docs/EXECUTION_QUEUE.md",
"taskCard": "docs/tasks/WBV2-P1292-001.md",
"taskIndex": "tests/golden/WBV2/task-index.json",
"parentManifest": "tests/golden/WBV2-P1292-000/manifest.json",
"parentStatus": "docs/status/WBV2-P1292-000.md"
},
"readPolicy": {
"required": [
"docs/EXECUTION_QUEUE.md",
"docs/tasks/WBV2-P1292-001.md",
"tests/golden/WBV2-P1292-000/manifest.json",
"docs/status/WBV2-P1292-000.md"
],
"machineOnly": [
"tests/golden/WBV2/task-index.json",
"tests/golden/M15-03A/task-catalog.jsonl"
],
"optionalByNeed": [
"docs/WEB_BLENDER_MODELER_V1_SCOPE.md",
"任务卡列出的精确协议/生产路径",
"任务卡明确命名的长期计划小节"
],
"forbiddenByDefault": [
"完整 CURRENT_EXECUTION_PLAN.md",
"完整 PROJECT_STATUS_AND_NEXT_WORK.md",
"全部 docs/status/*.md",
"完整 parity/WBS 计划",
"README 历史和 test-results/"
]
},
"parent": {
"manifest": {
"schemaVersion": 1,
"task": "WBV2-P1292-000",
"parentTask": "WBV2-P1291-001",
"status": "done",
"nextTask": "WBV2-P1292-001",
"artifactCount": 4
},
"statusSummary": [
"# WBV2-P1292-000 status",
"- task: `WBV2-P1292-000`; parent: `WBV2-P1291-001`; status: `done`",
"- taskClass: `QUEUE_ENABLEMENT`; no modifier-family parity completion claimed",
"- source-backed batch authorized: `OBJECT_DUPLICATE_MACRO_BATCH` (1 units)",
"- dynamic inventory: `3745` units; verified `1025`; unverified `2720`; bound delta `0`",
"- nextTask: `WBV2-P1292-001`"
]
},
"budgets": {
"queueBytes": 4096,
"taskBytes": 2263,
"parentManifestBytes": 24576,
"parentStatusBytes": 6144,
"evidenceFiles": 12,
"evidenceBytes": 8192,
"contextTokens": 3500,
"contextEnvelopeTokens": 1024,
"taskLines": 49,
"taskTokens": 566
},
"size": {
"documents": [
{
"path": "docs/EXECUTION_QUEUE.md",
"bytes": 4030,
"lines": 58,
"tokens": 1008
},
{
"path": "docs/tasks/WBV2-P1292-001.md",
"bytes": 2263,
"lines": 49,
"tokens": 566
},
{
"path": "tests/golden/WBV2-P1292-000/manifest.json",
"bytes": 1537,
"lines": 47,
"tokens": 385
},
{
"path": "docs/status/WBV2-P1292-000.md",
"bytes": 361,
"lines": 8,
"tokens": 91
}
],
"sourceTokens": 2050,
"evidenceFiles": 0,
"evidenceBytes": 0,
"evidenceTokens": 0,
"totalTokens": 2050,
"reservedEnvelopeTokens": 1024,
"estimatedContextTokens": 3074,
"serializedContextTokens": 654,
"withinBudget": true
}
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long