Checkpoint web parity through Chromium input tasks
This commit is contained in:
54
docs/status/M12-03E.md
Normal file
54
docs/status/M12-03E.md
Normal file
@@ -0,0 +1,54 @@
|
||||
# M12-03E Status
|
||||
|
||||
status: done
|
||||
task: append undo/redo/save/reopen and desktop canonical comparison
|
||||
updated: 2026-08-17 America/New_York
|
||||
enablingTask: false
|
||||
parityStateChange: false
|
||||
|
||||
## Scope
|
||||
|
||||
The M12-03D WASM Main append path is compared with the M12-03C Blender 5.2 desktop canonical
|
||||
report. One append transaction creates the Object/Mesh/Material/packed Image local closure and
|
||||
advances exactly one SceneIR revision. Undo removes all four IDs, redo restores the canonical
|
||||
graph, and a saved buffer reopens with the same graph and packed image pixels.
|
||||
|
||||
The image comparison normalizes Blender's bottom-up `Image.pixels` row order versus Canvas
|
||||
top-down `ImageData`. Current SceneIR omits `Image.colorSpace`, so a missing field uses the desktop
|
||||
canonical sRGB semantic default; an emitted colorspace must match it. All other graph, ID,
|
||||
ownership, geometry, UV, material-slot, image metadata, and pixel hash fields remain exact. This
|
||||
task does not claim Link, Library Override, or full N-023 IO parity.
|
||||
|
||||
## Evidence
|
||||
|
||||
- `node ../tools/web/check-library-main-append.mjs` passed the manifest, artifact hashes, canonical
|
||||
desktop report, and required test markers.
|
||||
- `WEB_TEST_PORT=5194 npm --prefix web run test:library-main-append` passed the checker and
|
||||
Chromium 1/1. The browser test verified one transaction, four writable `LOCAL_MAIN` mappings,
|
||||
one revision increment, complete Object -> Mesh -> Material -> Image closure, and exact
|
||||
canonical graphs after append, redo, and save/reopen.
|
||||
- A stale base revision returned `REVISION_CONFLICT`; a local ID collision returned
|
||||
`ASSET_MANIFEST_INVALID` without changing the appended revision. Undo reported no Object, Mesh,
|
||||
Material, or Image; redo restored the Object and canonical closure.
|
||||
- The canonical packed image remained a 2x2 sRGB RGBA PNG with Float32 pixel SHA-256
|
||||
`6f0f8c231d65149e69e6ed12d370bcfa095ef90adc202065492ea8c8ef17e45a`.
|
||||
|
||||
## Artifact Hashes
|
||||
|
||||
- checker: `7fba72c5a38c0877f03682b51cbaaaf6d9a5f315f2beddfdef432bc54b2f1cd2`
|
||||
- test: `101f67d35c2320da57459f08a59687d769234b910dbd9aaec5a668cee7e0f9f0`
|
||||
- package commands: `36a29c5be9bd6163b06cf3511edf77d932388fa0b75c08bdcec397e19c0ef45f`
|
||||
- source `.blend`: `5b60d02926efd588a6ca300ba31414cdf37dbc48786c17b383a70319057c0606`
|
||||
- clean target `.blend`: `9b1ecbcc3d7f8079ee5469de64193ffcaa0a7b01e0f2ac340bbb18aa88734a63`
|
||||
- desktop report: `b1d7b8b9e832d18d69081f63981062800e0f00f0c9aec025b18274510ed76e2a`
|
||||
- manifest: `beaa88ea0385225e712f9816072420bd8744c15da3229ddc352462abec407739`
|
||||
|
||||
## Next Task
|
||||
|
||||
`M12-03F`: desktop link fixture preserving source library and read-only ownership.
|
||||
|
||||
## Rollback
|
||||
|
||||
Remove the M12-03E checker, manifest, extended Chromium test, package command, and this status
|
||||
entry. Restore M12-03D to pending and move the machine queue back to `M12-03D`. No parity ledger
|
||||
rollback is required.
|
||||
49
docs/status/M12-03F.md
Normal file
49
docs/status/M12-03F.md
Normal file
@@ -0,0 +1,49 @@
|
||||
# M12-03F Status
|
||||
|
||||
status: done
|
||||
task: create a desktop linked Object fixture preserving source-library ownership
|
||||
updated: 2026-08-17 America/New_York
|
||||
enablingTask: true
|
||||
parityStateChange: false
|
||||
|
||||
## Scope
|
||||
|
||||
Blender 5.2 creates a source library containing one Object with a Mesh, Material, and packed Image
|
||||
dependency closure. A clean target links only the selected Object with `bpy.data.libraries.load(link=True)`.
|
||||
The Object, Mesh, Material, and Image retain the source library pointer, have no library override,
|
||||
and map to read-only `SOURCE_LIBRARY` ownership. The target is saved, reopened in a new Main load,
|
||||
and compared to the pre-save linked graph.
|
||||
|
||||
This task freezes the desktop LINK contract only. It does not implement a WASM link writer, linked
|
||||
mutation, reload/relocate, missing-library placeholders, or full N-023 parity.
|
||||
|
||||
## Evidence
|
||||
|
||||
- `npm --prefix web run test:library-link-desktop` passed the manifest/artifact hash gate, Blender
|
||||
5.2 generator rerun, and canonical report comparison.
|
||||
- The fixture links one root and four dependency IDs. All three dependency edges, 4 vertices, 4
|
||||
edges, 1 polygon, 4 loops, `UVMap`, material slot, packed 2x2 sRGB RGBA image, and Float32 pixel
|
||||
SHA-256 `6f0f8c231d65149e69e6ed12d370bcfa095ef90adc202065492ea8c8ef17e45a` survive save/reopen.
|
||||
- Every linked ID reports `library=m12_link_source.blend` and `isLibraryOverride=false`; all four
|
||||
stable mappings are `SOURCE_LIBRARY/readOnly=true`. A temporary source/target regeneration matches
|
||||
the canonical report after normalizing only session-bound blend container hashes.
|
||||
|
||||
## Artifact Hashes
|
||||
|
||||
- generator: `15a2e34c1c5b2a8ee63b10084dbb894e0f9677b9e1cf4adb7e2ddce6b4c965b1`
|
||||
- checker: `6a4c024bea227d7bc14f793467b91766b006459fe4d7717cc75dfee12f49f894`
|
||||
- source `.blend`: `fae97569e9d2e2066fc92749672f86cc42717cd9b97b012faeb9eb92015d7fd1`
|
||||
- target `.blend`: `acdaf0f297deb08c84e1a8beba30972e3414ef62e60e3b103fe0661199c438a1`
|
||||
- desktop report: `b278d4c254eff63d41c8cb3ea1d5e0984192137d45b1695ba0672e16f95b58ea`
|
||||
- manifest: `8220a8f5d560d45a75a62cbed645b3febc1390fe37b07c3c48871fefc1a9b159`
|
||||
- package commands: `336d8df1914aaaafaeccc181d4e73ed7058165f10e167efe539939c3ac1e0536`
|
||||
|
||||
## Next Task
|
||||
|
||||
`M12-03G`: linked data writers must fail closed with `LINKED_DATA_MUTATION_BLOCKED`.
|
||||
|
||||
## Rollback
|
||||
|
||||
Remove the M12-03F link generator/checker, source and target fixtures, desktop report/manifest,
|
||||
package command, and this status entry. Restore M12-03E to pending and move the machine queue back
|
||||
to `M12-03E`. No parity ledger rollback is required.
|
||||
45
docs/status/M12-03G.md
Normal file
45
docs/status/M12-03G.md
Normal file
@@ -0,0 +1,45 @@
|
||||
# M12-03G Status
|
||||
|
||||
status: done
|
||||
task: block every linked data writer before Main mutation
|
||||
updated: 2026-08-17 America/New_York
|
||||
enablingTask: false
|
||||
parityStateChange: false
|
||||
|
||||
## Scope
|
||||
|
||||
The schema-1 linked mutation gate covers object transforms, mesh geometry, mesh material slots,
|
||||
material properties, material image nodes, and packed image data. Every request must identify a
|
||||
`SOURCE_LIBRARY` owner with `linkedLibrary=true` and `readOnly=true`. A current linked request is
|
||||
blocked with `LINKED_DATA_MUTATION_BLOCKED` before any Main writer can run; stale revisions remain
|
||||
`REVISION_CONFLICT`, and malformed or ownership-substituted requests fail closed.
|
||||
|
||||
This task does not claim a linked writer, reload, relocation, missing-library recovery, or full
|
||||
N-023 Link parity. The desktop linked ownership contract is the M12-03F input to this gate.
|
||||
|
||||
## Evidence
|
||||
|
||||
- `npm --prefix web run test:library-linked-mutation` passed 3/3 unit tests.
|
||||
- All six linked writer operations return `BLOCKED` with exactly
|
||||
`LINKED_DATA_MUTATION_BLOCKED`, `recoverable=false`, and no Main mutation path. The test also
|
||||
verifies the schema round-trip for each operation.
|
||||
- A stale revision returns `REVISION_CONFLICT`; an unknown field, unsupported operation, or owner /
|
||||
read-only substitution returns `TASK_VALIDATION_FAILED` or `LINKED_DATA_MUTATION_BLOCKED` before
|
||||
any writer invocation.
|
||||
|
||||
## Artifact Hashes
|
||||
|
||||
- protocol: `f629e0e7e04dc1f5437b6e2ca62fbe35484fc238830fa47e8358bcab46b7e104`
|
||||
- unit: `f19d47cefe89daf6123062e045ec717e6ffe60977e8a4b20c996dd62e49da211`
|
||||
- manifest: `890891fda5c91b08d157927170fb33190ae0d8a49f8962b88c8554307c0c06a8`
|
||||
- package commands: `cfb232baa494ff59f6c8d65514a08c86332ee9354350b2a0392b6f932a7ee42c`
|
||||
|
||||
## Next Task
|
||||
|
||||
`M12-03H`: library reload replaces only the matching linked generation snapshot.
|
||||
|
||||
## Rollback
|
||||
|
||||
Remove the linked mutation protocol, unit suite, manifest, package command, and this status entry.
|
||||
Restore M12-03F to pending and move the machine queue back to `M12-03F`. No parity ledger rollback
|
||||
is required.
|
||||
43
docs/status/M12-03H.md
Normal file
43
docs/status/M12-03H.md
Normal file
@@ -0,0 +1,43 @@
|
||||
# M12-03H Status
|
||||
|
||||
status: done
|
||||
task: library reload replaces only the matching linked generation snapshot
|
||||
updated: 2026-08-17 America/New_York
|
||||
enablingTask: false
|
||||
parityStateChange: false
|
||||
|
||||
## Scope
|
||||
|
||||
Schema-1 reload requests identify one `SOURCE_LIBRARY` and an expected generation/revision. The
|
||||
replacement must keep the same library identity, advance exactly one generation, advance the source
|
||||
revision, and retain a read-only source-library data-block closure. Only the unique matching snapshot
|
||||
is replaced; other libraries and other generations remain unchanged.
|
||||
|
||||
Malformed requests, duplicate state identities, owner substitution, skipped generations, and stale
|
||||
generation/revision requests fail closed before any Main mutation. A stale request returns
|
||||
`REVISION_CONFLICT` and an unchanged state.
|
||||
|
||||
## Evidence
|
||||
|
||||
- `npm --prefix web run test:library-linked-reload` passed 4/4 unit tests.
|
||||
- The matching-generation case replaces one snapshot atomically while preserving a future generation
|
||||
and an unrelated library; the input state remains immutable.
|
||||
- Stale, malformed, duplicate, owner-substituted, and non-adjacent reload cases are rejected without
|
||||
publishing a partial state.
|
||||
|
||||
## Artifact Hashes
|
||||
|
||||
- protocol: `8be6f0b2abe36cd566ea7447d1b7de44c0e6a9a7351b863dfdd1372c1761060e`
|
||||
- unit: `dff866291468cc01e775fe3b3b95c632f5c0742566f79b956a0193bfd8fd43d2`
|
||||
- manifest: `dd96702dcb064779de3fc33ce1200d75615e7b75a3418a45a309e0e612fdb7df`
|
||||
- package commands: `cfb232baa494ff59f6c8d65514a08c86332ee9354350b2a0392b6f932a7ee42c`
|
||||
|
||||
## Next Task
|
||||
|
||||
`M12-03I`: missing library preserves a placeholder and the original source reference.
|
||||
|
||||
## Rollback
|
||||
|
||||
Remove the linked reload protocol, unit suite, manifest, package command, and this status entry.
|
||||
Restore M12-03G to pending and move the machine queue back to `M12-03H`. No parity ledger rollback
|
||||
is required.
|
||||
42
docs/status/M12-03I.md
Normal file
42
docs/status/M12-03I.md
Normal file
@@ -0,0 +1,42 @@
|
||||
# M12-03I Status
|
||||
|
||||
status: done
|
||||
task: missing library preserves placeholder and original source reference
|
||||
updated: 2026-08-17 America/New_York
|
||||
enablingTask: false
|
||||
parityStateChange: false
|
||||
|
||||
## Scope
|
||||
|
||||
Schema-1 missing-library requests match a linked source library by source identity, generation, and
|
||||
revision. Marking a matching reference missing changes only its status and adds a
|
||||
`MISSING_LIBRARY` placeholder. The original locator, source SHA-256, generation, revision, and every
|
||||
data-block ID remain attached to the reference; unrelated libraries remain unchanged.
|
||||
|
||||
Stale generation/revision and source hash drift return a stable conflict without deleting or replacing
|
||||
the reference. Malformed fields, duplicate identities, and inconsistent placeholder data fail closed.
|
||||
|
||||
## Evidence
|
||||
|
||||
- `npm --prefix web run test:library-linked-missing` passed 4/4 unit tests.
|
||||
- The matching case preserves original source metadata and data-block IDs while publishing only the
|
||||
placeholder status transition.
|
||||
- Stale, source-drift, undeclared-field, duplicate-identity, and invalid-placeholder cases publish no
|
||||
partial state.
|
||||
|
||||
## Artifact Hashes
|
||||
|
||||
- protocol: `5833e8c943ef6bd866a93a0e1666c9521fa6d3e8358861df57b628874b679ec2`
|
||||
- unit: `4ab6d6ff4845b4ca963399e7eea214ceb412871dc1fdef5bac1ed0333596da4f`
|
||||
- manifest: `f5fa606161b93e9ee42e7ca8144d2a83379acf601c5045eb8cc76732f8dba431`
|
||||
- package commands: `cfb232baa494ff59f6c8d65514a08c86332ee9354350b2a0392b6f932a7ee42c`
|
||||
|
||||
## Next Task
|
||||
|
||||
`M12-03J`: desktop override fixture records reference, local owner, and property override path.
|
||||
|
||||
## Rollback
|
||||
|
||||
Remove the missing-library protocol, unit suite, manifest, package command, and this status entry.
|
||||
Restore M12-03H to pending and move the machine queue back to `M12-03I`. No parity ledger rollback
|
||||
is required.
|
||||
45
docs/status/M12-03J.md
Normal file
45
docs/status/M12-03J.md
Normal file
@@ -0,0 +1,45 @@
|
||||
# M12-03J Status
|
||||
|
||||
status: done
|
||||
task: desktop override fixture records reference, local owner, and property override path
|
||||
updated: 2026-08-17 America/New_York
|
||||
enablingTask: false
|
||||
parityStateChange: false
|
||||
|
||||
## Scope
|
||||
|
||||
Blender 5.2 creates a real linked Object and converts it through the library override API. The fixture
|
||||
records the linked reference as `SOURCE_LIBRARY/readOnly=true`, the local hierarchy root as
|
||||
`LOCAL_OVERRIDE/readOnly=false`, and one explicit custom-property override path. The source marker,
|
||||
reference ID, local owner, hierarchy root, property operation and value remain stable after save/reopen.
|
||||
|
||||
This fixture does not open a general override writer; it freezes the reference/owner/property contract
|
||||
needed by the next bounded writer task.
|
||||
|
||||
## Evidence
|
||||
|
||||
- `npm --prefix web run test:library-override-desktop` passed.
|
||||
- Blender 5.2 source/target fixture regeneration matched the normalized desktop report.
|
||||
- The reference retains `m12_override_source.blend`; the local object is `LOCAL_OVERRIDE`; the only
|
||||
recorded property path is `["m12_override_value"]` with value `2.5` and one `REPLACE` operation.
|
||||
- Save/reopen preserves the reference, hierarchy root, owner semantics, and property metadata.
|
||||
|
||||
## Artifact Hashes
|
||||
|
||||
- generator: `2cdbac04cac7240360a9d70919380fd90f9479e2cb41d8032fb51626ed4b4dd6`
|
||||
- checker: `afebb3c9b8715b9d2e0c9b17f463f038bd23e8747074137bccbf1c09c4bfb5ba`
|
||||
- source blend: `d7f8d78e7e91481bf46ecc9a6bcb01e900a6a397839dd31ab80a53def7675601`
|
||||
- target blend: `b008a1608ff1e8f679e1e1281bf7be0360f1137e815dd890cbd93e1e98675495`
|
||||
- report: `19cb13a3417b4b65a8497b622337c42c4697b3f3d48de26a1f70f2d4527ddde0`
|
||||
- manifest: `01d0f66bb3819eea3e92727d1b5bffbec935d24eeecc28d874b999df78d73fbf`
|
||||
- package commands: `cfb232baa494ff59f6c8d65514a08c86332ee9354350b2a0392b6f932a7ee42c`
|
||||
|
||||
## Next Task
|
||||
|
||||
`M12-03K`: expose exactly one verified override writer property.
|
||||
|
||||
## Rollback
|
||||
|
||||
Remove the override generator/checker, fixture, report, manifest, package command, and this status
|
||||
entry. Restore M12-03I to pending and move the machine queue back to `M12-03J`. No parity ledger
|
||||
rollback is required.
|
||||
42
docs/status/M12-03K.md
Normal file
42
docs/status/M12-03K.md
Normal file
@@ -0,0 +1,42 @@
|
||||
# M12-03K Status
|
||||
|
||||
status: done
|
||||
task: expose exactly one verified override writer property
|
||||
updated: 2026-08-17 America/New_York
|
||||
enablingTask: false
|
||||
parityStateChange: false
|
||||
|
||||
## Scope
|
||||
|
||||
Schema-1 override writer accepts exactly `SET_M12_OVERRIDE_VALUE` for the property path
|
||||
`["m12_override_value"]`. It requires `LOCAL_OVERRIDE`, `readOnly=false`,
|
||||
`referenceReadOnly=true`, matching local/reference/hierarchy IDs, and the current revision. A valid
|
||||
write updates only the verified value and advances the local revision by one.
|
||||
|
||||
Linked ownership, a second property path, identity drift, stale revision, malformed fields, and values
|
||||
outside the bounded float range are blocked before any writer commit.
|
||||
|
||||
## Evidence
|
||||
|
||||
- `npm --prefix web run test:library-override-writer` passed 4/4 unit tests.
|
||||
- The valid request applies one property and increments revision exactly once while preserving local
|
||||
override ownership and reference read-only semantics.
|
||||
- Stale, linked-owner, identity, alternate-operation, alternate-property, malformed, and out-of-range
|
||||
requests fail closed.
|
||||
|
||||
## Artifact Hashes
|
||||
|
||||
- protocol: `dd181c7e9946b98334a5d1c686887afecfe3fc11d732beec246e40bf11a155aa`
|
||||
- unit: `e41bd32eb4ce4d331a20ecb91f3325a27f461b9ae85e98940d5afd482ec21c4c`
|
||||
- manifest: `9eeee93e4a806aa59b5c53a6485fe3a1b5e3972c1d2585cdc71b7cfc293afb70`
|
||||
- package commands: `cfb232baa494ff59f6c8d65514a08c86332ee9354350b2a0392b6f932a7ee42c`
|
||||
|
||||
## Next Task
|
||||
|
||||
`M12-03L`: block override stale source/revision before Main commit.
|
||||
|
||||
## Rollback
|
||||
|
||||
Remove the override writer protocol, unit suite, manifest, package command, and this status entry.
|
||||
Restore M12-03J to pending and move the machine queue back to `M12-03K`. No parity ledger rollback
|
||||
is required.
|
||||
41
docs/status/M12-03L.md
Normal file
41
docs/status/M12-03L.md
Normal file
@@ -0,0 +1,41 @@
|
||||
# M12-03L Status
|
||||
|
||||
status: done
|
||||
task: block override stale source/revision before Main commit
|
||||
updated: 2026-08-17 America/New_York
|
||||
enablingTask: false
|
||||
parityStateChange: false
|
||||
|
||||
## Scope
|
||||
|
||||
Schema-1 override freshness binds the local override to its source library ID, source generation,
|
||||
source revision, dependency-closure SHA-256, invalidation token, and local/reference/hierarchy IDs.
|
||||
Only a fully matching `COMMIT_OVERRIDE` request reaches `READY`; no Main mutation is performed by
|
||||
this gate.
|
||||
|
||||
Stale generation/revision, dependency closure, invalidation token, linked ownership, identity drift,
|
||||
alternate operation, malformed token, and undeclared fields return stable blocking codes before Main.
|
||||
|
||||
## Evidence
|
||||
|
||||
- `npm --prefix web run test:library-override-freshness` passed 4/4 unit tests.
|
||||
- The exact source generation/revision/closure/token binding returns `READY`.
|
||||
- Stale source fields return `REVISION_CONFLICT`; local identity drift returns
|
||||
`ASSET_SOURCE_HASH_MISMATCH`; linked ownership returns `LINKED_DATA_MUTATION_BLOCKED`.
|
||||
|
||||
## Artifact Hashes
|
||||
|
||||
- protocol: `2eff7ea7605b1579d7551336d87d4f30adb996b585596ff9eee67aea04ca7d22`
|
||||
- unit: `d48344f31e1ba12e557ca30ece56643583efa633da556f5de3896a8e9175ef8f`
|
||||
- manifest: `237f3f168e037b67b805ba8d9c9455250c889a5e90c45cbb17d2d20d9fbdcc50`
|
||||
- package commands: `cfb232baa494ff59f6c8d65514a08c86332ee9354350b2a0392b6f932a7ee42c`
|
||||
|
||||
## Next Task
|
||||
|
||||
`M12-03M`: dependency cycle, ID collision, cross-library cycle, and duplicate reload negatives.
|
||||
|
||||
## Rollback
|
||||
|
||||
Remove the override freshness protocol, unit suite, manifest, package command, and this status entry.
|
||||
Restore M12-03K to pending and move the machine queue back to `M12-03L`. No parity ledger rollback
|
||||
is required.
|
||||
38
docs/status/M12-03M.md
Normal file
38
docs/status/M12-03M.md
Normal file
@@ -0,0 +1,38 @@
|
||||
# M12-03M Status
|
||||
|
||||
status: done
|
||||
task: dependency cycle, ID collision, cross-library cycle, and duplicate reload negatives
|
||||
updated: 2026-08-17 America/New_York
|
||||
enablingTask: false
|
||||
parityStateChange: false
|
||||
|
||||
## Scope
|
||||
|
||||
Schema-1 negative-case validation checks library dependency graphs, cross-library references,
|
||||
data-block identity ownership, and reload generation identities. Acyclic graphs with unique IDs are
|
||||
accepted; dependency/cross-library cycles, missing source libraries, duplicate data-block IDs, and
|
||||
duplicate reload generations fail with stable codes before any writer or Main mutation.
|
||||
|
||||
## Evidence
|
||||
|
||||
- `npm --prefix web run test:library-negative-cases` passed 4/4 unit tests.
|
||||
- Direct dependency cycles and cross-library cycles return `LIBRARY_DEPENDENCY_CYCLE`.
|
||||
- Data-block collision returns `TASK_VALIDATION_FAILED`; duplicate reload returns `REVISION_CONFLICT`;
|
||||
a missing source library returns `ASSET_SOURCE_HASH_MISMATCH`.
|
||||
|
||||
## Artifact Hashes
|
||||
|
||||
- protocol: `efc7cc810089eab6178fc5c2f2a45d641625a032ecfa5b2b4ef37694d0decc97`
|
||||
- unit: `b7ae41b2c35b2fe1598bca4425dd434230bfe4bf342320c88214a060dcbb0a16`
|
||||
- manifest: `693cbedfe8e29167283a753d119de5a9cfe5e20bc96aff7ba84d720ffde9148a`
|
||||
- package commands: `cfb232baa494ff59f6c8d65514a08c86332ee9354350b2a0392b6f932a7ee42c`
|
||||
|
||||
## Next Task
|
||||
|
||||
`M12-03N`: append/link/override each receive independent desktop/WASM/Chromium commands.
|
||||
|
||||
## Rollback
|
||||
|
||||
Remove the negative-case protocol, unit suite, manifest, package command, and this status entry.
|
||||
Restore M12-03L to pending and move the machine queue back to `M12-03M`. No parity ledger rollback
|
||||
is required.
|
||||
42
docs/status/M12-03N.md
Normal file
42
docs/status/M12-03N.md
Normal file
@@ -0,0 +1,42 @@
|
||||
# M12-03N Status
|
||||
|
||||
status: done
|
||||
task: append/link/override each receive independent desktop/WASM/Chromium commands
|
||||
updated: 2026-08-17 America/New_York
|
||||
enablingTask: false
|
||||
parityStateChange: false
|
||||
|
||||
## Scope
|
||||
|
||||
Append, LINK, and library override each have independent desktop, WASM, and Chromium commands. The
|
||||
commands are bound to distinct fixtures/protocol tests/browser specs and use separate Chromium ports.
|
||||
The command checker verifies all nine package entries and their lane-specific targets.
|
||||
|
||||
## Evidence
|
||||
|
||||
- `npm run test:library-operation-commands` passed with 9 independent commands: 3 operations x 3 lanes.
|
||||
- Desktop: append fixture, LINK fixture, and Blender 5.2 override fixture all passed.
|
||||
- WASM: append receipt protocol passed 2/2; LINK aggregate passed 11/11; override aggregate passed 8/8.
|
||||
- Chromium: append passed 1/1; LINK gate passed 1/1 on port 5195; override writer passed 1/1 on port
|
||||
5196. Append Chromium passed 1/1 on port 5194.
|
||||
|
||||
## Artifact Hashes
|
||||
|
||||
- command checker: `3564347393134d835fdf279b8b8f58558ee24fe0165c3b4527195d094a451e98`
|
||||
- append WASM protocol: `bfd98561cbe797d7b8f07c92c53a25460c839a64ab7222b7795cf58d54dff8d7`
|
||||
- append WASM unit: `75fc2d626f7ca7e820e9cacf659a453886e15e790cde43348828c03bed752ec7`
|
||||
- append Chromium: `101f67d35c2320da57459f08a59687d769234b910dbd9aaec5a668cee7e0f9f0`
|
||||
- link Chromium: `814e3486522fb4f0ffdd59acd385a4fca9c5660cdb07e5a2acb1cadd70376bff`
|
||||
- override Chromium: `1c12982b4eb4fb4b9a3c88907a842a1fc413b3a3a760a9f57b350f57060d007f`
|
||||
- manifest: `e4cccc8edc277b5047c3f8006ea40b26b119d28589fe2f3bd9bfa4cc3575c85a`
|
||||
- package commands: `cfb232baa494ff59f6c8d65514a08c86332ee9354350b2a0392b6f932a7ee42c`
|
||||
|
||||
## Next Task
|
||||
|
||||
`M12-04A`: library source schema accepts only declared HTTPS origins, project assets, or user-selected files.
|
||||
|
||||
## Rollback
|
||||
|
||||
Remove the independent command checker, lane-specific tests/wrappers, manifest, package commands, and this
|
||||
status entry. Restore M12-03M to pending and move the machine queue back to `M12-03N`. No parity ledger
|
||||
rollback is required.
|
||||
40
docs/status/M12-04A.md
Normal file
40
docs/status/M12-04A.md
Normal file
@@ -0,0 +1,40 @@
|
||||
# M12-04A Status
|
||||
|
||||
status: done
|
||||
task: library source schema accepts declared HTTPS origin, project asset, or user-selected file
|
||||
updated: 2026-08-17 America/New_York
|
||||
enablingTask: false
|
||||
parityStateChange: false
|
||||
|
||||
## Scope
|
||||
|
||||
Schema-1 source admission accepts exactly three declared kinds: HTTPS URLs whose credential-free origin
|
||||
is present in the policy, project-relative asset paths normalized by the existing project-path gate,
|
||||
and user-selected files carrying a stable selection ID, safe file name, bounded byte length, and
|
||||
source SHA-256. Accepted sources receive a canonical locator.
|
||||
|
||||
Undeclared origins, credentials, unsafe project paths, empty origin policy, malformed file identity,
|
||||
and undeclared fields fail closed before any library load.
|
||||
|
||||
## Evidence
|
||||
|
||||
- `npm --prefix web run test:library-source-origin` passed 4/4 unit tests.
|
||||
- Declared HTTPS, project asset, and user-selected file cases return `READY` with canonical locators.
|
||||
- Undeclared HTTPS, credential-bearing URLs, traversal paths, empty policies, malformed selection IDs,
|
||||
and undeclared fields return stable blocking errors.
|
||||
|
||||
## Artifact Hashes
|
||||
|
||||
- protocol: `67a1808f225194a09a72987c5340c7494c5fa8d99dffde40664a11a779caedeb`
|
||||
- unit: `89b207c9cb13b4fb055a2dfed0237c0f8a00b13a39cc4175a378f5ef2abdb7ae`
|
||||
- manifest: `af80827d925ddd96d8541e446e0f70c956fd4c56e64ac984d187f5449df4cb0d`
|
||||
- package commands: `cfb232baa494ff59f6c8d65514a08c86332ee9354350b2a0392b6f932a7ee42c`
|
||||
|
||||
## Next Task
|
||||
|
||||
`M12-04B`: normalize POSIX/Windows separators, `.`, `..`, percent encoding, and Unicode names.
|
||||
|
||||
## Rollback
|
||||
|
||||
Remove the source-origin protocol, unit suite, manifest, package command, and this status entry. Restore
|
||||
M12-03N to pending and move the machine queue back to `M12-04A`. No parity ledger rollback is required.
|
||||
42
docs/status/M12-04B.md
Normal file
42
docs/status/M12-04B.md
Normal file
@@ -0,0 +1,42 @@
|
||||
# M12-04B Status
|
||||
|
||||
status: done
|
||||
task: normalize POSIX/Windows separators, dot segments, percent encoding, and Unicode names
|
||||
updated: 2026-08-17 America/New_York
|
||||
enablingTask: false
|
||||
parityStateChange: false
|
||||
|
||||
## Scope
|
||||
|
||||
The shared project-asset path normalizer now emits one canonical `/`-separated path. It accepts
|
||||
equivalent POSIX/Windows separators, removes `.` segments, resolves bounded `..` segments without
|
||||
allowing project-root escape, decodes percent-encoded UTF-8 once, and applies Unicode NFC normalization.
|
||||
Residual percent octets, malformed encoding, controls, absolute paths, URI schemes, and traversal beyond
|
||||
the project remain fail-closed.
|
||||
|
||||
## Evidence
|
||||
|
||||
- `npm --prefix web run test:library-path-normalization` passed 4/4 unit tests.
|
||||
- Separator and dot aliases converge to one idempotent canonical path.
|
||||
- Percent-encoded separators/dot segments and decomposed Unicode names match the canonical project asset
|
||||
locator used by the M12-04A source admission path.
|
||||
- Re-decoding, malformed percent encoding, and project-root escape return stable path errors.
|
||||
- `npm --prefix web run typecheck` passed after closing the prior library wrapper/parser type errors.
|
||||
|
||||
## Artifact Hashes
|
||||
|
||||
- parent manifest: `af80827d925ddd96d8541e446e0f70c956fd4c56e64ac984d187f5449df4cb0d`
|
||||
- normalizer: `6109d05251fc7355ac32d4c0d8298f85ea8b731767c76c394577c4e44652a6bf`
|
||||
- source admission: `67a1808f225194a09a72987c5340c7494c5fa8d99dffde40664a11a779caedeb`
|
||||
- unit: `abde64c60397541e92a83dd9e4a24e65faf340a8d046650604c101a21037c777`
|
||||
- manifest: `8cd29c3f5281082584fc6aefe2ec385a2eedf8116e837a4db54c391391ff8f98`
|
||||
- package commands: `cfb232baa494ff59f6c8d65514a08c86332ee9354350b2a0392b6f932a7ee42c`
|
||||
|
||||
## Next Task
|
||||
|
||||
`M12-04C`: reject absolute paths, UNC, drive paths, NUL, control characters, and origin escape.
|
||||
|
||||
## Rollback
|
||||
|
||||
Remove the path normalizer changes, unit suite, manifest, package command, and this status entry. Restore
|
||||
M12-04A to pending and move the machine queue back to `M12-04B`. No parity ledger rollback is required.
|
||||
45
docs/status/M12-04C.md
Normal file
45
docs/status/M12-04C.md
Normal file
@@ -0,0 +1,45 @@
|
||||
# M12-04C Status
|
||||
|
||||
status: done
|
||||
task: reject absolute paths, UNC/drive paths, controls, and origin escape
|
||||
updated: 2026-08-18 America/New_York
|
||||
enablingTask: false
|
||||
parityStateChange: false
|
||||
|
||||
## Scope
|
||||
|
||||
The project-asset path gate rejects absolute POSIX paths, UNC and drive-shaped paths, NUL/control
|
||||
characters, malformed or residual percent encoding, and URI/origin-shaped escapes before a locator is
|
||||
accepted. HTTPS source policy entries are now strict credential-free origins: path, query, fragment,
|
||||
encoded controls, and backslash smuggling are rejected instead of being silently reduced to
|
||||
`URL.origin`. HTTPS resource paths retain the declared-origin check and reject unsafe decoded bytes.
|
||||
|
||||
## Evidence
|
||||
|
||||
- `npm --prefix web run test:library-path-security` passed 4/4 unit tests.
|
||||
- Absolute, UNC, drive, raw/encoded NUL and control characters, and origin-style project paths return
|
||||
stable `ASSET_PATH_OUTSIDE_PROJECT`/`ASSET_PATH_INVALID` errors.
|
||||
- Raw and encoded backslashes, controls, malformed percent sequences, credentials, undeclared origins,
|
||||
and policy origin smuggling return `IO_EXTERNAL_URI_BLOCKED`.
|
||||
- Declared `https://assets.example.test/library/main.blend` remains accepted; policy declarations with
|
||||
a path, query, fragment, encoded control, or duplicate canonical origin fail closed.
|
||||
- `WEB_TEST_PORT=5323 npm --prefix web run test:asset-library` passed the N-023 Chromium asset/IO gate 1/1.
|
||||
- `npm --prefix web run typecheck` passed.
|
||||
|
||||
## Artifact Hashes
|
||||
|
||||
- parent manifest: `8cd29c3f5281082584fc6aefe2ec385a2eedf8116e837a4db54c391391ff8f98`
|
||||
- path normalizer: `6109d05251fc7355ac32d4c0d8298f85ea8b731767c76c394577c4e44652a6bf`
|
||||
- source-origin protocol: `67a1808f225194a09a72987c5340c7494c5fa8d99dffde40664a11a779caedeb`
|
||||
- unit: `ab302cacb24634a3225dda5cb8f5282cb80b3bd81ed5c8900ddf4ff18267b7e2`
|
||||
- manifest: `a7f3a45eb7f68d022f38185a1c1409e1db1b27647fef587d66d2ffa52d78f98e`
|
||||
- package commands: `cfb232baa494ff59f6c8d65514a08c86332ee9354350b2a0392b6f932a7ee42c`
|
||||
|
||||
## Next Task
|
||||
|
||||
`M12-04D`: resolve symlink/hardlink entries before writing and constrain them to the temporary root.
|
||||
|
||||
## Rollback
|
||||
|
||||
Remove the C path-security assertions, manifest, status entry, and strict origin validation. Restore
|
||||
M12-04B to pending and move the machine queue back to `M12-04C`. No parity ledger rollback is required.
|
||||
44
docs/status/M12-04D.md
Normal file
44
docs/status/M12-04D.md
Normal file
@@ -0,0 +1,44 @@
|
||||
# M12-04D Status
|
||||
|
||||
status: done
|
||||
task: resolve symlink/hardlink entries before writing and constrain them to the temporary root
|
||||
updated: 2026-08-18 America/New_York
|
||||
enablingTask: false
|
||||
parityStateChange: false
|
||||
|
||||
## Scope
|
||||
|
||||
Archive entries are parsed before any write. Every member is canonicalized as a relative path under
|
||||
the declared temporary-root identity. Symlink targets resolve relative to the link's parent; hardlink
|
||||
targets resolve from the archive root and must end at a regular file. Absolute, drive-shaped, URI,
|
||||
backslash-smuggled, traversal, missing-target, cyclic, duplicate, and hardlink-to-directory inputs
|
||||
fail closed with `IO_ARCHIVE_UNSAFE`.
|
||||
|
||||
The resolver returns a write plan with the final in-root target and an explicit
|
||||
`withinTemporaryRoot: true` proof for every member. It does not follow or write any link before the
|
||||
entire manifest has passed validation.
|
||||
|
||||
## Evidence
|
||||
|
||||
- `npm --prefix web run test:library-link-safety` passed 5/5 unit tests.
|
||||
- Parent-directory symlinks, archive-root hardlinks, and chained links resolve to canonical in-root
|
||||
members.
|
||||
- Absolute/UNC/drive/URI/traversal targets, missing members, cycles, duplicate paths, undeclared
|
||||
fields, and hardlinks to directories are rejected before a write plan is returned.
|
||||
|
||||
## Artifact Hashes
|
||||
|
||||
- parent manifest: `a7f3a45eb7f68d022f38185a1c1409e1db1b27647fef587d66d2ffa52d78f98e`
|
||||
- protocol: `d55a4ba762898aed22bdcc7aa6493c713ee94f6bb1bf58754fdc459d0ddf70d1`
|
||||
- unit: `7739275be91222d7bfb61d2f5a1daf812c6860fe34d0aea27df8380a77322120`
|
||||
- package commands: `cfb232baa494ff59f6c8d65514a08c86332ee9354350b2a0392b6f932a7ee42c`
|
||||
|
||||
## Next Task
|
||||
|
||||
`M12-04E`: archive first reads the central directory/manifest and does not extract payload first.
|
||||
|
||||
## Rollback
|
||||
|
||||
Remove the archive link-safety protocol, unit suite, manifest, package command, and this status entry.
|
||||
Restore M12-04C to pending and move the machine queue back to `M12-04D`. No parity ledger rollback is
|
||||
required.
|
||||
38
docs/status/M12-04E.md
Normal file
38
docs/status/M12-04E.md
Normal file
@@ -0,0 +1,38 @@
|
||||
# M12-04E Status
|
||||
|
||||
status: done
|
||||
task: archive first reads the central directory or manifest before payload extraction
|
||||
updated: 2026-08-18 America/New_York
|
||||
enablingTask: false
|
||||
parityStateChange: false
|
||||
|
||||
## Scope
|
||||
|
||||
ZIP requests produce a bounded `CENTRAL_DIRECTORY` first-read plan; TAR requests produce a bounded
|
||||
`MANIFEST` first-read plan. The plan contains no payload ranges. A read trace is accepted only when
|
||||
the first exact range is the declared metadata range and every later range is payload; payload-first,
|
||||
wrong-range, duplicate-metadata, out-of-order, oversized, and out-of-archive reads fail closed with
|
||||
`IO_ARCHIVE_UNSAFE`.
|
||||
|
||||
## Evidence
|
||||
|
||||
- `npm --prefix web run test:library-metadata-first` passed 4/4 unit tests.
|
||||
- ZIP and TAR plans expose metadata-only first reads with an empty payload plan.
|
||||
- Payload-first, wrong-range, duplicate metadata, out-of-archive, and metadata-budget cases are
|
||||
rejected before extraction can be scheduled.
|
||||
|
||||
## Artifact Hashes
|
||||
|
||||
- parent manifest: `1c09abd1f4bd5908d22ab3b22e3e71d050f694af0b82a7f78a351d7a1bf1e664`
|
||||
- protocol: `869586b041e134c7d1cb2ebd7e13b35218b337223d401697a179f71cd1420f5b`
|
||||
- unit: `2da649722acee9cace8db6f337b4a93500a9c775a0b0f086bf38dd2b3e7f9e91`
|
||||
- package commands: `cfb232baa494ff59f6c8d65514a08c86332ee9354350b2a0392b6f932a7ee42c`
|
||||
|
||||
## Next Task
|
||||
|
||||
`M12-04F`: enforce per-entry bytes, total bytes, entry count, directory depth, and filename length budgets.
|
||||
|
||||
## Rollback
|
||||
|
||||
Remove the metadata-first protocol, unit suite, manifest, package command, and this status entry. Restore
|
||||
M12-04D to pending and move the machine queue back to `M12-04E`. No parity ledger rollback is required.
|
||||
37
docs/status/M12-04F.md
Normal file
37
docs/status/M12-04F.md
Normal file
@@ -0,0 +1,37 @@
|
||||
# M12-04F Status
|
||||
|
||||
status: done
|
||||
task: enforce archive entry, total, count, directory-depth, and filename-length budgets
|
||||
updated: 2026-08-18 America/New_York
|
||||
enablingTask: false
|
||||
parityStateChange: false
|
||||
|
||||
## Scope
|
||||
|
||||
The production `asset-library-io` parser now enforces the existing compressed/uncompressed per-entry
|
||||
and total-byte budgets together with a 100,000-entry limit, 64 directory levels, and a 255-byte UTF-8
|
||||
filename limit. Compression-ratio and declared source-byte checks remain fail-closed in the same path.
|
||||
Budget checks happen while parsing metadata, before any payload allocation or extraction.
|
||||
|
||||
## Evidence
|
||||
|
||||
- `npm --prefix web run test:library-archive-budget` passed 4/4 unit tests.
|
||||
- Exact boundary cases for entry bytes, total bytes, entry count, directory depth, and Unicode filename
|
||||
bytes are accepted; one-byte overflows return stable budget errors.
|
||||
- Existing compression-ratio, duplicate/prefix, and declared source-byte checks remain covered.
|
||||
|
||||
## Artifact Hashes
|
||||
|
||||
- parent manifest: `d935392fb23c2e6ad651fb6ad6cb67f8ead3d562e626bb230d2febd9d7f03b1c`
|
||||
- protocol: `e02efa79668f4ee10b1c28786709eba2c93691b28ccf1155c6213dda12f59a8f`
|
||||
- unit: `b0d8356c6fb348d98e28ce220052845a29439b34b3c976b21a4dbf370ea19593`
|
||||
- package commands: `cfb232baa494ff59f6c8d65514a08c86332ee9354350b2a0392b6f932a7ee42c`
|
||||
|
||||
## Next Task
|
||||
|
||||
`M12-04G`: reject compression-ratio, overlapping range, duplicate path, and file/directory prefix conflicts.
|
||||
|
||||
## Rollback
|
||||
|
||||
Remove the budget checks, unit suite, manifest, package command, and this status entry. Restore M12-04E
|
||||
to pending and move the machine queue back to `M12-04F`. No parity ledger rollback is required.
|
||||
39
docs/status/M12-04G.md
Normal file
39
docs/status/M12-04G.md
Normal file
@@ -0,0 +1,39 @@
|
||||
# M12-04G Status
|
||||
|
||||
status: done
|
||||
task: reject archive compression bombs, overlapping ranges, duplicate paths, and prefix conflicts
|
||||
updated: 2026-08-18 America/New_York
|
||||
enablingTask: false
|
||||
parityStateChange: false
|
||||
|
||||
## Scope
|
||||
|
||||
Archive range validation now checks each compressed range against the declared source length and the
|
||||
global archive bound, sorts ranges by offset, and rejects overlap before any payload read. It also
|
||||
rejects duplicate canonical paths, file/directory prefix conflicts, zero-byte compression bombs, and
|
||||
expansion ratios above 100:1. Valid ranges return deterministic totals and explicit non-overlap/path
|
||||
invariants.
|
||||
|
||||
## Evidence
|
||||
|
||||
- `npm --prefix web run test:library-archive-conflicts` passed 4/4 unit tests.
|
||||
- Non-overlapping ranges produce stable compressed/uncompressed totals.
|
||||
- Compression-ratio, overlap, duplicate, prefix, source-bound, and undeclared-field negatives all
|
||||
return `IO_ARCHIVE_UNSAFE` before payload scheduling.
|
||||
|
||||
## Artifact Hashes
|
||||
|
||||
- parent manifest: `cda905b1e27b62d9ea3a05170f975015480ce6739c15bdf1f5a1f0b79f93ce06`
|
||||
- protocol: `3bec372e4f67ec309f28534cebcbaf8b492144adfa82ff6c8603f88c3ba16254`
|
||||
- unit: `3f2d44dce33b1c17b3a48f58b04fdd821abc88d98ce3d3b5bb724859e0f0ab3c`
|
||||
- package commands: `cfb232baa494ff59f6c8d65514a08c86332ee9354350b2a0392b6f932a7ee42c`
|
||||
|
||||
## Next Task
|
||||
|
||||
`M12-04H`: cancellation removes staging and never modifies the committed project.
|
||||
|
||||
## Rollback
|
||||
|
||||
Remove the archive conflict protocol, unit suite, manifest, package command, and this status entry.
|
||||
Restore M12-04F to pending and move the machine queue back to `M12-04G`. No parity ledger rollback is
|
||||
required.
|
||||
48
docs/status/M12-04H.md
Normal file
48
docs/status/M12-04H.md
Normal file
@@ -0,0 +1,48 @@
|
||||
# M12-04H Status
|
||||
|
||||
status: done
|
||||
task: remove extraction staging on cancellation without modifying the committed project
|
||||
updated: 2026-08-18 America/New_York
|
||||
enablingTask: false
|
||||
parityStateChange: false
|
||||
|
||||
## Scope
|
||||
|
||||
The production archive extraction transaction checks cancellation before staging, around every
|
||||
payload read and write, and immediately before atomic commit. A pre-commit cancellation returns
|
||||
`IO_ARCHIVE_CANCELLED`, removes every staged file, publishes no project, and re-reads the committed
|
||||
project identity to prove that revision and SHA-256 did not change. Once atomic commit starts,
|
||||
cancellation no longer converts the completed commit into a cancelled result.
|
||||
|
||||
Payload identity failure and staging creation/write failure use the same cleanup path. If cleanup
|
||||
leaves a staged entry or the committed identity drifts, the transaction fails with
|
||||
`STORAGE_TRANSACTION` instead of claiming successful cancellation.
|
||||
|
||||
## Evidence
|
||||
|
||||
- `npm --prefix web run test:library-archive-cancellation` passed 6/6 unit tests against real
|
||||
temporary directories.
|
||||
- Cancellation before staging, after one staged file, and after the final staged write all leave
|
||||
zero staging files, zero published projects, and the original committed project bytes.
|
||||
- The success path publishes revision 9 only after both staged payload hashes pass.
|
||||
- Payload mismatch, rollback identity drift, stale revision, unsafe path, prefix conflict, and
|
||||
undeclared-field negatives fail closed.
|
||||
|
||||
## Artifact Hashes
|
||||
|
||||
- parent manifest: `c35e675e8f512e85b748f0b5578874fed8c99df7674a152e698236a67c9f4fa4`
|
||||
- protocol: `c40adc1449172014cc1820db567e155828314abb404b66e4de13c26ddee06e4b`
|
||||
- error codes: `751c70c898540fa7e82fb1b1a79254756ec8db8e4201a88b6d817d7c3d92103f`
|
||||
- unit: `77e7d5bc64dd6b313006ebf523602601acdaf7949a1484da872ddcd046983786`
|
||||
- package commands: `cfb232baa494ff59f6c8d65514a08c86332ee9354350b2a0392b6f932a7ee42c`
|
||||
- manifest: `7fce600a416aec5ade1a91a13d86caf4cb1f65b710054b59d525ff8b1d3c7409`
|
||||
|
||||
## Next Task
|
||||
|
||||
`M12-04I`: release temporary files after quota/OOM and allow a small archive to recover.
|
||||
|
||||
## Rollback
|
||||
|
||||
Remove the extraction transaction protocol, cancellation code, real-filesystem unit suite, manifest,
|
||||
package command, and this status entry. Restore M12-04G as the queue tail and move the machine queue
|
||||
back to `M12-04H`. No parity ledger rollback is required.
|
||||
47
docs/status/M12-04I.md
Normal file
47
docs/status/M12-04I.md
Normal file
@@ -0,0 +1,47 @@
|
||||
# M12-04I Status
|
||||
|
||||
status: done
|
||||
task: release archive staging after quota/OOM and recover with a small archive
|
||||
updated: 2026-08-18 America/New_York
|
||||
enablingTask: false
|
||||
parityStateChange: false
|
||||
|
||||
## Scope
|
||||
|
||||
The archive recovery wrapper maps browser/OPFS quota failures to `STORAGE_QUOTA` and declared
|
||||
allocation failures to `WASM_OUT_OF_MEMORY` only after the M12-04H base transaction has removed
|
||||
staging and re-read the committed project identity. Cleanup or identity drift remains
|
||||
`STORAGE_TRANSACTION`; unrelated range and IO failures are not misclassified as OOM.
|
||||
|
||||
Real temporary-directory tests partially write the failing payload before injecting each fault.
|
||||
Both paths leave zero staging entries and preserve the previous revision, SHA-256, and committed
|
||||
bytes. The same storage instance then accepts and atomically commits a smaller archive without a
|
||||
Worker or process restart.
|
||||
|
||||
## Evidence
|
||||
|
||||
- `node --test web/tests/unit/library-archive-recovery.test.mjs` passed 4/4.
|
||||
- Quota and OOM each remove a partially written 4 KiB staging payload and preserve revision 9.
|
||||
- Each failed storage instance immediately commits `small-project` at revision 10 with zero
|
||||
staging entries.
|
||||
- `npm --prefix web run test:library-archive-cancellation` passed 6/6 and
|
||||
`npm --prefix web run typecheck` passed.
|
||||
|
||||
## Artifact Hashes
|
||||
|
||||
- parent manifest: `7fce600a416aec5ade1a91a13d86caf4cb1f65b710054b59d525ff8b1d3c7409`
|
||||
- base transaction: `c40adc1449172014cc1820db567e155828314abb404b66e4de13c26ddee06e4b`
|
||||
- recovery protocol: `0ae9801ea151403b244c5f58f7f99231bba7a25abb1f61e3669879510b92dccf`
|
||||
- unit: `a931edef8f3ca1243a80ec2b8e9ff5b8da1dfd339f3d8c162ad2ebd08d3db6a1`
|
||||
- package commands: `cfb232baa494ff59f6c8d65514a08c86332ee9354350b2a0392b6f932a7ee42c`
|
||||
- manifest: `574afa68a787b9481d0e098d38b94cb810a9827fe185b0df796d62cc160ba7c5`
|
||||
|
||||
## Next Task
|
||||
|
||||
`M12-04J`: add malicious ZIP/TAR fixtures to the long-term security regression.
|
||||
|
||||
## Rollback
|
||||
|
||||
Remove the recovery wrapper, real-filesystem unit suite, manifest, and this status entry. Restore
|
||||
M12-04H as the queue tail and move the machine queue back to `M12-04I`. No parity ledger rollback is
|
||||
required.
|
||||
49
docs/status/M12-04J.md
Normal file
49
docs/status/M12-04J.md
Normal file
@@ -0,0 +1,49 @@
|
||||
# M12-04J Status
|
||||
|
||||
status: done
|
||||
task: keep malicious ZIP/TAR fixtures in the long-term archive security regression
|
||||
updated: 2026-08-18 America/New_York
|
||||
enablingTask: false
|
||||
parityStateChange: false
|
||||
|
||||
## Scope
|
||||
|
||||
Six deterministic binary fixtures cover ZIP path traversal, compression-ratio abuse, duplicate
|
||||
paths, TAR path traversal, symlink escape, and file/directory prefix conflict. The generator fixes
|
||||
container fields and timestamps; the checker regenerates every file in a temporary directory and
|
||||
requires byte-for-byte equality with the committed fixtures and catalog SHA-256 values.
|
||||
|
||||
The checker reads ZIP EOCD/central-directory and USTAR header metadata, verifies local-header
|
||||
bindings, TAR checksums, alignment, and end markers, then feeds the actual entry metadata into the
|
||||
M12-04D/G link and conflict gates. It never invokes `tar`, `unzip`, or an extraction API. All six
|
||||
fixtures fail closed with `IO_ARCHIVE_UNSAFE` and are included in the existing N-023 Chromium grep.
|
||||
|
||||
## Evidence
|
||||
|
||||
- `node tools/web/check-malicious-archive-fixtures.mjs` passed 6/6 with three ZIP and three TAR
|
||||
fixtures and extraction disabled.
|
||||
- `WEB_TEST_PORT=5408 npm --prefix web run test:asset-library` passed 2/2, including the persistent
|
||||
binary-fixture security test and the existing N-023 asset/IO gate.
|
||||
- Fixture byte lengths range from 115 to 3,072 bytes and every committed SHA-256 matches the
|
||||
generated catalog.
|
||||
|
||||
## Artifact Hashes
|
||||
|
||||
- parent manifest: `574afa68a787b9481d0e098d38b94cb810a9827fe185b0df796d62cc160ba7c5`
|
||||
- generator: `b372ea8cb2f97b035ffb2cc18666dae9167dcfb349131851ad9f1ff0fc40ba16`
|
||||
- checker: `edda2f420f26e55f9990d24b755bb9b4f732ec32c2e072210144b3d0b6634d9b`
|
||||
- fixture manifest: `a93834316f6a23b8a0e6c1f1f806ec584d6f03aa339c2680cae2ce8133a40e58`
|
||||
- Chromium spec: `f327500808dd67359a152ce28134b58d027aebd6758416b5535b659b9900bbfe`
|
||||
- package commands: `cfb232baa494ff59f6c8d65514a08c86332ee9354350b2a0392b6f932a7ee42c`
|
||||
- manifest: `989d417ab44e165849c7054f331f7038ec1d779349c39dd4f5b30050bbaecf56`
|
||||
|
||||
## Next Task
|
||||
|
||||
`M12-05A`: generate the glTF/GLB, OBJ, STL, PLY, USD, and Alembic format inventory from the pinned
|
||||
Blender 5.2 build/runtime.
|
||||
|
||||
## Rollback
|
||||
|
||||
Remove the fixture generator/checker, six binary fixtures and catalog, Chromium spec, golden
|
||||
manifest, and this status entry. Restore M12-04I as the queue tail and move the machine queue back to
|
||||
`M12-04J`. No parity ledger rollback is required.
|
||||
49
docs/status/M12-05A.md
Normal file
49
docs/status/M12-05A.md
Normal file
@@ -0,0 +1,49 @@
|
||||
# M12-05A Status
|
||||
|
||||
status: done
|
||||
task: generate the Blender 5.2 runtime format inventory
|
||||
updated: 2026-08-18 America/New_York
|
||||
enablingTask: false
|
||||
parityStateChange: false
|
||||
|
||||
## Scope
|
||||
|
||||
The pinned `build_blender_5.2.0/bin/blender` runtime generated seven separate format records:
|
||||
GLTF, GLB, OBJ, STL, PLY, USD, and ALEMBIC. Each record binds import/export operator paths,
|
||||
registered state, RNA identifier, canonical property identifiers and enum items, file extensions,
|
||||
format variants, and the build option that gates the operator.
|
||||
|
||||
The runtime receipt also binds Blender 5.2.0 LTS version tuple, build hash/branch/platform/type/date,
|
||||
commit timestamp, selected build options, and the Blender binary SHA-256. On this pinned build,
|
||||
GLTF/GLB/OBJ/STL/PLY are `AVAILABLE`; USD and Alembic are explicitly `OPERATOR_UNREGISTERED` because
|
||||
`bpy.app.build_options.usd` and `alembic` are false. This is inventory evidence only and does not
|
||||
claim import/export round-trip parity.
|
||||
|
||||
## Evidence
|
||||
|
||||
- `node tools/web/check-io-format-runtime-inventory.mjs` passed; the generator was rerun in a fresh
|
||||
process and matched the committed JSON byte-for-byte.
|
||||
- Inventory has 7 formats, 5 available format families and 2 build-disabled families. All available
|
||||
operators have canonical non-empty RNA property lists; disabled operators fail closed.
|
||||
- Runtime receipt records binary SHA-256
|
||||
`d4483926610484ef9c2ad9241aae1469f934d955ebe791f1920e263e0ba85b82`.
|
||||
|
||||
## Artifact Hashes
|
||||
|
||||
- parent manifest: `989d417ab44e165849c7054f331f7038ec1d779349c39dd4f5b30050bbaecf56`
|
||||
- generator: `aa926397664240a5195f8864fc3ed5549bafcc963a03c513c7e37926b0559d7d`
|
||||
- checker: `12853306ea5eb2698ab636c7dfc2f27ae140295641473c57b84f93fa13d4864e`
|
||||
- inventory: `0d660b0fd8b647ebbf4e91afebd5006bd100973ab8e2507a5bfe759f477b33b4`
|
||||
- package commands: `cfb232baa494ff59f6c8d65514a08c86332ee9354350b2a0392b6f932a7ee42c`
|
||||
- manifest: `202b144c91f8e2c39477e257aeb26f9bd0b1b05b459ff8a246668024e94deec7`
|
||||
|
||||
## Next Task
|
||||
|
||||
`M12-05B`: declare import/export, local/server, geometry/material/animation support separately for
|
||||
each inventoried format.
|
||||
|
||||
## Rollback
|
||||
|
||||
Remove the runtime inventory generator/checker, format inventory, golden manifest, and this status
|
||||
entry. Restore M12-04J as the queue tail and move the machine queue back to `M12-05A`. No parity
|
||||
ledger rollback is required.
|
||||
48
docs/status/M12-05B.md
Normal file
48
docs/status/M12-05B.md
Normal file
@@ -0,0 +1,48 @@
|
||||
# M12-05B Status
|
||||
|
||||
status: done
|
||||
task: declare per-format import/export local/server and feature support
|
||||
updated: 2026-08-18 America/New_York
|
||||
enablingTask: false
|
||||
parityStateChange: false
|
||||
|
||||
## Scope
|
||||
|
||||
The schema-1 capability matrix binds all seven M12-05A runtime formats and the inventory SHA-256.
|
||||
Each format has separate IMPORT and EXPORT entries with local and server routes plus explicit
|
||||
geometry, material, and animation feature status. A runtime operator being registered does not
|
||||
make a Web route executable.
|
||||
|
||||
The only `READY` route is the existing bounded GLB EXPORT local path. All seven IMPORT routes and
|
||||
all server routes are explicit `BLOCKED/IO_FORMAT_UNSUPPORTED`; other local exports are also blocked.
|
||||
GLB export features are marked `PARTIAL` with the M12-06 round-trip dependency. Unimplemented
|
||||
operations stay `UNVERIFIED` rather than claiming geometry/material/animation support.
|
||||
|
||||
## Evidence
|
||||
|
||||
- `node --test web/tests/unit/io-format-capability-matrix.test.mjs` passed 3/3, including duplicate
|
||||
format, ready-without-executor, unverified-ready-feature, and missing blocked-code negatives.
|
||||
- `node tools/web/check-io-format-capability-matrix.mjs` passed; the matrix generator reproduced the
|
||||
committed JSON byte-for-byte and runtime statuses matched the M12-05A inventory.
|
||||
- The checker reports 7 formats, 1 local bounded GLB export route, and 27 blocked routes.
|
||||
|
||||
## Artifact Hashes
|
||||
|
||||
- parent manifest: `202b144c91f8e2c39477e257aeb26f9bd0b1b05b459ff8a246668024e94deec7`
|
||||
- protocol: `3063ae5e45f5b1642d329aa554187d121998d816a5a6740a2b9662f00c3c5738`
|
||||
- generator: `746078caaf29fa5aa2281b901b9ea5fc66f9a935eb3f6e282d4fbfb018d4c390`
|
||||
- checker: `4a8b35cd7f87238c13627a00c3bb0b34c130fc34d597773574efac7d8909b804`
|
||||
- unit: `0cc4d8f1df1ecdab20d8100cf5f12b44cb2a68bca4384ef7964a032b2f74b36e`
|
||||
- matrix: `139c9d764736da176b32414ecda840c07eb0ba5f3864da2dc08ce04bae161366`
|
||||
- package commands: `cfb232baa494ff59f6c8d65514a08c86332ee9354350b2a0392b6f932a7ee42c`
|
||||
- manifest: `8cc9517c9f25138c351bc5a79efe3b1ce6d9f6663d3b7c14397c5e4e8f11181a`
|
||||
|
||||
## Next Task
|
||||
|
||||
`M12-05C`: prevent matrix-undecared combinations from appearing in file selection and operator search.
|
||||
|
||||
## Rollback
|
||||
|
||||
Remove the capability matrix protocol/generator/checker, unit test, matrix, golden manifest, and this
|
||||
status entry. Restore M12-05A as the queue tail and move the machine queue back to `M12-05B`. No
|
||||
parity ledger rollback is required.
|
||||
52
docs/status/M12-05C.md
Normal file
52
docs/status/M12-05C.md
Normal file
@@ -0,0 +1,52 @@
|
||||
# M12-05C Status
|
||||
|
||||
status: done
|
||||
task: prevent matrix-undeclared combinations from appearing in file selection and operator search
|
||||
updated: 2026-08-18 America/New_York
|
||||
enablingTask: false
|
||||
parityStateChange: false
|
||||
|
||||
## Scope
|
||||
|
||||
The schema-1 UI registry is generated from the M12-05B capability matrix and is bound to its exact
|
||||
SHA-256. Only routes whose runtime operator is `AVAILABLE` and whose local matrix route is `READY`
|
||||
are exposed to the UI. The current registry therefore accepts `.blend` projects, exposes the existing
|
||||
bounded local GLB export command, and exposes no blocked import or export route.
|
||||
|
||||
The file input uses the registry-derived accept string and performs a second filename gate before
|
||||
opening. A matrix-blocked or unknown extension returns `IO_FORMAT_UNSUPPORTED` without invoking the
|
||||
engine or replacing the current scene. Operator search filters every format-tagged command through the
|
||||
same registry, so blocked server routes and undeclared formats cannot appear as executable results.
|
||||
|
||||
## Evidence
|
||||
|
||||
- Direct M12-05C lane passed: `node --test web/tests/unit/io-format-ui-gate.test.mjs`,
|
||||
`node tools/web/check-io-format-ui-gate.mjs`, and Chromium 1/1 on dynamic ports 5413/5417.
|
||||
- `node tools/web/check-io-format-ui-gate.mjs` reproduced the committed registry byte-for-byte;
|
||||
import routes=0, local export routes=1, project accept=`.blend,application/octet-stream`.
|
||||
- `npm --prefix web run typecheck` and `npm --prefix web run build` passed.
|
||||
- `WEB_TEST_PORT=5412 npm --prefix web run test:asset-library` passed 2/2 N-023 Chromium regressions.
|
||||
- An initial command without `WEB_TEST_PORT` was blocked by an already occupied 5173; rerunning on the
|
||||
isolated dynamic port passed and left no server/profile process in the test lane.
|
||||
|
||||
## Artifact Hashes
|
||||
|
||||
- parent manifest: `8cc9517c9f25138c351bc5a79efe3b1ce6d9f6663d3b7c14397c5e4e8f11181a`
|
||||
- protocol: `fc397ceb947d4ede6c34c1d51438253a6b59244fc40f5eb77ce155bf1c477476`
|
||||
- generator: `1ef4ae8a3e8d2f73101a87cba1c42ea99a065e1f6846f6a591841b97c0c39e6f`
|
||||
- checker: `81d6f27df26aab7b633fbe61c6d7b37519668aff41e43314924dceaacb3affde`
|
||||
- unit: `84ca8fb6022da9f167daa104c44489a6c7d9f059699e57ce621b8d7f64f19082`
|
||||
- Chromium: `eda2cdb9ede3bcbd717800c9c6fdb28d8cebef96f0296a2ee847a05e60cd0eed`
|
||||
- registry: `6b410bc6f2cad032af55bf13e1c8ddd841b01e9913ffc0ba381da8b7204285fd`
|
||||
- package commands: `cfb232baa494ff59f6c8d65514a08c86332ee9354350b2a0392b6f932a7ee42c`
|
||||
- manifest: `f46fd394e2144255d8b4304e8ce4fe60aad4302a80e991fd83d50cd915235ee3`
|
||||
|
||||
## Next Task
|
||||
|
||||
`M12-05D`: determine capability from runtime receipts and never infer it from filename extensions.
|
||||
|
||||
## Rollback
|
||||
|
||||
Remove the UI registry protocol, generator/checker, registry, unit/Chromium tests, package command,
|
||||
golden manifest, and this status entry. Restore M12-05B as the queue tail and move the machine queue
|
||||
back to `M12-05C`. No parity ledger rollback is required.
|
||||
54
docs/status/M12-05D.md
Normal file
54
docs/status/M12-05D.md
Normal file
@@ -0,0 +1,54 @@
|
||||
# M12-05D Status
|
||||
|
||||
status: done
|
||||
task: determine format capability from pinned Blender runtime receipts, never filename extensions
|
||||
updated: 2026-08-18 America/New_York
|
||||
enablingTask: false
|
||||
parityStateChange: false
|
||||
|
||||
## Scope
|
||||
|
||||
The schema-1 runtime receipt set is generated from the pinned Blender 5.2 M12-05A inventory and
|
||||
bound to that inventory's SHA-256. Each format/operation receipt preserves the operator path, RNA
|
||||
identifier, registered state, build option state, variants, and descriptive extensions. A route is
|
||||
`READY` only when the receipt says `AVAILABLE`, the operator is registered, an RNA identifier exists,
|
||||
and the build option is not disabled.
|
||||
|
||||
The route resolver takes an explicit format and operation from the receipt and never parses a file
|
||||
name or extension to grant capability. App filters format-tagged operator search entries and checks
|
||||
the GLB export route against this receipt set immediately before execution. The pinned runtime marks
|
||||
GLB export `READY`; USD/Alembic receipts are `OPERATOR_UNREGISTERED` and remain blocked.
|
||||
|
||||
## Evidence
|
||||
|
||||
- `node --test web/tests/unit/io-format-runtime-receipt.test.mjs` passed 3/3, covering receipt-bound
|
||||
GLB/USD routes, extension mutation without capability change, identity drift, and explicit status.
|
||||
- `node tools/web/check-io-format-runtime-receipts.mjs` passed; a fresh generator process reproduced
|
||||
14 receipts byte-for-byte from M12-05A inventory and verified operator/runtime identity fields.
|
||||
- `npm --prefix web run typecheck` and `npm --prefix web run build` passed; M12-05C Chromium UI
|
||||
regression passed 1/1 on port 5417 and N-023 asset/security regression passed 2/2 on port 5418.
|
||||
- The existing frozen package hash `cfb232baa494ff59f6c8d65514a08c86332ee9354350b2a0392b6f932a7ee42c`
|
||||
is preserved; dedicated commands remain direct to avoid invalidating prior release evidence.
|
||||
|
||||
## Artifact Hashes
|
||||
|
||||
- parent manifest: `f46fd394e2144255d8b4304e8ce4fe60aad4302a80e991fd83d50cd915235ee3`
|
||||
- protocol: `461a84557fa368c29dbc6707959b689faae7c8f7050dccc4d3f12e358b61bb22`
|
||||
- generator: `796cd641e86d8242c13317f771ae237cbf1692ff675a53bbdb689615edb5f372`
|
||||
- checker: `aaf9862041f155f96f50ea8481ff765089255bc59ecd8944f12362b81b8c1f1a`
|
||||
- unit: `a5f09277f5dcdacd25c44191f7407d6cee944f8022b1c467c2a69e172fc2ac6b`
|
||||
- runtime receipts: `f2c9a77e2cfad0ef3574b804fc06fb22972c07f55c72b0e6db2e359c4d95f57b`
|
||||
- App receipts: `f2c9a77e2cfad0ef3574b804fc06fb22972c07f55c72b0e6db2e359c4d95f57b`
|
||||
- App: `74216aac70992f8d879e983237ca324b998008582f0cd4658e90994cf9fae0a8`
|
||||
- package commands: `cfb232baa494ff59f6c8d65514a08c86332ee9354350b2a0392b6f932a7ee42c`
|
||||
- manifest: `3d0049a7b0331f01bb71df043270c18d1a5c9ce6dc74353c49c8ce591761df1b`
|
||||
|
||||
## Next Task
|
||||
|
||||
`M12-05E`: bind each runtime receipt to source, settings, and runtime hashes.
|
||||
|
||||
## Rollback
|
||||
|
||||
Remove the runtime receipt protocol, generator/checker, receipt set, App gate, unit test, golden
|
||||
manifest, and this status entry. Restore M12-05C as the queue tail and move the machine queue back to
|
||||
`M12-05D`. No parity ledger rollback is required.
|
||||
49
docs/status/M12-05E.md
Normal file
49
docs/status/M12-05E.md
Normal file
@@ -0,0 +1,49 @@
|
||||
# M12-05E Status
|
||||
|
||||
status: done
|
||||
task: bind every runtime receipt to source, settings, and runtime hashes
|
||||
updated: 2026-08-18 America/New_York
|
||||
enablingTask: false
|
||||
parityStateChange: false
|
||||
|
||||
## Scope
|
||||
|
||||
The schema-1 bound receipt set derives from M12-05A inventory and M12-05D runtime receipts. Every
|
||||
one of the 14 format/operation records carries three independent SHA-256 values: a source/operator
|
||||
identity hash, a settings/schema hash (including canonical variants/extensions and Blender RNA
|
||||
properties), and a runtime identity hash. The set also binds the parent M12-05D receipt-set hash and
|
||||
the M12-05A inventory hash.
|
||||
|
||||
The validator requires all three hashes and parent identities before a bound receipt can be resolved.
|
||||
The generator uses sorted-key canonical JSON and the checker independently recomputes every hash,
|
||||
then rebuilds the artifact in a fresh process for byte-for-byte determinism. No package metadata was
|
||||
changed, preserving the existing release evidence hash.
|
||||
|
||||
## Evidence
|
||||
|
||||
- `node --test web/tests/unit/io-format-receipt-binding.test.mjs` passed 2/2: valid three-hash
|
||||
resolution plus malformed source/settings/runtime and parent identity rejection.
|
||||
- `node tools/web/check-io-format-receipt-bindings.mjs` passed; all 14 source/settings/runtime hashes
|
||||
and parent/inventory identities matched a fresh deterministic regeneration.
|
||||
- `npm --prefix web run typecheck` passed; `git diff --check` passed.
|
||||
|
||||
## Artifact Hashes
|
||||
|
||||
- parent manifest: `3d0049a7b0331f01bb71df043270c18d1a5c9ce6dc74353c49c8ce591761df1b`
|
||||
- protocol: `681e719ab2b18eb85d056547fb70b461dd73b3a7fb4fdbe6295b8e49d5649e49`
|
||||
- generator: `eb7b5c499f141c1788bc37e53585662eedff3f2dabff870f4ad166f4a619796f`
|
||||
- checker: `ec2b22b468809ecc25ab2d4983065680a66ad3be6705d1827b44bf45ac622e26`
|
||||
- unit: `e9ae3e360ad41c32da3634a4efa915654853e79a35df36728c1ddf586a0bf7b5`
|
||||
- bound receipts: `7f765bf16b62466f579b3de00751a0e012fef1c788f229c8e9675a57caa18aad`
|
||||
- package commands: `cfb232baa494ff59f6c8d65514a08c86332ee9354350b2a0392b6f932a7ee42c`
|
||||
- manifest: `PENDING`
|
||||
|
||||
## Next Task
|
||||
|
||||
`M12-05F`: reject forged, stale, or cross-version runtime receipts before use.
|
||||
|
||||
## Rollback
|
||||
|
||||
Remove the binding protocol, generator/checker, bound receipt golden, unit test, manifest, and this
|
||||
status entry. Restore M12-05D as the queue tail and move the machine queue back to `M12-05E`. No
|
||||
parity ledger rollback is required.
|
||||
54
docs/status/M12-05F.md
Normal file
54
docs/status/M12-05F.md
Normal file
@@ -0,0 +1,54 @@
|
||||
# M12-05F Status
|
||||
|
||||
status: done
|
||||
task: reject forged, stale, or cross-version runtime receipts before use
|
||||
updated: 2026-08-18 America/New_York
|
||||
enablingTask: false
|
||||
parityStateChange: false
|
||||
|
||||
## Scope
|
||||
|
||||
The schema-1 freshness envelope is derived from the M12-05E bound receipt set. It carries the
|
||||
M12-05E byte identity, a canonical digest of the complete bound receipt set, and a canonical digest
|
||||
of the pinned Blender runtime identity. Before a route can be used, the parent binding hash,
|
||||
inventory hash, runtime identity, runtime hash, and receipt-set hash must all match the trusted
|
||||
expectation. The route resolver re-validates this gate on every use and only then returns `READY`.
|
||||
|
||||
Forged receipt content returns `RECEIPT_FORGED`; an older parent or inventory returns
|
||||
`RECEIPT_STALE`; a different Blender version/build identity returns `RECEIPT_CROSS_VERSION`.
|
||||
Malformed or unavailable routes remain fail-closed as `IO_FORMAT_UNSUPPORTED`. The App GLB export and
|
||||
format-tagged operator search now consume the freshness envelope rather than the unbound M12-05D set.
|
||||
|
||||
## Evidence
|
||||
|
||||
- `node --test web/tests/unit/io-format-receipt-freshness.test.mjs` passed 4/4: exact trusted route,
|
||||
canonical digest verification, forged content, stale parent, and cross-version negatives.
|
||||
- `node tools/web/check-io-format-receipt-freshness.mjs` passed; 14 receipts, App artifact parity,
|
||||
independent canonical digest verification, deterministic regeneration, and all three negative
|
||||
classes passed.
|
||||
- Existing M12-05D/M12-05E unit and checker commands passed unchanged.
|
||||
- `npm --prefix web run typecheck` and `npm --prefix web run build` passed; `git diff --check` passed.
|
||||
|
||||
## Artifact Hashes
|
||||
|
||||
- parent manifest: `2fbaaf39c6acd9f55fbdbadccc0b027e9e7763bf069c954a96ca49b193648990`
|
||||
- protocol: `111a630c7beccd31989dc4f78932b7d7b741fb6bef03e45cb39a8139f774d235`
|
||||
- generator: `6a1e798ce46e1d14d833091d4d7ae452dccb13efe583594277785465eb725bbf`
|
||||
- checker: `7a8fe69ea1aa2c1e121be008a9fb60fc236f7ef776d2088a7b00b14f46fe3fba`
|
||||
- unit: `cd1c2adca81653f98f9a1c6c7d104ad0e3052283213fb7166dac827c956928fe`
|
||||
- freshness receipts: `0187ad0d9ea05fc4b152b7abd4945191dbe9ec24dfde4ca7dbe4aadfd1230efe`
|
||||
- App freshness receipts: `0187ad0d9ea05fc4b152b7abd4945191dbe9ec24dfde4ca7dbe4aadfd1230efe`
|
||||
- App expected identity: `8d65f78aa774ff252871cb1cc09e69b4ff04fbb45e61200eaf67534c9d2651b2`
|
||||
- App: `043ff3a2f39ef3a1303791081b80851b427e7db5dfd9af2161926dd6f1ea9ca4`
|
||||
- package commands: `cfb232baa494ff59f6c8d65514a08c86332ee9354350b2a0392b6f932a7ee42c`
|
||||
- manifest: `63e1506801ddee2f1eaf64cad68a9d5c918405f642ca237c6a1ec249ff297623`
|
||||
|
||||
## Next Task
|
||||
|
||||
`M12-06A`: desktop generate the bounded Mesh/PBR/UV/skin/animation GLB fixture group.
|
||||
|
||||
## Rollback
|
||||
|
||||
Remove the freshness protocol, generator/checker, freshness artifacts, unit test, App imports/route
|
||||
gate, manifest, and this status entry. Restore M12-05E as the queue tail and move the machine queue
|
||||
back to `M12-05F`. No parity ledger rollback is required.
|
||||
59
docs/status/M12-06A.md
Normal file
59
docs/status/M12-06A.md
Normal file
@@ -0,0 +1,59 @@
|
||||
# M12-06A Status
|
||||
|
||||
status: done
|
||||
task: generate the bounded Mesh/PBR/UV/skin/animation GLB fixture group on desktop
|
||||
updated: 2026-08-18 America/New_York
|
||||
enablingTask: true
|
||||
parityStateChange: false
|
||||
|
||||
## Scope
|
||||
|
||||
The pinned Blender 5.2.0 LTS desktop runtime generates five independent GLB 2.0 fixtures: mesh,
|
||||
PBR, UV texture, two-joint skin, and object animation. Each file has one bounded triangle primitive,
|
||||
uses no required or optional glTF extension, and remains below the 512 KiB per-file budget. The
|
||||
fixtures isolate feature ownership so later Web import comparisons cannot hide one unsupported
|
||||
domain behind an all-in-one scene.
|
||||
|
||||
The canonical report records runtime identity, file bytes and SHA-256, nodes, topology accessors,
|
||||
attributes, materials, textures/images, skins, and animations. The checker binds the M12-05F parent
|
||||
manifest and the pinned M12-05A Blender binary identity, regenerates all five files in a fresh
|
||||
temporary directory, and requires both the semantic report and every GLB byte to match exactly.
|
||||
This enabling task does not claim Web import, `.blend` save/reopen, export loss reporting, or GLB
|
||||
round-trip parity.
|
||||
|
||||
## Evidence
|
||||
|
||||
- `node tools/web/check-glb-desktop-fixtures.mjs` passed: 5 fixtures, 8,676 aggregate bytes,
|
||||
Mesh/PBR/UV/skin/animation assertions, exact report regeneration, and exact GLB regeneration.
|
||||
- Mesh exports indexed triangles with POSITION/NORMAL/COLOR_0; UV exports TEXCOORD_0 plus one
|
||||
embedded PNG; skin exports JOINTS_0/WEIGHTS_0 and two inverse-bind matrices; animation exports
|
||||
translation and rotation channels sampled over 25 frames.
|
||||
- The runtime binary SHA-256 is
|
||||
`d4483926610484ef9c2ad9241aae1469f934d955ebe791f1920e263e0ba85b82`, matching M12-05A.
|
||||
- `npm --prefix web run typecheck`, `npm --prefix web run test:status-consistency`, and
|
||||
`git diff --check` passed. The package hash remains the frozen
|
||||
`cfb232baa494ff59f6c8d65514a08c86332ee9354350b2a0392b6f932a7ee42c`.
|
||||
|
||||
## Artifact Hashes
|
||||
|
||||
- parent manifest: `63e1506801ddee2f1eaf64cad68a9d5c918405f642ca237c6a1ec249ff297623`
|
||||
- generator: `0247dd2405a68b42d99c2b005546ad2aa99b46416e3fe9489832467f6ea4eb4d`
|
||||
- checker: `211ebdb66bf2e2d349455d5303e889a4a1ae3323639a89dd78b3bda574dd820b`
|
||||
- desktop report: `dea31cc861622166dc502b333bc177b70b66b54d9c62aaccc6522745dab5ae13`
|
||||
- mesh GLB: `e52b9268b6524744fb498691f976000635e544ba3b47e9f8ff22b03bcdf17a94`
|
||||
- PBR GLB: `244cc8a992c5a70692b8bbc8333533718b3bac7022110715ce3b23d2e4c0b361`
|
||||
- UV GLB: `1e0397d2b69d8261b3252451b50ab4aba6525b94713719f35069a9a9d96fcfa2`
|
||||
- skin GLB: `4086ee4c8873aa03090338b676575b7a5335fb7c9384fec6ccb36108e71929f6`
|
||||
- animation GLB: `44f6cc47961a146dc97ea337ae31a8b64bb4ab213b716f81ec22129db704f1fb`
|
||||
- manifest: `e3554a1e739cbe3f217f6169130532365538b0c0eafbb97afc58d4d56c4287cb`
|
||||
|
||||
## Next Task
|
||||
|
||||
`M12-06B`: import the desktop GLB fixture group on Web and compare topology, attributes, materials,
|
||||
nodes, and animations.
|
||||
|
||||
## Rollback
|
||||
|
||||
Remove the desktop fixture generator/checker, five GLB files, report, manifest, and this status
|
||||
entry. Restore M12-05F as the queue tail and move the machine queue back to `M12-06A`. No parity
|
||||
ledger rollback is required.
|
||||
57
docs/status/M12-06B.md
Normal file
57
docs/status/M12-06B.md
Normal file
@@ -0,0 +1,57 @@
|
||||
# M12-06B Status
|
||||
|
||||
status: done
|
||||
task: compare desktop GLB topology, attributes, materials, nodes, and animations in Web
|
||||
updated: 2026-08-18 America/New_York
|
||||
enablingTask: true
|
||||
parityStateChange: false
|
||||
|
||||
## Scope
|
||||
|
||||
The production TypeScript GLB parser now exposes a canonical bounded semantic surface for the five
|
||||
M12-06A desktop fixtures. It validates referenced accessors, nodes, materials, textures, skins, and
|
||||
animation samplers before returning primitive topology, sorted attributes, PBR material fields,
|
||||
node hierarchy/TRS, skin bindings, and animation channels. A field-level comparator checks that Web
|
||||
semantics exactly match the pinned Blender 5.2 desktop report.
|
||||
|
||||
Both Node and a real Chromium Worker consume the exact committed GLB bytes and verify each source
|
||||
SHA-256 before comparing all five domains. The existing summary import API remains compatible. This
|
||||
task does not create Blender Main data or expose GLB in the file picker; the runtime route remains
|
||||
`BLOCKED_UNTIL_MAIN_PERSISTENCE` until M12-06C proves save/reopen and stable IDs.
|
||||
|
||||
## Evidence
|
||||
|
||||
- `node --test web/tests/unit/glb-desktop-import.test.mjs` passed 3/3: five exact fixture imports,
|
||||
separate domain assertions, and a stable field-level PBR mismatch.
|
||||
- `node tools/web/check-glb-desktop-import.mjs` passed: 5 fixtures, 5 compared domains, exact
|
||||
desktop/Web canonical hashes, deterministic report regeneration, and the blocked route state.
|
||||
- `CHROME_PATH=/usr/bin/google-chrome-stable WEB_TEST_PORT=5425 node_modules/.bin/playwright test
|
||||
--config playwright.config.ts --workers=1 tests/e2e/glb-desktop-import.spec.ts` passed 1/1 from
|
||||
the `web/` directory using Chrome 150. The Worker verified source SHA-256 and all five semantic
|
||||
comparisons.
|
||||
- `npm --prefix web run typecheck`, `npm --prefix web run test:status-consistency`, and
|
||||
`git diff --check` passed. The package hash remains
|
||||
`cfb232baa494ff59f6c8d65514a08c86332ee9354350b2a0392b6f932a7ee42c`.
|
||||
|
||||
## Artifact Hashes
|
||||
|
||||
- parent manifest: `e3554a1e739cbe3f217f6169130532365538b0c0eafbb97afc58d4d56c4287cb`
|
||||
- protocol: `45d9a7912c4a59a552789a8ea0dfaff5f1849f8d213f14d238de024b77acdb0d`
|
||||
- generator: `6f97527b7da04c7b4f9b09c48b9f367d1270db9f7820498d33832a80754436c2`
|
||||
- checker: `804a4b5545d95d7ab1ba265469a981d0a10b71dab36f0c96283eb73b401443d2`
|
||||
- unit: `6bf2a96b3e43e5fae93589ea5dcf98e7a69b10266378e442988198925286a8d8`
|
||||
- Chromium Worker: `eb32049631113270fb62acb7ae9379e8ff9a03e38086db2fa309c6891cd707bf`
|
||||
- Chromium test: `fa3e06419c918406f24b5a4260523bd94cfe729a84786e9434517fdfed624d45`
|
||||
- Web import report: `79933888cc5aa2d1e3639ec349ca4c31d028fe89f751ebb8d4342f06d15ecfc2`
|
||||
- manifest: `5275310394b34726a05b30ab67658e1381662dddf9163a97cb02f47f646a8fa4`
|
||||
|
||||
## Next Task
|
||||
|
||||
`M12-06C`: create authoritative Main data from the imported GLB, save `.blend`, reopen it, and
|
||||
compare stable IDs.
|
||||
|
||||
## Rollback
|
||||
|
||||
Remove the canonical Web import surface, report generator/checker, Node/Chromium tests, report,
|
||||
manifest, and this status entry. Restore M12-06A as the queue tail and move the machine queue back to
|
||||
`M12-06B`. No parity ledger rollback is required.
|
||||
59
docs/status/M12-06C.md
Normal file
59
docs/status/M12-06C.md
Normal file
@@ -0,0 +1,59 @@
|
||||
# M12-06C Status
|
||||
|
||||
status: done
|
||||
task: import desktop GLB results into authoritative Main, save `.blend`, reopen, and compare stable IDs
|
||||
updated: 2026-08-18 America/New_York
|
||||
enablingTask: false
|
||||
parityStateChange: false
|
||||
|
||||
## Scope
|
||||
|
||||
The pinned Blender 5.2 desktop runtime imports each M12-06A GLB fixture and saves a `.blend`; the
|
||||
generator reopens every saved file and requires the complete stable Object/Mesh/Material/Image/
|
||||
Armature/Action ID set to remain unchanged. Chromium then opens those authoritative Main fixtures
|
||||
through the production WebEngine, applies one Main-owned visibility edit, saves the resulting
|
||||
`.blend`, reopens it in a fresh isolated open transaction, and compares the stable IDs with the
|
||||
desktop baseline. The saved edit is checked after reopen and the open resource counters are zero for
|
||||
input, staging, and active requests.
|
||||
|
||||
This task does not expose GLB in the normal `.blend` file picker, claim arbitrary glTF extensions,
|
||||
or change the N-023 full-parity ledger. M12-06B remains the bounded Web GLB semantic parser and
|
||||
M12-06D owns export loss reporting.
|
||||
|
||||
## Evidence
|
||||
|
||||
- `node tools/web/check-glb-main-persistence.mjs` passed the parent manifest, all artifact hashes,
|
||||
five desktop GLB/Main fixture bindings, stable-ID shape checks, and a fresh Blender regeneration
|
||||
with exact semantic report/stable-ID comparison.
|
||||
- `CHROME_PATH=/usr/bin/google-chrome-stable WEB_TEST_PORT=5437 node_modules/.bin/playwright test
|
||||
--config playwright.config.ts --workers=1 tests/e2e/glb-main-persistence.spec.ts` passed 1/1.
|
||||
Every fixture opened in the production WebEngine, performed one authoritative visibility edit,
|
||||
serialized a changed `.blend`, reopened it, preserved all stable IDs, restored visibility=false,
|
||||
and returned zero active requests/input/staging resources.
|
||||
- `npm --prefix web run typecheck` and `git diff --check` passed. The existing package manifest was
|
||||
left unchanged so prior M12 evidence remains bound to its frozen package hash.
|
||||
|
||||
## Artifact Hashes
|
||||
|
||||
- parent manifest: `5275310394b34726a05b30ab67658e1381662dddf9163a97cb02f47f646a8fa4`
|
||||
- generator: `8989d6ce4196f140a7bfb44b863dc530a6aa462ca4a57fa7b77c468e06ab61ad`
|
||||
- checker: `5bbbbeaf2d20ff9bbdeb74c8dd10fa6ffc421d1d59f86540e95f29c2cfd10903`
|
||||
- desktop report: `76b000454a9073ef762d25fa546d5c65a004659a93eb6ec82fad1e679b2e81be`
|
||||
- Chromium test: `7c97877f1cbbfd0166e106c80faee53f474f78816cca68ea924df5aa3c47776d`
|
||||
- package: `cfb232baa494ff59f6c8d65514a08c86332ee9354350b2a0392b6f932a7ee42c`
|
||||
- mesh `.blend`: `66e29adc016f07e220019b6f24eb7e5016c684dca4b3102b20c8e836968d422d`
|
||||
- PBR `.blend`: `ba08aeb2876d82ddf731abe81d3a42041a1be36617d0b6324c870d5bcd4cc771`
|
||||
- UV `.blend`: `1270cb452d34d2fd7a19181a2b20f70b7a028bdd2db7cf1bba4e1003f7de0f48`
|
||||
- skin `.blend`: `23f175e44ec588c75db99d3f9134863fc3d7d1f192bbd815d5d1c4e3218bce0c`
|
||||
- animation `.blend`: `fa6baf3a67ff11fe3d2922210089a7c508e4ee28bfaabe4cf628ba6addee1ff5`
|
||||
- manifest: `e3a57636a47591e3b02dff5a07e8a0aec5e0dc43bf6b4829bffc811035dbbb31`
|
||||
|
||||
## Next Task
|
||||
|
||||
`M12-06D`: Web export generates a machine loss report.
|
||||
|
||||
## Rollback
|
||||
|
||||
Remove the M12-06C generator/checker, manifest, desktop Main fixtures, report, Chromium test, and
|
||||
this status entry. Restore M12-06B as the queue tail and move the machine queue back to M12-06C. No
|
||||
parity ledger rollback is required.
|
||||
56
docs/status/M12-06D.md
Normal file
56
docs/status/M12-06D.md
Normal file
@@ -0,0 +1,56 @@
|
||||
# M12-06D Status
|
||||
|
||||
status: done
|
||||
task: Web GLB export generates a machine-readable loss report
|
||||
updated: 2026-08-18 America/New_York
|
||||
enablingTask: false
|
||||
parityStateChange: false
|
||||
|
||||
## Scope
|
||||
|
||||
The production GLB exporter now has a schema-1 deterministic loss-report wrapper. It records the
|
||||
source SceneIR identity/revision, exportability, error/warning counts, sorted loss entries and the
|
||||
bounded data-block surface. Chromium opens all five M12-06C authoritative Main fixtures and sends
|
||||
their real snapshot/geometry/packed assets through the production exporter Worker. Exportable
|
||||
PBR/UV/skin/animation outputs are byte-hashed; the mesh fixture's unsupported Color Attribute
|
||||
shader is reported as `SHADER_GRAPH_UNMAPPABLE` and no GLB bytes are emitted.
|
||||
|
||||
This task reports the bounded exporter surface only. It does not claim lossless GLB round-trip,
|
||||
desktop re-import, arbitrary shader mapping, or GLB file-picker import; those remain later M12-06E/G
|
||||
tasks or explicit blockers.
|
||||
|
||||
## Evidence
|
||||
|
||||
- `node --test web/tests/unit/glb-loss-report.test.mjs` passed deterministic sorting/count semantics.
|
||||
- `node tools/web/check-glb-loss-report.mjs` passed artifact hashes, parent Main fixture binding,
|
||||
deterministic loss ordering, mesh fail-closed output, and four exportable fixture output hashes.
|
||||
It reports `fixtures=5 blocked=mesh warnings=3`.
|
||||
- `CHROME_PATH=/usr/bin/google-chrome-stable WEB_TEST_PORT=5445 node_modules/.bin/playwright test
|
||||
--config playwright.config.ts --workers=1 tests/e2e/glb-export-loss-report.spec.ts` passed 1/1.
|
||||
The test uses `WebEngineClient` and a production module Worker, requests packed image assets,
|
||||
produces the report, and compares it byte-for-byte with the checked-in golden report.
|
||||
- `npm --prefix web run typecheck` and `git diff --check` passed. `web/package.json` remains
|
||||
unchanged so previous M12 package bindings stay valid.
|
||||
|
||||
## Artifact Hashes
|
||||
|
||||
- parent manifest: `e3a57636a47591e3b02dff5a07e8a0aec5e0dc43bf6b4829bffc811035dbbb31`
|
||||
- export protocol: `a5d342827860a9e55b49a3bb3a196a01b1e53546325d6e594778afb9360c3125`
|
||||
- loss report protocol: `dce9c790b2f52d46efe0908ecb044d63d21b3c6c3f7d77ddb5e697b29a7a2d6e`
|
||||
- Worker: `6f6294d26fe7b717416a5dd25fe834fb4b9a2ecbe8b011395c9559a26701ec77`
|
||||
- Chromium test: `ce334b6bb5d82c133d317e916c03711029fba1c19c634dec06c06da9eddbd776`
|
||||
- checker: `a23346860fa26405b2cd24591b0ab36fea29cb561ec8c2991ecfeabcffc17ee1`
|
||||
- unit: `dfcc2d968e4e0c0cef4496bc304cb481f10d1f0dc4c76a40ea1d6e2f11b6b708`
|
||||
- web loss report: `c6db52234d867985ef5fbcdc7c62298ec9aaa013028b5a54e2b9a16aa4133397`
|
||||
- package: `cfb232baa494ff59f6c8d65514a08c86332ee9354350b2a0392b6f932a7ee42c`
|
||||
- manifest: `c01c5861d493e1f177e8cde3038bc5283a7671fa39bf84484662d307623325a2`
|
||||
|
||||
## Next Task
|
||||
|
||||
`M12-06E`: desktop Blender re-imports Web GLB and compares the canonical report.
|
||||
|
||||
## Rollback
|
||||
|
||||
Remove the loss-report protocol/Worker, checker, manifest, golden report, Chromium test, and this
|
||||
status entry. Restore M12-06C as the queue tail and move the machine queue back to M12-06D. No parity
|
||||
ledger rollback is required.
|
||||
55
docs/status/M12-06E.md
Normal file
55
docs/status/M12-06E.md
Normal file
@@ -0,0 +1,55 @@
|
||||
# M12-06E Status
|
||||
|
||||
status: done
|
||||
task: desktop Blender re-imports Web GLB and compares canonical report
|
||||
updated: 2026-08-18 America/New_York
|
||||
enablingTask: false
|
||||
parityStateChange: false
|
||||
|
||||
## Scope
|
||||
|
||||
The four Web GLBs that produced bytes in M12-06D (PBR, UV, skin and animation) are re-imported by
|
||||
the pinned Blender 5.2 desktop runtime, saved as `.blend`, reopened, and emitted as canonical graph
|
||||
reports. The checker binds each Web output hash to the M12-06D report and compares Object/Mesh/
|
||||
Material/Image/Armature/Action graph fields against the M12-06C desktop-import baseline.
|
||||
|
||||
PBR and animation are exact. UV records four explicit differences (corner-expanded vertex topology
|
||||
and Blender's generated texture Mix node); skin records 31 explicit differences (the exporter emits
|
||||
an additional armature helper mesh and Blender's re-import tessellation changes). These are recorded
|
||||
machine mismatches, not silently treated as parity. The N-023 parity ledger remains blocked and this
|
||||
task does not claim lossless GLB round-trip.
|
||||
|
||||
## Evidence
|
||||
|
||||
- `node tools/web/check-glb-web-reimport.mjs` passed artifact hashes, four Web GLB source bindings,
|
||||
pinned Blender regeneration determinism, save/reopen stability, and canonical comparison. Output:
|
||||
`glb-web-reimport-ok fixtures=4 exact=2 mismatched=uv,skin deterministic=true next=M12-06F`.
|
||||
- The report binds Web GLB hashes `pbr=1ab793...`, `uv=8bd045...`, `skin=4a45d0...` and
|
||||
`animation=b83de1...`; exact/mismatch counts are fixed at PBR 0, UV 4, skin 31, animation 0.
|
||||
- The Web export Chromium test that produced the inputs passed 1/1; the desktop generator performs
|
||||
a fresh Blender import/save/reopen for every input. `npm --prefix web run typecheck` and
|
||||
`git diff --check` passed.
|
||||
|
||||
## Artifact Hashes
|
||||
|
||||
- parent manifest: `c01c5861d493e1f177e8cde3038bc5283a7671fa39bf84484662d307623325a2`
|
||||
- generator: `3ae1ba45e15cae5d0308fc3fcb3766764cd374c096e27eaaddba9228a3d75004`
|
||||
- checker: `c21b45a975ec70586da1b9e50b8cf4ccf74644300b4f381c3fee0ad735cfcdb9`
|
||||
- desktop report: `e4d03d25cfac3c4beff4d0af0769b1c39b058670c679c12f4a11ae30d2d91f3c`
|
||||
- Web export test: `ce334b6bb5d82c133d317e916c03711029fba1c19c634dec06c06da9eddbd776`
|
||||
- PBR Web GLB: `1ab7936fae6e0c28e1b90e8a6ae24b3893c075c9fc58ac8896f780fdefb8277e`
|
||||
- UV Web GLB: `8bd045388527ddad7cf886c0c7a2a45b6e7d6db603568a10a959bc6d423ae145`
|
||||
- skin Web GLB: `4a45d00dfa23638682bb61a4f74b283bcd986126da4890d068902e3c85efc332`
|
||||
- animation Web GLB: `b83de103df3f5a49487868f3ede3046875c90b0d084bbd998511c3a7c987a4fa`
|
||||
- package: `cfb232baa494ff59f6c8d65514a08c86332ee9354350b2a0392b6f932a7ee42c`
|
||||
- manifest: `3d3b13fd54a314fd6f6907fc2d314e66ef74e8ca770a8accd823370d272737fc`
|
||||
|
||||
## Next Task
|
||||
|
||||
`M12-06F`: sparse accessor, Draco/extension, external URI and over-budget negative cases.
|
||||
|
||||
## Rollback
|
||||
|
||||
Remove the desktop Web re-import generator/checker, manifest, report, four Web GLB fixtures, and
|
||||
this status entry. Restore M12-06D as the queue tail and move the machine queue back to M12-06E. No
|
||||
parity ledger rollback is required.
|
||||
49
docs/status/M12-06F.md
Normal file
49
docs/status/M12-06F.md
Normal file
@@ -0,0 +1,49 @@
|
||||
# M12-06F Status
|
||||
|
||||
status: done
|
||||
task: GLB sparse accessor, extension, external URI and over-budget negative cases
|
||||
updated: 2026-08-18 America/New_York
|
||||
enablingTask: false
|
||||
parityStateChange: false
|
||||
|
||||
## Scope
|
||||
|
||||
The bounded GLB importer now enforces a 512 KiB input budget, JSON/table budgets, rejects sparse
|
||||
accessors, rejects all extensions outside the pinned allowlist (currently empty), and blocks external
|
||||
buffer/image URIs. Errors are stable and fail before semantic/Main publication:
|
||||
`GLB_SPARSE_ACCESSOR_UNSUPPORTED`, `GLB_EXTENSION_UNSUPPORTED`, `GLB_EXTERNAL_URI_BLOCKED`, and
|
||||
`GLB_IMPORT_BUDGET_EXCEEDED`.
|
||||
|
||||
## Evidence
|
||||
|
||||
- `node --test web/tests/unit/glb-negative-cases.test.mjs` passed 2/2 for sparse, extension, external
|
||||
URI, byte-budget and table-count cases.
|
||||
- `CHROME_PATH=/usr/bin/google-chrome-stable WEB_TEST_PORT=5450 node_modules/.bin/playwright test
|
||||
--config playwright.config.ts --workers=1 tests/e2e/glb-negative-cases.spec.ts` passed 1/1 in a
|
||||
production Chromium Worker with all four stable codes.
|
||||
- `node tools/web/check-glb-negative-cases.mjs` passed the schema-1 negative report and artifact
|
||||
hashes: `glb-negative-cases-ok cases=4 budget=524288 deterministic=true next=M12-06G`.
|
||||
- `npm --prefix web run typecheck` and `git diff --check` passed. The package manifest remains
|
||||
unchanged.
|
||||
|
||||
## Artifact Hashes
|
||||
|
||||
- parent manifest: `3d3b13fd54a314fd6f6907fc2d314e66ef74e8ca770a8accd823370d272737fc`
|
||||
- protocol: `0b6329c08e6f3cd9af6f27ef7c463b037a7cab94192afb4538d3d6c4cfcbc147`
|
||||
- unit: `9af1c155143a0c685a62f569f705afd9fcc3bb49e0d724ebf3ad2c6356d63d6d`
|
||||
- Worker: `d84a6b884ce1bfedd598b2602d803493bf10f6ad62fdfac49d64fca3f30f3931`
|
||||
- Chromium test: `c6694689ce04ff2faea2c20be648f438a9f7eb25cdfd2f714b94c1f556ea1510`
|
||||
- checker: `08377c306fd7d1082f7fd734e37809960c9798d29d626681fe9ad3f94cb7a29e`
|
||||
- negative report: `7367a624b562a9613b4b908c894ab04c731ae0a348a3b58689075f4a9decd90c`
|
||||
- package: `cfb232baa494ff59f6c8d65514a08c86332ee9354350b2a0392b6f932a7ee42c`
|
||||
- manifest: `27b42da0683dab11a884553440088c30cf58d51364268fdaac86668786aaedd4`
|
||||
|
||||
## Next Task
|
||||
|
||||
`M12-06G`: import/export cancellation, Worker restart and OPFS quota recovery.
|
||||
|
||||
## Rollback
|
||||
|
||||
Remove the GLB negative-case budget/protocol changes, Worker, tests, checker, report, manifest, and
|
||||
this status entry. Restore M12-06E as the queue tail and move the machine queue back to M12-06F. No
|
||||
parity ledger rollback is required.
|
||||
57
docs/status/M12-06G.md
Normal file
57
docs/status/M12-06G.md
Normal file
@@ -0,0 +1,57 @@
|
||||
# M12-06G Status
|
||||
|
||||
status: done
|
||||
task: GLB import/export cancellation, Worker restart, and OPFS quota recovery
|
||||
updated: 2026-08-18 America/New_York
|
||||
enablingTask: false
|
||||
parityStateChange: false
|
||||
|
||||
## Scope
|
||||
|
||||
Schema-1 GLB recovery receipts now bind operation, worker generation, source/output SHA-256,
|
||||
revision, temporary bytes, live requests, commit state, and stable cancellation/restart/quota codes.
|
||||
Both import and export cancellation release all temporary bytes and publish no result. A new Worker
|
||||
repeats the same bounded GLB import with an identical semantic result hash.
|
||||
|
||||
The GLB asset persistence path uses the existing content-addressed OPFS store. A real Chromium
|
||||
origin quota of 64 KiB rejects a 128 KiB candidate, while the previously committed GLB remains
|
||||
readable after Storage Worker restart. Raising the quota allows a small follow-up asset to commit.
|
||||
|
||||
## Evidence
|
||||
|
||||
- `node --test web/tests/unit/glb-recovery.test.mjs` passed 2/2 for cancel, quota, commit, and
|
||||
generation transition invariants.
|
||||
- `CHROME_PATH=/usr/bin/google-chrome-stable WEB_TEST_PORT=5455 node_modules/.bin/playwright test
|
||||
--config playwright.config.ts --workers=1 tests/e2e/glb-recovery.spec.ts` passed 2/2 in Chrome
|
||||
150. The first real-quota run reached the expected browser failure but the assertion only accepted
|
||||
the injected error wording; the final run accepts both native and injected quota messages.
|
||||
- `node tools/web/check-glb-recovery.mjs` passed with
|
||||
`glb-recovery-ok cancelled=2 workerGeneration=2 quota=GLB_OPFS_QUOTA smallRecovery=true next=M12-07A`.
|
||||
- `npm --prefix web run typecheck`, `node --check tools/web/check-glb-recovery.mjs`, and
|
||||
`git diff --check` passed. The package manifest remains unchanged.
|
||||
|
||||
## Artifact Hashes
|
||||
|
||||
- parent manifest: `27b42da0683dab11a884553440088c30cf58d51364268fdaac86668786aaedd4`
|
||||
- recovery protocol: `da4e2a546d7598e80798cfebd105e52b7522c896acb545710c78bb8a5c3705aa`
|
||||
- storage protocol/client/Worker: `2c8ce9e32fcae973e9262a024fd849221680104bcd427ec308f99ef25112d951` /
|
||||
`00cd35e4632479e4cd153314113e201c822fd209ae6c8e9fbeff5f1399728565` /
|
||||
`80bf4d2ac59cbf7998c2a72c8961ae38abe43685b60df564d0746e1a45e9e1bc`
|
||||
- operation Worker/browser adapter: `947c4a768422725ff2f689b2eefa8068bee51bb7ff342af17e8d4a4d0a4a7ca2` /
|
||||
`2c753a04c153471c2bf7691073b836d968a1a1300e3da038f493983b46738cdf`
|
||||
- unit/Chromium: `6dd48f62a85c5aaf3a04b6e572a47a7986b23cbec84a099ea510af81e8dd3a3a` /
|
||||
`7d95e992f44fb913f70c104f0d6b23bd76f47d48db4a21899e35ae1d188e2093`
|
||||
- checker/report: `b185248fdcd6b3cee84252bd68fcb6921bb6385bfa4a00486e93c58e94755cce` /
|
||||
`1a008a76590573468446ca6e5cbdfe0ea5a8b27493291590d937b90db90d6e42`
|
||||
- package: `cfb232baa494ff59f6c8d65514a08c86332ee9354350b2a0392b6f932a7ee42c`
|
||||
- manifest: `1c732b8d9f1a0bdb502f44e2e843e91efea12e93483a35658f8a9c70a69a2430`
|
||||
|
||||
## Next Task
|
||||
|
||||
`M12-07A`: OBJ single-Mesh positive fixture covering position, normal, UV, and material group.
|
||||
|
||||
## Rollback
|
||||
|
||||
Remove the GLB recovery receipt, quota fault option, Worker/browser adapter, tests, checker, report,
|
||||
manifest, and this status entry. Restore M12-06F as the queue tail and move the machine queue back to
|
||||
M12-06G. No parity ledger rollback is required.
|
||||
49
docs/status/M12-07A.md
Normal file
49
docs/status/M12-07A.md
Normal file
@@ -0,0 +1,49 @@
|
||||
# M12-07A Status
|
||||
|
||||
status: done
|
||||
task: OBJ single-Mesh desktop positive fixture
|
||||
updated: 2026-08-18 America/New_York
|
||||
enablingTask: true
|
||||
parityStateChange: false
|
||||
|
||||
## Scope
|
||||
|
||||
Pinned Blender 5.2 `WM_OT_obj_export` now generates one deterministic Wavefront OBJ object with
|
||||
four positions, four UV coordinates, one explicit normal, two triangle faces, two material records,
|
||||
and two material groups. The `.mtl` sidecar is kept beside the OBJ and both files are bound to the
|
||||
canonical semantic report. Web parsing/import, multi-object and negative cases remain queued.
|
||||
|
||||
## Evidence
|
||||
|
||||
- `build_blender_5.2.0/bin/blender -b --factory-startup --python
|
||||
tools/web/generate-obj-single-mesh-fixture.py -- tests/files/web/m12_obj_desktop_v1
|
||||
tests/golden/M12-07A/desktop-fixture.json` completed with 4 positions, 4 UVs, 1 normal,
|
||||
2 faces, and 2 materials/groups.
|
||||
- `node tools/web/check-obj-single-mesh-fixture.mjs` passed deterministic regeneration in a fresh
|
||||
temporary directory and byte-for-byte OBJ/MTL comparison:
|
||||
`obj-single-mesh-fixture-ok vertices=4 normals=1 uv=4 faces=2 materials=2 deterministic=true next=M12-07B`.
|
||||
- Runtime identity matches the pinned M12-05A Blender 5.2 inventory; the report is anchored to
|
||||
`blender-5.2.0/source/blender/io/wavefront_obj` and `wm.obj_export`.
|
||||
- Package hash remains frozen; no Web route or parity ledger status was changed.
|
||||
|
||||
## Artifact Hashes
|
||||
|
||||
- parent manifest: `1c732b8d9f1a0bdb502f44e2e843e91efea12e93483a35658f8a9c70a69a2430`
|
||||
- generator: `604c3006f194c7c64a487b8f760693b66830f3cfa602928b46769955e7d4f358`
|
||||
- checker: `3d0208f61a86d4d29796d8284756f53931c90864b15b7dfe4fcc84d7f65a8040`
|
||||
- desktop report: `6c560a8eecf84973c2b05f9fd50d33bd45515e97c4f7970f1502de406c39f6a5`
|
||||
- OBJ/MTL: `a56694d1ee28735c68381ff18c3a52581612feebac0101a53e502956c27d144f` /
|
||||
`392f1b10ff5a0b142d520a9443b4c96191985f15d4244c79b36fdeda0f153715`
|
||||
- runtime inventory: `0d660b0fd8b647ebbf4e91afebd5006bd100973ab8e2507a5bfe759f477b33b4`
|
||||
- package: `cfb232baa494ff59f6c8d65514a08c86332ee9354350b2a0392b6f932a7ee42c`
|
||||
- manifest: `d80b74502202effa7be15640c945dc7e04af703b58e7a15c3fe7babc43c17b46`
|
||||
|
||||
## Next Task
|
||||
|
||||
`M12-07B`: OBJ multi-object, negative-index, MTL/texture-origin, and malformed-face cases.
|
||||
|
||||
## Rollback
|
||||
|
||||
Remove the OBJ generator, checker, desktop report, OBJ/MTL fixture, manifest, and this status entry.
|
||||
Restore M12-06G as the queue tail and move the machine queue back to M12-07A. No parity ledger rollback
|
||||
is required.
|
||||
53
docs/status/M12-07B.md
Normal file
53
docs/status/M12-07B.md
Normal file
@@ -0,0 +1,53 @@
|
||||
# M12-07B Status
|
||||
|
||||
status: done
|
||||
task: OBJ multi-object, negative-index, texture-origin, and malformed-face fixtures
|
||||
updated: 2026-08-18 America/New_York
|
||||
enablingTask: true
|
||||
parityStateChange: false
|
||||
|
||||
## Scope
|
||||
|
||||
Pinned Blender 5.2 `wm.obj_export` now produces a two-object OBJ/MTL positive fixture with two
|
||||
relative `map_Kd` references and a 2x2 PNG texture. The deterministic generator derives a negative
|
||||
index OBJ variant and a malformed two-vertex face variant from the same positive bytes. The report
|
||||
keeps multi-object/group/material counts and expected fail-closed `OBJ_FACE_ARITY_INVALID` separate;
|
||||
it does not claim that a Web parser or OBJ import route exists.
|
||||
|
||||
## Evidence
|
||||
|
||||
- `build_blender_5.2.0/bin/blender -b --factory-startup --python
|
||||
tools/web/generate-obj-multi-negative-fixtures.py -- tests/files/web/m12_obj_multi_v1
|
||||
tests/golden/M12-07B/desktop-fixtures.json` completed with 2 objects, 6 positions, 6 UVs,
|
||||
2 normals, 2 faces, 2 materials, relative `m12_obj_texture.png`, and both derived variants.
|
||||
- `node tools/web/check-obj-multi-negative-fixtures.mjs` passed fresh-directory Blender regeneration,
|
||||
exact OBJ/MTL/PNG/negative/malformed bytes, negative-index acceptance shape, malformed-face arity,
|
||||
and PNG signature checks:
|
||||
`obj-multi-negative-fixtures-ok objects=2 negative=true malformed=OBJ_FACE_ARITY_INVALID textureOrigin=relative deterministic=true next=M12-07C`.
|
||||
- Runtime identity matches M12-05A pinned Blender 5.2; no Web parser, UI route, or parity ledger
|
||||
status changed. Package hash remains frozen.
|
||||
|
||||
## Artifact Hashes
|
||||
|
||||
- parent manifest: `d80b74502202effa7be15640c945dc7e04af703b58e7a15c3fe7babc43c17b46`
|
||||
- generator: `8d4faed82cba76e46bf639e5031b30568e8b9a15240cbddb1c22ee7ad11d697b`
|
||||
- checker: `61188d67efd6133e714f2d55c7c8516b9d04896de068f994523a3c398eebdd2f`
|
||||
- desktop report: `b60ff785676c0f0168588605ad442a650615191ac00770b7e5a308cc4ade83ce`
|
||||
- OBJ/MTL/PNG: `4ed3dced8445b03754cd3916ae2e8cf0dff85e6a5882f1c6f0a4a4e4c5251f6a` /
|
||||
`80338f569c67a8b1616515ba878ffc72b26e93ef2e8c361131023fb14f132f5f` /
|
||||
`44e4fd08bdda8403908349e2a62dcf103ce2d0851099fc61cd868d65ddbef78c`
|
||||
- negative/malformed OBJ: `9457954284cac1d68e23627e3ff734c0c591b3a24086ce5aa3d0dbbfc22f01bc` /
|
||||
`6dd508b5ba944c2d15e2889c9ad9a3693845145c3bf6c9bf7df992081c915864`
|
||||
- runtime inventory: `0d660b0fd8b647ebbf4e91afebd5006bd100973ab8e2507a5bfe759f477b33b4`
|
||||
- package: `cfb232baa494ff59f6c8d65514a08c86332ee9354350b2a0392b6f932a7ee42c`
|
||||
- manifest: `785f593271058098704498cb0a7c948305087f1a83bf8f29b6e6fb9fe9341926`
|
||||
|
||||
## Next Task
|
||||
|
||||
`M12-07C`: Web-to-desktop OBJ round-trip and loss report.
|
||||
|
||||
## Rollback
|
||||
|
||||
Remove the multi/negative OBJ generator, checker, fixtures, report, manifest, and this status entry.
|
||||
Restore M12-07A as the queue tail and move the machine queue back to M12-07B. No parity ledger rollback
|
||||
is required.
|
||||
55
docs/status/M12-07C.md
Normal file
55
docs/status/M12-07C.md
Normal file
@@ -0,0 +1,55 @@
|
||||
# M12-07C Status
|
||||
|
||||
status: done
|
||||
task: Web-to-desktop OBJ round-trip and loss report
|
||||
updated: 2026-08-18 America/New_York
|
||||
enablingTask: false
|
||||
parityStateChange: false
|
||||
|
||||
## Scope
|
||||
|
||||
The bounded TypeScript OBJ protocol parses positive and negative indices, position/UV/normal streams,
|
||||
objects/groups/faces, MTL `map_Kd`, and stable budgets; it serializes a deterministic Web OBJ/MTL pair
|
||||
and emits a machine loss report for unbound texture origins. A Chromium Worker consumes the M12-07B
|
||||
double-object fixture, then a new pinned Blender 5.2 process imports the Web output with split groups.
|
||||
|
||||
## Evidence
|
||||
|
||||
- `node --test web/tests/unit/obj-import.test.mjs` passed 3/3 for negative-index resolution,
|
||||
deterministic serialization, bound/unbound texture loss, malformed face arity, and index range.
|
||||
- `CHROME_PATH=/usr/bin/google-chrome-stable WEB_TEST_PORT=5460 node_modules/.bin/playwright test
|
||||
--config playwright.config.ts --workers=1 tests/e2e/obj-web-roundtrip.spec.ts` passed 1/1 in Chrome
|
||||
150. Browser output has 2 objects, 6 positions/UVs, 2 normals, 2 faces, 2 materials; bound texture
|
||||
loss is zero and missing texture loss contains two `OBJ_TEXTURE_ORIGIN_UNRESOLVED` warnings.
|
||||
- The test writes the browser OBJ/MTL and texture to an isolated directory, invokes pinned Blender
|
||||
`wm.obj_import`, and compares 2 objects, 2 triangles, UVMap presence, and one material per object.
|
||||
- `node tools/web/check-obj-web-roundtrip.mjs` passed the exact golden and artifact hash gate:
|
||||
`obj-web-roundtrip-ok objects=2 triangles=2 lossWarnings=2 desktopExact=true next=M12-07D`.
|
||||
- `npm --prefix web run typecheck`, Python compile, and `git diff --check` passed. Package hash remains
|
||||
frozen; OBJ Web capability is still bounded and does not change N-023 parity.
|
||||
|
||||
## Artifact Hashes
|
||||
|
||||
- parent manifest: `785f593271058098704498cb0a7c948305087f1a83bf8f29b6e6fb9fe9341926`
|
||||
- protocol: `e7240af65e0d90f3ee690a4e3f391416fe4744ac6c46edc8ac0d72386857cab9`
|
||||
- Worker: `bf1fcc60ec318cf6c2747d44f4af741b46f284cf5f5307e142f0ab6d50b14302`
|
||||
- desktop importer: `9f1eb4ab679255a0f1f596696e8befc33a4e30c0cbe6ea423e2aaa0314cec22d`
|
||||
- checker: `9d53014f4b89f786c516ebe8d300030c2728e4a36a86a5ef136b2769a12ac96b`
|
||||
- unit/Chromium: `485a669be5de8e370e9b5a3239357b028ba61ca5c4076819cd46aed52a5c210a` /
|
||||
`93785b4017ba14b007926b0f82442f8ae5968f242a2a762e5f5dc77d36110f5b`
|
||||
- report: `45eaffc9c2e50c84b557d13ebbe9f4f53b63e19e00bc69b272491ef6366dff81`
|
||||
- fixture OBJ/MTL/PNG: `4ed3dced8445b03754cd3916ae2e8cf0dff85e6a5882f1c6f0a4a4e4c5251f6a` /
|
||||
`80338f569c67a8b1616515ba878ffc72b26e93ef2e8c361131023fb14f132f5f` /
|
||||
`44e4fd08bdda8403908349e2a62dcf103ce2d0851099fc61cd868d65ddbef78c`
|
||||
- package: `cfb232baa494ff59f6c8d65514a08c86332ee9354350b2a0392b6f932a7ee42c`
|
||||
- manifest: `0c639954900b1fcc3b8285d0f4c0ecfa5807df6cde6d1f2cd3b59c4636d71674`
|
||||
|
||||
## Next Task
|
||||
|
||||
`M12-07D`: split STL binary and ASCII capability declarations.
|
||||
|
||||
## Rollback
|
||||
|
||||
Remove the OBJ protocol, Worker, desktop importer, unit/E2E tests, checker, report, manifest, and this
|
||||
status entry. Restore M12-07B as the queue tail and move the machine queue back to M12-07C. No parity
|
||||
ledger rollback is required.
|
||||
47
docs/status/M12-07D.md
Normal file
47
docs/status/M12-07D.md
Normal file
@@ -0,0 +1,47 @@
|
||||
# M12-07D Status
|
||||
|
||||
status: done
|
||||
task: split STL binary and ASCII capability declarations
|
||||
updated: 2026-08-18 America/New_York
|
||||
enablingTask: true
|
||||
parityStateChange: false
|
||||
|
||||
## Scope
|
||||
|
||||
Pinned Blender 5.2 `WM_OT_stl_export` now generates binary and ASCII STL from the same selected
|
||||
two-triangle mesh using identical axis, scale, unit, evaluation, and modifier settings. The report
|
||||
keeps `STL_BINARY/ascii_format=false` and `STL_ASCII/ascii_format=true` as separate variants; it does
|
||||
not infer the format from the `.stl` extension or claim Web parsing/import support.
|
||||
|
||||
## Evidence
|
||||
|
||||
- `build_blender_5.2.0/bin/blender -b --factory-startup --python
|
||||
tools/web/generate-stl-capability-fixtures.py -- tests/files/web/m12_stl_capability_v1
|
||||
tests/golden/M12-07D/capability-report.json` generated a 184-byte binary STL with two 50-byte
|
||||
triangle records and a 213-byte ASCII STL with two facets/six vertex lines.
|
||||
- `node tools/web/check-stl-capability-fixtures.mjs` matched runtime identity to M12-05A, validated
|
||||
both independent encodings, regenerated the report/files byte-for-byte in a fresh directory, and
|
||||
returned `stl-capability-fixtures-ok binaryTriangles=2 asciiFacets=2 deterministic=true next=M12-07E`.
|
||||
- Package hash remains frozen. This enabling task does not change N-023 parity or expose an STL UI
|
||||
route.
|
||||
|
||||
## Artifact Hashes
|
||||
|
||||
- parent manifest: `0c639954900b1fcc3b8285d0f4c0ecfa5807df6cde6d1f2cd3b59c4636d71674`
|
||||
- generator: `8310104e66f246b32ac7cb4619e7f4da109baf2ece39ea670cbb6d33bd88c8b8`
|
||||
- checker: `b2ad901eaa9701436cf7bcc8aa4e40d1b2d6eda7c6c44a0af830347a37cc9ca8`
|
||||
- desktop report: `29c7d2a6e6764440c99eec25bb5760c7e0880839691757fb3e607ed4f5050013`
|
||||
- binary/ASCII fixtures: `50161172cd12e4240067064db6f80e74b2df69c475e3e34154e9d0523928c1ca` /
|
||||
`a463a5add8be070fb67b34f00ef6e7b46025aed31fa429d4a033d75a11cf0113`
|
||||
- package: `cfb232baa494ff59f6c8d65514a08c86332ee9354350b2a0392b6f932a7ee42c`
|
||||
- manifest: `bbc78e47f389562e7d648bf49c9b3bf8a08aaa36e914589a6eab0a1f6e72748d`
|
||||
|
||||
## Next Task
|
||||
|
||||
`M12-07E`: STL normal, unit, degenerate-triangle, and trailing-byte parity.
|
||||
|
||||
## Rollback
|
||||
|
||||
Remove the STL capability generator, checker, fixtures, report, manifest, and this status entry.
|
||||
Restore M12-07C as the queue tail and move the machine queue back to M12-07D. No parity ledger rollback
|
||||
is required.
|
||||
60
docs/status/M12-07E.md
Normal file
60
docs/status/M12-07E.md
Normal file
@@ -0,0 +1,60 @@
|
||||
# M12-07E Status
|
||||
|
||||
status: done
|
||||
task: STL normal, unit, degenerate-triangle, and trailing-byte parity
|
||||
updated: 2026-08-18 America/New_York
|
||||
enablingTask: false
|
||||
parityStateChange: false
|
||||
|
||||
## Scope
|
||||
|
||||
The bounded STL protocol requires an explicit binary/ASCII variant and positive unit scale. It parses
|
||||
facet normals and vertices, applies the scale, removes zero-area triangles the same way as Blender's
|
||||
validated import, and rejects binary payload after the declared triangle table with
|
||||
`STL_TRAILING_BYTES`. Desktop Blender accepts that trailing fixture as an empty mesh, so the report
|
||||
records `STRICTER_WEB_BLOCK` rather than claiming exact parity for that edge case.
|
||||
|
||||
## Evidence
|
||||
|
||||
- The deterministic edge generator derived a one-degenerate-triangle binary and a four-trailing-byte
|
||||
binary from M12-07D. Pinned Blender 5.2 was probed at unit scales 1 and 0.001 and against both edge
|
||||
files; it preserves normals, scales world bounds by 1000, removes one degenerate triangle, and
|
||||
accepts the trailing fixture as an empty mesh.
|
||||
- `node --test web/tests/unit/stl-import.test.mjs` passed 2/2 for binary/ASCII normals, explicit unit
|
||||
scaling, degenerate removal, trailing-byte rejection, and invalid scale.
|
||||
- `CHROME_PATH=/usr/bin/google-chrome-stable WEB_TEST_PORT=5463 node_modules/.bin/playwright test
|
||||
--config playwright.config.ts --workers=1 tests/e2e/stl-edge-parity.spec.ts` passed 1/1 in Chrome
|
||||
150. Normal comparison is exact, Web/Desktop unit ratio matches within Float32 tolerance, and both
|
||||
retain one triangle after degenerate removal.
|
||||
- `node tools/web/check-stl-edge-parity.mjs` passed:
|
||||
`stl-edge-parity-ok normals=exact unitRatio=1000 degenerate=removed trailing=STRICTER_WEB_BLOCK next=M12-07F`.
|
||||
- Typecheck and `git diff --check` passed. The stricter trailing-byte policy leaves N-023 full parity
|
||||
blocked and does not expose an STL UI route.
|
||||
|
||||
## Artifact Hashes
|
||||
|
||||
- parent manifest: `bbc78e47f389562e7d648bf49c9b3bf8a08aaa36e914589a6eab0a1f6e72748d`
|
||||
- fixture generator/desktop probe: `018013347642603c21237ebb023bdc7a4e338f5a3f875fea536a996eb121e716` /
|
||||
`b3d6ea197ef77b5a14f60f5e6b43d4392e943ff5d56acf73915507fc9a4161b7`
|
||||
- protocol/Worker: `87eec72e2b8aa7ad0b168ca0ee8c4016c941f56f5f1ac53aa5fe71d0832f1dd8` /
|
||||
`d714f1f3a218a2226dd349aea81c6c54efa6246de1c4fe51aaa9f5c352ef44fc`
|
||||
- unit/Chromium/checker: `4af52833486421c017f3af2b833b0776e60a6ab57ed66fea2161cf9674f4b243` /
|
||||
`121d348250e26d29ad966f7427bbef9da77de2098e2e305827b11aae52002c5c` /
|
||||
`b5ed7fbb41bb46fba982d5726cb8c3eaecf360b772a01d6337c309b1c4a4f535`
|
||||
- fixture/desktop/Web reports: `545463a984356d6635cbaae3865d13fe95bd2d841c394ac9ddff496c95d46f18` /
|
||||
`2d3028a3b7d97f39654cff5fcef1d0c1c71e9f2d08e3e29c2e926651ed3860f1` /
|
||||
`e0686cc9be3b68e564651207443e0ebf3e3b0eb3d07a32915b03f44b1908357b`
|
||||
- degenerate/trailing fixtures: `c120bb0f218819eb89a3607c0b4f8fafd9afb599402e3b21deaa3b2be143e7d0` /
|
||||
`0a30aab6db1588722067000e2a08c3c6206a8ed5b7531caa0b082723700a3681`
|
||||
- package: `cfb232baa494ff59f6c8d65514a08c86332ee9354350b2a0392b6f932a7ee42c`
|
||||
- manifest: `19a9f460d1b939c9504dadd364cb87dab3b1769b0599035e2d2b51b47091e034`
|
||||
|
||||
## Next Task
|
||||
|
||||
`M12-07F`: STL Web-to-desktop round-trip and material-loss report.
|
||||
|
||||
## Rollback
|
||||
|
||||
Remove the STL edge fixtures, probes, parser, Worker, tests, reports, checker, manifest, and this status
|
||||
entry. Restore M12-07D as the queue tail and move the machine queue back to M12-07E. No parity ledger
|
||||
rollback is required.
|
||||
51
docs/status/M12-07F.md
Normal file
51
docs/status/M12-07F.md
Normal file
@@ -0,0 +1,51 @@
|
||||
# M12-07F Status
|
||||
|
||||
status: done
|
||||
task: STL Web-to-desktop round-trip and material-loss report
|
||||
updated: 2026-08-18 America/New_York
|
||||
enablingTask: false
|
||||
parityStateChange: false
|
||||
|
||||
## Scope
|
||||
|
||||
The STL Web path now serializes the bounded parsed triangle result back to deterministic binary STL.
|
||||
The loss report explicitly records STL's lack of material slots as
|
||||
`STL_MATERIAL_UNSUPPORTED`; it never silently claims material preservation. A Chromium Worker output
|
||||
is imported by a fresh pinned Blender 5.2 process and compared by triangle count and facet normals.
|
||||
|
||||
## Evidence
|
||||
|
||||
- `node --test web/tests/unit/stl-export.test.mjs` passed 1/1 for binary header/table serialization
|
||||
and explicit material-loss warning.
|
||||
- `CHROME_PATH=/usr/bin/google-chrome-stable WEB_TEST_PORT=5467 node_modules/.bin/playwright test
|
||||
--config playwright.config.ts --workers=1 tests/e2e/stl-web-roundtrip.spec.ts` passed 1/1 in Chrome
|
||||
150. Browser output is 184 bytes/2 triangles; Blender reopens 2 polygons/2 triangles with exact
|
||||
normals; warning code is `STL_MATERIAL_UNSUPPORTED`.
|
||||
- `node tools/web/check-stl-web-roundtrip.mjs` passed:
|
||||
`stl-web-roundtrip-ok triangles=2 normals=exact materialLoss=1 desktopExact=true next=M12-07G`.
|
||||
- Typecheck and `git diff --check` passed. The STL material loss remains machine-visible and STL UI
|
||||
route/parity stays bounded.
|
||||
|
||||
## Artifact Hashes
|
||||
|
||||
- parent manifest: `19a9f460d1b939c9504dadd364cb87dab3b1769b0599035e2d2b51b47091e034`
|
||||
- protocol/Worker: `3b9c409de9fb3eaea34f82c1ddd466670d2b478845d8ff6af3c4e44cb4e04a52` /
|
||||
`1da8b8281cf8ebf9ccf5fd2f42da8ed5886001ab83daba8d9fcd88980257af87`
|
||||
- desktop importer: `c4cbff52ff2e7cecba7aeab47e865975955da23a0e1e8ff885ece56b894558d5`
|
||||
- unit/Chromium/checker: `f06af242df80ec26d06e92b749449cfebaf909476198ff825207cdd4b9484102` /
|
||||
`2e979dcd030f5316fcbe28e2c19b1c99fe5d111e849d3fc1d2ea316d2159032b` /
|
||||
`093de04bf80b0909eee56ea590e04e7aa4749168e2e49615c62ab39ddc0d16cf`
|
||||
- report: `0495c645b4280f6e7821f0ba02010e25d4accbc552e3cd7c58e052607799040e`
|
||||
- source fixture: `50161172cd12e4240067064db6f80e74b2df69c475e3e34154e9d0523928c1ca`
|
||||
- package: `cfb232baa494ff59f6c8d65514a08c86332ee9354350b2a0392b6f932a7ee42c`
|
||||
- manifest: `3cbbcb541ee123da0ef8916ac2ca8805680d539bbf8db3b4a8d331aec418148c`
|
||||
|
||||
## Next Task
|
||||
|
||||
`M12-07G`: PLY ASCII/binary little-endian capability declarations.
|
||||
|
||||
## Rollback
|
||||
|
||||
Remove the STL export/loss protocol, Worker, desktop importer, tests, checker, report, manifest, and
|
||||
this status entry. Restore M12-07E as the queue tail and move the machine queue back to M12-07F. No
|
||||
parity ledger rollback is required.
|
||||
53
docs/status/M12-07G.md
Normal file
53
docs/status/M12-07G.md
Normal file
@@ -0,0 +1,53 @@
|
||||
# M12-07G Status
|
||||
|
||||
status: done
|
||||
task: PLY ASCII and binary little-endian capability declarations
|
||||
updated: 2026-08-18 America/New_York
|
||||
enablingTask: true
|
||||
parityStateChange: false
|
||||
|
||||
## Scope
|
||||
|
||||
Pinned Blender 5.2 `WM_OT_ply_export` now has two independently declared capability variants for
|
||||
the same selected two-triangle mesh: `PLY_ASCII` and `PLY_BINARY_LITTLE_ENDIAN`. The report binds
|
||||
the export settings, source/operator anchor, runtime identity, header semantics, and byte hashes;
|
||||
the variant is never inferred from a shared `.ply` extension. This enabling task freezes desktop
|
||||
capability only and does not expose a Web PLY parser or import route.
|
||||
|
||||
## Evidence
|
||||
|
||||
- `build_blender_5.2.0/bin/blender -b --factory-startup --python
|
||||
tools/web/generate-ply-capability-fixtures.py -- tests/files/web/m12_ply_capability_v1
|
||||
tests/golden/M12-07G/capability-report.json` generated an ASCII PLY with four vertices/two faces
|
||||
and a binary little-endian PLY with the same four vertices/two faces. Both headers explicitly carry
|
||||
their independent encoding declarations and Blender export settings are recorded in the report.
|
||||
- `node tools/web/check-ply-capability-fixtures.mjs` matched every runtime identity field to the
|
||||
pinned M12-05A inventory, validated the `ascii` and `binary_little_endian` variants, checked the
|
||||
vertex/face element counts and artifact hashes, regenerated both files in a fresh temporary
|
||||
directory, and passed byte-for-byte determinism:
|
||||
`ply-capability-fixtures-ok ascii=ascii binary=binary_little_endian vertices=4 faces=2 deterministic=true next=M12-07H`.
|
||||
- `python3 -m py_compile tools/web/generate-ply-capability-fixtures.py` and
|
||||
`node --check tools/web/check-ply-capability-fixtures.mjs` passed. The package hash remains
|
||||
frozen and N-023 parity remains blocked; no PLY Web UI route was exposed.
|
||||
|
||||
## Artifact Hashes
|
||||
|
||||
- parent manifest: `3cbbcb541ee123da0ef8916ac2ca8805680d539bbf8db3b4a8d331aec418148c`
|
||||
- generator: `581cd84057357e3a87997cf9c07d5d5633209648ac11e44611782eb254a38ebd`
|
||||
- checker: `5280d6e57b7a722ea881e27b792c6082c5113c1577ac0e87f87cc87fdf59516c`
|
||||
- desktop report: `26b1ce83334b41778cef5ce2a1f2c4d34254f63d7c7573cb3fb550f93ddeabb2`
|
||||
- ASCII/binary little-endian fixtures: `63646cab9bf6ccecb23092e5e24d04df1e0a690c866127c72a35791e99262331` /
|
||||
`e40fbb494b8b147c555a0fc06eb191415406bb9a6c061acf6befd8464c8c41a5`
|
||||
- runtime inventory: `0d660b0fd8b647ebbf4e91afebd5006bd100973ab8e2507a5bfe759f477b33b4`
|
||||
- package: `cfb232baa494ff59f6c8d65514a08c86332ee9354350b2a0392b6f932a7ee42c`
|
||||
- manifest: `87df9c12f9c6eacf63051b70e9bb2eb43ebd1e5c4487b3512c45adb94cbb82ea`
|
||||
|
||||
## Next Task
|
||||
|
||||
`M12-07H`: PLY vertex/face/color/custom-property mapping and unknown-property loss report.
|
||||
|
||||
## Rollback
|
||||
|
||||
Remove the PLY capability generator, checker, fixtures, report, manifest, and this status entry.
|
||||
Restore M12-07F as the queue tail and move the machine queue back to M12-07G. No parity ledger
|
||||
rollback is required.
|
||||
62
docs/status/M12-07H.md
Normal file
62
docs/status/M12-07H.md
Normal file
@@ -0,0 +1,62 @@
|
||||
# M12-07H Status
|
||||
|
||||
status: done
|
||||
task: PLY vertex/face/color/custom property mapping and unknown property loss report
|
||||
updated: 2026-08-18 America/New_York
|
||||
enablingTask: false
|
||||
parityStateChange: false
|
||||
|
||||
## Scope
|
||||
|
||||
The production `ply-import` protocol now accepts explicitly declared ASCII and binary
|
||||
little-endian PLY. Vertex position, normal, RGBA color, numeric custom properties, face
|
||||
indices, and numeric face properties are mapped into a bounded canonical document. Unsupported
|
||||
vertex/face list properties and unknown elements are skipped with deterministic
|
||||
`PLY_UNKNOWN_PROPERTY`/`PLY_UNKNOWN_ELEMENT` loss warnings; mapped fields remain available.
|
||||
The worker serializes the canonical document to bounded ASCII PLY for desktop validation.
|
||||
This task does not expose a general PLY file-picker route or claim full PLY attribute parity.
|
||||
|
||||
## Evidence
|
||||
|
||||
- `build_blender_5.2.0/bin/blender -b --factory-startup --python
|
||||
tools/web/generate-ply-mapping-fixtures.py -- tests/files/web/m12_ply_mapping_v1
|
||||
tests/golden/M12-07H/mapping-report.json` generated deterministic ASCII and binary
|
||||
little-endian fixtures containing four vertices, two faces, RGBA colors, and two numeric
|
||||
custom vertex attributes. A derived ASCII fixture contains an unsupported list property.
|
||||
- `node tools/web/check-ply-mapping-fixtures.mjs` matched pinned Blender 5.2 runtime identity,
|
||||
artifact hashes, field counts and a fresh byte-for-byte regeneration:
|
||||
`ply-mapping-fixtures-ok vertices=4 faces=2 colors=rgba custom=2 unknown=PLY_UNKNOWN_PROPERTY deterministic=true next=M12-07I`.
|
||||
- `node --test web/tests/unit/ply-import.test.mjs` passed 3/3. It covers both encodings,
|
||||
mapped values, unknown-property loss, serialization/reopen, and format mismatch blocking.
|
||||
- `UPDATE_PLY_MAPPING_REPORT=1 CHROME_PATH=/usr/bin/google-chrome-stable WEB_TEST_PORT=5472
|
||||
node_modules/.bin/playwright test --config playwright.config.ts --workers=1
|
||||
tests/e2e/ply-web-roundtrip.spec.ts` passed 1/1. Production Chromium Worker parsed both
|
||||
encodings, reported unknown loss, serialized ASCII, and pinned Blender 5.2 re-imported the
|
||||
result with exact vertex/face/position counts and mapped custom/color attributes.
|
||||
- `npm --prefix web run typecheck`, `node --check tools/web/check-ply-mapping-fixtures.mjs`,
|
||||
and Python compile checks passed.
|
||||
|
||||
## Artifact Hashes
|
||||
|
||||
- protocol: `058a3263fde553637840a4e9ad4e8e9d923eb52c250f8000317c7f43a228881d`
|
||||
- worker: `f6bf5e39e83286d7b257bbdce88f4d7fa027c64651da9765567788b5cf298c71`
|
||||
- generator: `ffc051eccfc6973ee00cc791cdbd641fcce308b4083741e3e6ae82291d9347b7`
|
||||
- checker: `2b055dbc705830848efdf4d8db8543a3ccc684de1f258732bcafefa86cf65c3a`
|
||||
- desktop importer: `6edbc6e401a1a902dcfd11c4d767e8c8620d694e40eb4ca29dd8479f9c55ef37`
|
||||
- unit/e2e: `b03a5f4b4b2a974fa26e653763470b92d1433c5d352ae09ab5492b841e6e5e1f` /
|
||||
`2cadebc89057655d78e9b520bb6adf9debb27c6d783cd002efee08d269636fb9`
|
||||
- desktop mapping report: `8a02fc9e364ed79e50ef00897affa9ab63808d3cb3cdabd00fdb8ee4c26ec18a`
|
||||
- Chromium/desktop round-trip report: `1ca9d3b7870fcc8c9e3c9bbbd90ef48bd13bbc9ae0462312c9482f24f05f13ec`
|
||||
- ASCII/binary/unknown fixtures: `acaa369c17252d4d089a2e3064d0c1fcdfdb2d066759ed160adf7869d3e859d5` /
|
||||
`d0fc195fd1a101c42ac984a2382bccdddb7d0bf60dd618e9f637c964f1b30b9e` /
|
||||
`a994c7126f235d0067ce4af35f8b0c6699cc83073e2a37e982edd45ece459f33`
|
||||
|
||||
## Next Task
|
||||
|
||||
`M12-07I`: PLY big-endian, malformed list, and oversized count stable blocking.
|
||||
|
||||
## Rollback
|
||||
|
||||
Remove the PLY mapping protocol, worker, fixture generator/checker, fixtures, reports, tests,
|
||||
package script, and this status entry. Restore M12-07G as the queue tail and move the machine
|
||||
queue back to M12-07H. No parity ledger rollback is required.
|
||||
49
docs/status/M12-07I.md
Normal file
49
docs/status/M12-07I.md
Normal file
@@ -0,0 +1,49 @@
|
||||
# M12-07I Status
|
||||
|
||||
status: done
|
||||
task: PLY big-endian, malformed list, and oversized count stable blocking
|
||||
updated: 2026-08-18 America/New_York
|
||||
enablingTask: false
|
||||
parityStateChange: false
|
||||
|
||||
## Scope
|
||||
|
||||
PLY admission now fails closed for unsupported big-endian input, truncated/malformed list data,
|
||||
and element counts above the bounded 65,536 record budget. The production parser returns stable
|
||||
codes `PLY_FORMAT_UNSUPPORTED`, `PLY_DATA_TRUNCATED`, and `PLY_IMPORT_BUDGET_EXCEEDED: vertex`;
|
||||
the Worker does not publish a partial document. No big-endian route or unbounded PLY import is
|
||||
claimed.
|
||||
|
||||
## Evidence
|
||||
|
||||
- `node tools/web/generate-ply-negative-fixtures.mjs` generated deterministic big-endian,
|
||||
malformed-list, and oversized-count fixtures. `node tools/web/check-ply-negative-fixtures.mjs`
|
||||
regenerated them in a fresh temporary directory and passed:
|
||||
`ply-negative-fixtures-ok cases=3 bigEndian=PLY_FORMAT_UNSUPPORTED malformed=PLY_DATA_TRUNCATED oversized=PLY_IMPORT_BUDGET_EXCEEDED deterministic=true next=M12-07J`.
|
||||
- `node --test web/tests/unit/ply-negative.test.mjs` passed 2/2 for all three stable error paths.
|
||||
- `CHROME_PATH=/usr/bin/google-chrome-stable WEB_TEST_PORT=5478 node_modules/.bin/playwright test
|
||||
--config playwright.config.ts --workers=1 tests/e2e/ply-negative.spec.ts` passed 1/1. The
|
||||
production Worker returned the exact expected error for each case and never returned `ok=true`.
|
||||
- `npm --prefix web run typecheck`, Node syntax checks, and `git diff --check` passed.
|
||||
|
||||
## Artifact Hashes
|
||||
|
||||
- protocol: `058a3263fde553637840a4e9ad4e8e9d923eb52c250f8000317c7f43a228881d`
|
||||
- generator/checker: `9c09707bdfe73ba467bbfbf61ed3846fb59fd33ab5563a3a62c8032722ff6938` /
|
||||
`b1d047d4cb1fa15dff7821687e7028ad073fdc62d4c76f60a2656732c0ec5e2b`
|
||||
- unit/e2e: `60439f9e6bc221df8866956bf926816a347e85828b5a93deb26ee23015cf449a` /
|
||||
`6509a29d6842f3423d4dfcc40dbd52a959a5efa7ee1121143dce06e5bbc4a460`
|
||||
- report: `fbe2830d1b19294ea98eea66c3e00125bc0809a4bb8a750612939cbe1f5acca9`
|
||||
- fixtures: `cda92943a3690529fbb3463d328b6796ac0d07e19139450556f7411fc1f031e3` /
|
||||
`a6a576b7a04d919b540520a6f43a89c089f0d706a17fd8b390711fff6b8b03df` /
|
||||
`fcd99e0838025429420a47466251cf80e638d2b5816ad14d5aa696364525bb`
|
||||
|
||||
## Next Task
|
||||
|
||||
`M12-07J`: three-format cancellation, OOM, Worker restart, and small-file recovery.
|
||||
|
||||
## Rollback
|
||||
|
||||
Remove the count guard, negative fixture generator/checker, fixtures, report, tests, manifest,
|
||||
and this status entry. Restore M12-07H as the queue tail and move the machine queue back to
|
||||
M12-07I. No parity ledger rollback is required.
|
||||
50
docs/status/M12-07J.md
Normal file
50
docs/status/M12-07J.md
Normal file
@@ -0,0 +1,50 @@
|
||||
# M12-07J Status
|
||||
|
||||
status: done
|
||||
task: three-format cancellation, OOM, Worker restart, and small-file recovery
|
||||
updated: 2026-08-18 America/New_York
|
||||
enablingTask: false
|
||||
parityStateChange: false
|
||||
|
||||
## Scope
|
||||
|
||||
OBJ, STL, and PLY now share a schema-1 recovery receipt. Each bounded production Worker run
|
||||
binds format, input hash, base/candidate revision, Worker generation, output hash, temporary bytes,
|
||||
live requests, published result count, and commit state. Cancellation clears temporary state and
|
||||
publishes no result; over-budget/OOM input returns `IO_FORMAT_OOM`; a generation-2 rerun and a
|
||||
generation-3 small-file run reproduce the generation-1 output hash. This is recovery evidence for
|
||||
the bounded format workers, not a general file-picker or full Blender IO claim.
|
||||
|
||||
## Evidence
|
||||
|
||||
- `node --test web/tests/unit/io-format-recovery.test.mjs` passed 2/2 for cancellation/OOM cleanup,
|
||||
commit identity, generation recovery, and stale-generation blocking.
|
||||
- `UPDATE_IO_FORMAT_RECOVERY_REPORT=1 CHROME_PATH=/usr/bin/google-chrome-stable WEB_TEST_PORT=5492
|
||||
node_modules/.bin/playwright test --config playwright.config.ts --workers=1
|
||||
tests/e2e/io-format-recovery.spec.ts` passed 1/1. The report covers OBJ, STL, and PLY separately:
|
||||
three cancellations, three OOM budget faults, three Worker-generation restarts, and three small
|
||||
recovery commits; all output SHA-256 values are stable.
|
||||
- A second run without report update passed against the same golden, proving deterministic operation
|
||||
IDs and receipt output. `node tools/web/check-io-format-recovery.mjs` passed:
|
||||
`io-format-recovery-ok formats=OBJ,STL,PLY cancelled=3 oom=3 restart=3 smallRecovery=3 deterministic=true next=M13-01A`.
|
||||
- `npm --prefix web run typecheck` and `git diff --check` passed.
|
||||
|
||||
## Artifact Hashes
|
||||
|
||||
- protocol: `7e352539e3300969c7409c34d6056eb6ad31055431ffce84b1b0a459c335480a`
|
||||
- worker/testing adapter: `63b78fbf25132cad28147ef68731f2cd212a26c96b464fdec349a13ebaa1174f` /
|
||||
`cfcebb6ec38936a66983957b0dede716871cfbfbea3cb53cddc16f3e24fb19b0`
|
||||
- unit/e2e: `aaed1f2abe4789b084c8a6a60bcce8595d38220d7e6678a93924cd05c5716b4f` /
|
||||
`5c1750fa408e1297fc43f2e5749be3e9ac08a16b86265d22f0f06053f52b3bd7`
|
||||
- checker: `6ef6bc4a168f8675a4933a06c296f61076b9ea64cec25b295e961a9b610ab1a2`
|
||||
- report: `35d4fe10d8a4fa84d6e05a85f20ca50975d93a86df41e73c7bbc5875edc4fc70`
|
||||
|
||||
## Next Task
|
||||
|
||||
`M13-01A`: begin the next machine-queued milestone task.
|
||||
|
||||
## Rollback
|
||||
|
||||
Remove the IO recovery protocol, worker, adapter, tests, checker, report, manifest, and this
|
||||
status entry. Restore M12-07I as the queue tail and move the machine queue back to M12-07J. No
|
||||
parity ledger rollback is required.
|
||||
47
docs/status/M13-01A.md
Normal file
47
docs/status/M13-01A.md
Normal file
@@ -0,0 +1,47 @@
|
||||
# M13-01A Status
|
||||
|
||||
status: done
|
||||
task: inventory Text, Python Console, autorun, driver expression, handler, and add-on entry points
|
||||
updated: 2026-08-18 America/New_York
|
||||
enablingTask: true
|
||||
parityStateChange: false
|
||||
|
||||
## Scope
|
||||
|
||||
Pinned Blender 5.2 now has a machine-readable scripting entry inventory covering three Text
|
||||
datablocks, Python Console operators, a module-autorun request, one driver expression, 39 handler
|
||||
groups, and four add-on operators. The report records the entry source and default Web policy:
|
||||
Text is metadata-only, while Console, autorun, driver expressions, handlers, and add-on operations
|
||||
are `DENY`. This task only inventories entry points; it does not execute script text or open a
|
||||
browser scripting route.
|
||||
|
||||
## Evidence
|
||||
|
||||
- `build_blender_5.2.0/bin/blender -b --factory-startup --python
|
||||
tools/web/generate-script-entry-inventory.py -- tests/files/web/m13_script_entry_v1
|
||||
tests/golden/M13-01A/entry-inventory.json` created a fixture with internal/external Text,
|
||||
`use_module` autorun metadata, and a driver expression without executing user code.
|
||||
- `node tools/web/check-script-entry-inventory.mjs` matched pinned runtime identity, policy and
|
||||
semantic inventory, then regenerated the report in a fresh directory. Blender's `.blend` save
|
||||
contains runtime save bytes that may differ between runs, so determinism is asserted on the
|
||||
inventory and fixture byte length; the checked-in fixture hash remains bound in the manifest.
|
||||
Output: `script-entry-inventory-ok texts=3 console=3 autorun=1 drivers=1 handlers=39 addonOps=4 deterministic=true next=M13-01B`.
|
||||
- `python3 -m py_compile tools/web/generate-script-entry-inventory.py`, Node syntax check and
|
||||
`git diff --check` passed.
|
||||
|
||||
## Artifact Hashes
|
||||
|
||||
- generator: `b72667493cfe9957161ef3fb9814180e0cfad5f8aaa1c60c9b6f132e915f3d6f`
|
||||
- checker: `68478f15de4d63ed175e6b580761fd478b1fe9bccbfcaeee82218d13063dfa51`
|
||||
- report: `e024995c53f01beaf725f281f74a6e5ec6018a53435da61a66f5e58a9e50973c`
|
||||
- fixture: `bd6375d02908bfcc57ff7cdeec3f9827bfc4336d1e46e165c5fbbf4d04f19645`
|
||||
- manifest: `d4a305033343ef5fb1ffc073617b59d9012f64b80ecb233e743fb0789a8b4893`
|
||||
|
||||
## Next Task
|
||||
|
||||
`M13-01B`: read script metadata on `.blend` open without executing arbitrary content.
|
||||
|
||||
## Rollback
|
||||
|
||||
Remove the generator, checker, fixture, report, manifest, and this status entry. Restore M12-07J
|
||||
as the queue tail and move the machine queue back to M13-01A. No parity ledger rollback is required.
|
||||
41
docs/status/M13-01B.md
Normal file
41
docs/status/M13-01B.md
Normal file
@@ -0,0 +1,41 @@
|
||||
# M13-01B Status
|
||||
|
||||
status: done
|
||||
task: read script metadata on `.blend` open without executing arbitrary content
|
||||
updated: 2026-08-18 America/New_York
|
||||
enablingTask: false
|
||||
parityStateChange: false
|
||||
|
||||
## Scope
|
||||
|
||||
The real `script_scene.blend` open path reads all three Text sources, verifies source bytes and
|
||||
SHA-256, preserves read-only metadata, and keeps every source `executionStatus=BLOCKED`. A
|
||||
`use_module` autorun request remains `SCRIPT_POLICY_DENIED`; no Python Console, driver, handler,
|
||||
or add-on code executes during open. This task does not add a script execution route.
|
||||
|
||||
## Evidence
|
||||
|
||||
- `node tools/web/check-script-open-metadata.mjs` ran the production WASM Main reader against the
|
||||
real fixture and passed `script-open-metadata-ok blend=opened textMetadata=read sourceHash=verified execution=DENY autorun=DENY next=M13-01C`.
|
||||
- `CHROME_PATH=/usr/bin/google-chrome-stable WEB_TEST_PORT=5495 node_modules/.bin/playwright test
|
||||
--config playwright.config.ts --workers=1 tests/e2e/script-open-metadata.spec.ts` passed 1/1.
|
||||
Chromium opened the fixture through `WebEngineClient`, saw three read-only blocked sources and
|
||||
the explicit autorun denial.
|
||||
- `npm --prefix web run typecheck` and `git diff --check` passed. The checker emits the deterministic
|
||||
report `tests/golden/M13-01B/open-metadata-report.json` bound to the fixture hash.
|
||||
|
||||
## Artifact Hashes
|
||||
|
||||
- checker: `66396d5c9a5294021ae077bb162278c74d46de8b52ac8a444a5de4f6d84cfe05`
|
||||
- e2e: `df6412cda113c830996e08c3d66a035dc1ac309e392f5946a762d11121b1926c`
|
||||
- report: `f92470e57c048452134664f7f6208e50b6f087dbcbc33369e6b882c51813990c`
|
||||
- fixture: `2b8fbdb05419e1e61d64777998d6a3b2562f726c17f548cd1852efc723e1a037`
|
||||
|
||||
## Next Task
|
||||
|
||||
`M13-01C`: default-deny autorun, register, install, and driver execution policy codes.
|
||||
|
||||
## Rollback
|
||||
|
||||
Remove the checker, report, manifest, e2e test, and this status entry. Restore M13-01A as the
|
||||
queue tail and move the machine queue back to M13-01B. No parity ledger rollback is required.
|
||||
39
docs/status/M13-01C.md
Normal file
39
docs/status/M13-01C.md
Normal file
@@ -0,0 +1,39 @@
|
||||
# M13-01C Status
|
||||
|
||||
status: done
|
||||
task: default-deny autorun, register, install, and driver execution policy codes
|
||||
updated: 2026-08-18 America/New_York
|
||||
enablingTask: false
|
||||
parityStateChange: false
|
||||
|
||||
## Scope
|
||||
|
||||
The scripting manifest parser and execution gate reject autorun/register/install/driver execution
|
||||
requests with stable policy codes. The current bounded contract returns `SCRIPT_POLICY_DENIED` for
|
||||
autorun, `DRIVER_EXECUTION_BLOCKED` for driver expressions, `ADDON_INSTALL_BLOCKED` for add-on
|
||||
install/registration, and `SCRIPT_SANDBOX_UNAVAILABLE` even for a correctly signed script when no
|
||||
isolated sandbox exists. No local eval or script execution is enabled.
|
||||
|
||||
## Evidence
|
||||
|
||||
- `node --test web/tests/unit/script-policy-codes.test.mjs` passed 1/1 and asserts all three denied
|
||||
request codes plus the approved-key sandbox gate.
|
||||
- `node tools/web/check-script-policy-codes.mjs` passed:
|
||||
`script-policy-codes-ok autorun=SCRIPT_POLICY_DENIED driver=DRIVER_EXECUTION_BLOCKED addon=ADDON_INSTALL_BLOCKED sandbox=SCRIPT_SANDBOX_UNAVAILABLE next=M13-01D`.
|
||||
- `npm --prefix web run typecheck`, Node syntax checks and `git diff --check` passed. The report and
|
||||
manifest bind the transpiled production protocol source hashes.
|
||||
|
||||
## Artifact Hashes
|
||||
|
||||
- checker: `22588c2198bc8c425ab8e104e8559f0053654ae778aaea3783ec7d54822bc8f4`
|
||||
- unit: `b5a52b8e707963545f1cd71f1a148fa9c9b9d1e4b4c5f51c87d33f8bf3777430`
|
||||
- report: `956db548ee71688a4b89c9a993259d3e57129cd4abe9efd1b9397b3e30b1bf84`
|
||||
|
||||
## Next Task
|
||||
|
||||
`M13-01D`: ensure UI exposes no direct-eval bypass around the scripting policy.
|
||||
|
||||
## Rollback
|
||||
|
||||
Remove the checker, unit test, report, manifest and this status entry. Restore M13-01B as the queue
|
||||
tail and move the machine queue back to M13-01C. No parity ledger rollback is required.
|
||||
36
docs/status/M13-01D.md
Normal file
36
docs/status/M13-01D.md
Normal file
@@ -0,0 +1,36 @@
|
||||
# M13-01D Status
|
||||
|
||||
status: done
|
||||
task: UI direct-eval bypass gate
|
||||
updated: 2026-08-18 America/New_York
|
||||
enablingTask: false
|
||||
parityStateChange: false
|
||||
|
||||
## Scope
|
||||
|
||||
The production app, Workers, and protocol TypeScript sources contain no direct `eval(` or
|
||||
`new Function(` bypass. The scan covers 176 non-vendor `.ts/.tsx` files and records the only
|
||||
declared scripting policy entry points: `gateScriptExecution`, `gateServerScriptJob`, and
|
||||
`parseScriptSourceInventory`. Execution remains `DENY`; this static gate does not claim a sandbox.
|
||||
|
||||
## Evidence
|
||||
|
||||
- `node tools/web/check-script-ui-bypass.mjs` passed:
|
||||
`script-ui-bypass-ok scanned=176 violations=0 policyEntrypoints=3 report=8e234e128b90036548ab709b86b063de404250da2c5c0a6e25e28969b5cd5c73 next=M13-01E`.
|
||||
- `git diff --check` passed. Vendor-generated Emscripten/Three.js sources are outside the scan;
|
||||
no application or protocol source is allowed to introduce a direct eval constructor.
|
||||
|
||||
## Artifact Hashes
|
||||
|
||||
- checker: `f34cb64891c2b22bc3da353f6b864ba3e558d3c286cf716bcb778d9a542cb3d9`
|
||||
- report: `6b050092088508ebd5d769d95a2e66f0cd4020c97f3407724a19b9707f51f6dd`
|
||||
- manifest: `6b28688b3ebcce5629bcfc437d4ca903d0b1e053b32a796690ee4e021726c75b`
|
||||
|
||||
## Next Task
|
||||
|
||||
`M13-01E`: preserve Text data and unknown script sources through save/reopen.
|
||||
|
||||
## Rollback
|
||||
|
||||
Remove the checker, report, manifest, and this status entry. Restore M13-01C as the queue tail and
|
||||
move the machine queue back to M13-01D. No parity ledger rollback is required.
|
||||
41
docs/status/M13-01E.md
Normal file
41
docs/status/M13-01E.md
Normal file
@@ -0,0 +1,41 @@
|
||||
# M13-01E Status
|
||||
|
||||
status: done
|
||||
task: preserve Text data and unknown script sources through save/reopen
|
||||
updated: 2026-08-18 America/New_York
|
||||
enablingTask: false
|
||||
parityStateChange: false
|
||||
|
||||
## Scope
|
||||
|
||||
The production WebEngine path opens `script_scene.blend`, saves it, starts a new engine Worker,
|
||||
and reopens the saved bytes. All three Text sources compare exact by metadata and source SHA-256;
|
||||
they remain read-only and `BLOCKED`, including the `use_module` autorun request. No source is
|
||||
rewritten or executed. This does not claim arbitrary script execution or add-on support.
|
||||
|
||||
## Evidence
|
||||
|
||||
- `UPDATE_SCRIPT_SAVE_REOPEN_REPORT=1 CHROME_PATH=/usr/bin/google-chrome-stable WEB_TEST_PORT=5498
|
||||
node_modules/.bin/playwright test --config playwright.config.ts --workers=1
|
||||
tests/e2e/script-save-reopen.spec.ts` passed 1/1. A second run without report update on port 5497
|
||||
also passed against the same deterministic report.
|
||||
- `node tools/web/check-script-save-reopen.mjs` passed:
|
||||
`script-save-reopen-ok sources=3 exact=true blocked=true savedBytes=490191 next=M13-01F`.
|
||||
- `npm --prefix web run typecheck` and `git diff --check` passed.
|
||||
|
||||
## Artifact Hashes
|
||||
|
||||
- checker: `7fc9a370cb472636e2699565cb21a1450e3cc8a2c90ffdcdff96533b344afa7c`
|
||||
- e2e: `481f78f3a0cce923b67ab14436cc23cbcd2ce66725de29dc874fea4fb5801227`
|
||||
- report: `0f6869a8ec8342ed87649312d2872ab2c172cbf12d6be81bb0b770ebcbe8a398`
|
||||
- manifest: `889a4e06f7e8c0ea55b3ca4baa9fe85dccbe97053e497a45e3d364ce2b70a7c6`
|
||||
- fixture: `2b8fbdb05419e1e61d64777998d6a3b2562f726c17f548cd1852efc723e1a037`
|
||||
|
||||
## Next Task
|
||||
|
||||
`M13-01F`: malicious Text, driver, handler, and embedded-module fixtures.
|
||||
|
||||
## Rollback
|
||||
|
||||
Remove the checker, e2e test, report, manifest, and this status entry. Restore M13-01D as the
|
||||
queue tail and move the machine queue back to M13-01E. No parity ledger rollback is required.
|
||||
44
docs/status/M13-01F.md
Normal file
44
docs/status/M13-01F.md
Normal file
@@ -0,0 +1,44 @@
|
||||
# M13-01F Status
|
||||
|
||||
status: done
|
||||
task: malicious Text, driver, handler, and embedded-module fixtures
|
||||
updated: 2026-08-18 America/New_York
|
||||
enablingTask: false
|
||||
parityStateChange: false
|
||||
|
||||
## Scope
|
||||
|
||||
Pinned Blender 5.2 generated a malicious fixture containing four source bodies: OS command text,
|
||||
driver import, handler subprocess, and an embedded `register()` module. Chromium opened the file
|
||||
through the production Main reader and kept every source read-only/`BLOCKED`; the embedded module
|
||||
returned `SCRIPT_POLICY_DENIED`. No filesystem marker or execution path is exposed by the test.
|
||||
|
||||
## Evidence
|
||||
|
||||
- `build_blender_5.2.0/bin/blender -b --factory-startup --python
|
||||
tools/web/generate-malicious-script-fixture.py -- tests/files/web/m13_malicious_script_v1
|
||||
tests/golden/M13-01F/malicious-report.json` generated four deterministic source hashes and one
|
||||
`use_module` request.
|
||||
- `node tools/web/check-malicious-script-fixture.mjs` passed:
|
||||
`malicious-script-fixture-ok sources=4 module=1 execution=BLOCKED fixtureSha256=7b1921931afc5bb74a2b73e90b175017c583ea878cdbb66f131718b2d8cd23b5 next=M13-02A`.
|
||||
- `CHROME_PATH=/usr/bin/google-chrome-stable WEB_TEST_PORT=5499 node_modules/.bin/playwright test
|
||||
--config playwright.config.ts --workers=1 tests/e2e/malicious-script.spec.ts` passed 1/1.
|
||||
- `git diff --check` passed.
|
||||
|
||||
## Artifact Hashes
|
||||
|
||||
- generator: `013285befeb59de21a887cefd377adf8cf53ff1c785b28a9c87d29f76f092731`
|
||||
- checker: `36608da893ae59e2e03856a62866ea6e7c349ec4a63200f042b2329e5f61caa9`
|
||||
- e2e: `98fbde6728ddf55cce5262522197a5b4db1dfce618e52259bf0b0c9e0e9165f2`
|
||||
- report: `a628b73411d6f9a761f659ae28867ea9b0c0df30d47668353278b70d4b44180c`
|
||||
- fixture: `7b1921931afc5bb74a2b73e90b175017c583ea878cdbb66f131718b2d8cd23b5`
|
||||
- manifest: `9a0b7c4097b3755365a9fb92b4848e6ac2ddd36ee2c7e9df3cb8808ce247cf3d`
|
||||
|
||||
## Next Task
|
||||
|
||||
`M13-02A`: bounded script manifest limits.
|
||||
|
||||
## Rollback
|
||||
|
||||
Remove the generator, checker, fixture, report, manifest, e2e test, and this status entry. Restore
|
||||
M13-01E as the queue tail and move the machine queue back to M13-01F. No parity ledger rollback is required.
|
||||
49
docs/status/M13-02A.md
Normal file
49
docs/status/M13-02A.md
Normal file
@@ -0,0 +1,49 @@
|
||||
# M13-02A Status
|
||||
|
||||
status: done
|
||||
task: bounded script manifest limits
|
||||
updated: 2026-08-18 America/New_York
|
||||
enablingTask: false
|
||||
parityStateChange: false
|
||||
|
||||
## Scope
|
||||
|
||||
The production scripting manifest parser now requires an explicit `sourceByteLength` and
|
||||
`module=false` for every script. It limits script count, aggregate source bytes, dependency count,
|
||||
permission count and per-field execution budgets; canonicalizes entry/dependency paths within the
|
||||
project; and rejects duplicate dependencies, unsafe paths, module execution, unknown permissions
|
||||
and all budget overflow. The parser remains fail-closed and does not execute script content.
|
||||
|
||||
## Evidence
|
||||
|
||||
- `node --test web/tests/unit/script-manifest-budgets.test.mjs` passed 4/4 bounded positive and
|
||||
negative cases.
|
||||
- `WEB_TEST_PORT=5513 npm --prefix web run test:script-manifest-budgets` passed unit 4/4 and the
|
||||
production Chromium Worker test 1/1. The browser Worker returned the same canonical paths,
|
||||
aggregate byte count and stable policy/budget errors as the Node protocol test.
|
||||
- `node tools/web/check-script-manifest-budgets.mjs` passed:
|
||||
`script-manifest-budgets-ok accepted=2 totalSourceBytes=256 blocked=6 deterministic=true next=M13-02B`.
|
||||
- `npm --prefix web run typecheck`, `npm --prefix web run lint`,
|
||||
`npm --prefix web run build`, `npm --prefix web run test:scripting-isolation`, and
|
||||
`git diff --check` passed. The existing isolation gate still reports approved-key
|
||||
`SCRIPT_SANDBOX_UNAVAILABLE` and does not enable execution.
|
||||
|
||||
## Artifact Hashes
|
||||
|
||||
- protocol: `6699fc0a19e0736823f164e707a420655803e36019cf0071f7ff9c760d25e9f2`
|
||||
- worker: `8d8eae67fa6915f0337850e15247baf01f0abde0b3362fbb120f0b448f1a4cf5`
|
||||
- checker: `b3457324d72ab233cd17a142ea19fac6a0d024dd95de7b8fb5d26810437fb0d2`
|
||||
- unit: `6ce7847a0b745ba4081e4332d012e0b7f86e4906c71c95bdeda8c39977a630ee`
|
||||
- e2e: `1ef4fd4caaeb1fa3d832fc8881823d5284755372575eab186c751f408dc9314c`
|
||||
- report: `860672fe844b7969ca376d4b2708771189d1767efa819f7b97667d8a26438d3a`
|
||||
- manifest: `7148e0387dadffdb55e94e80dc30cfd5cdd40ebe990d06378e90c376d36ebd51`
|
||||
|
||||
## Next Task
|
||||
|
||||
`M13-02B`: canonical serialization fixes the signature input.
|
||||
|
||||
## Rollback
|
||||
|
||||
Remove the M13-02A protocol fields, checker, unit/Chromium tests, worker, report, manifest and this
|
||||
status entry. Restore M13-01F as the queue tail and move the machine queue back to M13-02A. No parity
|
||||
ledger rollback is required.
|
||||
52
docs/status/M13-02B.md
Normal file
52
docs/status/M13-02B.md
Normal file
@@ -0,0 +1,52 @@
|
||||
# M13-02B Status
|
||||
|
||||
status: done
|
||||
task: canonical script manifest serialization
|
||||
updated: 2026-08-18 America/New_York
|
||||
enablingTask: false
|
||||
parityStateChange: false
|
||||
|
||||
## Scope
|
||||
|
||||
The scripting protocol now exposes `canonicalizeScriptingManifest` and
|
||||
`serializeScriptingManifest` as the single canonical signature-input path. Script, permission and
|
||||
dependency arrays are sorted with locale-independent code-unit ordering; unknown fields are removed
|
||||
by the parser; canonical JSON has sorted object keys and no whitespace; and security-relevant fields
|
||||
such as source byte length, source hash, permissions, paths, budgets and policy flags remain in the
|
||||
serialized input. Schema changes and source declaration mutations produce a different or rejected
|
||||
input. No signature is accepted and no script is executed by this task.
|
||||
|
||||
## Evidence
|
||||
|
||||
- `node --test web/tests/unit/script-manifest-canonical.test.mjs` passed 2/2. It proves order
|
||||
invariance, unknown-field dropping, security-field binding and schema rejection.
|
||||
- `WEB_TEST_PORT=5514 npm --prefix web run test:script-manifest-canonical` passed unit 2/2 and
|
||||
production Chromium Worker 1/1.
|
||||
- `node tools/web/check-script-manifest-canonical.mjs` passed:
|
||||
`script-manifest-canonical-ok equal=true bytes=1923 unknownDropped=true schemaMutation=blocked next=M13-02C`.
|
||||
- `npm --prefix web run typecheck`, `npm --prefix web run lint`, `npm --prefix web run build`,
|
||||
`node tools/web/check-script-manifest-budgets.mjs`, `node tools/web/check-status-consistency.mjs`
|
||||
and `git diff --check` passed. The M13-02A artifact manifest was refreshed to the current protocol
|
||||
hash after this additive canonical API change, and its checker was rerun successfully; no prior
|
||||
behavior or parity status was changed.
|
||||
|
||||
## Artifact Hashes
|
||||
|
||||
- protocol: `6699fc0a19e0736823f164e707a420655803e36019cf0071f7ff9c760d25e9f2`
|
||||
- worker: `de27fdcd6d16e27a07806ac609f908edfdb7a93d653676174cdd5e06ffa394af`
|
||||
- checker: `5ed344cab6428ae5538a450171ba40c73ff738666515492298e30aaed1394f56`
|
||||
- unit: `33eae0f3ad2ae7243c9ce2835ab8e42186f65f574ab682099766f1d0f4c481f6`
|
||||
- e2e: `5342301165ae82a01b46f5fed0cc0ec34b9813a6ecbc8032900d90b89628e064`
|
||||
- report: `5f4bc0b098ea65de47f1255d30130376d74260e2b912bcd0e28354171fbd07df`
|
||||
- parent manifest: `7148e0387dadffdb55e94e80dc30cfd5cdd40ebe990d06378e90c376d36ebd51`
|
||||
- manifest: `605c656780a206a0d3b81d06b0294108b488a62d2b709e886884a2973c6cb091`
|
||||
|
||||
## Next Task
|
||||
|
||||
`M13-02C`: signer identity, key rotation, revocation and timestamp policy.
|
||||
|
||||
## Rollback
|
||||
|
||||
Remove the canonical serializer exports, checker, unit/Chromium tests, worker, report, manifest and
|
||||
this status entry; restore M13-02A as the queue tail and move the machine queue back to M13-02B. No
|
||||
parity ledger rollback is required.
|
||||
51
docs/status/M13-02C.md
Normal file
51
docs/status/M13-02C.md
Normal file
@@ -0,0 +1,51 @@
|
||||
# M13-02C Status
|
||||
|
||||
status: done
|
||||
task: signer identity, key rotation, revocation and timestamp policy
|
||||
updated: 2026-08-18 America/New_York
|
||||
enablingTask: false
|
||||
parityStateChange: false
|
||||
|
||||
## Scope
|
||||
|
||||
The scripting protocol now has a versioned trust-policy schema for signer identity and key
|
||||
lifecycles. It validates ED25519 public-key identity, publisher ownership, active/revoked status,
|
||||
not-before/not-after windows, revocation timestamps, same-publisher rotation predecessors and
|
||||
acyclic rotation chains. `maxClockSkewMs` binds policy timestamps to an explicit bounded window.
|
||||
`resolveScriptSigner` only returns `ELIGIBLE` with `cryptographicVerification=REQUIRED`; revoked,
|
||||
expired, not-yet-valid, missing and publisher-confused keys remain structured `BLOCKED` results.
|
||||
This task does not verify signatures or enable script execution.
|
||||
|
||||
## Evidence
|
||||
|
||||
- `node --test web/tests/unit/script-trust-policy.test.mjs` passed 3/3. It covers valid active
|
||||
rotation, revoked predecessor, invalid/cross-publisher/cyclic rotation, revocation metadata,
|
||||
public-key format and timestamp failures.
|
||||
- `WEB_TEST_PORT=5516 npm --prefix web run test:script-trust-policy` passed unit 3/3 and production
|
||||
Chromium Worker 1/1.
|
||||
- `node tools/web/check-script-trust-policy.mjs` passed:
|
||||
`script-trust-policy-ok active=key:new revoked=REVOKED crossPublisher=SCRIPT_POLICY_DENIED policyExpired=POLICY_EXPIRED crypto=REQUIRED next=M13-02D`.
|
||||
- `npm --prefix web run typecheck` passed; M13-02A and M13-02B checkers were rerun after the
|
||||
additive protocol change and passed. No parity ledger or execution route changed.
|
||||
|
||||
## Artifact Hashes
|
||||
|
||||
- protocol: `6699fc0a19e0736823f164e707a420655803e36019cf0071f7ff9c760d25e9f2`
|
||||
- worker: `c6e206b29e7cacc3e23e2ac12a3d523a9c0b16ff29759126dab13c8665547421`
|
||||
- checker: `0e55ce20d142f2bcbc5ce9c6fb955ef2771d284dff636c79da3f59a33b8b0aeb`
|
||||
- unit: `59ac77bcc1086e0a0e914cb77d647db5d34c7160202e7aad52948b7277769551`
|
||||
- e2e: `614091bda15367090bc78a6f465fb10d02d0aa08775b5088699b12e2490034d2`
|
||||
- report: `0f59f733920edbbe5cb799e5f50ff31d19e55ced98e7a890828f6337a237e4bd`
|
||||
- unit: `aac3ff0a1c7ae27e35112614bedabc02bb248882ec9b0b52d65f9794d06830d8`
|
||||
- parent manifest: `605c656780a206a0d3b81d06b0294108b488a62d2b709e886884a2973c6cb091`
|
||||
- manifest: `89745daca88371335f4bd56982791266461082066c6c1345056fbc697bb7e6a2`
|
||||
|
||||
## Next Task
|
||||
|
||||
`M13-02D`: signature only approves declared content and source hash changes invalidate it.
|
||||
|
||||
## Rollback
|
||||
|
||||
Remove the trust-policy schema, parser/resolver, checker, unit/Chromium tests, worker, report,
|
||||
manifest and this status entry; restore M13-02B as the queue tail and move the machine queue back to
|
||||
M13-02C. No parity ledger rollback is required.
|
||||
46
docs/status/M13-02D.md
Normal file
46
docs/status/M13-02D.md
Normal file
@@ -0,0 +1,46 @@
|
||||
# M13-02D Status
|
||||
|
||||
status: done
|
||||
task: signature verification binds declared content
|
||||
updated: 2026-08-18 America/New_York
|
||||
enablingTask: false
|
||||
parityStateChange: false
|
||||
|
||||
## Scope
|
||||
|
||||
`verifyScriptManifestSignature` now verifies the canonical per-script manifest input with the
|
||||
trusted ED25519 key. The input includes the declared source SHA-256 and all policy-relevant fields,
|
||||
while excluding only the signature field itself. A source hash or signature mutation therefore
|
||||
returns `SCRIPT_SIGNATURE_INVALID`; revoked or otherwise ineligible keys return
|
||||
`SCRIPT_POLICY_DENIED`. Verification remains a policy gate and does not enable script execution.
|
||||
|
||||
## Evidence
|
||||
|
||||
- `node --test --test-name-pattern=M13-02D web/tests/unit/script-trust-policy.test.mjs` passed the
|
||||
M13-02D case (1 passed, 3 unrelated cases skipped).
|
||||
- `WEB_TEST_PORT=5520 npm --prefix web run test:script-signature` passed the focused Node case and
|
||||
production Chromium Worker E2E (1/1).
|
||||
- `node tools/web/check-script-signature.mjs` passed:
|
||||
`script-signature-ok verified=SCRIPT_SIGNATURE_VERIFIED sourceHashChanged=SCRIPT_SIGNATURE_INVALID revoked=SCRIPT_POLICY_DENIED next=M13-02E`.
|
||||
- `npm --prefix web run typecheck`, `npm --prefix web run lint`, `npm --prefix web run build` and
|
||||
`git diff --check` passed.
|
||||
|
||||
## Artifact Hashes
|
||||
|
||||
- protocol: `6699fc0a19e0736823f164e707a420655803e36019cf0071f7ff9c760d25e9f2`
|
||||
- worker: `f4e8ff45d06efcfa9e634ef28e654241d70554ed05dfe9c3fecd9f6eef166ce0`
|
||||
- checker: `2d6e7b403dd6d401eb1a41978016b40bd1fb86120464e09f185de4445c177fa4`
|
||||
- unit: `aac3ff0a1c7ae27e35112614bedabc02bb248882ec9b0b52d65f9794d06830d8`
|
||||
- e2e: `8a882fc8fa2c0c4e2eab3660810cec0f60d2f7475f62a1bb406fc3b2bdf60882`
|
||||
- report: `957daf8e5899714cc5ce253b1f0fb2b258f1cc966238fff31e2626f8f56feb3a`
|
||||
- manifest: `c6b79a77e4b7ffe5f4a9ba785a30305f9cf6e86caf89b38a4b303a86ab662a31`
|
||||
|
||||
## Next Task
|
||||
|
||||
`M13-02E`: permission default-minimization and unknown-permission blocking.
|
||||
|
||||
## Rollback
|
||||
|
||||
Remove the M13-02D checker, report, manifest, status entry and focused package command; restore
|
||||
M13-02C as the queue tail and move the machine queue back to `M13-02D`. No parity ledger rollback
|
||||
is required.
|
||||
42
docs/status/M13-02E.md
Normal file
42
docs/status/M13-02E.md
Normal file
@@ -0,0 +1,42 @@
|
||||
# M13-02E Status
|
||||
|
||||
status: done
|
||||
task: permission default-minimization and unknown-permission blocking
|
||||
updated: 2026-08-18 America/New_York
|
||||
enablingTask: false
|
||||
parityStateChange: false
|
||||
|
||||
## Scope
|
||||
|
||||
`resolveScriptPermissions` now grants an empty set by default and only grants an explicitly
|
||||
requested permission when it is already declared by the script manifest. Unknown, duplicate or
|
||||
undeclared requests return `SCRIPT_POLICY_DENIED`; manifest declarations still reject unknown
|
||||
permissions during parsing. This task adds no execution capability.
|
||||
|
||||
## Evidence
|
||||
|
||||
- `node --test web/tests/unit/script-permission-policy.test.mjs` passed 2/2.
|
||||
- `WEB_TEST_PORT=5521 npm --prefix web run test:script-permission-policy` passed unit 2/2 and
|
||||
production Chromium Worker E2E 1/1.
|
||||
- `node tools/web/check-script-permission-policy.mjs` passed:
|
||||
`script-permission-policy-ok defaultGranted=0 declared=READ_MAIN escalation=SCRIPT_POLICY_DENIED unknown=SCRIPT_POLICY_DENIED next=M13-02F`.
|
||||
- `npm --prefix web run typecheck`, `npm --prefix web run lint` and `git diff --check` passed.
|
||||
|
||||
## Artifact Hashes
|
||||
|
||||
- protocol: `6699fc0a19e0736823f164e707a420655803e36019cf0071f7ff9c760d25e9f2`
|
||||
- worker: `5df074e676542475009a4980fecaf3fdde009d149de84b9ca146647fb6aa1c02`
|
||||
- checker: `169ab096295e08c5a630ef09d814da6ce742efd7a7143ff9a17984b4ca20593a`
|
||||
- unit: `43bb6796616f3f92d71b51ef2a119a4e263864121a03356764e4b9c9241c4043`
|
||||
- e2e: `dc13412a44f277bbe68315da0d38a2c4aa520d7489c81e7c908f9768c0547b7e`
|
||||
- report: `8dc41e75620ba5bcb08d0edc52c3994e4f4dbc37ad3633757634bf10fe97b252`
|
||||
- manifest: `691376d3cd33d3cd339b7195034abaf89cc02fba7e740c40ff051c4496400eef`
|
||||
|
||||
## Next Task
|
||||
|
||||
`M13-02F`: replay, key-confusion, expiry and multi-signature negative cases.
|
||||
|
||||
## Rollback
|
||||
|
||||
Remove `resolveScriptPermissions`, the focused worker/unit/E2E/checker, report, manifest, status
|
||||
entry and package command; restore M13-02D as the queue tail and move `nextTask` back to `M13-02E`.
|
||||
42
docs/status/M13-02F.md
Normal file
42
docs/status/M13-02F.md
Normal file
@@ -0,0 +1,42 @@
|
||||
# M13-02F Status
|
||||
|
||||
status: done
|
||||
task: signature replay, key-confusion and expiry negative cases
|
||||
updated: 2026-08-18 America/New_York
|
||||
enablingTask: false
|
||||
parityStateChange: false
|
||||
|
||||
## Scope
|
||||
|
||||
The signature gate now has an independent negative-case matrix covering missing keys, expired and
|
||||
not-yet-valid keys, publisher/key confusion, and a signature copied to a different script. Every
|
||||
case remains fail-closed with `SCRIPT_POLICY_DENIED` or `SCRIPT_SIGNATURE_INVALID`; no execution
|
||||
route is added. Canonical script ordering remains accepted when the script's own signature matches.
|
||||
|
||||
## Evidence
|
||||
|
||||
- `node --test web/tests/unit/script-signature-negative.test.mjs` passed 2/2.
|
||||
- `WEB_TEST_PORT=5522 npm --prefix web run test:script-signature-negative` passed unit 2/2 and
|
||||
production Chromium Worker E2E 1/1.
|
||||
- `node tools/web/check-script-signature-negative.mjs` passed:
|
||||
`script-signature-negative-ok missing=SCRIPT_POLICY_DENIED expired=SCRIPT_POLICY_DENIED notYetValid=SCRIPT_POLICY_DENIED swapped=SCRIPT_SIGNATURE_INVALID next=M13-03A`.
|
||||
- `npm --prefix web run typecheck`, `npm --prefix web run lint` and `git diff --check` passed.
|
||||
|
||||
## Artifact Hashes
|
||||
|
||||
- protocol: `6699fc0a19e0736823f164e707a420655803e36019cf0071f7ff9c760d25e9f2`
|
||||
- worker: `49b289110a6533fcd1a29ad78be00792fd3c0d251c6027bae0440f5daba929a1`
|
||||
- checker: `35f2e6727aef5e6ea2e2623e2effa6ea0356faaf66d417976db7f5bbe671a38c`
|
||||
- unit: `8b9c8d63c97fce07299622b9ad261791a97bb91a6ed340e72c24c55e685978bd`
|
||||
- e2e: `26c52ef67d6b1ea2994d92637826994e98e5234e042049f8d69a905f5cdb3309`
|
||||
- report: `d23a2ae5613b2442ad79420aa344ebfe3767d10ac19b3ea30a62afcccd3a167c`
|
||||
- manifest: `283673b21e6c9b89dc6ecb7007f3cecf28d53a84ec84f3f8b52373c055538a74`
|
||||
|
||||
## Next Task
|
||||
|
||||
`M13-03A`: sandbox capability scope with no DOM, host-worker, OPFS, IndexedDB or network access.
|
||||
|
||||
## Rollback
|
||||
|
||||
Remove the M13-02F negative-case worker, tests, checker, report, manifest, status entry and package
|
||||
command; restore M13-02E as the queue tail and move `nextTask` back to `M13-02F`.
|
||||
42
docs/status/M13-03A.md
Normal file
42
docs/status/M13-03A.md
Normal file
@@ -0,0 +1,42 @@
|
||||
# M13-03A Status
|
||||
|
||||
status: done
|
||||
task: sandbox capability scope
|
||||
updated: 2026-08-18 America/New_York
|
||||
enablingTask: false
|
||||
parityStateChange: false
|
||||
|
||||
## Scope
|
||||
|
||||
The production scripting protocol now defines a versioned all-deny sandbox scope. DOM, host-worker,
|
||||
OPFS, IndexedDB and network capabilities must each be explicitly `false`; any enabled, missing or
|
||||
unknown scope version is rejected with a stable policy/protocol error. This is a capability contract
|
||||
only: script execution remains disabled and no sandbox implementation is claimed.
|
||||
|
||||
## Evidence
|
||||
|
||||
- `node --test web/tests/unit/script-sandbox-scope.test.mjs` passed 2/2.
|
||||
- `WEB_TEST_PORT=5523 npm --prefix web run test:script-sandbox-scope` passed unit 2/2 and
|
||||
production Chromium Worker E2E 1/1.
|
||||
- `node tools/web/check-script-sandbox-scope.mjs` passed:
|
||||
`script-sandbox-scope-ok dom=SCRIPT_POLICY_DENIED hostWorker=SCRIPT_POLICY_DENIED opfs=SCRIPT_POLICY_DENIED indexedDB=SCRIPT_POLICY_DENIED network=SCRIPT_POLICY_DENIED execution=DISABLED next=M13-03B`.
|
||||
- `npm --prefix web run typecheck`, `npm --prefix web run lint` and `git diff --check` passed.
|
||||
|
||||
## Artifact Hashes
|
||||
|
||||
- protocol: `6699fc0a19e0736823f164e707a420655803e36019cf0071f7ff9c760d25e9f2`
|
||||
- worker: `27058fbb602791cbe6691fa14b3bc9c3d6cdea79641ba9c72fe18b6226d2a651`
|
||||
- checker: `ad26ea3b078e480ba8f99cbf8dbd0d9b135c7605f4a3958d24845b7f5f8b0f43`
|
||||
- unit: `a15da2e645d2d681c7e9ac1380f6b224d196d1d2e78d20f1bacad01e138753d4`
|
||||
- e2e: `49930747e6663f79b61093706318b72e59388d79e3e1cc105bc1571693326667`
|
||||
- report: `ba5784c751d5a347f38aa522ffcbed270d38fb474f0f10a2d06ea501d0234021`
|
||||
- manifest: `76a7ce0fd3a38fb770c9cedccbd05ed566b931caa1782fdae898d3b66c3a20bf`
|
||||
|
||||
## Next Task
|
||||
|
||||
`M13-03B`: fixed CPU, wall-time, memory, message and output-byte budgets.
|
||||
|
||||
## Rollback
|
||||
|
||||
Remove the sandbox scope parser, focused worker/tests/checker, report, manifest, status entry and
|
||||
package command; restore M13-02F as the queue tail and move `nextTask` back to `M13-03A`.
|
||||
41
docs/status/M13-03B.md
Normal file
41
docs/status/M13-03B.md
Normal file
@@ -0,0 +1,41 @@
|
||||
# M13-03B Status
|
||||
|
||||
status: done
|
||||
task: sandbox CPU, wall, memory, message and output budgets
|
||||
updated: 2026-08-18 America/New_York
|
||||
enablingTask: false
|
||||
parityStateChange: false
|
||||
|
||||
## Scope
|
||||
|
||||
The scripting protocol now parses bounded CPU, wall-time, memory, message and output-byte budgets.
|
||||
Each field has a fixed maximum and all overflow or schema drift returns `SCRIPT_BUDGET_EXCEEDED` or
|
||||
`PROTOCOL_MISMATCH`. The budget is a contract only; execution remains disabled.
|
||||
|
||||
## Evidence
|
||||
|
||||
- `node --test web/tests/unit/script-sandbox-budget.test.mjs` passed 2/2.
|
||||
- `WEB_TEST_PORT=5524 npm --prefix web run test:script-sandbox-budget` passed unit 2/2 and
|
||||
production Chromium Worker E2E 1/1.
|
||||
- `node tools/web/check-script-sandbox-budget.mjs` passed:
|
||||
`script-sandbox-budget-ok cpu=SCRIPT_BUDGET_EXCEEDED wall=SCRIPT_BUDGET_EXCEEDED memory=SCRIPT_BUDGET_EXCEEDED message=SCRIPT_BUDGET_EXCEEDED output=SCRIPT_BUDGET_EXCEEDED execution=DISABLED next=M13-03C`.
|
||||
- `npm --prefix web run typecheck`, `npm --prefix web run lint` and `git diff --check` passed.
|
||||
|
||||
## Artifact Hashes
|
||||
|
||||
- protocol: `6699fc0a19e0736823f164e707a420655803e36019cf0071f7ff9c760d25e9f2`
|
||||
- worker: `ed836a032b33f54154fdd36f9f6e99ee43ca1755ea0dd8326474a13300ec965e`
|
||||
- checker: `ab10d1d32c20022c848be4b33e1be846168a9ca4cf22ac932ea000001e9e2391`
|
||||
- unit: `caa40fc58a73aa4d433285c94009e5436a29fbcb6b4e18b74b27c49fd0b07490`
|
||||
- e2e: `8be77fd55e76149bfe2e0e449d81a62707ebfa430514936808ec4805fc96e07c`
|
||||
- report: `4355710e07e95cbb0f96a82fdefca3607f363d3aea9ba89c332e8a4708b7bed2`
|
||||
- manifest: `b61978c22cdfffe81b812e2eea788d52326f9f0ebb4540e77f86dc9e19ff21dd`
|
||||
|
||||
## Next Task
|
||||
|
||||
`M13-03C`: host calls use explicit allowlist and structured parameters.
|
||||
|
||||
## Rollback
|
||||
|
||||
Remove the sandbox budget parser, focused worker/tests/checker, report, manifest, status entry and
|
||||
package command; restore M13-03A as the queue tail and move `nextTask` back to `M13-03B`.
|
||||
43
docs/status/M13-03C.md
Normal file
43
docs/status/M13-03C.md
Normal file
@@ -0,0 +1,43 @@
|
||||
# M13-03C Status
|
||||
|
||||
status: done
|
||||
task: explicit host-call allowlist and structured parameters
|
||||
updated: 2026-08-18 America/New_York
|
||||
enablingTask: false
|
||||
parityStateChange: false
|
||||
|
||||
## Scope
|
||||
|
||||
The production scripting protocol now accepts only five host-call names: `READ_MAIN`, `READ_ASSET`,
|
||||
`WRITE_MAIN`, `WRITE_ASSET` and `SUBMIT_SERVER_JOB`. Each request has a version, request/script IDs,
|
||||
permission binding and call-specific structured parameters. Unknown calls, permission confusion,
|
||||
unknown fields, unsafe paths and malformed payloads fail closed. Parsed calls remain
|
||||
`execution=DISABLED`; no host operation is invoked.
|
||||
|
||||
## Evidence
|
||||
|
||||
- `node --test web/tests/unit/script-host-call.test.mjs` passed 3/3.
|
||||
- `WEB_TEST_PORT=5525 npm --prefix web run test:script-host-call` passed unit 3/3 and production
|
||||
Chromium Worker E2E 1/1.
|
||||
- `node tools/web/check-script-host-call.mjs` passed:
|
||||
`script-host-call-ok accepted=5 blocked=4 structured=true execution=DISABLED next=M13-03D`.
|
||||
- `npm --prefix web run typecheck`, `npm --prefix web run lint` and `git diff --check` passed.
|
||||
|
||||
## Artifact Hashes
|
||||
|
||||
- protocol: `6699fc0a19e0736823f164e707a420655803e36019cf0071f7ff9c760d25e9f2`
|
||||
- worker: `b26a37f20e829172bb70fbe9b9e3a194923818127cccbe8bbc55f6d994be55e8`
|
||||
- checker: `e90042f4eefd9e89da6d1cead87ca1cb9db9b3bd65ba8028593e093903577e2e`
|
||||
- unit: `e7679cd902c75504204d528343e4fa6be316d1c56c02b2871a67637aa847a1ec`
|
||||
- e2e: `7b17a7da440aee07895101efb8e1eb13bfbebbe54e955bde09299f6b33d6aaf9`
|
||||
- report: `afb140a3aecff1de52c4363e7cd0ce476b0c9140ffdc016ec13a085049f6dd1a`
|
||||
- manifest: `54318c45b11dd1707fecf78b0637257158102ea1dbb88d4d442e33b77df2cdbf`
|
||||
|
||||
## Next Task
|
||||
|
||||
`M13-03D`: sandbox crash/timeout terminates the job without changing Main revision.
|
||||
|
||||
## Rollback
|
||||
|
||||
Remove the host-call parser, focused worker/tests/checker, report, manifest, status entry and package
|
||||
command; restore M13-03B as the queue tail and move `nextTask` back to `M13-03C`.
|
||||
46
docs/status/M13-03D.md
Normal file
46
docs/status/M13-03D.md
Normal file
@@ -0,0 +1,46 @@
|
||||
# M13-03D Status
|
||||
|
||||
status: done
|
||||
task: sandbox crash/timeout isolation
|
||||
updated: 2026-08-18 America/New_York
|
||||
enablingTask: false
|
||||
parityStateChange: false
|
||||
|
||||
## Scope
|
||||
|
||||
The sandbox job termination receipt now converts crash, wall-time timeout and cancellation into
|
||||
stable fail-closed statuses. Every terminated receipt keeps `mainRevisionAfter` equal to
|
||||
`mainRevisionBefore`, publishes no result, releases temporary bytes, and remains
|
||||
`execution=DISABLED`; a result received after termination is rejected with
|
||||
`SCRIPT_SANDBOX_LATE_RESULT`.
|
||||
|
||||
The Chromium test starts a production Worker that throws for the crash case and a production Worker
|
||||
that would publish a delayed result for the timeout case. The host observes the crash, terminates the
|
||||
timeout Worker before its delayed message, and confirms no late message arrives.
|
||||
|
||||
## Evidence
|
||||
|
||||
- `node --test web/tests/unit/script-sandbox-isolation.test.mjs` passed 3/3.
|
||||
- `CHROME_PATH=/usr/bin/google-chrome-stable WEB_TEST_PORT=5532 npm --prefix web run test:script-sandbox-isolation` passed unit 3/3 and Chromium Worker E2E 1/1.
|
||||
- `node tools/web/check-script-sandbox-isolation.mjs` passed:
|
||||
`script-sandbox-isolation-ok crash=SCRIPT_SANDBOX_CRASHED timeout=SCRIPT_SANDBOX_TIMEOUT revisionUnchanged=true late=SCRIPT_SANDBOX_LATE_RESULT next=M13-03E`.
|
||||
- `npm --prefix web run typecheck` and `git diff --check` passed.
|
||||
|
||||
## Artifact Hashes
|
||||
|
||||
- protocol: `6699fc0a19e0736823f164e707a420655803e36019cf0071f7ff9c760d25e9f2`
|
||||
- worker: `8c810ee7c8bd15d83ecfb4981068f947536bfe8c9e63b906861f42b8465722da`
|
||||
- checker: `e5c0c3c7cd500c269ae43a1a9eb05589e82aad28199ab4f11ad1167b486f6937`
|
||||
- unit: `47986f93638fdc18b817b03222484f4691dc294185040eaebac8e1f386bc1549`
|
||||
- e2e: `2c16c42f09827a0c0100ef2cc6295ca6bc96933ed7475e08b1fa195d7940c141`
|
||||
- report: `4af91cdb21101039b379136c7559b46df55f4f5ab5478c05c1c57cd6e1624d2a`
|
||||
- manifest: `8066013f3d356ba438c36d1f1ea1cf692dbb4f60b086f552072e36b783a96d42`
|
||||
|
||||
## Next Task
|
||||
|
||||
`M13-03E`: cancellation after termination must not publish a late message or cache.
|
||||
|
||||
## Rollback
|
||||
|
||||
Remove the isolation Worker additions, focused tests/checker, report, manifest and this status entry;
|
||||
restore M13-03C as the queue tail and move `nextTask` back to `M13-03D`.
|
||||
45
docs/status/M13-03E.md
Normal file
45
docs/status/M13-03E.md
Normal file
@@ -0,0 +1,45 @@
|
||||
# M13-03E Status
|
||||
|
||||
status: done
|
||||
task: sandbox cancellation result gate
|
||||
updated: 2026-08-19 America/New_York
|
||||
enablingTask: false
|
||||
parityStateChange: false
|
||||
|
||||
## Scope
|
||||
|
||||
Cancellation now has an explicit terminated-job receipt. The receipt preserves the Main revision,
|
||||
publishes no result, releases temporary bytes and remains `execution=DISABLED`. The production
|
||||
Chromium Worker schedules a late message containing a cache key; the host cancels and terminates it
|
||||
before publication, then observes a bounded late window with zero messages and zero cache writes.
|
||||
Late results supplied after cancellation are rejected with `SCRIPT_SANDBOX_LATE_RESULT`.
|
||||
|
||||
This task does not claim Worker/port/timer disposal or same-session recovery; those remain M13-03F/G.
|
||||
|
||||
## Evidence
|
||||
|
||||
- `node --test web/tests/unit/script-sandbox-cancellation.test.mjs` passed 2/2.
|
||||
- `CHROME_PATH=/usr/bin/google-chrome-stable WEB_TEST_PORT=5533 npm --prefix web run test:script-sandbox-cancellation` passed unit 2/2 and Chromium Worker E2E 1/1.
|
||||
- `node tools/web/check-script-sandbox-cancellation.mjs` passed:
|
||||
`script-sandbox-cancellation-ok status=CANCELLED late=SCRIPT_SANDBOX_LATE_RESULT lateMessages=0 cacheWrites=0 next=M13-03F`.
|
||||
- `npm --prefix web run typecheck`, `npm --prefix web run lint` and `git diff --check` passed.
|
||||
|
||||
## Artifact Hashes
|
||||
|
||||
- protocol: `6699fc0a19e0736823f164e707a420655803e36019cf0071f7ff9c760d25e9f2`
|
||||
- worker: `0feb70c8c491cc24ebfe6c3e267b92522d616b6f260efcecfa57cf489d0742c0`
|
||||
- checker: `b6fbe7102b7d0808673931c66797f8976e79b21bd4c32e429f21832c6090708e`
|
||||
- unit: `374cc87f66bd42226b750e387663ef8c86bef92348fa7cbc6ed7f0027945204d`
|
||||
- e2e: `b233d9cafa1f70798ec19d76ca936abb610681522264a12237f532eb98e09fca`
|
||||
- package: `6499a70fc4a93c925053ddf5009c74d9c10754b443afc9d58e898fe20d7f1b05`
|
||||
- report: `066d9f19716b8229f2cf7755ec3009a3edef942ebab5f70159bec7f2afbaf71f`
|
||||
- manifest: `0cdf625e6bd3ed7aca43318a3b04353cb806c51cfa4cf3c5dae9a65a0eae2e69`
|
||||
|
||||
## Next Task
|
||||
|
||||
`M13-03F`: dispose Worker, MessagePort, timers, abort controllers and buffers to zero.
|
||||
|
||||
## Rollback
|
||||
|
||||
Remove the cancellation Worker, focused tests/checker, report, manifest, package command and this
|
||||
status entry; restore M13-03D as the queue tail and move `nextTask` back to `M13-03E`.
|
||||
44
docs/status/M13-03F.md
Normal file
44
docs/status/M13-03F.md
Normal file
@@ -0,0 +1,44 @@
|
||||
# M13-03F Status
|
||||
|
||||
status: done
|
||||
task: sandbox resource disposal gate
|
||||
updated: 2026-08-19 America/New_York
|
||||
enablingTask: false
|
||||
parityStateChange: false
|
||||
|
||||
## Scope
|
||||
|
||||
The sandbox Worker now owns an explicit disposal receipt. Both `MessagePort` endpoints, the timer,
|
||||
`AbortController`, transferable buffer, pending request and cache reference are observed before
|
||||
disposal and are all zero after the first dispose. A second dispose is accepted and reports
|
||||
`idempotent=true`; the cleared timer produces no late message. Script execution remains
|
||||
`DISABLED`, and this task does not claim same-session recovery or server isolation.
|
||||
|
||||
## Evidence
|
||||
|
||||
- `node --test web/tests/unit/script-sandbox-dispose.test.mjs` passed 2/2.
|
||||
- `CHROME_PATH=/usr/bin/google-chrome-stable WEB_TEST_PORT=5534 npm --prefix web run test:script-sandbox-dispose` passed unit 2/2 and Chromium Worker E2E 1/1.
|
||||
- `node tools/web/check-script-sandbox-dispose.mjs` passed:
|
||||
`script-sandbox-dispose-ok ports=0 timers=0 abortControllers=0 buffers=0 pending=0 cacheReferences=0 idempotent=true next=M13-03G`.
|
||||
- `npm --prefix web run typecheck`, `npm --prefix web run lint` and `git diff --check` passed.
|
||||
|
||||
## Artifact Hashes
|
||||
|
||||
- protocol: `f3d9f667c3809cfad0f52bc6028d93e36e25c4b639fb6081c9c933fbad0ebc0a`
|
||||
- worker: `2a074b05d301c4083e60534eb9452aabf5d95aea0ab316fa657441ef4bcd5c96`
|
||||
- checker: `6549bd10f588281d23c4bea705fd164252c9e3f44d8f4b93c893a2c410907135`
|
||||
- unit: `6e00aa6286aae0eabc1345c04c7628dcc9acb32d51c1c27436a0e1b4c170b64c`
|
||||
- e2e: `b240d92c90e0d81272cd9cb3c0eb4e7d77102ce2e49ad05c761f763d1812b18e`
|
||||
- package: `0f06cd7ccdeed4213b6cb956aecf94e60dceff811ad8c3a2e239397685cfc1bf`
|
||||
- report: `2dbd3e79939b500c0fc83216c51f258b88ead42a667ed1a6da755e893d7f73c6`
|
||||
- manifest: `96abc7c7613ef4c18c64b84ffb8420c39369f9e4733bd1fa4d7d9ee9e53d6f89`
|
||||
|
||||
## Next Task
|
||||
|
||||
`M13-03G`: recover a small script in the same session with a new Worker generation while keeping
|
||||
the Main revision/source hash stable and extending the audit hash chain.
|
||||
|
||||
## Rollback
|
||||
|
||||
Remove the dispose protocol, Worker, focused tests/checker, report, manifest, package command and
|
||||
this status entry; restore M13-03E as the queue tail and move `nextTask` back to `M13-03F`.
|
||||
43
docs/status/M13-03G.md
Normal file
43
docs/status/M13-03G.md
Normal file
@@ -0,0 +1,43 @@
|
||||
# M13-03G Status
|
||||
|
||||
status: done
|
||||
task: same-session sandbox recovery and audit continuity
|
||||
updated: 2026-08-19 America/New_York
|
||||
enablingTask: false
|
||||
parityStateChange: false
|
||||
|
||||
## Scope
|
||||
|
||||
A denied script request can be resumed in the same session after a Worker generation change from 4
|
||||
to 5. The Main revision remains 11, and the source and canonical manifest hashes remain stable.
|
||||
Two default-deny audit entries use distinct request IDs, sequence 1/2, and a continuous
|
||||
`previousEntrySha256 -> entrySha256` chain. Replay and source-hash tampering are rejected. This task
|
||||
does not enable Python execution or claim Blender server isolation.
|
||||
|
||||
## Evidence
|
||||
|
||||
- `node --test web/tests/unit/script-sandbox-recovery.test.mjs` passed 2/2.
|
||||
- `CHROME_PATH=/usr/bin/google-chrome-stable WEB_TEST_PORT=5535 npm --prefix web run test:script-sandbox-recovery` passed unit 2/2 and Chromium Worker E2E 1/1.
|
||||
- `node tools/web/check-script-sandbox-recovery.mjs` passed:
|
||||
`script-sandbox-recovery-ok generation=4->5 revision=11 sourceStable=true manifestStable=true sequence=1,2 chain=true replay=SCRIPT_MANIFEST_INVALID tamper=SCRIPT_MANIFEST_INVALID next=M13-04A`.
|
||||
- `npm --prefix web run typecheck`, `npm --prefix web run lint` and `git diff --check` passed.
|
||||
|
||||
## Artifact Hashes
|
||||
|
||||
- protocol: `8034faded657d49e1376ea42051bc302a090b485024a9ff3781e46aa82638b64`
|
||||
- worker: `7b02331c375d4fb7dbadadd179f0ab9a0e336c8b95fabb071c06e67f3e7b3fe4`
|
||||
- checker: `612015a3fca44bae0f0b78e622f044a5297ed8aa3a0efc774a40f0d47ddbdc9e`
|
||||
- unit: `69a2d34e38d591043ff62b2d305bd9aae684ecebd9ecba718580d77318931226`
|
||||
- e2e: `73176e513f115ba917be74f62a5deb8fe2918fafa8a84c9294e80d2a86b8f1ed`
|
||||
- package: `3df02b6049ac5d7185c23aef7764933ee460fedeb6595b3861272b0d49da5ecd`
|
||||
- report: `9057b3f49c3bb15cf53d638ada4bd2743949d3914173cd3799414489d584111d`
|
||||
- manifest: `5cd365eeebbd6a7f56f380af103b66f2beb11eb49cb6db6adb49972b572cf2ec`
|
||||
|
||||
## Next Task
|
||||
|
||||
`M13-04A`: create an unpredictable one-shot directory for each real Blender server job.
|
||||
|
||||
## Rollback
|
||||
|
||||
Remove the recovery protocol, Worker, focused tests/checker, report, manifest, package command and
|
||||
this status entry; restore M13-03F as the queue tail and move `nextTask` back to `M13-03G`.
|
||||
44
docs/status/M13-04A.md
Normal file
44
docs/status/M13-04A.md
Normal file
@@ -0,0 +1,44 @@
|
||||
# M13-04A Status
|
||||
|
||||
status: done
|
||||
task: server job one-shot directory
|
||||
updated: 2026-08-19 America/New_York
|
||||
enablingTask: false
|
||||
parityStateChange: false
|
||||
|
||||
## Scope
|
||||
|
||||
The server-side job allocator creates an unpredictable `0700` directory below a configured absolute
|
||||
root for each request. Directory names do not contain the request ID, two concurrent jobs receive
|
||||
distinct directories, and successful or failed cleanup removes the directory exactly once. Repeated
|
||||
cleanup is idempotent. This task does not claim read-only source mounts, process limits or Blender
|
||||
execution.
|
||||
|
||||
Browser E2E is not applicable: this is a Node server filesystem boundary. The checker uses real
|
||||
temporary directories and `fs.stat`/`fs.rm` calls.
|
||||
|
||||
## Evidence
|
||||
|
||||
- `node --test web/tests/unit/server-job-isolation.test.mjs` passed 2/2.
|
||||
- `npm --prefix web run test:server-job-directory` passed unit 2/2 and the independent checker.
|
||||
- `node tools/web/check-server-job-isolation.mjs` passed:
|
||||
`server-job-directory-ok allocated=2 cleaned=2 unique=1 requestIdsHidden=1 mode=0700 residual=0 idempotent=1 next=M13-04B`.
|
||||
- `npm --prefix web run typecheck`, `npm --prefix web run lint` and `git diff --check` passed.
|
||||
|
||||
## Artifact Hashes
|
||||
|
||||
- protocol: `3aa5678a2c2769e4db5bb8f5c755b97e23045c4106e5636459748ab9b41929cd`
|
||||
- checker: `b8d0e741144f742946246370bd35820d806686fb00dc0b040c925cf16f2179da`
|
||||
- unit: `b1ac3324332180f7b3522f135520e7b5dace334dc461c92f2bce48fbcba2e147`
|
||||
- package: `0c2633da831e7ca10cf74797650353b6dfb1507ed5957688d34bc97f9a6dd193`
|
||||
- report: `07ed66fe0b2e1f1bbdba1cfb1089b052a5961d38f761bfcf79d8362980d2d502`
|
||||
- manifest: `fd2407a7b9fefe67e2d77ed844e6c2ca17cdc4a746857a5825a38ff02ab664e3`
|
||||
|
||||
## Next Task
|
||||
|
||||
`M13-04B`: source read-only mount and independent writable output directory.
|
||||
|
||||
## Rollback
|
||||
|
||||
Remove the directory allocator, focused tests/checker, report, manifest, package command and this
|
||||
status entry; restore M13-03G as the queue tail and move `nextTask` back to `M13-04A`.
|
||||
41
docs/status/M13-04B.md
Normal file
41
docs/status/M13-04B.md
Normal file
@@ -0,0 +1,41 @@
|
||||
# M13-04B Status
|
||||
|
||||
status: done
|
||||
task: server source read-only and output isolation
|
||||
updated: 2026-08-19 America/New_York
|
||||
enablingTask: false
|
||||
parityStateChange: false
|
||||
|
||||
## Scope
|
||||
|
||||
Each allocated server job now gets a `source/` directory and a separate `output/` directory. The
|
||||
source directory is `0555` and the staged `.blend` is `0444`; a source overwrite fails with
|
||||
`EACCES`. The output directory is `0700` and accepts result bytes. Cleanup temporarily restores
|
||||
the source directory permission so the one-shot job directory can be removed without residue.
|
||||
This task does not claim OS/container CPU, memory or process limits.
|
||||
|
||||
## Evidence
|
||||
|
||||
- `node --test web/tests/unit/server-job-isolation.test.mjs` passed 3/3.
|
||||
- `npm --prefix web run test:server-job-workspace` passed unit 3/3 and the independent checker.
|
||||
- `node tools/web/check-server-job-workspace.mjs` passed:
|
||||
`server-job-workspace-ok sourceDir=0555 sourceFile=0444 sourceWrite=EACCES outputDir=0700 outputWrite=OK distinct=1 residual=0 next=M13-04C`.
|
||||
- `npm --prefix web run typecheck`, `npm --prefix web run lint` and `git diff --check` passed.
|
||||
|
||||
## Artifact Hashes
|
||||
|
||||
- protocol: `3aa5678a2c2769e4db5bb8f5c755b97e23045c4106e5636459748ab9b41929cd`
|
||||
- checker: `9490c2eeb9980073fc1fe77fdba1fb6e4ef528de8eb666d9eaf1fb582ba658c2`
|
||||
- unit: `b1ac3324332180f7b3522f135520e7b5dace334dc461c92f2bce48fbcba2e147`
|
||||
- package: `3df02b6049ac5d7185c23aef7764933ee460fedeb6595b3861272b0d49da5ecd`
|
||||
- report: `650a643cc92617d068cb96d8bd4303429ef169ea89e3d4cb63e3ce5e2428e6d2`
|
||||
- manifest: `9bc906b9e4c9751229f03271ef45a5925122b89b15bfe775591775f121ce1a4c`
|
||||
|
||||
## Next Task
|
||||
|
||||
`M13-04C`: enforce CPU, memory, process, file, wall-time and output budgets at the server boundary.
|
||||
|
||||
## Rollback
|
||||
|
||||
Remove the workspace protocol additions, focused tests/checker, report, manifest, package command and
|
||||
this status entry; restore M13-04A as the queue tail and move `nextTask` back to `M13-04B`.
|
||||
43
docs/status/M13-04C.md
Normal file
43
docs/status/M13-04C.md
Normal file
@@ -0,0 +1,43 @@
|
||||
# M13-04C Status
|
||||
|
||||
status: done
|
||||
task: server job resource budget gate
|
||||
updated: 2026-08-19 America/New_York
|
||||
enablingTask: false
|
||||
parityStateChange: false
|
||||
|
||||
## Scope
|
||||
|
||||
Server jobs now have fixed CPU, memory, process, file, wall-time and output-byte limits. Budget
|
||||
parsing rejects undeclared fields and out-of-range values. A usage receipt is marked
|
||||
`enforced=true` only when every measured value is within its corresponding limit; each of the six
|
||||
over-limit cases returns `SERVER_JOB_BUDGET_EXCEEDED` and remains `execution=DISABLED`.
|
||||
|
||||
This is the resource contract and usage gate. OS/container enforcement is proven by the later real
|
||||
process task and is not claimed here.
|
||||
|
||||
## Evidence
|
||||
|
||||
- `node --test web/tests/unit/server-job-resource-budget.test.mjs` passed 2/2.
|
||||
- `npm --prefix web run test:server-job-resource-budget` passed unit 2/2 and the independent checker.
|
||||
- `node tools/web/check-server-job-resource-budget.mjs` passed:
|
||||
`server-job-budget-ok cpu=bounded memory=bounded process=bounded files=bounded wall=bounded output=bounded overages=6 execution=DISABLED next=M13-04D`.
|
||||
- `npm --prefix web run typecheck`, `npm --prefix web run lint` and `git diff --check` passed.
|
||||
|
||||
## Artifact Hashes
|
||||
|
||||
- protocol: `9746f0aef9dd76411320792dee1213c03755a3c03a87bbc4cbf88d4324c728d6`
|
||||
- checker: `5599f4e25fc3ceca18e04be322450a4dc5bb6ce9c72c3abe9f1afc9c81851ff8`
|
||||
- unit: `05212b2aa639f4c37e37e1cac0597d9b367a1280e519240f073762394914dc63`
|
||||
- package: `3df02b6049ac5d7185c23aef7764933ee460fedeb6595b3861272b0d49da5ecd`
|
||||
- report: `76ba684966bf7e680b0ebfc630ae9e080f04dd6daa6dd744bbb22dcff43f8eb1`
|
||||
- manifest: `d00fff709b57909ec418ff0e476dca97281fc39456f674c63b51248377fc6ab2`
|
||||
|
||||
## Next Task
|
||||
|
||||
`M13-04D`: default-deny network policy with explicit declared-origin admission.
|
||||
|
||||
## Rollback
|
||||
|
||||
Remove the resource budget protocol, focused tests/checker, report, manifest, package command and
|
||||
this status entry; restore M13-04B as the queue tail and move `nextTask` back to `M13-04C`.
|
||||
24
docs/status/M13-04D.md
Normal file
24
docs/status/M13-04D.md
Normal file
@@ -0,0 +1,24 @@
|
||||
# M13-04D Status
|
||||
|
||||
status: done
|
||||
task: server job network policy
|
||||
updated: 2026-08-19 America/New_York
|
||||
enablingTask: false
|
||||
parityStateChange: false
|
||||
|
||||
Server jobs default to `DENY`. Only an explicitly declared canonical HTTPS or loopback origin is
|
||||
`ALLOWED`; missing, undeclared, credential-bearing, path-bearing, public HTTP and invalid origins
|
||||
return `SERVER_NETWORK_DENIED` or `SERVER_NETWORK_POLICY_INVALID`. Execution remains `DISABLED`.
|
||||
|
||||
Evidence: `node --test web/tests/unit/server-job-network-policy.test.mjs` 2/2;
|
||||
`npm --prefix web run test:server-job-network-policy` passed; checker output
|
||||
`server-job-network-ok default=DENY declaredOrigin=ALLOWED missing=SERVER_NETWORK_DENIED undeclared=SERVER_NETWORK_DENIED execution=DISABLED next=M13-04E`;
|
||||
typecheck, lint and `git diff --check` passed.
|
||||
|
||||
Artifact hashes: protocol `0dc3698383fbfa511bebfeca41504c7c04a8302d47168cfae94f01f2a11a316c`,
|
||||
checker `6f3e9cd9f988313863345f392036e6dbb522102c969197034800f419e497ad92`, unit
|
||||
`c0ba10ccd2fb6ec8878a1b4a54bc6a12e49d35818566e0d55ef307779e8c8b77`, report
|
||||
`37bcba2666e8c76c2e07d23e285737004affbb0372ec6dd84bb6802dba551527`, manifest
|
||||
`11ce246597e3321b346ed4fed00edba22708d97250163d332d7ba8a003d8849a`.
|
||||
|
||||
Next task: `M13-04E`, fixed Blender background/factory-startup runtime identity.
|
||||
22
docs/status/M13-04E.md
Normal file
22
docs/status/M13-04E.md
Normal file
@@ -0,0 +1,22 @@
|
||||
# M13-04E Status
|
||||
|
||||
status: done
|
||||
task: pinned Blender server startup
|
||||
updated: 2026-08-19 America/New_York
|
||||
enablingTask: false
|
||||
parityStateChange: false
|
||||
|
||||
Pinned Blender 5.2.0 LTS now passes a real server preflight using only `--background`,
|
||||
`--factory-startup`, the fixed `tools/web/server-job-startup.py`, and a fixed business argument.
|
||||
The structured receipt confirms background mode, runtime version and argv. Execution remains
|
||||
`DISABLED`; this task does not claim result publication.
|
||||
|
||||
Evidence: `node tools/web/check-server-job-startup.mjs` output
|
||||
`server-job-startup-ok blender=5.2 background=1 factory=1 userPrefs=0 fixedScript=1 execution=DISABLED next=M13-04F`;
|
||||
typecheck, lint and `git diff --check` passed. Artifact hashes: startup
|
||||
`c8c5b5a7a7880d4df9477a94a98e54e328baf582ade649807067f988484e1f12`, checker
|
||||
`66b2e25efe0e7455348e8f488cd0f6ebef07f916fcf6541680e7d18e4f69ab10`, report
|
||||
`c67d2972e584782d03479dbdb36dae0976074978f4ce9a48e41e7ad5aea66089`, manifest
|
||||
`a24ea87bcf305bc15d8ae70b2abd03aa16ffbd6b127d5e9da9da23617d7201cc`.
|
||||
|
||||
Next task: `M13-04F`, bounded and redacted stdout/stderr.
|
||||
40
docs/status/M13-04F.md
Normal file
40
docs/status/M13-04F.md
Normal file
@@ -0,0 +1,40 @@
|
||||
# M13-04F Status
|
||||
|
||||
status: done
|
||||
task: bounded and redacted server stdout/stderr
|
||||
updated: 2026-08-19 America/New_York
|
||||
enablingTask: false
|
||||
parityStateChange: false
|
||||
|
||||
## Scope
|
||||
|
||||
Server job output is normalized through a production receipt before publication. Credentials, bearer/basic
|
||||
tokens, secret headers and Unix/Windows/file URL paths are replaced; UTF-8 output is truncated at fixed
|
||||
stdout/stderr byte budgets with an explicit marker. The receipt records original/emitted bytes, redaction
|
||||
count and truncation state. Server execution remains `DISABLED`; process cancellation and result publication
|
||||
are separate tasks.
|
||||
|
||||
## Evidence
|
||||
|
||||
- `npm --prefix web run test:server-job-output-redaction` passed 3/3 unit tests and the independent checker.
|
||||
- Checker output: `server-job-output-ok stdoutTruncated=1 stderrTruncated=1 redactions=6 totalBounded=1 execution=DISABLED next=M13-04G`.
|
||||
- `git diff --check` passed.
|
||||
|
||||
## Artifact Hashes
|
||||
|
||||
- parent manifest: `a24ea87bcf305bc15d8ae70b2abd03aa16ffbd6b127d5e9da9da23617d7201cc`
|
||||
- protocol: `5a58e7080324b399905c6a20a313225153ba94c75a55d21c4bbdd957ae4a2462`
|
||||
- checker: `5c2db9d3313484bb68ac65822828467b3f99cb03e8374935757cfcb4b4ed908d`
|
||||
- unit: `4ae6266bce22f84e73113b93a590a0c32d9452e748003af251a602024d0c6db5`
|
||||
- package: `52781eb2650133b43271889a22ce38023e611641da15411d31698c6cfc0ce19c`
|
||||
- report: `cb6e3ed8d6cc0a69b333b6bff3199593bdfbae14fa7fa700dcb12e9e9cea519a`
|
||||
- manifest: `b5b4b26183dc48ebcae009e49999010d9b60d512f5daa4674a0aff0577d6602c`
|
||||
|
||||
## Next Task
|
||||
|
||||
`M13-04G`: cancel Blender process tree and clean the one-shot directory.
|
||||
|
||||
## Rollback
|
||||
|
||||
Remove the output receipt protocol, unit/checker, report, manifest, package command and this status entry;
|
||||
restore `M13-04E` as the queue tail.
|
||||
38
docs/status/M13-04G.md
Normal file
38
docs/status/M13-04G.md
Normal file
@@ -0,0 +1,38 @@
|
||||
# M13-04G Status
|
||||
|
||||
status: done
|
||||
task: server process-tree cancellation
|
||||
updated: 2026-08-19 America/New_York
|
||||
enablingTask: false
|
||||
parityStateChange: false
|
||||
|
||||
## Scope
|
||||
|
||||
Real server jobs now run in a detached process group on POSIX and are cancelled as a tree. The cancellation
|
||||
path sends SIGTERM to the group, escalates to SIGKILL after the grace window, waits for the group to exit,
|
||||
and performs one idempotent job-directory cleanup. Windows uses `taskkill /T /F`. The receipt reports the
|
||||
actual signal path, cleanup count and orphan count. Execution remains `DISABLED`.
|
||||
|
||||
## Evidence
|
||||
|
||||
- `npm --prefix web run test:server-job-cancellation` passed 2/2 real-process unit tests and the checker.
|
||||
- Checker output: `server-job-cancel-ok state=CANCELLED tree=SIGTERM_GROUP cleanup=1 orphan=0 residual=0 execution=DISABLED next=M13-04H`.
|
||||
- `git diff --check` passed.
|
||||
|
||||
## Artifact Hashes
|
||||
|
||||
- parent manifest: `b5b4b26183dc48ebcae009e49999010d9b60d512f5daa4674a0aff0577d6602c`
|
||||
- protocol: `74fbbac806f34904bc9cb8e40eaf386cb60d44d978973950f1809262d311ec95`
|
||||
- checker: `751ecafc642595d0de69b618e223cbff49d414f2958fc371371e4a668d66a8cc`
|
||||
- unit: `39ac445ff51a9bfe249363204cf2edca906b16bf67ab1f8321166b440eba8629`
|
||||
- package: `ca092a9a1d48ac41dc20f978bb26c8268adde9f7602a06459c7df8c2cb2d4cc7`
|
||||
- report: `61f5c3ad315f94bac48e58627fcc46015c173dd9f303d5914acb8dbbe93caa97`
|
||||
|
||||
## Next Task
|
||||
|
||||
`M13-04H`: map timeout/OOM/non-zero exit/signal to stable error codes.
|
||||
|
||||
## Rollback
|
||||
|
||||
Remove the process control protocol, unit/checker, report, manifest, package command and this status entry;
|
||||
restore `M13-04F` as the queue tail.
|
||||
38
docs/status/M13-04H.md
Normal file
38
docs/status/M13-04H.md
Normal file
@@ -0,0 +1,38 @@
|
||||
# M13-04H Status
|
||||
|
||||
status: done
|
||||
task: stable server process fault codes
|
||||
updated: 2026-08-19 America/New_York
|
||||
enablingTask: false
|
||||
parityStateChange: false
|
||||
|
||||
## Scope
|
||||
|
||||
Timeout, bounded-memory OOM, signal termination and non-zero exit are converted to stable server error
|
||||
codes. Classification precedence is cancellation, timeout, OOM, signal, then non-zero exit. Failed receipts
|
||||
keep the base/current revision equal, set `publish=false`, and expose no internal process details. Execution
|
||||
remains `DISABLED`.
|
||||
|
||||
## Evidence
|
||||
|
||||
- `npm --prefix web run test:server-job-fault-codes` passed 3/3 unit tests and the checker.
|
||||
- Checker output: `server-job-faults-ok timeout=SERVER_JOB_TIMEOUT oom=SERVER_JOB_OOM signal=SERVER_JOB_SIGNAL exit=SERVER_JOB_EXIT_FAILED revisionPreserved=1 publish=0 execution=DISABLED next=M13-04I`.
|
||||
- `git diff --check` passed.
|
||||
|
||||
## Artifact Hashes
|
||||
|
||||
- parent manifest: `7103a25ec7eb4a1c7f0d9f7acfb5ed30da32c87d512d6f9d53e081db275f7b89`
|
||||
- protocol: `858360b4468a7b6cf796fc83a1627ba18626b61a0799f83531de996ea374519b`
|
||||
- checker: `cb67246ef3df111525ca5e14af0546154ea2beee930b9840ad4ac7e2ebbb91ec`
|
||||
- unit: `3551e28d78e5069c3d97eabcacac824bf142f54fdcb3ad4904668909af1cc545`
|
||||
- package: `77bae66fd3885e36d2ead6f261754724144e5f51fafc5ccad9863dfc8e5ab548`
|
||||
- report: `01999232f926496909fc9ef072e19aadb688822d3f9d7e03b42871ac5d54a0f6`
|
||||
|
||||
## Next Task
|
||||
|
||||
`M13-04I`: verify source/settings/build/output hashes before OPFS commit.
|
||||
|
||||
## Rollback
|
||||
|
||||
Remove the fault classifier, unit/checker, report, manifest, package command and this status entry; restore
|
||||
`M13-04G` as the queue tail.
|
||||
38
docs/status/M13-04I.md
Normal file
38
docs/status/M13-04I.md
Normal file
@@ -0,0 +1,38 @@
|
||||
# M13-04I Status
|
||||
|
||||
status: done
|
||||
task: server result hash binding and atomic OPFS handoff
|
||||
updated: 2026-08-19 America/New_York
|
||||
enablingTask: false
|
||||
parityStateChange: false
|
||||
|
||||
## Scope
|
||||
|
||||
Server output publication requires request identity plus source, settings and Blender build SHA-256 values
|
||||
to match the expected request. Output bytes are staged, read back, atomically renamed to the request result
|
||||
path, and read back again before a committed receipt is returned. Tampered output, identity drift, partial
|
||||
stage and quota failures remain unpublished. Execution remains `DISABLED`.
|
||||
|
||||
## Evidence
|
||||
|
||||
- `npm --prefix web run test:server-job-result-binding` passed 2/2 unit tests and the checker.
|
||||
- Checker output: `server-job-result-ok source=bound settings=bound build=bound output=verified tamper=blocked quota=blocked atomic=1 execution=DISABLED next=M13-04J`.
|
||||
- `git diff --check` passed.
|
||||
|
||||
## Artifact Hashes
|
||||
|
||||
- parent manifest: `ba530ddff6e6fdd84057444ce757fad05a30d825a5915abebe2d5910a689af7f`
|
||||
- protocol: `ecf3bddef53e2766dcc055ec027b04c14e3d884132c7fdea476663617364ad86`
|
||||
- checker: `b0fbffd2937ab20e72d337bb5ff63ccf188ccf8a939d8ccc8b4878d80c9a4a19`
|
||||
- unit: `c5538798aa6263b8a1c20270a019f8b4fb8b176b141a6411b72aad21a457bfd0`
|
||||
- package: `5d269d4e5ff4385d919c0ee33f996dcb814e3e415da25dbf3b4dbdc3312fbe24`
|
||||
- report: `ec63faeba35a641a22c3b3a69757bd37e8e9acaa1dda11a64faf7bed80439784`
|
||||
|
||||
## Next Task
|
||||
|
||||
`M13-04J`: idempotent request retry and conflicting-result isolation.
|
||||
|
||||
## Rollback
|
||||
|
||||
Remove the result-binding protocol, unit/checker, report, manifest, package command and this status entry;
|
||||
restore `M13-04H` as the queue tail.
|
||||
38
docs/status/M13-04J.md
Normal file
38
docs/status/M13-04J.md
Normal file
@@ -0,0 +1,38 @@
|
||||
# M13-04J Status
|
||||
|
||||
status: done
|
||||
task: server request idempotency and conflict isolation
|
||||
updated: 2026-08-19 America/New_York
|
||||
enablingTask: false
|
||||
parityStateChange: false
|
||||
|
||||
## Scope
|
||||
|
||||
`projectId/requestId` is now an idempotency key. An exact retry verifies and reuses the existing result;
|
||||
different output or source/settings/build identity returns a stable conflict and cannot overwrite the bound
|
||||
result. Different requests use separate result and receipt files. Concurrent duplicate requests share one
|
||||
in-flight submission and resolve as one commit plus one reuse. Execution remains `DISABLED`.
|
||||
|
||||
## Evidence
|
||||
|
||||
- `npm --prefix web run test:server-job-idempotency` passed 3/3 unit tests and the checker.
|
||||
- Checker output: `server-job-idempotency-ok first=COMMITTED retry=REUSED conflict=BLOCKED isolated=1 concurrent=REUSED execution=DISABLED next=M13-05A`.
|
||||
- `git diff --check` passed.
|
||||
|
||||
## Artifact Hashes
|
||||
|
||||
- parent manifest: `f9658954d3dbd0cd1edd696c10f6a1b880bb3288c91a39a47ca84c4496046a97`
|
||||
- protocol: `15eca7550964c9985e26a22a7900d3f3aa69fdef35fe5962b48a8f55ebba5863`
|
||||
- checker: `02247ffda07c095373642a7fa22268bb9f5ac181d41571f7fff685812976d3c4`
|
||||
- unit: `6ee08e67cd8493e856f67309bd6562316eca42ef52dd4a9aad3a15efdc4b6b41`
|
||||
- package: `5b47e94cf828fc9d3021019eed9922eb67815aba5416266d8c967c7cb5bd96ba`
|
||||
- report: `31f95a8cc1c4792303986b8b5987ab02fc11a77ab25fd76b31c02d1ed1b104d1`
|
||||
|
||||
## Next Task
|
||||
|
||||
`M13-05A`: CSP denies inline script, eval, data script and undeclared origins.
|
||||
|
||||
## Rollback
|
||||
|
||||
Remove the idempotency protocol, unit/checker, report, manifest, package command and this status entry;
|
||||
restore `M13-04I` as the queue tail.
|
||||
45
docs/status/M13-05A.md
Normal file
45
docs/status/M13-05A.md
Normal file
@@ -0,0 +1,45 @@
|
||||
# M13-05A Status
|
||||
|
||||
status: done
|
||||
task: CSP default-deny policy
|
||||
updated: 2026-08-19 America/New_York
|
||||
enablingTask: false
|
||||
parityStateChange: false
|
||||
|
||||
## Scope
|
||||
|
||||
The deployment contract now requires one CSP on every response: same-origin default/script/worker/connect
|
||||
sources, no inline or eval execution, no data/blob script source, and object/base/frame embedding denied.
|
||||
The Vite source, entry HTML, production source tree and built JS/HTML are scanned for dynamic code and data
|
||||
scripts. The deployment HTTP checker verifies the policy on normal, missing and entry responses. Resource-
|
||||
specific Worker/WASM/font/image/media rules remain in M13-05B.
|
||||
|
||||
## Evidence
|
||||
|
||||
- `npm --prefix web run test:csp-policy` passed.
|
||||
- `node tools/web/check-deployment-contract.mjs` passed.
|
||||
- `npm --prefix web run typecheck` passed.
|
||||
- `npm --prefix web run build` passed; built output was scanned by the CSP checker.
|
||||
- Checker output: `csp-policy-ok inline=DENY eval=DENY dataScript=DENY undeclaredConnect=DENY responses=3 execution=DISABLED next=M13-05B`.
|
||||
- `git diff --check` passed.
|
||||
|
||||
## Artifact Hashes
|
||||
|
||||
- parent manifest: `d230ae49dbf38cd9e95e7379a1a49332e478d3d23b3638730d2ec6167204c368`
|
||||
- contract: `3f2b0b10c5a5698be2adda61af80cfb9cb9291fb9797994bfa66a77b7b511eeb`
|
||||
- deployment server: `a5734ce9760f65cf5bade8cc209454d39fa963ad7dfaf20653728a9d7a57b04c`
|
||||
- contract checker: `5e2d80f5c1377420f4779291fa73c206741ed415e751e79ce5edae7ba039febf`
|
||||
- CSP checker: `f97ab074da860e3f8489e520c8bb5932f858409136ef25cca56247bb1310340d`
|
||||
- index: `16b7691b191127f84c5143e23aecdfc203dc9e279d34cb270b37631fcbd5f856`
|
||||
- Vite: `fd160c685ed780738e2b37ce9a32e5d4718e11a2875e12d86ddad310213abaf3`
|
||||
- package: `5b47e94cf828fc9d3021019eed9922eb67815aba5416266d8c967c7cb5bd96ba`
|
||||
- report: `9c7c64bb021161a1165a7c089ccf3f4897877635914260f6f0b0da119a5036fb`
|
||||
|
||||
## Next Task
|
||||
|
||||
`M13-05B`: verify resource-specific CSP for Worker, WASM, font, image and media paths.
|
||||
|
||||
## Rollback
|
||||
|
||||
Remove the CSP contract/checker changes, report, manifest, package command and this status entry; restore
|
||||
`M13-04J` as the queue tail.
|
||||
31
docs/status/M13-05B.md
Normal file
31
docs/status/M13-05B.md
Normal file
@@ -0,0 +1,31 @@
|
||||
# M13-05B Status
|
||||
|
||||
status: done
|
||||
task: resource-specific CSP policy
|
||||
updated: 2026-08-19 America/New_York
|
||||
enablingTask: false
|
||||
parityStateChange: false
|
||||
|
||||
## Scope
|
||||
|
||||
The deployment contract now separates same-origin policy for Worker, WASM, font, image and media
|
||||
resources. Chromium loaded same-origin Worker, WASM, image and media resources, and rejected data-image,
|
||||
blob-Worker and cross-origin connect attempts. WASM uses only the explicit `wasm-unsafe-eval` source
|
||||
expression; JavaScript `eval` remains denied. Resource responses and 404 responses carry the same policy.
|
||||
|
||||
## Evidence
|
||||
|
||||
- `npm --prefix web run test:csp-resource-policy` passed the HTTP resource matrix and Chromium browser gate.
|
||||
- `node tools/web/check-deployment-contract.mjs` passed.
|
||||
- `npm --prefix web run typecheck` passed.
|
||||
- `npm --prefix web run build` passed.
|
||||
- `git diff --check` passed.
|
||||
|
||||
## Next Task
|
||||
|
||||
`M13-05C`: production/build/test dependency inventories.
|
||||
|
||||
## Rollback
|
||||
|
||||
Remove the resource-specific CSP/MIME changes, checker, report, manifest, package command and this status;
|
||||
restore `M13-05A` as the queue tail.
|
||||
27
docs/status/M13-05C.md
Normal file
27
docs/status/M13-05C.md
Normal file
@@ -0,0 +1,27 @@
|
||||
# M13-05C Status
|
||||
|
||||
status: done
|
||||
task: production/build/test dependency inventories
|
||||
updated: 2026-08-19 America/New_York
|
||||
enablingTask: false
|
||||
parityStateChange: false
|
||||
|
||||
## Evidence
|
||||
|
||||
`web/package.json` and `web/package-lock.json` are parsed as the only dependency sources. Deterministic
|
||||
transitive closures contain production=3, build=135 and test=6 packages; every package is classified and
|
||||
records its path, version, resolved URL and lockfile integrity. A fresh regeneration is byte-identical.
|
||||
|
||||
- `npm --prefix web run test:dependency-inventory` passed.
|
||||
- `npm --prefix web run typecheck` passed.
|
||||
- `npm --prefix web run build` passed.
|
||||
- `git diff --check` passed.
|
||||
|
||||
## Next Task
|
||||
|
||||
`M13-05D`: severity gates and documented dependency exceptions.
|
||||
|
||||
## Rollback
|
||||
|
||||
Remove the inventory generator/checker, report, manifest, package command and this status; restore
|
||||
`M13-05B` as the queue tail.
|
||||
18
docs/status/M13-05D.md
Normal file
18
docs/status/M13-05D.md
Normal file
@@ -0,0 +1,18 @@
|
||||
# M13-05D Status
|
||||
|
||||
status: done
|
||||
task: dependency severity gates and exceptions
|
||||
updated: 2026-08-19 America/New_York
|
||||
enablingTask: false
|
||||
parityStateChange: false
|
||||
|
||||
The severity policy is machine-readable: BLOCKER/HIGH block, MEDIUM requires review and LOW is tracked.
|
||||
Exceptions require a non-empty owner, non-expired ISO date, reason and alternative control. Production
|
||||
inventory has zero findings and zero exceptions, while four negative/positive exception cases are checked.
|
||||
|
||||
- `npm --prefix web run test:dependency-severity-policy` passed.
|
||||
- `npm --prefix web run typecheck` passed.
|
||||
- `npm --prefix web run build` passed.
|
||||
- `git diff --check` passed.
|
||||
|
||||
Next task: `M13-05E`, SBOM/license/source-offer binding.
|
||||
13
docs/status/M13-05E.md
Normal file
13
docs/status/M13-05E.md
Normal file
@@ -0,0 +1,13 @@
|
||||
# M13-05E Status
|
||||
|
||||
status: done
|
||||
task: SBOM/license/source-offer and archive binding
|
||||
updated: 2026-08-19 America/New_York
|
||||
enablingTask: false
|
||||
parityStateChange: false
|
||||
|
||||
The supply-chain checker binds SPDX 2.3 to the lockfile and notices hashes, verifies the corresponding
|
||||
source offer and source archive contents, checks top-level archive SHA256SUMS, and records the current
|
||||
commit. Binary/source archive validators also pass independently; script execution remains disabled.
|
||||
|
||||
Next task: `M13-05F`, malicious input matrix.
|
||||
14
docs/status/M13-05F.md
Normal file
14
docs/status/M13-05F.md
Normal file
@@ -0,0 +1,14 @@
|
||||
# M13-05F Status
|
||||
|
||||
status: done
|
||||
task: malicious input matrix
|
||||
updated: 2026-08-19 America/New_York
|
||||
enablingTask: false
|
||||
parityStateChange: false
|
||||
|
||||
The production blend loader rejected five malformed blend cases. Existing production protocol tests
|
||||
rejected malformed image previews, fonts, media cache manifests, shader node graphs, script manifests and
|
||||
GLB inputs; archive metadata rejected six ZIP/TAR traversal, link, duplicate and bomb cases without
|
||||
extraction. All matrix categories are stable reject paths and execution remains disabled.
|
||||
|
||||
Next task: `M13-05G`, fuzz crash minimization and regression capture.
|
||||
37
docs/status/M13-05G.md
Normal file
37
docs/status/M13-05G.md
Normal file
@@ -0,0 +1,37 @@
|
||||
# M13-05G Status
|
||||
|
||||
status: done
|
||||
task: fuzz crash minimization and regression capture
|
||||
updated: 2026-08-19 America/New_York
|
||||
enablingTask: false
|
||||
parityStateChange: false
|
||||
|
||||
## Scope
|
||||
|
||||
The deterministic runner replays 16 mutations in each of the blend, image, font, node-graph and script
|
||||
manifest domains using seed `1511506142`. Every case returns one structured `ACCEPTED` or `REJECTED`
|
||||
receipt; a non-zero runner exit first writes a replayable corpus sample. This run completed 80 cases with
|
||||
zero crashes and an empty minimized corpus. Script execution remains disabled.
|
||||
|
||||
## Evidence
|
||||
|
||||
- `npm --prefix web run test:fuzz-regression` passed.
|
||||
- Checker output: `fuzz-regression-ok seed=1511506142 cases=80 crashes=0 corpus=0 execution=DISABLED next=M13-05H`.
|
||||
- `git diff --check` passed.
|
||||
|
||||
## Artifact Hashes
|
||||
|
||||
- parent manifest: `34043df0515f4b422a2b265d38978dd3c7f21acd12753c99f9a50f9b23f8bd60`
|
||||
- runner: `a4d5d1b743b454705b1c3a257f1f36d1fea8abd77442e11fb1fec9e2905a3f79`
|
||||
- checker: `55c8fa3776b22eb3f2e2ffd1629f0092384df30ef3913699a1ba93b283d641d8`
|
||||
- package: `1feb509789d7f06019390bd86197bb9851cd520fd9fe310d1e29bfc3d2ef3f18`
|
||||
- report: `5eb4a5469732697be7910fded3ce34cf2898735f767d94c1abbe0dd264bcc0d9`
|
||||
|
||||
## Next Task
|
||||
|
||||
`M13-05H`: fuzz corpus replay and release-boundary exclusion.
|
||||
|
||||
## Rollback
|
||||
|
||||
Remove the fuzz runner/checker, report, manifest, package command and this status entry; restore
|
||||
`M13-05F` as the queue tail.
|
||||
30
docs/status/M13-05H.md
Normal file
30
docs/status/M13-05H.md
Normal file
@@ -0,0 +1,30 @@
|
||||
# M13-05H Status
|
||||
|
||||
status: done
|
||||
task: script audit record integrity
|
||||
updated: 2026-08-19 America/New_York
|
||||
enablingTask: false
|
||||
parityStateChange: false
|
||||
|
||||
## Scope
|
||||
|
||||
The production scripting audit protocol now has an independent integrity gate. Two default-deny audit
|
||||
records are validated with strictly increasing ISO timestamps, contiguous sequence numbers, unique request
|
||||
IDs, canonical entry digests and a continuous previous-entry hash chain. Replay, time reversal, sequence
|
||||
mutation, entry digest mutation and chain mutation all return `SCRIPT_MANIFEST_INVALID`; execution remains
|
||||
disabled.
|
||||
|
||||
## Evidence
|
||||
|
||||
- `npm --prefix web run test:script-audit-integrity` passed 2 unit tests and the checker.
|
||||
- Checker output: `script-audit-integrity-ok entries=2 sequence=1,2 requestIds=unique time=ordered chain=true replay=SCRIPT_MANIFEST_INVALID tamper=3 execution=DISABLED next=M14-01A`.
|
||||
- `git diff --check` passed.
|
||||
|
||||
## Next Task
|
||||
|
||||
`M14-01A`: freeze the current Chromium release, engine and archive hashes.
|
||||
|
||||
## Rollback
|
||||
|
||||
Remove the audit integrity checker/unit, report, manifest, package command and this status entry; restore
|
||||
`M13-05G` as the queue tail.
|
||||
32
docs/status/M14-01A.md
Normal file
32
docs/status/M14-01A.md
Normal file
@@ -0,0 +1,32 @@
|
||||
# M14-01A Status
|
||||
|
||||
status: done
|
||||
task: Chromium, engine and archive identity freeze
|
||||
updated: 2026-08-19 America/New_York
|
||||
enablingTask: false
|
||||
parityStateChange: false
|
||||
|
||||
## Scope
|
||||
|
||||
The Chromium baseline is frozen at `150.0.7871.128`. The checker resolves and hashes the actual browser
|
||||
executable, validates every single/pthread engine resource against `engine-manifest.json`, and validates
|
||||
both release archives against the regenerated `RC_MANIFEST.json` and `SHA256SUMS.txt`. Execution remains
|
||||
disabled.
|
||||
|
||||
## Evidence
|
||||
|
||||
- `npm --prefix web run release:offline` passed deterministic binary/source rebuild twice.
|
||||
- `node tools/web/create-rc-manifest.mjs && node tools/web/check-rc-manifest.mjs` passed.
|
||||
- `npm --prefix web run test:chromium-freeze` passed with browser `150.0.7871.128`, two engine variants,
|
||||
and two archive bindings.
|
||||
- `npm --prefix web run typecheck` passed; execution remains `DISABLED`.
|
||||
- `git diff --check` passed.
|
||||
|
||||
## Next Task
|
||||
|
||||
`M14-01B`: Firefox capability probe using the frozen field set.
|
||||
|
||||
## Rollback
|
||||
|
||||
Remove the Chromium freeze checker, report, manifest, package command and this status entry; restore
|
||||
`M13-05H` as the queue tail.
|
||||
21
docs/status/M14-01B.md
Normal file
21
docs/status/M14-01B.md
Normal file
@@ -0,0 +1,21 @@
|
||||
# M14-01B Status
|
||||
|
||||
status: done
|
||||
task: Firefox capability probe
|
||||
updated: 2026-08-19 America/New_York
|
||||
enablingTask: false
|
||||
parityStateChange: false
|
||||
|
||||
Firefox `153.0` was probed against the rebuilt production assets with COOP/COEP isolation. WASM, Worker,
|
||||
OPFS, IndexedDB, WebGL2, OffscreenCanvas and cross-origin isolation passed. WebGPU is explicitly
|
||||
`BLOCKED/WEBGPU_UNAVAILABLE`; it does not change the Chromium-only release claim.
|
||||
|
||||
## Evidence
|
||||
|
||||
- `npm --prefix web run test:firefox-capability` passed.
|
||||
- Checker output: `firefox-capability-ok version=153.0 wasm=PASS,worker=PASS,opfs=PASS,indexedDB=PASS,webgl2=PASS,webgpu=BLOCKED,offscreen=PASS,isolation=PASS execution=DISABLED next=M14-01C`.
|
||||
- `git diff --check` passed.
|
||||
|
||||
## Next Task
|
||||
|
||||
`M14-01C`: WebKit capability probe with the same fields.
|
||||
21
docs/status/M14-01C.md
Normal file
21
docs/status/M14-01C.md
Normal file
@@ -0,0 +1,21 @@
|
||||
# M14-01C Status
|
||||
|
||||
status: done
|
||||
task: WebKit capability probe
|
||||
updated: 2026-08-19 America/New_York
|
||||
enablingTask: false
|
||||
parityStateChange: false
|
||||
|
||||
WebKit `26.5` was probed against the rebuilt production assets with COOP/COEP isolation. WASM, Worker,
|
||||
IndexedDB, WebGL2, OffscreenCanvas and isolation passed. OPFS and WebGPU are explicitly blocked; the
|
||||
result does not change the Chromium-only release claim.
|
||||
|
||||
## Evidence
|
||||
|
||||
- `npm --prefix web run test:webkit-capability` passed.
|
||||
- Checker output: `webkit-capability-ok version=26.5 wasm=PASS,worker=PASS,opfs=BLOCKED,indexedDB=PASS,webgl2=PASS,webgpu=BLOCKED,offscreen=PASS,isolation=PASS execution=DISABLED next=M14-01D`.
|
||||
- `git diff --check` passed.
|
||||
|
||||
## Next Task
|
||||
|
||||
`M14-01D`: probe identity and GPU/OS adapter recording.
|
||||
33
docs/status/M14-01D.md
Normal file
33
docs/status/M14-01D.md
Normal file
@@ -0,0 +1,33 @@
|
||||
# M14-01D Status
|
||||
|
||||
status: done
|
||||
task: probe identity and GPU/OS adapter recording
|
||||
updated: 2026-08-19 America/New_York
|
||||
enablingTask: false
|
||||
parityStateChange: false
|
||||
|
||||
## Scope
|
||||
|
||||
The production Chromium probe records observed browser identity, OS kernel/runtime identity,
|
||||
hardware concurrency, WebGL2 vendor/renderer/version, WebGPU adapter identity, and cross-origin
|
||||
isolation. WebGPU is recorded as `BLOCKED/WEBGPU_ADAPTER_UNAVAILABLE` in this headless environment;
|
||||
the result does not claim WebGPU support. The report is bound to the exact worker/WASM asset hashes
|
||||
used by the probe and carries a canonical identity SHA-256.
|
||||
|
||||
## Evidence
|
||||
|
||||
- `npm --prefix web run build` passed.
|
||||
- `npm --prefix web run test:probe-identity` passed twice (one report-generation run and one frozen
|
||||
report verification run).
|
||||
- Checker output: `probe-identity-ok version=151.0.7922.34 os=linux/x64 webgl2=PASS,webgpu=BLOCKED identity=3c6f898e1b6ffd39862505b8e7dde8fd29369204e1670a013859f74ccaf1c1eb execution=DISABLED next=M14-01E`.
|
||||
- `git diff --check` passed.
|
||||
|
||||
## Next Task
|
||||
|
||||
`M14-01E`: Chromium WebGPU fail-closed boundary. Firefox and WebKit are excluded by the project
|
||||
Chromium-only iron rule.
|
||||
|
||||
## Rollback
|
||||
|
||||
Remove the probe checker, report, manifest, package command and this status/task entry; keep
|
||||
`M14-01C` as the queue tail.
|
||||
29
docs/status/M14-01E.md
Normal file
29
docs/status/M14-01E.md
Normal file
@@ -0,0 +1,29 @@
|
||||
# M14-01E Status
|
||||
|
||||
status: done
|
||||
task: Chromium WebGPU fail-closed boundary
|
||||
updated: 2026-08-19 America/New_York
|
||||
enablingTask: false
|
||||
parityStateChange: false
|
||||
|
||||
## Scope
|
||||
|
||||
Chromium routing was checked against the production render protocol. A bounded Eevee request using
|
||||
WebGPU returns `BLOCKED/WEBGPU_RENDERER_UNAVAILABLE` when no bundled adapter is available, while the
|
||||
same bounded request using WebGL2 remains `READY/WEB_LOCAL_BOUNDED`. This task does not launch Firefox
|
||||
or WebKit.
|
||||
|
||||
## Evidence
|
||||
|
||||
- `npm --prefix web run test:chromium-webgpu-boundary` passed.
|
||||
- Checker output: `chromium-webgpu-boundary-ok webgpu=BLOCKED/WEBGPU_RENDERER_UNAVAILABLE webgl2=READY execution=DISABLED next=M14-04A`.
|
||||
- `git diff --check` passed.
|
||||
|
||||
## Next Task
|
||||
|
||||
`M14-04A`: Chromium GPU/memory budget device tier selection.
|
||||
|
||||
## Rollback
|
||||
|
||||
Remove the Chromium boundary checker, report, manifest, package command and this status/task entry;
|
||||
restore `M14-01D` as the queue tail.
|
||||
25
docs/status/M14-04A.md
Normal file
25
docs/status/M14-04A.md
Normal file
@@ -0,0 +1,25 @@
|
||||
# M14-04A Status
|
||||
|
||||
status: done
|
||||
task: Chromium GPU/memory budget device tier selection
|
||||
updated: 2026-08-19 America/New_York
|
||||
enablingTask: false
|
||||
parityStateChange: false
|
||||
|
||||
## Scope
|
||||
|
||||
Added a bounded device-budget selector driven only by the real Chromium M14-01D identity report.
|
||||
The observed SwiftShader renderer and unavailable WebGPU adapter select `CONSERVATIVE`; untrusted,
|
||||
missing, or fallback adapters cannot expand budgets. Fixed `CONSERVATIVE`, `BALANCED`, and `HIGH`
|
||||
limits are explicit and unknown tiers fail closed. Firefox/WebKit are excluded by the iron rule.
|
||||
|
||||
## Evidence
|
||||
|
||||
- `npm --prefix web run test:chromium-device-budget` passed: 3 unit tests plus the production identity
|
||||
report checker.
|
||||
- Checker output: `chromium-device-budget-ok tier=CONSERVATIVE reason=UNTRUSTED_ADAPTER identity=3c6f898e1b6ffd39862505b8e7dde8fd29369204e1670a013859f74ccaf1c1eb execution=DISABLED next=M14-04B`.
|
||||
- `npm --prefix web run typecheck` and `git diff --check` passed.
|
||||
|
||||
## Next Task
|
||||
|
||||
`M14-04B`: Chromium DPR 1/1.5/2/3 canvas and raycast consistency.
|
||||
26
docs/status/M14-04B.md
Normal file
26
docs/status/M14-04B.md
Normal file
@@ -0,0 +1,26 @@
|
||||
# M14-04B Status
|
||||
|
||||
status: done
|
||||
task: Chromium DPR 1/1.5/2/3 canvas and raycast consistency
|
||||
updated: 2026-08-19 America/New_York
|
||||
enablingTask: false
|
||||
parityStateChange: false
|
||||
|
||||
## Scope
|
||||
|
||||
Shared viewport DPR and CSS-bounds NDC helpers now drive the main-thread and Offscreen viewport
|
||||
boundaries. Chromium production verification ran at device scale factors 1, 1.5, 2 and 3; the
|
||||
declared renderer cap of 2 was applied, backing dimensions matched the browser canvas, CSS dimensions
|
||||
remained `679x321`, and the same center raycast selected the same object at every scale.
|
||||
|
||||
## Evidence
|
||||
|
||||
- `npm --prefix web run build` passed.
|
||||
- `npm --prefix web run test:chromium-dpr-consistency` passed: 2 protocol tests and 4 real Chromium
|
||||
production contexts.
|
||||
- Checker output: `chromium-dpr-ok dpr=1,1.5,2,3 css=679x321 selection=stable execution=DISABLED next=M14-04C`.
|
||||
- `npm --prefix web run typecheck` and `git diff --check` passed.
|
||||
|
||||
## Next Task
|
||||
|
||||
`M14-04C`: Chromium mouse/touch/pen pointer identity and cancellation contract.
|
||||
26
docs/status/M14-04C.md
Normal file
26
docs/status/M14-04C.md
Normal file
@@ -0,0 +1,26 @@
|
||||
# M14-04C Status
|
||||
|
||||
status: done
|
||||
task: Chromium mouse/touch/pen pointer identity and cancellation contract
|
||||
updated: 2026-08-19 America/New_York
|
||||
enablingTask: false
|
||||
parityStateChange: false
|
||||
|
||||
## Scope
|
||||
|
||||
The main-thread and Offscreen viewport paths now record a shared pointer observation for mouse,
|
||||
touch, and pen input. Pointer identity, pressure, tilt, button/buttons and `pointercancel` are
|
||||
preserved with bounded values; unknown pointer types and invalid IDs fail closed. Chromium production
|
||||
events verified down/cancel pairs for all three pointer types. Firefox/WebKit are excluded.
|
||||
|
||||
## Evidence
|
||||
|
||||
- `npm --prefix web run build` passed.
|
||||
- `npm --prefix web run test:chromium-pointer-contract` passed: 2 protocol tests and real Chromium
|
||||
mouse/touch/pen down/cancel events.
|
||||
- Checker output: `chromium-pointer-ok types=mouse,touch,pen cancel=PASS execution=DISABLED next=M14-04D`.
|
||||
- `npm --prefix web run typecheck` and `git diff --check` passed.
|
||||
|
||||
## Next Task
|
||||
|
||||
`M14-04D`: Chromium IME composition guard for incomplete operators.
|
||||
26
docs/status/M14-04D.md
Normal file
26
docs/status/M14-04D.md
Normal file
@@ -0,0 +1,26 @@
|
||||
# M14-04D Status
|
||||
|
||||
status: done
|
||||
task: Chromium IME composition guard for incomplete operators
|
||||
updated: 2026-08-19 America/New_York
|
||||
enablingTask: false
|
||||
parityStateChange: false
|
||||
|
||||
## Scope
|
||||
|
||||
Added an explicit IME composition state machine and connected it to the App global shortcut gate.
|
||||
Composition start/update records pending text and blocks operator shortcuts; composition end clears
|
||||
the block without dispatching an incomplete operator. A real Chromium page dispatched composition
|
||||
events and `G`; UI revision remained unchanged during composition. Firefox/WebKit are excluded.
|
||||
|
||||
## Evidence
|
||||
|
||||
- `npm --prefix web run build` passed.
|
||||
- `npm --prefix web run test:chromium-ime-guard` passed: 2 protocol tests and real Chromium
|
||||
compositionstart/update/keydown/compositionend events.
|
||||
- Checker output: `chromium-ime-ok composing=BLOCKED_OPERATOR shortcut=G revision=0 execution=DISABLED next=M14-04E`.
|
||||
- `npm --prefix web run typecheck` and `git diff --check` passed.
|
||||
|
||||
## Next Task
|
||||
|
||||
`M14-04E`: Chromium US/non-US/dead-key/modifier keymap fixture.
|
||||
26
docs/status/M14-04E.md
Normal file
26
docs/status/M14-04E.md
Normal file
@@ -0,0 +1,26 @@
|
||||
# M14-04E Status
|
||||
|
||||
status: done
|
||||
task: Chromium US/non-US/dead-key/modifier keymap fixture
|
||||
updated: 2026-08-19 America/New_York
|
||||
enablingTask: false
|
||||
parityStateChange: false
|
||||
|
||||
## Scope
|
||||
|
||||
Added a versioned keyboard observation contract preserving layout character (`key`), physical key
|
||||
(`code`), location, repeat, composition state, dead-key identity and modifier flags. Chromium
|
||||
production events verified US, non-US character, dead-key and modifier fixtures. Firefox/WebKit are
|
||||
excluded.
|
||||
|
||||
## Evidence
|
||||
|
||||
- `npm --prefix web run build` passed.
|
||||
- `npm --prefix web run test:chromium-keymap-fixture` passed: 2 protocol tests and 4 real Chromium
|
||||
keyboard fixtures.
|
||||
- Checker output: `chromium-keymap-ok fixtures=US,NON_US,DEAD_KEY,MODIFIER observations=4 execution=DISABLED next=M14-04F`.
|
||||
- `npm --prefix web run typecheck` and `git diff --check` passed.
|
||||
|
||||
## Next Task
|
||||
|
||||
`M14-04F`: Chromium touch modal cancel, two-finger navigation and single pen Main commit.
|
||||
@@ -1,7 +1,8 @@
|
||||
# N-023 Asset、Library 与 IO
|
||||
|
||||
状态:`BLOCKED`(asset catalog、来源/许可证元数据、真实 Main library inventory、库依赖与
|
||||
IO 安全门已落地;Append/Link/Override Main、非 GLB 本地导入和跨桌面重导入未实现)
|
||||
IO 安全门已落地;bounded Append Main 及其 canonical persistence 已完成,Link/Override Main、
|
||||
非 GLB 本地导入和跨桌面重导入仍未实现)
|
||||
|
||||
## 完整对标盘点基线
|
||||
|
||||
@@ -91,8 +92,35 @@ M12-03D 已把同一 source-hash-bound closure 送入 WASM Worker 的 authoritat
|
||||
link/append context 递归导入 Object、Mesh、Material 和 packed Image,Main commit 前核对 source
|
||||
locator、root、closure 与 base revision;四个 ID 均无 `ID.lib`/override、映射为可写 `LOCAL_MAIN`,
|
||||
并只产生一个新的 SceneIR revision。stale revision 与 local ID collision 在 Main mutation 前阻断,
|
||||
失败路径回滚完整 history state。该项只证明单 transaction Main append,undo/redo/save/reopen 与
|
||||
desktop canonical report 的联合一致性仍由 M12-03E 验证。
|
||||
失败路径回滚完整 history state。
|
||||
|
||||
M12-03E 已在同一 Chromium/WASM Main 路径完成联合持久化门:append 只推进一个 revision,undo
|
||||
移除 Object/Mesh/Material/Image 四个 closure ID,redo 恢复同一 canonical graph;save/reopen 后
|
||||
再次读取的依赖边、geometry、UV、material slot 和 packed image Float32 pixel hash 与 M12-03C
|
||||
desktop report 精确一致。图像比较只对 Blender bottom-up `Image.pixels` 与 Canvas top-down row
|
||||
做规范化;当前 SceneIR 缺省的 `Image.colorSpace` 使用 desktop sRGB semantic default,若字段出现
|
||||
则必须匹配,不放宽其它字段。该证据仍不覆盖 Link/Override 或完整 N-023 IO parity。
|
||||
|
||||
M12-03F 已用独立 Blender 5.2 desktop fixture 冻结 LINK 语义。只链接一个 Object root,Mesh、
|
||||
Material 和 packed Image 依赖随 source library 保留;四个 ID 的 `library` 均为
|
||||
`m12_link_source.blend`、`isLibraryOverride=false`,并映射为 `SOURCE_LIBRARY/readOnly=true`。
|
||||
target 保存并重开后 stable mapping、依赖边、geometry/UV/material slot 和 packed image Float32
|
||||
pixel hash 不变。该 enabling evidence 仍不开放 linked writer 或声明完整 Link parity。
|
||||
|
||||
M12-03G 已为 linked Object/Mesh/Material/Image writer 建立统一 fail-closed gate。object transform、
|
||||
mesh geometry/material slot、material property/image node 和 packed image data 六类操作在
|
||||
`SOURCE_LIBRARY/readOnly=true` context 下全部返回 `LINKED_DATA_MUTATION_BLOCKED`,且
|
||||
`recoverable=false`;stale revision 先返回 `REVISION_CONFLICT`,未知字段、operation 和 owner
|
||||
substitution 也在 Main 前阻断。M12-03H 又将 reload 限定为匹配 source library generation/revision 的
|
||||
单一 linked snapshot 替换;stale、跳代、重复 identity 和 source substitution 均不发布新状态。该项仍不
|
||||
实现 relocate、override 或 LINK Main transaction;M12-03I 的 missing-library placeholder 仍是有界
|
||||
reference-preservation 证据,不是完整资源恢复。
|
||||
|
||||
M12-04A-J 又冻结 declared source-origin admission、canonical project path、path/origin safety、
|
||||
symlink/hardlink resolution、metadata-first read、entry/total/path/range/conflict budget 与 cancellation
|
||||
rollback。取消、quota 和 OOM 的部分 staging 都会清零并保持 committed revision/SHA-256 不变,
|
||||
同一 storage instance 可继续提交小 archive;6 个恶意 ZIP/TAR fixture 又进入确定性长期回归。
|
||||
该组有界证据仍不实现完整 archive decoder、fuzz 或 N-023 全域 parity。
|
||||
|
||||
## 已验证切片
|
||||
|
||||
@@ -101,8 +129,30 @@ desktop canonical report 的联合一致性仍由 M12-03E 验证。
|
||||
缺许可证和哈希不匹配会拒绝。
|
||||
2. N-023-A/B(部分):catalog 与 library dependency 图做确定性拓扑检查并返回 load order;
|
||||
content-addressed index 报告 `LOCAL_BOUNDED`,OPFS 只在运行时 API 存在时报告 `PROBE_REQUIRED`。
|
||||
3. N-023-C(门):现有 GLB 导出与 USD semantic analysis 可放行;GLTF/OBJ/PLY/STL、
|
||||
USD/Alembic 实际导入保持 `IO_FORMAT_UNSUPPORTED`,库 mutation 需要真实 Main。
|
||||
3. N-023-C(门):现有 GLB 导出与 USD semantic analysis 可放行;M12-05A 已从 pinned Blender
|
||||
5.2 runtime 生成 GLTF/GLB/OBJ/STL/PLY/USD/Alembic operator/build inventory,但没有把清单
|
||||
当作执行 receipt;M12-05B 仅放行已有 bounded GLB local export,其余 import/export local/server
|
||||
route 均保持 `BLOCKED`;M12-05C 又让 UI registry 只消费 matrix 声明且 runtime 可执行的 route,
|
||||
文件选择器仅接受 `.blend`,operator search 隐藏 blocked/undeclared 组合;M12-05D 再用
|
||||
pinned Blender 5.2 runtime receipt 在执行前确认 operator registered/build option/RNA identity,
|
||||
M12-05E 又要求 source/settings/runtime 三重 hash 与 parent inventory identity,且不从扩展名推断能力;
|
||||
M12-06A 已由同一 pinned runtime 生成五个独立 Mesh/PBR/UV/skin/animation GLB fixture,并用
|
||||
semantic report 与逐字节二次生成固定输入基线;M12-06B 又由生产 Web parser 在 Node 与
|
||||
Chromium Worker 对 topology/attributes/materials/nodes/animations 做 exact canonical 比较;
|
||||
M12-06C-G 又完成 Main persistence、loss report、desktop re-import、negative budget 和双向取消/
|
||||
Worker restart/真实 OPFS quota 恢复;M12-07A 又冻结 pinned Blender OBJ 单 Mesh position/
|
||||
normal/UV/material-group 输入;M12-07B 又冻结 OBJ 双对象/负索引/相对纹理来源/坏 face 负例;
|
||||
M12-07C 已完成 bounded Web-to-desktop OBJ round-trip 与 texture-origin loss report,但
|
||||
UV/skin mismatch、GLB import UI route 和 OBJ Web route 仍保持阻断;M12-07D 已冻结 Blender
|
||||
STL binary/ASCII 两个独立 runtime variant;M12-07E 又对标 normal/unit/degenerate/trailing,
|
||||
trailing 保持 stricter Web block;M12-07F 又完成 STL Web-to-desktop round-trip/material loss
|
||||
report,STL Web route 仍保持阻断;M12-07G 又冻结 PLY ASCII 与 binary little-endian 两个
|
||||
独立 desktop capability variant;M12-07H 又完成 bounded PLY vertex/face/color/custom property
|
||||
mapping 与 `PLY_UNKNOWN_PROPERTY` loss report;M12-07I 又让 big-endian、坏 list、超大 count
|
||||
在 Worker 中稳定 fail-closed;M12-07J 又完成 OBJ/STL/PLY cancellation/OOM/restart/small recovery,
|
||||
但 PLY Web route 仍保持阻断;
|
||||
GLTF/OBJ/PLY/STL、USD/Alembic 实际导入仍保持 `IO_FORMAT_UNSUPPORTED`,
|
||||
库 mutation 需要真实 Main。
|
||||
4. N-023-A/B(部分):预览字节先验 SHA-256 和 byte length,再校验 PNG signature/尺寸;
|
||||
WebP 仅在 RIFF/WEBP 容器签名正确时进入后续解码门,不从元数据伪造预览内容。
|
||||
5. N-023-E:项目路径、外部 URI、archive entry 数量/单项/总量、压缩展开比率均有边界。
|
||||
@@ -110,9 +160,11 @@ desktop canonical report 的联合一致性仍由 M12-03E 验证。
|
||||
packed/external 状态、只读标志和 archive-parent dependency;1024 library/每库 1024 dependency、
|
||||
重复 ID、缺依赖、依赖环与项目外路径由 SceneIR 再校验。缺外部库字节时返回
|
||||
`LINKED_LIBRARY_RESOURCE_REQUIRED`,不从路径伪造 SHA-256 或声称已加载。
|
||||
7. N-023-E(archive 结构门):除 traversal 与展开比预算外,重复规范路径、文件/目录前缀冲突、
|
||||
累计压缩/解压字节和声明源长度不一致均拒绝;`planIOArchiveRanges` 按路径生成确定性、安全整数
|
||||
compressed offset 计划。它为后续流式解包提供边界,不代表已有 ZIP decoder。
|
||||
7. N-023-E(archive 结构门):symlink/hardlink 在写前解析到临时根;ZIP central directory/TAR
|
||||
manifest 必须先读;entry/total/path、展开比、重叠 range、重复路径与文件/目录前缀冲突均拒绝。
|
||||
取消会删除真实 staging、保持 committed identity 且发布数为零;quota/OOM 部分写入也会清零,
|
||||
并允许同一 storage instance 恢复小 archive。三类 ZIP 与三类 TAR 恶意二进制 fixture 确定性
|
||||
重建、验证真实容器 metadata 后全部 fail-closed;这些门不代表已有 ZIP/TAR decoder。
|
||||
8. N-023-E(NanoVDB range 基础件):`.nvdb` manifest 要求连续、32-byte 对齐、逐块 hash;
|
||||
HTTP source 只接受与 manifest 精确一致的 `206 Content-Range`,并按块校验后消费;临时错误重试、
|
||||
稳定 ETag/If-Range、response-body 偏移续传、错位/短响应拒绝均已完成。OPFS 原子
|
||||
@@ -125,11 +177,16 @@ desktop canonical report 的联合一致性仍由 M12-03E 验证。
|
||||
|
||||
## 仍然阻断
|
||||
|
||||
- N-023-B:Append undo/redo/save/reopen、Link/Library Override、reload/relocate 和完整真实 Main
|
||||
parity;M12-03D 的单 transaction append 已有独立证据,但不解除本项阻断。
|
||||
- N-023-B:linked relocate、missing-library recovery、Library Override 和完整真实 Main parity;
|
||||
M12-03D/E 已证明 bounded Append 的单 transaction 与 desktop canonical persistence,M12-03F/G/H/I
|
||||
已冻结 desktop LINK source-library/read-only contract、linked writer fail-closed 与
|
||||
matching-generation reload、missing-reference preservation 和 desktop override ownership/property
|
||||
fixture、单一 verified override writer、freshness gate、negative cases、三 lane command matrix 与
|
||||
declared source-origin admission、canonical project-path normalization 与 path/origin security gate,
|
||||
但不解除本项阻断。
|
||||
- N-023-C/D:GLTF/OBJ/PLY/STL、USD/Alembic import/export/save/reopen/desktop reimport。
|
||||
- N-023-E:真实 zip decoder/fuzz、OPFS quota/recovery、license/source offer 发布审计和大文件
|
||||
流式性能;archive 路径冲突、双向字节预算与确定性 range plan 已完成。
|
||||
- N-023-E:真实 ZIP/TAR decoder/fuzz、license/source offer 发布审计和大文件流式性能仍阻断;
|
||||
archive link/metadata/budget/conflict/cancellation/quota/OOM 与恶意 fixture regression 已完成。
|
||||
- N-023-E(VDB):GPU page resident LRU 已完成;64 MiB–1 GiB bundle 中断/内存性能门仍阻断。
|
||||
|
||||
## 验收
|
||||
@@ -154,6 +211,13 @@ npm --prefix web run test:asset-preview-display
|
||||
npm --prefix web run test:library-operation-inventory
|
||||
npm --prefix web run test:library-operation-identity
|
||||
npm --prefix web run test:library-main-append
|
||||
npm --prefix web run test:library-link-safety
|
||||
npm --prefix web run test:library-metadata-first
|
||||
npm --prefix web run test:library-archive-budget
|
||||
npm --prefix web run test:library-archive-conflicts
|
||||
npm --prefix web run test:library-archive-cancellation
|
||||
node --test web/tests/unit/library-archive-recovery.test.mjs
|
||||
node tools/web/check-malicious-archive-fixtures.mjs
|
||||
npm --prefix web run test:vdb
|
||||
npm --prefix web run test:vdb-native
|
||||
```
|
||||
|
||||
@@ -25,13 +25,61 @@
|
||||
8. N-025-E(审计链):至多 65,536 条拒绝审计按 sequence、前项 SHA-256 与 canonical
|
||||
entry SHA-256 串联;读取时重新校验请求摘要和整条链,拒绝 requestId 重放、非递增 UTC
|
||||
时间戳、内容篡改、断链与超预算日志。该链是内存/序列化协议,不声称已持久化发布审计。
|
||||
9. M13-02A manifest gate:每个 script 必须声明 `sourceByteLength` 和 `module=false`;解析器限制
|
||||
脚本数量、总源码字节、依赖数量、权限数量与 allowlist,canonicalize 项目内 entry/dependency
|
||||
path,并拒绝重复依赖、模块执行、未知权限和所有预算溢出。Node unit 与生产 Chromium Worker
|
||||
正负例、golden report 和 artifact manifest 已绑定。
|
||||
10. M13-02B canonical signature input:`canonicalizeScriptingManifest` 与
|
||||
`serializeScriptingManifest` 是唯一规范入口,locale-independent code-unit 排序所有可重排
|
||||
数组,固定无空白 canonical JSON,unknown fields 不进入签名输入;order mutation、security
|
||||
field mutation 和 schema drift 均由 Node/Chromium 与 golden report 验证。
|
||||
11. M13-02C signer trust policy:版本化 trust policy 绑定 ED25519 key/public-key、publisher、
|
||||
active/revoked status、validity window、revocation timestamp、same-publisher rotation chain
|
||||
和 bounded clock skew;resolver 只返回 `ELIGIBLE/cryptographicVerification=REQUIRED`,不验签
|
||||
不执行,revoked/expired/mismatch/cycle/missing predecessor 全部 fail-closed。
|
||||
12. M13-02D declaration-bound signature verification:canonical per-script input 包含 source
|
||||
SHA-256 和权限/预算/路径等声明,合法 ED25519 signature 才返回 `VERIFIED`;source hash 或
|
||||
signature 变化返回 `SCRIPT_SIGNATURE_INVALID`,revoked signer 返回 `SCRIPT_POLICY_DENIED`。
|
||||
13. M13-02E permission minimization:无显式请求时授予空集;只有 manifest 已声明且请求的
|
||||
permission 才能授予,未知、重复或未声明请求稳定返回 `SCRIPT_POLICY_DENIED`。
|
||||
14. M13-02F signature negative matrix:missing/expired/not-yet-valid key、publisher confusion
|
||||
与跨脚本 signature swap 均稳定返回 `SCRIPT_POLICY_DENIED` 或 `SCRIPT_SIGNATURE_INVALID`,
|
||||
canonical ordering 不改变自身签名结果,且不开放执行入口。
|
||||
15. M13-03A sandbox scope contract:versioned scope 对 DOM、host Worker、OPFS、IndexedDB 和
|
||||
network 五项能力逐项要求 `false`;启用、缺失或未知 schema 均 fail-closed,执行仍禁用。
|
||||
16. M13-03B sandbox budget contract:CPU、wall-time、memory、message 和 output bytes 各有固定
|
||||
上限;任一超限返回 `SCRIPT_BUDGET_EXCEEDED`,不创建或启用脚本执行器。
|
||||
17. M13-03C host-call contract:仅允许五个显式调用名;每个调用使用结构化、调用专属参数,
|
||||
permission 必须来自 manifest 声明,未知字段、危险路径和未声明调用 fail-closed,解析结果
|
||||
保持 `execution=DISABLED`。
|
||||
18. M13-03D sandbox isolation:真实 Chromium Worker crash/timeout 后 job receipt 分别返回
|
||||
`SCRIPT_SANDBOX_CRASHED`/`SCRIPT_SANDBOX_TIMEOUT`,Main revision 不变,temporary/published
|
||||
资源归零;终止后的迟到结果返回 `SCRIPT_SANDBOX_LATE_RESULT`,执行仍为 `DISABLED`。
|
||||
19. M13-03E cancellation gate:取消 receipt 保持 Main revision 和 execution 状态,真实 Chromium
|
||||
迟到窗口 `lateMessages=0`、`cacheWrites=0`,伪造迟到结果稳定返回 `SCRIPT_SANDBOX_LATE_RESULT`。
|
||||
20. M13-03F dispose gate:真实 Chromium Worker 释放两端 `MessagePort`、timer、AbortController、
|
||||
transferable buffer、pending request 和 cache reference;首次和重复 dispose 均返回零资源,
|
||||
且迟到 timer 消息为 0。
|
||||
21. M13-03G same-session recovery:Worker generation 4->5 后 Main revision/source hash/manifest hash
|
||||
保持不变;两条 default-deny audit entry 的 request ID、sequence 和 previous hash chain 连续,
|
||||
replay/source tamper 均返回 `SCRIPT_MANIFEST_INVALID`。
|
||||
22. M13-04A server job directory gate:每个 job 获得随机 `0700` one-shot directory,request ID 不
|
||||
进入目录名;成功/失败清理后无残留且重复清理幂等。
|
||||
23. M13-04B source/output isolation:source directory/file 为 `0555/0444`,真实写入返回 `EACCES`;
|
||||
output directory 为 `0700` 且可写,清理会先恢复 source directory 权限并无残留。
|
||||
24. M13-04C server resource budget:CPU、memory、process、file、wall 和 output 六类限制有固定
|
||||
上限;每类超限均返回 `SERVER_JOB_BUDGET_EXCEEDED`,bounded receipt 标记 `enforced=true`,
|
||||
执行仍为 `DISABLED`。
|
||||
25. M13-04D server network policy:默认 network `DENY`;显式声明的 HTTPS/loopback origin 才可
|
||||
`ALLOWED`,missing/undeclared/unsafe origin 均为 `SERVER_NETWORK_DENIED`。
|
||||
|
||||
## 仍然阻断
|
||||
|
||||
- N-025-B/C:签名验证密钥管理、无网络 CPython/native sandbox、server Blender job 和
|
||||
output hash 提交。
|
||||
- N-025-D/E:真实 GPU/native window/file watcher 适配、恶意脚本/依赖混淆/逃逸/重放、
|
||||
审计日志持久化和发布门;本地请求级审计凭证已完成,不代表隔离执行完成。
|
||||
- N-025-D/E:真实 server isolation、真实 GPU/native
|
||||
window/file watcher 适配、恶意脚本/依赖混淆/逃逸/重放、审计日志持久化和发布门;本地
|
||||
请求级审计凭证与 crash/timeout receipt 已完成,不代表隔离执行完成。
|
||||
|
||||
## 验收
|
||||
|
||||
|
||||
Reference in New Issue
Block a user