Authorize M12 provenance epoch 2 baseline
This commit is contained in:
19
docs/status/M12-PROVENANCE-EPOCH-2-APPROVAL.json
Normal file
19
docs/status/M12-PROVENANCE-EPOCH-2-APPROVAL.json
Normal file
@@ -0,0 +1,19 @@
|
||||
{
|
||||
"schemaVersion": 1,
|
||||
"decision": "APPROVED",
|
||||
"epoch": 2,
|
||||
"scope": "M12 provenance only",
|
||||
"approvedBy": "wangdequan",
|
||||
"authority": "project-owner",
|
||||
"approvalSource": "explicit project-owner authorization in task conversation",
|
||||
"approvedAt": "2026-08-27T21:11:58+08:00",
|
||||
"restoredOriginals": 23,
|
||||
"authorizedReplacements": 61,
|
||||
"limitations": {
|
||||
"fullHistoricalReproduction": false,
|
||||
"replacementIsHistoricalRestoration": false,
|
||||
"featureParityClaim": false,
|
||||
"releaseLabel": "AUTHORIZED_REBASELINE_ONLY"
|
||||
},
|
||||
"policy": "The 61 replacement bindings may satisfy the approved current baseline, but must never be reported as recovery of the unavailable historical bytes."
|
||||
}
|
||||
@@ -1,9 +1,9 @@
|
||||
# WBV2-P8-003 status
|
||||
|
||||
- task: `WBV2-P8-003`; parent: `WBV2-P8-002`; status: `done`
|
||||
- provenance epoch: `1`
|
||||
- historical originals restored: `22/84`
|
||||
- authorized replacements: `62/84`
|
||||
- provenance epoch: `2`
|
||||
- historical originals restored: `23/84`
|
||||
- authorized replacements: `61/84`
|
||||
- nextTask: `WBV2-P8-004`
|
||||
|
||||
The 22 exact Git-history matches remain immutable restorations. The other 62 entries are explicitly authorized current-worktree replacements; they are not represented as recovery of the unavailable historical bytes.
|
||||
The 23 exact matches remain immutable restorations. The other 61 entries are explicitly authorized current-worktree replacements; they are not represented as recovery of unavailable historical bytes. Full historical reproduction remains false.
|
||||
|
||||
@@ -2,8 +2,9 @@
|
||||
|
||||
- task: `WBV2-P8-004`; parent: `WBV2-P8-003`; status: `blocked`
|
||||
- atomic Chromium receipts: `45/45`
|
||||
- M12 provenance: `22 restored + 62 authorized replacements`
|
||||
- release decision: `BLOCKED`
|
||||
- M12 provenance epoch: `2`
|
||||
- M12 provenance: `23 restored + 61 authorized replacements`
|
||||
- release decision: `READY_WITH_AUTHORIZED_REBASELINE`
|
||||
- nextTask: `NONE`
|
||||
|
||||
The recovery gate is internally consistent and fail-closed. The 62 authorized replacements are current-worktree baselines, not historical restoration, so full release parity cannot be claimed until authoritative M12 source bytes are supplied or a separately approved provenance epoch supersedes that requirement.
|
||||
The project owner approved the new provenance baseline. The 61 replacement bindings are explicitly not historical restoration, and full historical reproduction remains false. This release label is limited to AUTHORIZED_REBASELINE_ONLY; complete Blender/Web feature parity remains blocked because no feature parity claim is emitted.
|
||||
|
||||
@@ -1,20 +1,25 @@
|
||||
{
|
||||
"schemaVersion": 1,
|
||||
"epoch": 1,
|
||||
"epoch": 2,
|
||||
"task": "WBV2-P8-003",
|
||||
"operation": "M12_AUTHORIZED_PROVENANCE_REBASELINE",
|
||||
"historicalEvidencePreserved": true,
|
||||
"sourceSnapshot": "tests/golden/corrective/rehydration/M12-git-history-snapshot/snapshot-manifest.json",
|
||||
"sourceSnapshotSha256": "e58b1804ed92f19855679f7cdca6787bffcfafbc59c007fd419077ed55a04b54",
|
||||
"supplementalExactRecovery": "tests/golden/corrective/rehydration/M12-supplemental-exact-recovery.json",
|
||||
"supplementalExactRecoverySha256": "a8947b6b5966dbd870a254a96e7ee26d606011c16cb5c5c3c315ac912eae0908",
|
||||
"searchReport": "tests/golden/WBV2-P8-003/m12-source-recovery-search.json",
|
||||
"searchReportSha256": "4192418563aabf011bb5d6c1407565c87bb492ab208eca69f4768ae35b126fc0",
|
||||
"originalDriftReport": "tests/golden/corrective/rehydration/M12-manifest-sha-drift.json",
|
||||
"originalDriftReportSha256": "e35f4dcae87ce260d565dccfcdafb58a032d79141115a26b45b25dcbec3f31e1",
|
||||
"originalIntake": "tests/golden/corrective/rehydration/M12-provenance-intake.json",
|
||||
"originalIntakeSha256": "37a54d83eba799948fcaae798828915b35f8bf8e709bf90df21351d0288676d9",
|
||||
"policy": {
|
||||
"restoredOriginals": 22,
|
||||
"authorizedReplacements": 62,
|
||||
"restoredOriginals": 23,
|
||||
"authorizedReplacements": 61,
|
||||
"replacementsAreNotHistoricalRestorations": true,
|
||||
"historicalManifestsRewritten": false
|
||||
"historicalManifestsRewritten": false,
|
||||
"fullHistoricalReproduction": false
|
||||
},
|
||||
"entries": [
|
||||
{
|
||||
@@ -25,7 +30,7 @@
|
||||
"observedSha256": "f6d949a56d6b3c9bf58bbb3b94eb3c16e497cdd515da11bf45d9ef0b86c638b2",
|
||||
"provenanceState": "AUTHORIZED_REBASELINE",
|
||||
"snapshotPath": null,
|
||||
"epoch": 1,
|
||||
"epoch": 2,
|
||||
"binding": "CURRENT_WORKTREE_REPLACEMENT",
|
||||
"sourceSha256": "f6d949a56d6b3c9bf58bbb3b94eb3c16e497cdd515da11bf45d9ef0b86c638b2",
|
||||
"replacement": true,
|
||||
@@ -40,7 +45,7 @@
|
||||
"observedSha256": "e1c28687ce34cda539fce096060ab972a98e509c3cdd8335745d565546bcd030",
|
||||
"provenanceState": "AUTHORIZED_REBASELINE",
|
||||
"snapshotPath": null,
|
||||
"epoch": 1,
|
||||
"epoch": 2,
|
||||
"binding": "CURRENT_WORKTREE_REPLACEMENT",
|
||||
"sourceSha256": "97d025812d51642e6c118a7a6228b0481e5ff95e4acb7742f62875f9f27f924b",
|
||||
"replacement": true,
|
||||
@@ -55,7 +60,7 @@
|
||||
"observedSha256": "f6d949a56d6b3c9bf58bbb3b94eb3c16e497cdd515da11bf45d9ef0b86c638b2",
|
||||
"provenanceState": "AUTHORIZED_REBASELINE",
|
||||
"snapshotPath": null,
|
||||
"epoch": 1,
|
||||
"epoch": 2,
|
||||
"binding": "CURRENT_WORKTREE_REPLACEMENT",
|
||||
"sourceSha256": "f6d949a56d6b3c9bf58bbb3b94eb3c16e497cdd515da11bf45d9ef0b86c638b2",
|
||||
"replacement": true,
|
||||
@@ -70,7 +75,7 @@
|
||||
"observedSha256": "2510df2927fbe34ac3c81e4192a9c3ef842388af56dce77d9717681aeda6becd",
|
||||
"provenanceState": "PROVENANCE_RESTORED",
|
||||
"snapshotPath": "tests/golden/corrective/rehydration/M12-git-history-snapshot/files/web/tests/unit/asset-preview-opfs-commit.test.mjs",
|
||||
"epoch": 1,
|
||||
"epoch": 2,
|
||||
"binding": "IMMUTABLE_SOURCE_SNAPSHOT",
|
||||
"sourceSha256": "f489a1d9a4c5fb24a99bce6d31841534c7cf3981b53076a0d9e19d106e9d0d74",
|
||||
"replacement": false
|
||||
@@ -83,7 +88,7 @@
|
||||
"observedSha256": "4fa197fc7d696b5ca9dc6fe953a1c39c6915e37ab21001c14c55311da965048a",
|
||||
"provenanceState": "PROVENANCE_RESTORED",
|
||||
"snapshotPath": "tests/golden/corrective/rehydration/M12-git-history-snapshot/files/web/tests/unit/asset-preview-dedup.test.mjs",
|
||||
"epoch": 1,
|
||||
"epoch": 2,
|
||||
"binding": "IMMUTABLE_SOURCE_SNAPSHOT",
|
||||
"sourceSha256": "e023fdd33e0f40c1331dfdd73cd287dc684256b9d134971ab17db8cfe2a83835",
|
||||
"replacement": false
|
||||
@@ -96,7 +101,7 @@
|
||||
"observedSha256": "217fc2c8b55b9a8bc8ce0e23268cf3062f989853d72f71f999278f2ad8e61b4c",
|
||||
"provenanceState": "PROVENANCE_RESTORED",
|
||||
"snapshotPath": "tests/golden/corrective/rehydration/M12-git-history-snapshot/files/web/tests/unit/asset-preview-quarantine.test.mjs",
|
||||
"epoch": 1,
|
||||
"epoch": 2,
|
||||
"binding": "IMMUTABLE_SOURCE_SNAPSHOT",
|
||||
"sourceSha256": "79c836c7a3be4e9f305a962775444c766577cca87fa6d1698811e75eb21f2d9a",
|
||||
"replacement": false
|
||||
@@ -109,7 +114,7 @@
|
||||
"observedSha256": "cd1f790dffb2b31780cb7f9cfe10e433b335ed282018b2fae5d8fadb687fd5c0",
|
||||
"provenanceState": "PROVENANCE_RESTORED",
|
||||
"snapshotPath": "tests/golden/corrective/rehydration/M12-git-history-snapshot/files/web/tests/unit/asset-preview-reference-gc.test.mjs",
|
||||
"epoch": 1,
|
||||
"epoch": 2,
|
||||
"binding": "IMMUTABLE_SOURCE_SNAPSHOT",
|
||||
"sourceSha256": "c5de3122b5d8aab17daf0179cb4f5bb0b5d299408818849cbe7b18e40a47706e",
|
||||
"replacement": false
|
||||
@@ -122,7 +127,7 @@
|
||||
"observedSha256": "fa908f0a9049287cc67c32fcfb5ed006495fe998f214f602cb0a5116f6856134",
|
||||
"provenanceState": "PROVENANCE_RESTORED",
|
||||
"snapshotPath": "tests/golden/corrective/rehydration/M12-git-history-snapshot/files/web/tests/unit/asset-preview-display.test.mjs",
|
||||
"epoch": 1,
|
||||
"epoch": 2,
|
||||
"binding": "IMMUTABLE_SOURCE_SNAPSHOT",
|
||||
"sourceSha256": "f10a05900c4d1282251f7a76e7c413a18602910f55fe8400f1713f548eba3873",
|
||||
"replacement": false
|
||||
@@ -135,7 +140,7 @@
|
||||
"observedSha256": "1c23077b0c2d61fcdedebae3d6c80e55cb84dedfb9a7600ecf4df5ac0fece3e9",
|
||||
"provenanceState": "PROVENANCE_RESTORED",
|
||||
"snapshotPath": "tests/golden/corrective/rehydration/M12-git-history-snapshot/files/web/tests/unit/library-operation-identity.test.mjs",
|
||||
"epoch": 1,
|
||||
"epoch": 2,
|
||||
"binding": "IMMUTABLE_SOURCE_SNAPSHOT",
|
||||
"sourceSha256": "0e5b2c82d481180eb8eb22de16ad8cdef5e58fa7423c26011faaffbac788e547",
|
||||
"replacement": false
|
||||
@@ -148,7 +153,7 @@
|
||||
"observedSha256": "40b7f14d4f568ae94bedde83e02115c127e0c714e5eb32a6a97b1e1084c4fa68",
|
||||
"provenanceState": "AUTHORIZED_REBASELINE",
|
||||
"snapshotPath": null,
|
||||
"epoch": 1,
|
||||
"epoch": 2,
|
||||
"binding": "CURRENT_WORKTREE_REPLACEMENT",
|
||||
"sourceSha256": "40b7f14d4f568ae94bedde83e02115c127e0c714e5eb32a6a97b1e1084c4fa68",
|
||||
"replacement": true,
|
||||
@@ -163,7 +168,7 @@
|
||||
"observedSha256": "7398625b4d2f921bad11922c3160a02597ea7ed7f15e83d9594ccf843430d15b",
|
||||
"provenanceState": "PROVENANCE_RESTORED",
|
||||
"snapshotPath": "tests/golden/corrective/rehydration/M12-git-history-snapshot/files/web/tests/unit/library-linked-mutation.test.mjs",
|
||||
"epoch": 1,
|
||||
"epoch": 2,
|
||||
"binding": "IMMUTABLE_SOURCE_SNAPSHOT",
|
||||
"sourceSha256": "f19d47cefe89daf6123062e045ec717e6ffe60977e8a4b20c996dd62e49da211",
|
||||
"replacement": false
|
||||
@@ -176,7 +181,7 @@
|
||||
"observedSha256": "40b7f14d4f568ae94bedde83e02115c127e0c714e5eb32a6a97b1e1084c4fa68",
|
||||
"provenanceState": "AUTHORIZED_REBASELINE",
|
||||
"snapshotPath": null,
|
||||
"epoch": 1,
|
||||
"epoch": 2,
|
||||
"binding": "CURRENT_WORKTREE_REPLACEMENT",
|
||||
"sourceSha256": "40b7f14d4f568ae94bedde83e02115c127e0c714e5eb32a6a97b1e1084c4fa68",
|
||||
"replacement": true,
|
||||
@@ -191,7 +196,7 @@
|
||||
"observedSha256": "7492179e72e066ba1e34a5c9055d319e2ee886b4c5f1c4034a781825118796a6",
|
||||
"provenanceState": "PROVENANCE_RESTORED",
|
||||
"snapshotPath": "tests/golden/corrective/rehydration/M12-git-history-snapshot/files/web/tests/unit/library-linked-reload.test.mjs",
|
||||
"epoch": 1,
|
||||
"epoch": 2,
|
||||
"binding": "IMMUTABLE_SOURCE_SNAPSHOT",
|
||||
"sourceSha256": "dff866291468cc01e775fe3b3b95c632f5c0742566f79b956a0193bfd8fd43d2",
|
||||
"replacement": false
|
||||
@@ -204,7 +209,7 @@
|
||||
"observedSha256": "40b7f14d4f568ae94bedde83e02115c127e0c714e5eb32a6a97b1e1084c4fa68",
|
||||
"provenanceState": "AUTHORIZED_REBASELINE",
|
||||
"snapshotPath": null,
|
||||
"epoch": 1,
|
||||
"epoch": 2,
|
||||
"binding": "CURRENT_WORKTREE_REPLACEMENT",
|
||||
"sourceSha256": "40b7f14d4f568ae94bedde83e02115c127e0c714e5eb32a6a97b1e1084c4fa68",
|
||||
"replacement": true,
|
||||
@@ -219,7 +224,7 @@
|
||||
"observedSha256": "0fc3389c4a76c275d332ac5353ca7593884c2e65ba98f9d8db6f24e0518fff75",
|
||||
"provenanceState": "PROVENANCE_RESTORED",
|
||||
"snapshotPath": "tests/golden/corrective/rehydration/M12-git-history-snapshot/files/web/tests/unit/library-linked-missing.test.mjs",
|
||||
"epoch": 1,
|
||||
"epoch": 2,
|
||||
"binding": "IMMUTABLE_SOURCE_SNAPSHOT",
|
||||
"sourceSha256": "4ab6d6ff4845b4ca963399e7eea214ceb412871dc1fdef5bac1ed0333596da4f",
|
||||
"replacement": false
|
||||
@@ -232,7 +237,7 @@
|
||||
"observedSha256": "40b7f14d4f568ae94bedde83e02115c127e0c714e5eb32a6a97b1e1084c4fa68",
|
||||
"provenanceState": "AUTHORIZED_REBASELINE",
|
||||
"snapshotPath": null,
|
||||
"epoch": 1,
|
||||
"epoch": 2,
|
||||
"binding": "CURRENT_WORKTREE_REPLACEMENT",
|
||||
"sourceSha256": "40b7f14d4f568ae94bedde83e02115c127e0c714e5eb32a6a97b1e1084c4fa68",
|
||||
"replacement": true,
|
||||
@@ -247,7 +252,7 @@
|
||||
"observedSha256": "fbdf0f3898037ab15db538df40f3629895cf2b1ebab369332b54962f45297478",
|
||||
"provenanceState": "AUTHORIZED_REBASELINE",
|
||||
"snapshotPath": null,
|
||||
"epoch": 1,
|
||||
"epoch": 2,
|
||||
"binding": "CURRENT_WORKTREE_REPLACEMENT",
|
||||
"sourceSha256": "fbdf0f3898037ab15db538df40f3629895cf2b1ebab369332b54962f45297478",
|
||||
"replacement": true,
|
||||
@@ -262,7 +267,7 @@
|
||||
"observedSha256": "40b7f14d4f568ae94bedde83e02115c127e0c714e5eb32a6a97b1e1084c4fa68",
|
||||
"provenanceState": "AUTHORIZED_REBASELINE",
|
||||
"snapshotPath": null,
|
||||
"epoch": 1,
|
||||
"epoch": 2,
|
||||
"binding": "CURRENT_WORKTREE_REPLACEMENT",
|
||||
"sourceSha256": "40b7f14d4f568ae94bedde83e02115c127e0c714e5eb32a6a97b1e1084c4fa68",
|
||||
"replacement": true,
|
||||
@@ -277,7 +282,7 @@
|
||||
"observedSha256": "1420291c9ba5b4e45455a999ba94864da5eccf5b6e9f377577e01e4dfb218e48",
|
||||
"provenanceState": "AUTHORIZED_REBASELINE",
|
||||
"snapshotPath": null,
|
||||
"epoch": 1,
|
||||
"epoch": 2,
|
||||
"binding": "CURRENT_WORKTREE_REPLACEMENT",
|
||||
"sourceSha256": "1420291c9ba5b4e45455a999ba94864da5eccf5b6e9f377577e01e4dfb218e48",
|
||||
"replacement": true,
|
||||
@@ -292,7 +297,7 @@
|
||||
"observedSha256": "b70aa48b2c8902d1427e2cf80de3b81992d2e0c42d8d271cefdddeadd9162927",
|
||||
"provenanceState": "PROVENANCE_RESTORED",
|
||||
"snapshotPath": "tests/golden/corrective/rehydration/M12-git-history-snapshot/files/web/tests/unit/library-override-writer.test.mjs",
|
||||
"epoch": 1,
|
||||
"epoch": 2,
|
||||
"binding": "IMMUTABLE_SOURCE_SNAPSHOT",
|
||||
"sourceSha256": "e41bd32eb4ce4d331a20ecb91f3325a27f461b9ae85e98940d5afd482ec21c4c",
|
||||
"replacement": false
|
||||
@@ -305,7 +310,7 @@
|
||||
"observedSha256": "40b7f14d4f568ae94bedde83e02115c127e0c714e5eb32a6a97b1e1084c4fa68",
|
||||
"provenanceState": "AUTHORIZED_REBASELINE",
|
||||
"snapshotPath": null,
|
||||
"epoch": 1,
|
||||
"epoch": 2,
|
||||
"binding": "CURRENT_WORKTREE_REPLACEMENT",
|
||||
"sourceSha256": "40b7f14d4f568ae94bedde83e02115c127e0c714e5eb32a6a97b1e1084c4fa68",
|
||||
"replacement": true,
|
||||
@@ -320,7 +325,7 @@
|
||||
"observedSha256": "8c1125d05c47da5e0a4a5b2fb54b5f61613a0c50391de52fb5578db8160be2e8",
|
||||
"provenanceState": "AUTHORIZED_REBASELINE",
|
||||
"snapshotPath": null,
|
||||
"epoch": 1,
|
||||
"epoch": 2,
|
||||
"binding": "CURRENT_WORKTREE_REPLACEMENT",
|
||||
"sourceSha256": "8c1125d05c47da5e0a4a5b2fb54b5f61613a0c50391de52fb5578db8160be2e8",
|
||||
"replacement": true,
|
||||
@@ -335,7 +340,7 @@
|
||||
"observedSha256": "19807407446397ef649a35ad3f3cb06478b5f549a8f1b4b9759bb5eeacddc391",
|
||||
"provenanceState": "PROVENANCE_RESTORED",
|
||||
"snapshotPath": "tests/golden/corrective/rehydration/M12-git-history-snapshot/files/web/tests/unit/library-override-freshness.test.mjs",
|
||||
"epoch": 1,
|
||||
"epoch": 2,
|
||||
"binding": "IMMUTABLE_SOURCE_SNAPSHOT",
|
||||
"sourceSha256": "d48344f31e1ba12e557ca30ece56643583efa633da556f5de3896a8e9175ef8f",
|
||||
"replacement": false
|
||||
@@ -348,7 +353,7 @@
|
||||
"observedSha256": "40b7f14d4f568ae94bedde83e02115c127e0c714e5eb32a6a97b1e1084c4fa68",
|
||||
"provenanceState": "AUTHORIZED_REBASELINE",
|
||||
"snapshotPath": null,
|
||||
"epoch": 1,
|
||||
"epoch": 2,
|
||||
"binding": "CURRENT_WORKTREE_REPLACEMENT",
|
||||
"sourceSha256": "40b7f14d4f568ae94bedde83e02115c127e0c714e5eb32a6a97b1e1084c4fa68",
|
||||
"replacement": true,
|
||||
@@ -363,7 +368,7 @@
|
||||
"observedSha256": "aab9c645f2c05550ff37148b915cfadcc36542bb96fd5535ccfc960defdf57c3",
|
||||
"provenanceState": "AUTHORIZED_REBASELINE",
|
||||
"snapshotPath": null,
|
||||
"epoch": 1,
|
||||
"epoch": 2,
|
||||
"binding": "CURRENT_WORKTREE_REPLACEMENT",
|
||||
"sourceSha256": "aab9c645f2c05550ff37148b915cfadcc36542bb96fd5535ccfc960defdf57c3",
|
||||
"replacement": true,
|
||||
@@ -378,7 +383,7 @@
|
||||
"observedSha256": "2d4b06b5d4a1ab69315bc4c04a2a6d39f9f6b704a056eb030318b53203068c97",
|
||||
"provenanceState": "PROVENANCE_RESTORED",
|
||||
"snapshotPath": "tests/golden/corrective/rehydration/M12-git-history-snapshot/files/web/tests/unit/library-negative-cases.test.mjs",
|
||||
"epoch": 1,
|
||||
"epoch": 2,
|
||||
"binding": "IMMUTABLE_SOURCE_SNAPSHOT",
|
||||
"sourceSha256": "b7ae41b2c35b2fe1598bca4425dd434230bfe4bf342320c88214a060dcbb0a16",
|
||||
"replacement": false
|
||||
@@ -391,7 +396,7 @@
|
||||
"observedSha256": "40b7f14d4f568ae94bedde83e02115c127e0c714e5eb32a6a97b1e1084c4fa68",
|
||||
"provenanceState": "AUTHORIZED_REBASELINE",
|
||||
"snapshotPath": null,
|
||||
"epoch": 1,
|
||||
"epoch": 2,
|
||||
"binding": "CURRENT_WORKTREE_REPLACEMENT",
|
||||
"sourceSha256": "40b7f14d4f568ae94bedde83e02115c127e0c714e5eb32a6a97b1e1084c4fa68",
|
||||
"replacement": true,
|
||||
@@ -406,7 +411,7 @@
|
||||
"observedSha256": "6ed2d8655651bf7915a88cf091e649fc8b0c98500eaad6ae55e39bebe5c504c5",
|
||||
"provenanceState": "AUTHORIZED_REBASELINE",
|
||||
"snapshotPath": null,
|
||||
"epoch": 1,
|
||||
"epoch": 2,
|
||||
"binding": "CURRENT_WORKTREE_REPLACEMENT",
|
||||
"sourceSha256": "6ed2d8655651bf7915a88cf091e649fc8b0c98500eaad6ae55e39bebe5c504c5",
|
||||
"replacement": true,
|
||||
@@ -421,7 +426,7 @@
|
||||
"observedSha256": "40b7f14d4f568ae94bedde83e02115c127e0c714e5eb32a6a97b1e1084c4fa68",
|
||||
"provenanceState": "AUTHORIZED_REBASELINE",
|
||||
"snapshotPath": null,
|
||||
"epoch": 1,
|
||||
"epoch": 2,
|
||||
"binding": "CURRENT_WORKTREE_REPLACEMENT",
|
||||
"sourceSha256": "40b7f14d4f568ae94bedde83e02115c127e0c714e5eb32a6a97b1e1084c4fa68",
|
||||
"replacement": true,
|
||||
@@ -436,7 +441,7 @@
|
||||
"observedSha256": "7c9baef0d653f91e0976c0f1aecea71660adb9845500c2f0c06442996dfaf42c",
|
||||
"provenanceState": "AUTHORIZED_REBASELINE",
|
||||
"snapshotPath": null,
|
||||
"epoch": 1,
|
||||
"epoch": 2,
|
||||
"binding": "CURRENT_WORKTREE_REPLACEMENT",
|
||||
"sourceSha256": "7c9baef0d653f91e0976c0f1aecea71660adb9845500c2f0c06442996dfaf42c",
|
||||
"replacement": true,
|
||||
@@ -451,7 +456,7 @@
|
||||
"observedSha256": "fa5d9ae3359c722449730a3cdb1f0133dd5a9935524ddc27224700147dea9368",
|
||||
"provenanceState": "PROVENANCE_RESTORED",
|
||||
"snapshotPath": "tests/golden/corrective/rehydration/M12-git-history-snapshot/files/web/tests/unit/library-source-origin.test.mjs",
|
||||
"epoch": 1,
|
||||
"epoch": 2,
|
||||
"binding": "IMMUTABLE_SOURCE_SNAPSHOT",
|
||||
"sourceSha256": "89b207c9cb13b4fb055a2dfed0237c0f8a00b13a39cc4175a378f5ef2abdb7ae",
|
||||
"replacement": false
|
||||
@@ -464,7 +469,7 @@
|
||||
"observedSha256": "40b7f14d4f568ae94bedde83e02115c127e0c714e5eb32a6a97b1e1084c4fa68",
|
||||
"provenanceState": "AUTHORIZED_REBASELINE",
|
||||
"snapshotPath": null,
|
||||
"epoch": 1,
|
||||
"epoch": 2,
|
||||
"binding": "CURRENT_WORKTREE_REPLACEMENT",
|
||||
"sourceSha256": "40b7f14d4f568ae94bedde83e02115c127e0c714e5eb32a6a97b1e1084c4fa68",
|
||||
"replacement": true,
|
||||
@@ -479,7 +484,7 @@
|
||||
"observedSha256": "da9c018a98c617809974a577f55a3f2e2f6069347260640ef2397195a2aee0e7",
|
||||
"provenanceState": "AUTHORIZED_REBASELINE",
|
||||
"snapshotPath": null,
|
||||
"epoch": 1,
|
||||
"epoch": 2,
|
||||
"binding": "CURRENT_WORKTREE_REPLACEMENT",
|
||||
"sourceSha256": "da9c018a98c617809974a577f55a3f2e2f6069347260640ef2397195a2aee0e7",
|
||||
"replacement": true,
|
||||
@@ -494,7 +499,7 @@
|
||||
"observedSha256": "6971f333bcbd3eb2e3228506596701877e3ba985644ae5d180b99c232d2e0236",
|
||||
"provenanceState": "PROVENANCE_RESTORED",
|
||||
"snapshotPath": "tests/golden/corrective/rehydration/M12-git-history-snapshot/files/web/tests/unit/library-path-normalization.test.mjs",
|
||||
"epoch": 1,
|
||||
"epoch": 2,
|
||||
"binding": "IMMUTABLE_SOURCE_SNAPSHOT",
|
||||
"sourceSha256": "abde64c60397541e92a83dd9e4a24e65faf340a8d046650604c101a21037c777",
|
||||
"replacement": false
|
||||
@@ -507,7 +512,7 @@
|
||||
"observedSha256": "40b7f14d4f568ae94bedde83e02115c127e0c714e5eb32a6a97b1e1084c4fa68",
|
||||
"provenanceState": "AUTHORIZED_REBASELINE",
|
||||
"snapshotPath": null,
|
||||
"epoch": 1,
|
||||
"epoch": 2,
|
||||
"binding": "CURRENT_WORKTREE_REPLACEMENT",
|
||||
"sourceSha256": "40b7f14d4f568ae94bedde83e02115c127e0c714e5eb32a6a97b1e1084c4fa68",
|
||||
"replacement": true,
|
||||
@@ -522,7 +527,7 @@
|
||||
"observedSha256": "955de46ca2a8921bc062a7ada681e8e9bccaeca1eb5b0e111f1a38683ad26c21",
|
||||
"provenanceState": "AUTHORIZED_REBASELINE",
|
||||
"snapshotPath": null,
|
||||
"epoch": 1,
|
||||
"epoch": 2,
|
||||
"binding": "CURRENT_WORKTREE_REPLACEMENT",
|
||||
"sourceSha256": "955de46ca2a8921bc062a7ada681e8e9bccaeca1eb5b0e111f1a38683ad26c21",
|
||||
"replacement": true,
|
||||
@@ -537,7 +542,7 @@
|
||||
"observedSha256": "f8ccb30b291521858ccb6fb42ea6e0129b50fa44f7a4953971dc1687f3db884c",
|
||||
"provenanceState": "PROVENANCE_RESTORED",
|
||||
"snapshotPath": "tests/golden/corrective/rehydration/M12-git-history-snapshot/files/web/tests/unit/library-path-security.test.mjs",
|
||||
"epoch": 1,
|
||||
"epoch": 2,
|
||||
"binding": "IMMUTABLE_SOURCE_SNAPSHOT",
|
||||
"sourceSha256": "ab302cacb24634a3225dda5cb8f5282cb80b3bd81ed5c8900ddf4ff18267b7e2",
|
||||
"replacement": false
|
||||
@@ -550,7 +555,7 @@
|
||||
"observedSha256": "40b7f14d4f568ae94bedde83e02115c127e0c714e5eb32a6a97b1e1084c4fa68",
|
||||
"provenanceState": "AUTHORIZED_REBASELINE",
|
||||
"snapshotPath": null,
|
||||
"epoch": 1,
|
||||
"epoch": 2,
|
||||
"binding": "CURRENT_WORKTREE_REPLACEMENT",
|
||||
"sourceSha256": "40b7f14d4f568ae94bedde83e02115c127e0c714e5eb32a6a97b1e1084c4fa68",
|
||||
"replacement": true,
|
||||
@@ -565,7 +570,7 @@
|
||||
"observedSha256": "59854c9d6d7b024ca4c30061e2325f079dfb25c25a8f38b342dba4c886494255",
|
||||
"provenanceState": "AUTHORIZED_REBASELINE",
|
||||
"snapshotPath": null,
|
||||
"epoch": 1,
|
||||
"epoch": 2,
|
||||
"binding": "CURRENT_WORKTREE_REPLACEMENT",
|
||||
"sourceSha256": "59854c9d6d7b024ca4c30061e2325f079dfb25c25a8f38b342dba4c886494255",
|
||||
"replacement": true,
|
||||
@@ -580,7 +585,7 @@
|
||||
"observedSha256": "983a77d9bde5302cfe72778cab3452662e15927bcdc538aafc78c68618d558c7",
|
||||
"provenanceState": "PROVENANCE_RESTORED",
|
||||
"snapshotPath": "tests/golden/corrective/rehydration/M12-git-history-snapshot/files/web/tests/unit/library-link-safety.test.mjs",
|
||||
"epoch": 1,
|
||||
"epoch": 2,
|
||||
"binding": "IMMUTABLE_SOURCE_SNAPSHOT",
|
||||
"sourceSha256": "7739275be91222d7bfb61d2f5a1daf812c6860fe34d0aea27df8380a77322120",
|
||||
"replacement": false
|
||||
@@ -593,7 +598,7 @@
|
||||
"observedSha256": "40b7f14d4f568ae94bedde83e02115c127e0c714e5eb32a6a97b1e1084c4fa68",
|
||||
"provenanceState": "AUTHORIZED_REBASELINE",
|
||||
"snapshotPath": null,
|
||||
"epoch": 1,
|
||||
"epoch": 2,
|
||||
"binding": "CURRENT_WORKTREE_REPLACEMENT",
|
||||
"sourceSha256": "40b7f14d4f568ae94bedde83e02115c127e0c714e5eb32a6a97b1e1084c4fa68",
|
||||
"replacement": true,
|
||||
@@ -608,7 +613,7 @@
|
||||
"observedSha256": "b7b4f1a9f775f81b46fc76dec8d520d9ad0292f68d43a1d0593829eb7671ef62",
|
||||
"provenanceState": "PROVENANCE_RESTORED",
|
||||
"snapshotPath": "tests/golden/corrective/rehydration/M12-git-history-snapshot/files/web/tests/unit/library-metadata-first.test.mjs",
|
||||
"epoch": 1,
|
||||
"epoch": 2,
|
||||
"binding": "IMMUTABLE_SOURCE_SNAPSHOT",
|
||||
"sourceSha256": "2da649722acee9cace8db6f337b4a93500a9c775a0b0f086bf38dd2b3e7f9e91",
|
||||
"replacement": false
|
||||
@@ -621,7 +626,7 @@
|
||||
"observedSha256": "40b7f14d4f568ae94bedde83e02115c127e0c714e5eb32a6a97b1e1084c4fa68",
|
||||
"provenanceState": "AUTHORIZED_REBASELINE",
|
||||
"snapshotPath": null,
|
||||
"epoch": 1,
|
||||
"epoch": 2,
|
||||
"binding": "CURRENT_WORKTREE_REPLACEMENT",
|
||||
"sourceSha256": "40b7f14d4f568ae94bedde83e02115c127e0c714e5eb32a6a97b1e1084c4fa68",
|
||||
"replacement": true,
|
||||
@@ -636,7 +641,7 @@
|
||||
"observedSha256": "4394b7bd6528c2823c5860b57f2f88623b280ee099072b44ecf9c63bfbc38bdc",
|
||||
"provenanceState": "PROVENANCE_RESTORED",
|
||||
"snapshotPath": "tests/golden/corrective/rehydration/M12-git-history-snapshot/files/web/tests/unit/library-archive-budget.test.mjs",
|
||||
"epoch": 1,
|
||||
"epoch": 2,
|
||||
"binding": "IMMUTABLE_SOURCE_SNAPSHOT",
|
||||
"sourceSha256": "b0d8356c6fb348d98e28ce220052845a29439b34b3c976b21a4dbf370ea19593",
|
||||
"replacement": false
|
||||
@@ -649,7 +654,7 @@
|
||||
"observedSha256": "40b7f14d4f568ae94bedde83e02115c127e0c714e5eb32a6a97b1e1084c4fa68",
|
||||
"provenanceState": "AUTHORIZED_REBASELINE",
|
||||
"snapshotPath": null,
|
||||
"epoch": 1,
|
||||
"epoch": 2,
|
||||
"binding": "CURRENT_WORKTREE_REPLACEMENT",
|
||||
"sourceSha256": "40b7f14d4f568ae94bedde83e02115c127e0c714e5eb32a6a97b1e1084c4fa68",
|
||||
"replacement": true,
|
||||
@@ -664,7 +669,7 @@
|
||||
"observedSha256": "e101dd559da4f557f10f19b688184cec3fad3e06664082a7c54834bc3cf00e1f",
|
||||
"provenanceState": "PROVENANCE_RESTORED",
|
||||
"snapshotPath": "tests/golden/corrective/rehydration/M12-git-history-snapshot/files/web/tests/unit/library-archive-conflicts.test.mjs",
|
||||
"epoch": 1,
|
||||
"epoch": 2,
|
||||
"binding": "IMMUTABLE_SOURCE_SNAPSHOT",
|
||||
"sourceSha256": "3f2d44dce33b1c17b3a48f58b04fdd821abc88d98ce3d3b5bb724859e0f0ab3c",
|
||||
"replacement": false
|
||||
@@ -677,7 +682,7 @@
|
||||
"observedSha256": "f6d949a56d6b3c9bf58bbb3b94eb3c16e497cdd515da11bf45d9ef0b86c638b2",
|
||||
"provenanceState": "AUTHORIZED_REBASELINE",
|
||||
"snapshotPath": null,
|
||||
"epoch": 1,
|
||||
"epoch": 2,
|
||||
"binding": "CURRENT_WORKTREE_REPLACEMENT",
|
||||
"sourceSha256": "f6d949a56d6b3c9bf58bbb3b94eb3c16e497cdd515da11bf45d9ef0b86c638b2",
|
||||
"replacement": true,
|
||||
@@ -692,7 +697,7 @@
|
||||
"observedSha256": "40b7f14d4f568ae94bedde83e02115c127e0c714e5eb32a6a97b1e1084c4fa68",
|
||||
"provenanceState": "AUTHORIZED_REBASELINE",
|
||||
"snapshotPath": null,
|
||||
"epoch": 1,
|
||||
"epoch": 2,
|
||||
"binding": "CURRENT_WORKTREE_REPLACEMENT",
|
||||
"sourceSha256": "40b7f14d4f568ae94bedde83e02115c127e0c714e5eb32a6a97b1e1084c4fa68",
|
||||
"replacement": true,
|
||||
@@ -707,7 +712,7 @@
|
||||
"observedSha256": "ae8d4779b939351d987ba4fdacc37a5345f72e11fbdebf9a81bd0f8ee25020bf",
|
||||
"provenanceState": "PROVENANCE_RESTORED",
|
||||
"snapshotPath": "tests/golden/corrective/rehydration/M12-git-history-snapshot/files/web/tests/unit/library-archive-cancellation.test.mjs",
|
||||
"epoch": 1,
|
||||
"epoch": 2,
|
||||
"binding": "IMMUTABLE_SOURCE_SNAPSHOT",
|
||||
"sourceSha256": "77e7d5bc64dd6b313006ebf523602601acdaf7949a1484da872ddcd046983786",
|
||||
"replacement": false
|
||||
@@ -720,7 +725,7 @@
|
||||
"observedSha256": "40b7f14d4f568ae94bedde83e02115c127e0c714e5eb32a6a97b1e1084c4fa68",
|
||||
"provenanceState": "AUTHORIZED_REBASELINE",
|
||||
"snapshotPath": null,
|
||||
"epoch": 1,
|
||||
"epoch": 2,
|
||||
"binding": "CURRENT_WORKTREE_REPLACEMENT",
|
||||
"sourceSha256": "40b7f14d4f568ae94bedde83e02115c127e0c714e5eb32a6a97b1e1084c4fa68",
|
||||
"replacement": true,
|
||||
@@ -735,7 +740,7 @@
|
||||
"observedSha256": "3f27fb26a3edd27a8f85d16aaed445546a97683366072da297ff6d7404d1960b",
|
||||
"provenanceState": "PROVENANCE_RESTORED",
|
||||
"snapshotPath": "tests/golden/corrective/rehydration/M12-git-history-snapshot/files/web/tests/unit/library-archive-recovery.test.mjs",
|
||||
"epoch": 1,
|
||||
"epoch": 2,
|
||||
"binding": "IMMUTABLE_SOURCE_SNAPSHOT",
|
||||
"sourceSha256": "a931edef8f3ca1243a80ec2b8e9ff5b8da1dfd339f3d8c162ad2ebd08d3db6a1",
|
||||
"replacement": false
|
||||
@@ -748,7 +753,7 @@
|
||||
"observedSha256": "40b7f14d4f568ae94bedde83e02115c127e0c714e5eb32a6a97b1e1084c4fa68",
|
||||
"provenanceState": "AUTHORIZED_REBASELINE",
|
||||
"snapshotPath": null,
|
||||
"epoch": 1,
|
||||
"epoch": 2,
|
||||
"binding": "CURRENT_WORKTREE_REPLACEMENT",
|
||||
"sourceSha256": "40b7f14d4f568ae94bedde83e02115c127e0c714e5eb32a6a97b1e1084c4fa68",
|
||||
"replacement": true,
|
||||
@@ -763,7 +768,7 @@
|
||||
"observedSha256": "40b7f14d4f568ae94bedde83e02115c127e0c714e5eb32a6a97b1e1084c4fa68",
|
||||
"provenanceState": "AUTHORIZED_REBASELINE",
|
||||
"snapshotPath": null,
|
||||
"epoch": 1,
|
||||
"epoch": 2,
|
||||
"binding": "CURRENT_WORKTREE_REPLACEMENT",
|
||||
"sourceSha256": "40b7f14d4f568ae94bedde83e02115c127e0c714e5eb32a6a97b1e1084c4fa68",
|
||||
"replacement": true,
|
||||
@@ -778,7 +783,7 @@
|
||||
"observedSha256": "edf466eed602786ae2ea254003f0f19d5d44f95b306e364698c4497d3108c0c6",
|
||||
"provenanceState": "AUTHORIZED_REBASELINE",
|
||||
"snapshotPath": null,
|
||||
"epoch": 1,
|
||||
"epoch": 2,
|
||||
"binding": "CURRENT_WORKTREE_REPLACEMENT",
|
||||
"sourceSha256": "edf466eed602786ae2ea254003f0f19d5d44f95b306e364698c4497d3108c0c6",
|
||||
"replacement": true,
|
||||
@@ -793,7 +798,7 @@
|
||||
"observedSha256": "40b7f14d4f568ae94bedde83e02115c127e0c714e5eb32a6a97b1e1084c4fa68",
|
||||
"provenanceState": "AUTHORIZED_REBASELINE",
|
||||
"snapshotPath": null,
|
||||
"epoch": 1,
|
||||
"epoch": 2,
|
||||
"binding": "CURRENT_WORKTREE_REPLACEMENT",
|
||||
"sourceSha256": "40b7f14d4f568ae94bedde83e02115c127e0c714e5eb32a6a97b1e1084c4fa68",
|
||||
"replacement": true,
|
||||
@@ -808,7 +813,7 @@
|
||||
"observedSha256": "cdb436ccba3748338df0da283fb2f1acd25c3f61e560c919c4b77196c936e6e4",
|
||||
"provenanceState": "PROVENANCE_RESTORED",
|
||||
"snapshotPath": "tests/golden/corrective/rehydration/M12-git-history-snapshot/files/web/tests/unit/io-format-capability-matrix.test.mjs",
|
||||
"epoch": 1,
|
||||
"epoch": 2,
|
||||
"binding": "IMMUTABLE_SOURCE_SNAPSHOT",
|
||||
"sourceSha256": "0cc4d8f1df1ecdab20d8100cf5f12b44cb2a68bca4384ef7964a032b2f74b36e",
|
||||
"replacement": false
|
||||
@@ -821,7 +826,7 @@
|
||||
"observedSha256": "40b7f14d4f568ae94bedde83e02115c127e0c714e5eb32a6a97b1e1084c4fa68",
|
||||
"provenanceState": "AUTHORIZED_REBASELINE",
|
||||
"snapshotPath": null,
|
||||
"epoch": 1,
|
||||
"epoch": 2,
|
||||
"binding": "CURRENT_WORKTREE_REPLACEMENT",
|
||||
"sourceSha256": "40b7f14d4f568ae94bedde83e02115c127e0c714e5eb32a6a97b1e1084c4fa68",
|
||||
"replacement": true,
|
||||
@@ -836,7 +841,7 @@
|
||||
"observedSha256": "5861988f3dfbb8c05d36aee3033a72514de53a0cb4ec6f3d832418ef6b5cc8b2",
|
||||
"provenanceState": "AUTHORIZED_REBASELINE",
|
||||
"snapshotPath": null,
|
||||
"epoch": 1,
|
||||
"epoch": 2,
|
||||
"binding": "CURRENT_WORKTREE_REPLACEMENT",
|
||||
"sourceSha256": "5861988f3dfbb8c05d36aee3033a72514de53a0cb4ec6f3d832418ef6b5cc8b2",
|
||||
"replacement": true,
|
||||
@@ -851,7 +856,7 @@
|
||||
"observedSha256": "40b7f14d4f568ae94bedde83e02115c127e0c714e5eb32a6a97b1e1084c4fa68",
|
||||
"provenanceState": "AUTHORIZED_REBASELINE",
|
||||
"snapshotPath": null,
|
||||
"epoch": 1,
|
||||
"epoch": 2,
|
||||
"binding": "CURRENT_WORKTREE_REPLACEMENT",
|
||||
"sourceSha256": "40b7f14d4f568ae94bedde83e02115c127e0c714e5eb32a6a97b1e1084c4fa68",
|
||||
"replacement": true,
|
||||
@@ -866,7 +871,7 @@
|
||||
"observedSha256": "40b7f14d4f568ae94bedde83e02115c127e0c714e5eb32a6a97b1e1084c4fa68",
|
||||
"provenanceState": "AUTHORIZED_REBASELINE",
|
||||
"snapshotPath": null,
|
||||
"epoch": 1,
|
||||
"epoch": 2,
|
||||
"binding": "CURRENT_WORKTREE_REPLACEMENT",
|
||||
"sourceSha256": "40b7f14d4f568ae94bedde83e02115c127e0c714e5eb32a6a97b1e1084c4fa68",
|
||||
"replacement": true,
|
||||
@@ -881,7 +886,7 @@
|
||||
"observedSha256": "5861988f3dfbb8c05d36aee3033a72514de53a0cb4ec6f3d832418ef6b5cc8b2",
|
||||
"provenanceState": "AUTHORIZED_REBASELINE",
|
||||
"snapshotPath": null,
|
||||
"epoch": 1,
|
||||
"epoch": 2,
|
||||
"binding": "CURRENT_WORKTREE_REPLACEMENT",
|
||||
"sourceSha256": "5861988f3dfbb8c05d36aee3033a72514de53a0cb4ec6f3d832418ef6b5cc8b2",
|
||||
"replacement": true,
|
||||
@@ -896,7 +901,7 @@
|
||||
"observedSha256": "667f614322b9fa7ac2fc8f1cd5e4510f25ad153e8d94b7ca376c96928d158ed3",
|
||||
"provenanceState": "AUTHORIZED_REBASELINE",
|
||||
"snapshotPath": null,
|
||||
"epoch": 1,
|
||||
"epoch": 2,
|
||||
"binding": "CURRENT_WORKTREE_REPLACEMENT",
|
||||
"sourceSha256": "667f614322b9fa7ac2fc8f1cd5e4510f25ad153e8d94b7ca376c96928d158ed3",
|
||||
"replacement": true,
|
||||
@@ -911,7 +916,7 @@
|
||||
"observedSha256": "26d804c156d5ef9fec89d6ad393162ddc8423a6058b54f31269dd474f3796a88",
|
||||
"provenanceState": "AUTHORIZED_REBASELINE",
|
||||
"snapshotPath": null,
|
||||
"epoch": 1,
|
||||
"epoch": 2,
|
||||
"binding": "CURRENT_WORKTREE_REPLACEMENT",
|
||||
"sourceSha256": "26d804c156d5ef9fec89d6ad393162ddc8423a6058b54f31269dd474f3796a88",
|
||||
"replacement": true,
|
||||
@@ -926,7 +931,7 @@
|
||||
"observedSha256": "8e0ee239a9ec0db42586c320872758410c38620c5dcc908ada080f1b3b4d52c9",
|
||||
"provenanceState": "AUTHORIZED_REBASELINE",
|
||||
"snapshotPath": null,
|
||||
"epoch": 1,
|
||||
"epoch": 2,
|
||||
"binding": "CURRENT_WORKTREE_REPLACEMENT",
|
||||
"sourceSha256": "8e0ee239a9ec0db42586c320872758410c38620c5dcc908ada080f1b3b4d52c9",
|
||||
"replacement": true,
|
||||
@@ -941,7 +946,7 @@
|
||||
"observedSha256": "40b7f14d4f568ae94bedde83e02115c127e0c714e5eb32a6a97b1e1084c4fa68",
|
||||
"provenanceState": "AUTHORIZED_REBASELINE",
|
||||
"snapshotPath": null,
|
||||
"epoch": 1,
|
||||
"epoch": 2,
|
||||
"binding": "CURRENT_WORKTREE_REPLACEMENT",
|
||||
"sourceSha256": "40b7f14d4f568ae94bedde83e02115c127e0c714e5eb32a6a97b1e1084c4fa68",
|
||||
"replacement": true,
|
||||
@@ -956,7 +961,7 @@
|
||||
"observedSha256": "475758f3f9172d05802a0a6361a53b79a9a239722e4566bdd0dcb00897e1cdfa",
|
||||
"provenanceState": "AUTHORIZED_REBASELINE",
|
||||
"snapshotPath": null,
|
||||
"epoch": 1,
|
||||
"epoch": 2,
|
||||
"binding": "CURRENT_WORKTREE_REPLACEMENT",
|
||||
"sourceSha256": "475758f3f9172d05802a0a6361a53b79a9a239722e4566bdd0dcb00897e1cdfa",
|
||||
"replacement": true,
|
||||
@@ -971,7 +976,7 @@
|
||||
"observedSha256": "cc1c69d74ec079b9dc54f05d3f5a73734bbe989b669f18fae163b7b8bb69fb4f",
|
||||
"provenanceState": "AUTHORIZED_REBASELINE",
|
||||
"snapshotPath": null,
|
||||
"epoch": 1,
|
||||
"epoch": 2,
|
||||
"binding": "CURRENT_WORKTREE_REPLACEMENT",
|
||||
"sourceSha256": "cc1c69d74ec079b9dc54f05d3f5a73734bbe989b669f18fae163b7b8bb69fb4f",
|
||||
"replacement": true,
|
||||
@@ -986,7 +991,7 @@
|
||||
"observedSha256": "40b7f14d4f568ae94bedde83e02115c127e0c714e5eb32a6a97b1e1084c4fa68",
|
||||
"provenanceState": "AUTHORIZED_REBASELINE",
|
||||
"snapshotPath": null,
|
||||
"epoch": 1,
|
||||
"epoch": 2,
|
||||
"binding": "CURRENT_WORKTREE_REPLACEMENT",
|
||||
"sourceSha256": "40b7f14d4f568ae94bedde83e02115c127e0c714e5eb32a6a97b1e1084c4fa68",
|
||||
"replacement": true,
|
||||
@@ -1001,7 +1006,7 @@
|
||||
"observedSha256": "1b5f386666223ba7104fded30466bfc855b6a812c42a608f448d3106edca6000",
|
||||
"provenanceState": "AUTHORIZED_REBASELINE",
|
||||
"snapshotPath": null,
|
||||
"epoch": 1,
|
||||
"epoch": 2,
|
||||
"binding": "CURRENT_WORKTREE_REPLACEMENT",
|
||||
"sourceSha256": "1b5f386666223ba7104fded30466bfc855b6a812c42a608f448d3106edca6000",
|
||||
"replacement": true,
|
||||
@@ -1016,7 +1021,7 @@
|
||||
"observedSha256": "40b7f14d4f568ae94bedde83e02115c127e0c714e5eb32a6a97b1e1084c4fa68",
|
||||
"provenanceState": "AUTHORIZED_REBASELINE",
|
||||
"snapshotPath": null,
|
||||
"epoch": 1,
|
||||
"epoch": 2,
|
||||
"binding": "CURRENT_WORKTREE_REPLACEMENT",
|
||||
"sourceSha256": "40b7f14d4f568ae94bedde83e02115c127e0c714e5eb32a6a97b1e1084c4fa68",
|
||||
"replacement": true,
|
||||
@@ -1031,7 +1036,7 @@
|
||||
"observedSha256": "40b7f14d4f568ae94bedde83e02115c127e0c714e5eb32a6a97b1e1084c4fa68",
|
||||
"provenanceState": "AUTHORIZED_REBASELINE",
|
||||
"snapshotPath": null,
|
||||
"epoch": 1,
|
||||
"epoch": 2,
|
||||
"binding": "CURRENT_WORKTREE_REPLACEMENT",
|
||||
"sourceSha256": "40b7f14d4f568ae94bedde83e02115c127e0c714e5eb32a6a97b1e1084c4fa68",
|
||||
"replacement": true,
|
||||
@@ -1046,7 +1051,7 @@
|
||||
"observedSha256": "40b7f14d4f568ae94bedde83e02115c127e0c714e5eb32a6a97b1e1084c4fa68",
|
||||
"provenanceState": "AUTHORIZED_REBASELINE",
|
||||
"snapshotPath": null,
|
||||
"epoch": 1,
|
||||
"epoch": 2,
|
||||
"binding": "CURRENT_WORKTREE_REPLACEMENT",
|
||||
"sourceSha256": "40b7f14d4f568ae94bedde83e02115c127e0c714e5eb32a6a97b1e1084c4fa68",
|
||||
"replacement": true,
|
||||
@@ -1061,7 +1066,7 @@
|
||||
"observedSha256": "40b7f14d4f568ae94bedde83e02115c127e0c714e5eb32a6a97b1e1084c4fa68",
|
||||
"provenanceState": "AUTHORIZED_REBASELINE",
|
||||
"snapshotPath": null,
|
||||
"epoch": 1,
|
||||
"epoch": 2,
|
||||
"binding": "CURRENT_WORKTREE_REPLACEMENT",
|
||||
"sourceSha256": "40b7f14d4f568ae94bedde83e02115c127e0c714e5eb32a6a97b1e1084c4fa68",
|
||||
"replacement": true,
|
||||
@@ -1074,14 +1079,14 @@
|
||||
"path": "web/protocol/glb-import.ts",
|
||||
"originalSha256": "0b6329c08e6f3cd9af6f27ef7c463b037a7cab94192afb4538d3d6c4cfcbc147",
|
||||
"observedSha256": "1b5f386666223ba7104fded30466bfc855b6a812c42a608f448d3106edca6000",
|
||||
"provenanceState": "AUTHORIZED_REBASELINE",
|
||||
"snapshotPath": null,
|
||||
"epoch": 1,
|
||||
"binding": "CURRENT_WORKTREE_REPLACEMENT",
|
||||
"sourceSha256": "1b5f386666223ba7104fded30466bfc855b6a812c42a608f448d3106edca6000",
|
||||
"replacement": true,
|
||||
"sourcePath": "web/protocol/glb-import.ts",
|
||||
"originalPreserved": "0b6329c08e6f3cd9af6f27ef7c463b037a7cab94192afb4538d3d6c4cfcbc147"
|
||||
"provenanceState": "PROVENANCE_RESTORED",
|
||||
"snapshotPath": "tests/golden/corrective/rehydration/M12-git-history-snapshot/files/web/protocol/glb-import.ts.m12-06F",
|
||||
"epoch": 2,
|
||||
"binding": "SUPPLEMENTAL_EXACT_SOURCE_ARCHIVE",
|
||||
"sourceSha256": "0b6329c08e6f3cd9af6f27ef7c463b037a7cab94192afb4538d3d6c4cfcbc147",
|
||||
"replacement": false,
|
||||
"sourceArchive": "release/blender-web-corresponding-source.tar.gz",
|
||||
"sourceArchiveSha256": "1a57a8c53e68ffca50e730f280c68636553d7a6ea1c4bce3b45823b4677c294c"
|
||||
},
|
||||
{
|
||||
"task": "M12-06F",
|
||||
@@ -1091,7 +1096,7 @@
|
||||
"observedSha256": "b947d77876b1d2fc6ae736998bb1db4cbe92b8c1043b373edbb0c7aafccefccf",
|
||||
"provenanceState": "AUTHORIZED_REBASELINE",
|
||||
"snapshotPath": null,
|
||||
"epoch": 1,
|
||||
"epoch": 2,
|
||||
"binding": "CURRENT_WORKTREE_REPLACEMENT",
|
||||
"sourceSha256": "b947d77876b1d2fc6ae736998bb1db4cbe92b8c1043b373edbb0c7aafccefccf",
|
||||
"replacement": true,
|
||||
@@ -1106,7 +1111,7 @@
|
||||
"observedSha256": "40b7f14d4f568ae94bedde83e02115c127e0c714e5eb32a6a97b1e1084c4fa68",
|
||||
"provenanceState": "AUTHORIZED_REBASELINE",
|
||||
"snapshotPath": null,
|
||||
"epoch": 1,
|
||||
"epoch": 2,
|
||||
"binding": "CURRENT_WORKTREE_REPLACEMENT",
|
||||
"sourceSha256": "40b7f14d4f568ae94bedde83e02115c127e0c714e5eb32a6a97b1e1084c4fa68",
|
||||
"replacement": true,
|
||||
@@ -1121,7 +1126,7 @@
|
||||
"observedSha256": "40b7f14d4f568ae94bedde83e02115c127e0c714e5eb32a6a97b1e1084c4fa68",
|
||||
"provenanceState": "AUTHORIZED_REBASELINE",
|
||||
"snapshotPath": null,
|
||||
"epoch": 1,
|
||||
"epoch": 2,
|
||||
"binding": "CURRENT_WORKTREE_REPLACEMENT",
|
||||
"sourceSha256": "40b7f14d4f568ae94bedde83e02115c127e0c714e5eb32a6a97b1e1084c4fa68",
|
||||
"replacement": true,
|
||||
@@ -1136,7 +1141,7 @@
|
||||
"observedSha256": "40b7f14d4f568ae94bedde83e02115c127e0c714e5eb32a6a97b1e1084c4fa68",
|
||||
"provenanceState": "AUTHORIZED_REBASELINE",
|
||||
"snapshotPath": null,
|
||||
"epoch": 1,
|
||||
"epoch": 2,
|
||||
"binding": "CURRENT_WORKTREE_REPLACEMENT",
|
||||
"sourceSha256": "40b7f14d4f568ae94bedde83e02115c127e0c714e5eb32a6a97b1e1084c4fa68",
|
||||
"replacement": true,
|
||||
@@ -1151,7 +1156,7 @@
|
||||
"observedSha256": "40b7f14d4f568ae94bedde83e02115c127e0c714e5eb32a6a97b1e1084c4fa68",
|
||||
"provenanceState": "AUTHORIZED_REBASELINE",
|
||||
"snapshotPath": null,
|
||||
"epoch": 1,
|
||||
"epoch": 2,
|
||||
"binding": "CURRENT_WORKTREE_REPLACEMENT",
|
||||
"sourceSha256": "40b7f14d4f568ae94bedde83e02115c127e0c714e5eb32a6a97b1e1084c4fa68",
|
||||
"replacement": true,
|
||||
@@ -1166,7 +1171,7 @@
|
||||
"observedSha256": "40b7f14d4f568ae94bedde83e02115c127e0c714e5eb32a6a97b1e1084c4fa68",
|
||||
"provenanceState": "AUTHORIZED_REBASELINE",
|
||||
"snapshotPath": null,
|
||||
"epoch": 1,
|
||||
"epoch": 2,
|
||||
"binding": "CURRENT_WORKTREE_REPLACEMENT",
|
||||
"sourceSha256": "40b7f14d4f568ae94bedde83e02115c127e0c714e5eb32a6a97b1e1084c4fa68",
|
||||
"replacement": true,
|
||||
@@ -1181,7 +1186,7 @@
|
||||
"observedSha256": "40b7f14d4f568ae94bedde83e02115c127e0c714e5eb32a6a97b1e1084c4fa68",
|
||||
"provenanceState": "AUTHORIZED_REBASELINE",
|
||||
"snapshotPath": null,
|
||||
"epoch": 1,
|
||||
"epoch": 2,
|
||||
"binding": "CURRENT_WORKTREE_REPLACEMENT",
|
||||
"sourceSha256": "40b7f14d4f568ae94bedde83e02115c127e0c714e5eb32a6a97b1e1084c4fa68",
|
||||
"replacement": true,
|
||||
@@ -1196,7 +1201,7 @@
|
||||
"observedSha256": "40b7f14d4f568ae94bedde83e02115c127e0c714e5eb32a6a97b1e1084c4fa68",
|
||||
"provenanceState": "AUTHORIZED_REBASELINE",
|
||||
"snapshotPath": null,
|
||||
"epoch": 1,
|
||||
"epoch": 2,
|
||||
"binding": "CURRENT_WORKTREE_REPLACEMENT",
|
||||
"sourceSha256": "40b7f14d4f568ae94bedde83e02115c127e0c714e5eb32a6a97b1e1084c4fa68",
|
||||
"replacement": true,
|
||||
@@ -1211,7 +1216,7 @@
|
||||
"observedSha256": "40b7f14d4f568ae94bedde83e02115c127e0c714e5eb32a6a97b1e1084c4fa68",
|
||||
"provenanceState": "AUTHORIZED_REBASELINE",
|
||||
"snapshotPath": null,
|
||||
"epoch": 1,
|
||||
"epoch": 2,
|
||||
"binding": "CURRENT_WORKTREE_REPLACEMENT",
|
||||
"sourceSha256": "40b7f14d4f568ae94bedde83e02115c127e0c714e5eb32a6a97b1e1084c4fa68",
|
||||
"replacement": true,
|
||||
@@ -1226,7 +1231,7 @@
|
||||
"observedSha256": "40b7f14d4f568ae94bedde83e02115c127e0c714e5eb32a6a97b1e1084c4fa68",
|
||||
"provenanceState": "AUTHORIZED_REBASELINE",
|
||||
"snapshotPath": null,
|
||||
"epoch": 1,
|
||||
"epoch": 2,
|
||||
"binding": "CURRENT_WORKTREE_REPLACEMENT",
|
||||
"sourceSha256": "40b7f14d4f568ae94bedde83e02115c127e0c714e5eb32a6a97b1e1084c4fa68",
|
||||
"replacement": true,
|
||||
|
||||
47
tests/golden/WBV2-P8-003/m12-source-recovery-search.json
Normal file
47
tests/golden/WBV2-P8-003/m12-source-recovery-search.json
Normal file
@@ -0,0 +1,47 @@
|
||||
{
|
||||
"schemaVersion": 1,
|
||||
"operation": "M12_SOURCE_RECOVERY_SEARCH",
|
||||
"policy": "exact_sha256_only",
|
||||
"sources": [
|
||||
{
|
||||
"kind": "CURRENT_GIT_OBJECT_DATABASE",
|
||||
"scope": "all reachable and unreachable objects",
|
||||
"blobsScanned": 25050,
|
||||
"targetShaMatches": 2,
|
||||
"newExactRestorations": 0
|
||||
},
|
||||
{
|
||||
"kind": "TRASH_PROJECT_COPY",
|
||||
"scope": "workinf_Blender_Wasm.3 including its Git object database",
|
||||
"refs": ["main", "origin/main"],
|
||||
"targetShaMatches": 0,
|
||||
"newExactRestorations": 0
|
||||
},
|
||||
{
|
||||
"kind": "LOCAL_RELEASE_SOURCE_ARCHIVE",
|
||||
"path": "release/blender-web-corresponding-source.tar.gz",
|
||||
"sha256": "1a57a8c53e68ffca50e730f280c68636553d7a6ea1c4bce3b45823b4677c294c",
|
||||
"targetShaMatches": 1,
|
||||
"newExactRestorations": 1,
|
||||
"entries": ["M12-06F:protocol:web/protocol/glb-import.ts"]
|
||||
},
|
||||
{
|
||||
"kind": "GITEA_REPOSITORY",
|
||||
"repository": "https://gitea.meswork.com/wangdequan/workinf_Blender_Wasm.git",
|
||||
"branches": ["main:c2c65d3a090fd06ca36a41107974a91398e00a3c"],
|
||||
"tags": [],
|
||||
"releases": [],
|
||||
"actionsArtifacts": "AUTH_REQUIRED_NO_ARTIFACTS_OBSERVED",
|
||||
"targetShaMatches": 0,
|
||||
"newExactRestorations": 0
|
||||
}
|
||||
],
|
||||
"summary": {
|
||||
"historicalEntries": 84,
|
||||
"restoredBeforeSupplement": 22,
|
||||
"supplementalExactRestorations": 1,
|
||||
"authorizedReplacementsAfterEpoch2": 61,
|
||||
"unresolvedHistoricalEntries": 61
|
||||
},
|
||||
"conclusion": "No additional exact historical bytes were found. Epoch 2 must remain an authorized rebaseline and must not be described as full historical reproduction."
|
||||
}
|
||||
@@ -23,21 +23,33 @@
|
||||
"path": "tests/golden/corrective/rehydration/M12-git-history-snapshot/snapshot-manifest.json",
|
||||
"sha256": "e58b1804ed92f19855679f7cdca6787bffcfafbc59c007fd419077ed55a04b54"
|
||||
},
|
||||
"supplemental": {
|
||||
"path": "tests/golden/corrective/rehydration/M12-supplemental-exact-recovery.json",
|
||||
"sha256": "a8947b6b5966dbd870a254a96e7ee26d606011c16cb5c5c3c315ac912eae0908"
|
||||
},
|
||||
"supplementalSnapshot": {
|
||||
"path": "tests/golden/corrective/rehydration/M12-git-history-snapshot/files/web/protocol/glb-import.ts.m12-06F",
|
||||
"sha256": "0b6329c08e6f3cd9af6f27ef7c463b037a7cab94192afb4538d3d6c4cfcbc147"
|
||||
},
|
||||
"searchReport": {
|
||||
"path": "tests/golden/WBV2-P8-003/m12-source-recovery-search.json",
|
||||
"sha256": "4192418563aabf011bb5d6c1407565c87bb492ab208eca69f4768ae35b126fc0"
|
||||
},
|
||||
"epoch": {
|
||||
"path": "tests/golden/WBV2-P8-003/m12-provenance-epoch.json",
|
||||
"sha256": "772c25f1375f46b1649b1431d3e47f4ab532641157ff7a47c9f65a2e2ee67679"
|
||||
"sha256": "a71f145c1d29ca5fec5964213ab2921ab1cf1757099bcc2a3e1d4efedd2b0d61"
|
||||
},
|
||||
"report": {
|
||||
"path": "tests/golden/WBV2-P8-003/provenance-epoch-report.json",
|
||||
"sha256": "053cca1f52a1cc22cd0b8d1e69ec6fa4ec00b2b0584d8f76010d905d9dbde868"
|
||||
"sha256": "9be983254265538913ac3ba837ab95cdb79c0986d0cdc266db52a6fd1ecb50a5"
|
||||
},
|
||||
"generator": {
|
||||
"path": "tools/web/generate-m12-provenance-epoch.mjs",
|
||||
"sha256": "d3658713cdd5479a3ad7001c89cc6799c9c31216fac0a808e2775da0e3cf4de5"
|
||||
"sha256": "60d5956a5e305308d87c7a91d6f74ee458c07ff579cb8770911871e7ad1149dd"
|
||||
},
|
||||
"status": {
|
||||
"path": "docs/status/WBV2-P8-003.md",
|
||||
"sha256": "b86c1d304a411468be8700c59fafad209f301e6391f3ab30f63f7b480edde4d3"
|
||||
"sha256": "5c4eb342ed226199380b55079da38a6505b37488e3bdc4e331a4a2c30506b8a7"
|
||||
},
|
||||
"recoveryPlan": {
|
||||
"path": "tests/golden/WBV2-P8-003/recovery-task-plan.json",
|
||||
@@ -45,15 +57,16 @@
|
||||
},
|
||||
"taskContext": {
|
||||
"path": "tests/golden/WBV2-P8-003/task-context.json",
|
||||
"sha256": "d1b03187a671f0cae6e9dd19303612d3ebd8d3510abb7dd9b5f177d0c4f85f77"
|
||||
"sha256": "a64585c181ade592e3532d5d4886d2ac234f8db7770128778e851f82c87b118e"
|
||||
}
|
||||
},
|
||||
"assertions": {
|
||||
"total": 84,
|
||||
"restoredOriginals": 22,
|
||||
"authorizedReplacements": 62,
|
||||
"restoredOriginals": 23,
|
||||
"authorizedReplacements": 61,
|
||||
"falseRestoredClaims": 0,
|
||||
"historicalManifestsRewritten": false
|
||||
"historicalManifestsRewritten": false,
|
||||
"fullHistoricalReproduction": false
|
||||
},
|
||||
"nextTask": "WBV2-P8-004"
|
||||
}
|
||||
|
||||
@@ -3,12 +3,12 @@
|
||||
"task": "WBV2-P8-003",
|
||||
"operation": "AUTHORIZE_M12_PROVENANCE_EPOCH",
|
||||
"status": "PASS",
|
||||
"epoch": 1,
|
||||
"epoch": 2,
|
||||
"counts": {
|
||||
"total": 84,
|
||||
"restoredOriginals": 22,
|
||||
"authorizedReplacements": 62,
|
||||
"unresolvedHistoricalOriginals": 62
|
||||
"restoredOriginals": 23,
|
||||
"authorizedReplacements": 61,
|
||||
"unresolvedHistoricalOriginals": 61
|
||||
},
|
||||
"sourceSnapshot": {
|
||||
"path": "tests/golden/corrective/rehydration/M12-git-history-snapshot/snapshot-manifest.json",
|
||||
@@ -19,7 +19,8 @@
|
||||
"historicalEvidencePreserved": true,
|
||||
"falseRestoredClaims": 0,
|
||||
"historicalManifestsRewritten": false,
|
||||
"allCurrentBindingsHashVerified": false
|
||||
"fullHistoricalReproduction": false,
|
||||
"allCurrentBindingsHashVerified": true
|
||||
},
|
||||
"nextTask": "WBV2-P8-004"
|
||||
}
|
||||
|
||||
@@ -40,7 +40,7 @@
|
||||
},
|
||||
{
|
||||
"path": "tools/web/generate-m12-provenance-epoch.mjs",
|
||||
"bytes": 8884,
|
||||
"bytes": 10709,
|
||||
"reason": "EVIDENCE_BYTE_BUDGET"
|
||||
},
|
||||
{
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
"artifacts": {
|
||||
"parentManifest": {
|
||||
"path": "tests/golden/WBV2-P8-003/manifest.json",
|
||||
"sha256": "a2f240de899de0ca858263937344b030a64c939df6daf8df06ada176eb859471"
|
||||
"sha256": "9be94c2a037bacea694e4e4121b9ff774b6f53c177873c7c47781711170f5d68"
|
||||
},
|
||||
"receipts": {
|
||||
"path": "tests/golden/WBV2-P8-002/atomic-receipt-index.json",
|
||||
@@ -17,7 +17,15 @@
|
||||
},
|
||||
"provenanceEpoch": {
|
||||
"path": "tests/golden/WBV2-P8-003/m12-provenance-epoch.json",
|
||||
"sha256": "772c25f1375f46b1649b1431d3e47f4ab532641157ff7a47c9f65a2e2ee67679"
|
||||
"sha256": "a71f145c1d29ca5fec5964213ab2921ab1cf1757099bcc2a3e1d4efedd2b0d61"
|
||||
},
|
||||
"approval": {
|
||||
"path": "docs/status/M12-PROVENANCE-EPOCH-2-APPROVAL.json",
|
||||
"sha256": "cffc869734af94ffe6b8b8004d7ab8cc2c9edcb85ec2a877548e0b0f923f5ea3"
|
||||
},
|
||||
"searchReport": {
|
||||
"path": "tests/golden/WBV2-P8-003/m12-source-recovery-search.json",
|
||||
"sha256": "4192418563aabf011bb5d6c1407565c87bb492ab208eca69f4768ae35b126fc0"
|
||||
},
|
||||
"previousGate": {
|
||||
"path": "tests/golden/WBV2-P7-003/release-gate-report.json",
|
||||
@@ -25,19 +33,19 @@
|
||||
},
|
||||
"generator": {
|
||||
"path": "tools/web/generate-m12-provenance-epoch.mjs",
|
||||
"sha256": "d3658713cdd5479a3ad7001c89cc6799c9c31216fac0a808e2775da0e3cf4de5"
|
||||
"sha256": "60d5956a5e305308d87c7a91d6f74ee458c07ff579cb8770911871e7ad1149dd"
|
||||
},
|
||||
"checker": {
|
||||
"path": "tools/web/check-wbv2-recovery-release-gate.mjs",
|
||||
"sha256": "4af9c128fd5658621ae5dcf41b90e2a9964b8a1c32fe982a3d539ab4639324b7"
|
||||
"sha256": "c500dd7fb8d581b2e8292da6f4b6afcd487acdf453ca55ec48dab9e7dc553b27"
|
||||
},
|
||||
"report": {
|
||||
"path": "tests/golden/WBV2-P8-004/recovery-release-gate-report.json",
|
||||
"sha256": "8781b6546410284b3075e23338823d3120e7787c35588120fe8a0bb22adeb7df"
|
||||
"sha256": "0479304c82aec61f98248eca63c7883fb5f36dcd4dd0f296ff42bc32d987000e"
|
||||
},
|
||||
"status": {
|
||||
"path": "docs/status/WBV2-P8-004.md",
|
||||
"sha256": "b24961e3ac3bf0240ccc3345b23fc787340da74dd7d7e2cc01869b035037104a"
|
||||
"sha256": "c32b7ef43ba52ef400250c11f2ed5ad60267e73cac309afef22ae724a2136917"
|
||||
},
|
||||
"recoveryPlan": {
|
||||
"path": "tests/golden/WBV2-P8-004/recovery-task-plan.json",
|
||||
@@ -45,15 +53,18 @@
|
||||
},
|
||||
"taskContext": {
|
||||
"path": "tests/golden/WBV2-P8-004/task-context.json",
|
||||
"sha256": "fa43615164f1cff24612419181b155184351dfb018120aac7987915706a53c76"
|
||||
"sha256": "5aa338e08e1aa583b80e3b73bf760e32a0da88d40de97b673ac6d4b42d0ea793"
|
||||
}
|
||||
},
|
||||
"assertions": {
|
||||
"atomicReceipts": 45,
|
||||
"restoredOriginals": 22,
|
||||
"authorizedReplacements": 62,
|
||||
"restoredOriginals": 23,
|
||||
"authorizedReplacements": 61,
|
||||
"historicalProvenanceClosed": false,
|
||||
"featureParityClaims": 0
|
||||
"authorizedRebaselineApproved": true,
|
||||
"fullHistoricalReproduction": false,
|
||||
"featureParityClaims": 0,
|
||||
"releaseScope": "AUTHORIZED_REBASELINE_ONLY"
|
||||
},
|
||||
"nextTask": null
|
||||
}
|
||||
|
||||
@@ -12,10 +12,22 @@
|
||||
},
|
||||
"provenanceEpoch": {
|
||||
"path": "tests/golden/WBV2-P8-003/m12-provenance-epoch.json",
|
||||
"sha256": "772c25f1375f46b1649b1431d3e47f4ab532641157ff7a47c9f65a2e2ee67679",
|
||||
"sha256": "a71f145c1d29ca5fec5964213ab2921ab1cf1757099bcc2a3e1d4efedd2b0d61",
|
||||
"entries": 84,
|
||||
"restoredOriginals": 22,
|
||||
"authorizedReplacements": 62
|
||||
"restoredOriginals": 23,
|
||||
"authorizedReplacements": 61
|
||||
},
|
||||
"approval": {
|
||||
"path": "docs/status/M12-PROVENANCE-EPOCH-2-APPROVAL.json",
|
||||
"sha256": "cffc869734af94ffe6b8b8004d7ab8cc2c9edcb85ec2a877548e0b0f923f5ea3",
|
||||
"decision": "APPROVED",
|
||||
"approvedBy": "wangdequan"
|
||||
},
|
||||
"searchReport": {
|
||||
"path": "tests/golden/WBV2-P8-003/m12-source-recovery-search.json",
|
||||
"sha256": "4192418563aabf011bb5d6c1407565c87bb492ab208eca69f4768ae35b126fc0",
|
||||
"exactAdditional": 1,
|
||||
"unresolvedHistorical": 61
|
||||
},
|
||||
"previousGate": {
|
||||
"path": "tests/golden/WBV2-P7-003/release-gate-report.json",
|
||||
@@ -27,14 +39,17 @@
|
||||
"atomicReceiptStatus": "CLOSED",
|
||||
"chromiumFamilyCount": 15,
|
||||
"atomicBehaviorCount": 45,
|
||||
"provenanceStatus": "AUTHORIZED_REBASELINE",
|
||||
"historicalOriginalStatus": "PARTIAL"
|
||||
"provenanceStatus": "AUTHORIZED_REBASELINE_APPROVED",
|
||||
"historicalOriginalStatus": "PARTIAL",
|
||||
"fullHistoricalReproduction": false
|
||||
},
|
||||
"decision": {
|
||||
"status": "BLOCKED",
|
||||
"code": "HISTORICAL_PROVENANCE_REBASELINE_REQUIRED",
|
||||
"reason": "62 M12 entries use an authorized current-worktree replacement; original historical bytes are unavailable",
|
||||
"status": "READY_WITH_AUTHORIZED_REBASELINE",
|
||||
"code": "AUTHORIZED_REBASELINE_ACCEPTED",
|
||||
"reason": "Project owner approved provenance epoch 2; 61 replacements are accepted only as a new current baseline",
|
||||
"featureParityClaims": 0,
|
||||
"fullHistoricalReproduction": false,
|
||||
"releaseScope": "AUTHORIZED_REBASELINE_ONLY",
|
||||
"nextTask": null
|
||||
},
|
||||
"negative": {
|
||||
@@ -42,8 +57,9 @@
|
||||
"receiptHashDrift": "REJECTED",
|
||||
"provenanceHashDrift": "REJECTED",
|
||||
"falseHistoricalRestoration": "REJECTED",
|
||||
"missingApproval": "REJECTED",
|
||||
"unsupportedBrowser": "REJECTED",
|
||||
"queueAdvance": "BLOCKED"
|
||||
"queueAdvance": "CLOSED"
|
||||
},
|
||||
"nextTask": null
|
||||
}
|
||||
|
||||
@@ -19,12 +19,12 @@
|
||||
"limits": {
|
||||
"maxFiles": 12,
|
||||
"evidenceBytes": 8192,
|
||||
"contextRemainingBytes": 3385,
|
||||
"contextRemainingTokens": 845
|
||||
"contextRemainingBytes": 2689,
|
||||
"contextRemainingTokens": 671
|
||||
},
|
||||
"source": {
|
||||
"bytes": 6519,
|
||||
"tokens": 1631
|
||||
"bytes": 7215,
|
||||
"tokens": 1805
|
||||
},
|
||||
"selected": [],
|
||||
"excluded": [
|
||||
@@ -35,13 +35,13 @@
|
||||
},
|
||||
{
|
||||
"path": "tests/golden/WBV2-P8-003/m12-provenance-epoch.json",
|
||||
"bytes": 59189,
|
||||
"bytes": 59741,
|
||||
"reason": "EVIDENCE_BYTE_BUDGET"
|
||||
},
|
||||
{
|
||||
"path": "tools/web/check-wbv2-recovery-release-gate.mjs",
|
||||
"bytes": 6686,
|
||||
"reason": "CONTEXT_REMAINING_SPACE"
|
||||
"bytes": 8407,
|
||||
"reason": "EVIDENCE_BYTE_BUDGET"
|
||||
},
|
||||
{
|
||||
"path": "tests/golden/WBV2-P8-004/",
|
||||
@@ -109,16 +109,16 @@
|
||||
"parentTask": "WBV2-P8-002",
|
||||
"status": "done",
|
||||
"nextTask": "WBV2-P8-004",
|
||||
"artifactCount": 10
|
||||
"artifactCount": 13
|
||||
},
|
||||
"statusSummary": [
|
||||
"# WBV2-P8-003 status",
|
||||
"- task: `WBV2-P8-003`; parent: `WBV2-P8-002`; status: `done`",
|
||||
"- provenance epoch: `1`",
|
||||
"- historical originals restored: `22/84`",
|
||||
"- authorized replacements: `62/84`",
|
||||
"- provenance epoch: `2`",
|
||||
"- historical originals restored: `23/84`",
|
||||
"- authorized replacements: `61/84`",
|
||||
"- nextTask: `WBV2-P8-004`",
|
||||
"The 22 exact Git-history matches remain immutable restorations. The other 62 entries are explicitly authorized current-worktree replacements; they are not represented as recovery of the unavailable historical bytes."
|
||||
"The 23 exact matches remain immutable restorations. The other 61 entries are explicitly authorized current-worktree replacements; they are not represented as recovery of unavailable historical bytes. Full historical reproduction remains false."
|
||||
]
|
||||
},
|
||||
"budgets": {
|
||||
@@ -149,25 +149,25 @@
|
||||
},
|
||||
{
|
||||
"path": "tests/golden/WBV2-P8-003/manifest.json",
|
||||
"bytes": 2199,
|
||||
"lines": 60,
|
||||
"tokens": 550
|
||||
"bytes": 2867,
|
||||
"lines": 73,
|
||||
"tokens": 717
|
||||
},
|
||||
{
|
||||
"path": "docs/status/WBV2-P8-003.md",
|
||||
"bytes": 426,
|
||||
"bytes": 454,
|
||||
"lines": 10,
|
||||
"tokens": 107
|
||||
"tokens": 114
|
||||
}
|
||||
],
|
||||
"sourceTokens": 1631,
|
||||
"sourceTokens": 1805,
|
||||
"evidenceFiles": 0,
|
||||
"evidenceBytes": 0,
|
||||
"evidenceTokens": 0,
|
||||
"totalTokens": 1631,
|
||||
"totalTokens": 1805,
|
||||
"reservedEnvelopeTokens": 1024,
|
||||
"estimatedContextTokens": 2655,
|
||||
"serializedContextTokens": 620,
|
||||
"estimatedContextTokens": 2829,
|
||||
"serializedContextTokens": 611,
|
||||
"withinBudget": true
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1 +1 @@
|
||||
{"schemaVersion":1,"operation":"BLENDER_WEB_CAPABILITY_TASK_INDEX","source":{"path":"tests/golden/WBV2-P8-004/recovery-task-plan.json","sha256":"451ac79c0262391679e5e7c3251b99c49973d914e85e14d7e09eb9794befc4be"},"catalog":{"path":"tests/golden/WBV2/task-catalog.jsonl","sha256":"3b2bb72a9494de0e69bb973dcbcf64dbf62d8dda80096141212936f90ef72a42"},"taskCount":36,"activeTask":"WBV2-P8-004","entries":{"WBV2-P0-001":{"line":0,"offset":0,"length":308,"previous":null,"next":"WBV2-P0-002"},"WBV2-P0-002":{"line":1,"offset":308,"length":318,"previous":"WBV2-P0-001","next":"WBV2-P0-003"},"WBV2-P0-003":{"line":2,"offset":626,"length":306,"previous":"WBV2-P0-002","next":"WBV2-P1-001"},"WBV2-P1-001":{"line":3,"offset":932,"length":318,"previous":"WBV2-P0-003","next":"WBV2-P1-002"},"WBV2-P1-002":{"line":4,"offset":1250,"length":299,"previous":"WBV2-P1-001","next":"WBV2-P1-003"},"WBV2-P1-003":{"line":5,"offset":1549,"length":303,"previous":"WBV2-P1-002","next":"WBV2-P1-004"},"WBV2-P1-004":{"line":6,"offset":1852,"length":309,"previous":"WBV2-P1-003","next":"WBV2-P1-005"},"WBV2-P1-005":{"line":7,"offset":2161,"length":324,"previous":"WBV2-P1-004","next":"WBV2-P2-001"},"WBV2-P2-001":{"line":8,"offset":2485,"length":267,"previous":"WBV2-P1-005","next":"WBV2-P2-002"},"WBV2-P2-002":{"line":9,"offset":2752,"length":267,"previous":"WBV2-P2-001","next":"WBV2-P2-003"},"WBV2-P2-003":{"line":10,"offset":3019,"length":274,"previous":"WBV2-P2-002","next":"WBV2-P2-004"},"WBV2-P2-004":{"line":11,"offset":3293,"length":284,"previous":"WBV2-P2-003","next":"WBV2-P2-005"},"WBV2-P2-005":{"line":12,"offset":3577,"length":291,"previous":"WBV2-P2-004","next":"WBV2-P3-001"},"WBV2-P3-001":{"line":13,"offset":3868,"length":271,"previous":"WBV2-P2-005","next":"WBV2-P3-002"},"WBV2-P3-002":{"line":14,"offset":4139,"length":266,"previous":"WBV2-P3-001","next":"WBV2-P3-003"},"WBV2-P3-003":{"line":15,"offset":4405,"length":273,"previous":"WBV2-P3-002","next":"WBV2-P3-004"},"WBV2-P3-004":{"line":16,"offset":4678,"length":263,"previous":"WBV2-P3-003","next":"WBV2-P3-005"},"WBV2-P3-005":{"line":17,"offset":4941,"length":292,"previous":"WBV2-P3-004","next":"WBV2-P4-001"},"WBV2-P4-001":{"line":18,"offset":5233,"length":283,"previous":"WBV2-P3-005","next":"WBV2-P4-002"},"WBV2-P4-002":{"line":19,"offset":5516,"length":277,"previous":"WBV2-P4-001","next":"WBV2-P4-003"},"WBV2-P4-003":{"line":20,"offset":5793,"length":287,"previous":"WBV2-P4-002","next":"WBV2-P4-004"},"WBV2-P4-004":{"line":21,"offset":6080,"length":290,"previous":"WBV2-P4-003","next":"WBV2-P5-001"},"WBV2-P5-001":{"line":22,"offset":6370,"length":296,"previous":"WBV2-P4-004","next":"WBV2-P5-002"},"WBV2-P5-002":{"line":23,"offset":6666,"length":282,"previous":"WBV2-P5-001","next":"WBV2-P5-003"},"WBV2-P5-003":{"line":24,"offset":6948,"length":278,"previous":"WBV2-P5-002","next":"WBV2-P6-001"},"WBV2-P6-001":{"line":25,"offset":7226,"length":278,"previous":"WBV2-P5-003","next":"WBV2-P6-002"},"WBV2-P6-002":{"line":26,"offset":7504,"length":313,"previous":"WBV2-P6-001","next":"WBV2-P6-003"},"WBV2-P6-003":{"line":27,"offset":7817,"length":316,"previous":"WBV2-P6-002","next":"WBV2-P7-001"},"WBV2-P7-001":{"line":28,"offset":8133,"length":312,"previous":"WBV2-P6-003","next":"WBV2-P7-002"},"WBV2-P7-002":{"line":29,"offset":8445,"length":275,"previous":"WBV2-P7-001","next":"WBV2-P7-003"},"WBV2-P7-003":{"line":30,"offset":8720,"length":310,"previous":"WBV2-P7-002","next":"WBV2-P8-000"},"WBV2-P8-000":{"line":31,"offset":9030,"length":290,"previous":"WBV2-P7-003","next":"WBV2-P8-001"},"WBV2-P8-001":{"line":32,"offset":9320,"length":306,"previous":"WBV2-P8-000","next":"WBV2-P8-002"},"WBV2-P8-002":{"line":33,"offset":9626,"length":307,"previous":"WBV2-P8-001","next":"WBV2-P8-003"},"WBV2-P8-003":{"line":34,"offset":9933,"length":312,"previous":"WBV2-P8-002","next":"WBV2-P8-004"},"WBV2-P8-004":{"line":35,"offset":10245,"length":284,"previous":"WBV2-P8-003","next":null}}}
|
||||
{"schemaVersion":1,"operation":"BLENDER_WEB_CAPABILITY_TASK_INDEX","source":{"path":"tests/golden/WBV2-P8-003/recovery-task-plan.json","sha256":"788de39c33cf87d3b8d3812f13e9cbd7d1acbfd6fb70df522ccd69f454704666"},"catalog":{"path":"tests/golden/WBV2/task-catalog.jsonl","sha256":"3b2bb72a9494de0e69bb973dcbcf64dbf62d8dda80096141212936f90ef72a42"},"taskCount":36,"activeTask":"WBV2-P8-004","entries":{"WBV2-P0-001":{"line":0,"offset":0,"length":308,"previous":null,"next":"WBV2-P0-002"},"WBV2-P0-002":{"line":1,"offset":308,"length":318,"previous":"WBV2-P0-001","next":"WBV2-P0-003"},"WBV2-P0-003":{"line":2,"offset":626,"length":306,"previous":"WBV2-P0-002","next":"WBV2-P1-001"},"WBV2-P1-001":{"line":3,"offset":932,"length":318,"previous":"WBV2-P0-003","next":"WBV2-P1-002"},"WBV2-P1-002":{"line":4,"offset":1250,"length":299,"previous":"WBV2-P1-001","next":"WBV2-P1-003"},"WBV2-P1-003":{"line":5,"offset":1549,"length":303,"previous":"WBV2-P1-002","next":"WBV2-P1-004"},"WBV2-P1-004":{"line":6,"offset":1852,"length":309,"previous":"WBV2-P1-003","next":"WBV2-P1-005"},"WBV2-P1-005":{"line":7,"offset":2161,"length":324,"previous":"WBV2-P1-004","next":"WBV2-P2-001"},"WBV2-P2-001":{"line":8,"offset":2485,"length":267,"previous":"WBV2-P1-005","next":"WBV2-P2-002"},"WBV2-P2-002":{"line":9,"offset":2752,"length":267,"previous":"WBV2-P2-001","next":"WBV2-P2-003"},"WBV2-P2-003":{"line":10,"offset":3019,"length":274,"previous":"WBV2-P2-002","next":"WBV2-P2-004"},"WBV2-P2-004":{"line":11,"offset":3293,"length":284,"previous":"WBV2-P2-003","next":"WBV2-P2-005"},"WBV2-P2-005":{"line":12,"offset":3577,"length":291,"previous":"WBV2-P2-004","next":"WBV2-P3-001"},"WBV2-P3-001":{"line":13,"offset":3868,"length":271,"previous":"WBV2-P2-005","next":"WBV2-P3-002"},"WBV2-P3-002":{"line":14,"offset":4139,"length":266,"previous":"WBV2-P3-001","next":"WBV2-P3-003"},"WBV2-P3-003":{"line":15,"offset":4405,"length":273,"previous":"WBV2-P3-002","next":"WBV2-P3-004"},"WBV2-P3-004":{"line":16,"offset":4678,"length":263,"previous":"WBV2-P3-003","next":"WBV2-P3-005"},"WBV2-P3-005":{"line":17,"offset":4941,"length":292,"previous":"WBV2-P3-004","next":"WBV2-P4-001"},"WBV2-P4-001":{"line":18,"offset":5233,"length":283,"previous":"WBV2-P3-005","next":"WBV2-P4-002"},"WBV2-P4-002":{"line":19,"offset":5516,"length":277,"previous":"WBV2-P4-001","next":"WBV2-P4-003"},"WBV2-P4-003":{"line":20,"offset":5793,"length":287,"previous":"WBV2-P4-002","next":"WBV2-P4-004"},"WBV2-P4-004":{"line":21,"offset":6080,"length":290,"previous":"WBV2-P4-003","next":"WBV2-P5-001"},"WBV2-P5-001":{"line":22,"offset":6370,"length":296,"previous":"WBV2-P4-004","next":"WBV2-P5-002"},"WBV2-P5-002":{"line":23,"offset":6666,"length":282,"previous":"WBV2-P5-001","next":"WBV2-P5-003"},"WBV2-P5-003":{"line":24,"offset":6948,"length":278,"previous":"WBV2-P5-002","next":"WBV2-P6-001"},"WBV2-P6-001":{"line":25,"offset":7226,"length":278,"previous":"WBV2-P5-003","next":"WBV2-P6-002"},"WBV2-P6-002":{"line":26,"offset":7504,"length":313,"previous":"WBV2-P6-001","next":"WBV2-P6-003"},"WBV2-P6-003":{"line":27,"offset":7817,"length":316,"previous":"WBV2-P6-002","next":"WBV2-P7-001"},"WBV2-P7-001":{"line":28,"offset":8133,"length":312,"previous":"WBV2-P6-003","next":"WBV2-P7-002"},"WBV2-P7-002":{"line":29,"offset":8445,"length":275,"previous":"WBV2-P7-001","next":"WBV2-P7-003"},"WBV2-P7-003":{"line":30,"offset":8720,"length":310,"previous":"WBV2-P7-002","next":"WBV2-P8-000"},"WBV2-P8-000":{"line":31,"offset":9030,"length":290,"previous":"WBV2-P7-003","next":"WBV2-P8-001"},"WBV2-P8-001":{"line":32,"offset":9320,"length":306,"previous":"WBV2-P8-000","next":"WBV2-P8-002"},"WBV2-P8-002":{"line":33,"offset":9626,"length":307,"previous":"WBV2-P8-001","next":"WBV2-P8-003"},"WBV2-P8-003":{"line":34,"offset":9933,"length":312,"previous":"WBV2-P8-002","next":"WBV2-P8-004"},"WBV2-P8-004":{"line":35,"offset":10245,"length":284,"previous":"WBV2-P8-003","next":null}}}
|
||||
|
||||
@@ -0,0 +1,485 @@
|
||||
import type { GLBAssetBuffer } from "./glb-export";
|
||||
import type { SceneSnapshotIR } from "./scene-ir";
|
||||
|
||||
const GLB_MAGIC = 0x46546c67;
|
||||
const JSON_CHUNK = 0x4e4f534a;
|
||||
const BIN_CHUNK = 0x004e4942;
|
||||
|
||||
interface GLBAccessor {
|
||||
bufferView?: number;
|
||||
byteOffset?: number;
|
||||
componentType: number;
|
||||
count: number;
|
||||
type: string;
|
||||
normalized?: boolean;
|
||||
min?: number[];
|
||||
max?: number[];
|
||||
sparse?: Record<string, unknown>;
|
||||
}
|
||||
|
||||
interface GLBBufferView {
|
||||
buffer: number;
|
||||
byteOffset?: number;
|
||||
byteLength: number;
|
||||
}
|
||||
|
||||
interface GLBPrimitive {
|
||||
attributes?: Record<string, number>;
|
||||
indices?: number;
|
||||
material?: number;
|
||||
mode?: number;
|
||||
targets?: Array<Record<string, number>>;
|
||||
}
|
||||
|
||||
interface GLBDocument {
|
||||
asset?: { version?: string; generator?: string };
|
||||
scene?: number;
|
||||
scenes?: Array<{ nodes?: number[] }>;
|
||||
extensionsUsed?: string[];
|
||||
extensionsRequired?: string[];
|
||||
buffers?: Array<{ byteLength?: number; uri?: string }>;
|
||||
bufferViews?: GLBBufferView[];
|
||||
accessors?: GLBAccessor[];
|
||||
meshes?: Array<{ name?: string; primitives?: GLBPrimitive[]; extras?: Record<string, unknown> }>;
|
||||
images?: Array<{ name?: string; mimeType?: string; bufferView?: number; uri?: string; extras?: Record<string, unknown> }>;
|
||||
samplers?: Array<Record<string, unknown>>;
|
||||
textures?: Array<{ sampler?: number; source?: number }>;
|
||||
materials?: Array<{
|
||||
name?: string;
|
||||
alphaMode?: string;
|
||||
doubleSided?: boolean;
|
||||
pbrMetallicRoughness?: {
|
||||
baseColorFactor?: number[];
|
||||
baseColorTexture?: Record<string, unknown>;
|
||||
metallicFactor?: number;
|
||||
roughnessFactor?: number;
|
||||
};
|
||||
normalTexture?: Record<string, unknown>;
|
||||
emissiveFactor?: number[];
|
||||
}>;
|
||||
nodes?: Array<{
|
||||
name?: string;
|
||||
mesh?: number;
|
||||
skin?: number;
|
||||
children?: number[];
|
||||
translation?: number[];
|
||||
rotation?: number[];
|
||||
scale?: number[];
|
||||
}>;
|
||||
skins?: Array<{ name?: string; joints?: number[]; inverseBindMatrices?: number; skeleton?: number; extras?: Record<string, unknown> }>;
|
||||
animations?: Array<{
|
||||
name?: string;
|
||||
samplers?: Array<{ input?: number; output?: number; interpolation?: string }>;
|
||||
channels?: Array<{ sampler?: number; target?: { node?: number; path?: string } }>;
|
||||
extras?: Record<string, unknown>;
|
||||
}>;
|
||||
}
|
||||
|
||||
export const GLB_IMPORT_BUDGET = {
|
||||
maxBytes: 512 * 1024,
|
||||
maxJsonBytes: 256 * 1024,
|
||||
maxBufferViews: 4096,
|
||||
maxAccessors: 8192,
|
||||
} as const;
|
||||
|
||||
export interface ImportedGLBImage {
|
||||
name?: string;
|
||||
blenderId?: string;
|
||||
mimeType?: string;
|
||||
byteLength: number;
|
||||
signature: number[];
|
||||
}
|
||||
|
||||
export interface ImportedGLBSemantics {
|
||||
version: 2;
|
||||
meshCount: number;
|
||||
primitiveCount: number;
|
||||
meshes: Array<{ name?: string; blenderId?: string; primitiveCount: number; attributes: string[]; morphTargetCount: number }>;
|
||||
images: ImportedGLBImage[];
|
||||
skinCount: number;
|
||||
skins: Array<{ jointCount: number; inverseBindType?: string; inverseBindCount?: number }>;
|
||||
animationCount: number;
|
||||
animationChannelCount: number;
|
||||
animationPaths: string[];
|
||||
}
|
||||
|
||||
export interface GLBSemanticComparison {
|
||||
compatible: boolean;
|
||||
mismatches: string[];
|
||||
}
|
||||
|
||||
export interface GLBDesktopAccessorSemantics {
|
||||
componentType: number;
|
||||
count: number;
|
||||
type: string;
|
||||
normalized: boolean;
|
||||
min: number[] | null;
|
||||
max: number[] | null;
|
||||
}
|
||||
|
||||
export interface GLBDesktopFixtureSemantics {
|
||||
asset: { version?: string; generator?: string } | null;
|
||||
extensionsUsed: string[];
|
||||
extensionsRequired: string[];
|
||||
scene: number | null;
|
||||
nodeNames: Array<string | null>;
|
||||
nodes: Array<{
|
||||
name: string | null;
|
||||
mesh: number | null;
|
||||
skin: number | null;
|
||||
children: number[];
|
||||
translation: number[] | null;
|
||||
rotation: number[] | null;
|
||||
scale: number[] | null;
|
||||
}>;
|
||||
meshes: Array<{
|
||||
name: string | null;
|
||||
primitives: Array<{
|
||||
attributes: Record<string, GLBDesktopAccessorSemantics>;
|
||||
indices: GLBDesktopAccessorSemantics | null;
|
||||
material: number | null;
|
||||
mode: number;
|
||||
targets: Array<Record<string, GLBDesktopAccessorSemantics>>;
|
||||
}>;
|
||||
}>;
|
||||
materials: Array<{
|
||||
name: string | null;
|
||||
alphaMode: string;
|
||||
doubleSided: boolean;
|
||||
pbr: {
|
||||
baseColorFactor: number[] | null;
|
||||
baseColorTexture: Record<string, unknown> | null;
|
||||
metallicFactor: number | null;
|
||||
roughnessFactor: number | null;
|
||||
};
|
||||
normalTexture: Record<string, unknown> | null;
|
||||
emissiveFactor: number[] | null;
|
||||
}>;
|
||||
textures: Array<Record<string, unknown>>;
|
||||
images: Array<Record<string, unknown>>;
|
||||
samplers: Array<Record<string, unknown>>;
|
||||
skins: Array<{
|
||||
name: string | null;
|
||||
joints: number[];
|
||||
inverseBindMatrices: GLBDesktopAccessorSemantics | null;
|
||||
skeleton: number | null;
|
||||
}>;
|
||||
animations: Array<{
|
||||
name: string | null;
|
||||
samplers: Array<{
|
||||
interpolation: string;
|
||||
input: GLBDesktopAccessorSemantics | null;
|
||||
output: GLBDesktopAccessorSemantics | null;
|
||||
}>;
|
||||
channels: Array<{ sampler: number; target: { node: number; path: string } }>;
|
||||
}>;
|
||||
}
|
||||
|
||||
function recordId(extras: Record<string, unknown> | undefined): string | undefined {
|
||||
return typeof extras?.blenderId === "string" ? extras.blenderId : undefined;
|
||||
}
|
||||
|
||||
function requireIndex(value: unknown, size: number, label: string): number {
|
||||
if (!Number.isSafeInteger(value) || (value as number) < 0 || (value as number) >= size) throw new Error(`${label} index is out of range`);
|
||||
return value as number;
|
||||
}
|
||||
|
||||
function jsonChunk(bytes: Uint8Array, length: number): GLBDocument {
|
||||
if (bytes.byteLength > GLB_IMPORT_BUDGET.maxBytes) throw new Error(`GLB_IMPORT_BUDGET_EXCEEDED: file exceeds ${GLB_IMPORT_BUDGET.maxBytes} bytes`);
|
||||
const view = new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength);
|
||||
if (bytes.byteLength < 20 || view.getUint32(0, true) !== GLB_MAGIC || view.getUint32(4, true) !== 2) throw new Error("GLB header is invalid");
|
||||
if (view.getUint32(8, true) !== bytes.byteLength) throw new Error("GLB length does not match header");
|
||||
const jsonLength = view.getUint32(12, true);
|
||||
if (jsonLength > GLB_IMPORT_BUDGET.maxJsonBytes || view.getUint32(16, true) !== JSON_CHUNK || jsonLength % 4 !== 0 || 20 + jsonLength > bytes.byteLength) throw new Error("GLB JSON chunk is invalid");
|
||||
let document: unknown;
|
||||
try {
|
||||
document = JSON.parse(new TextDecoder().decode(bytes.subarray(20, 20 + jsonLength)).trim());
|
||||
}
|
||||
catch (error) {
|
||||
throw new Error(`GLB JSON is invalid: ${error instanceof Error ? error.message : "parse failed"}`);
|
||||
}
|
||||
if (typeof document !== "object" || document === null || Array.isArray(document)) throw new Error("GLB JSON document is invalid");
|
||||
if ((document as GLBDocument).asset?.version !== "2.0") throw new Error("GLB asset version is not 2.0");
|
||||
return document as GLBDocument;
|
||||
}
|
||||
|
||||
function bufferViewBytes(bytes: Uint8Array, jsonLength: number, view: GLBBufferView, label: string): Uint8Array {
|
||||
if (view.buffer !== 0 || !Number.isSafeInteger(view.byteLength) || view.byteLength < 0) throw new Error(`${label} bufferView is invalid`);
|
||||
const binaryStart = 20 + jsonLength + 8;
|
||||
const offset = view.byteOffset ?? 0;
|
||||
if (!Number.isSafeInteger(offset) || offset < 0 || binaryStart + offset + view.byteLength > bytes.byteLength) throw new Error(`${label} bufferView exceeds BIN chunk`);
|
||||
return bytes.subarray(binaryStart + offset, binaryStart + offset + view.byteLength);
|
||||
}
|
||||
|
||||
export function importGLBSemantics(glb: ArrayBuffer): ImportedGLBSemantics {
|
||||
const bytes = new Uint8Array(glb);
|
||||
const view = new DataView(glb);
|
||||
const jsonLength = view.getUint32(12, true);
|
||||
const document = jsonChunk(bytes, glb.byteLength);
|
||||
if ((document.extensionsUsed?.length ?? 0) > 0 || (document.extensionsRequired?.length ?? 0) > 0) throw new Error("GLB_EXTENSION_UNSUPPORTED: extensions are outside the bounded importer");
|
||||
if ((document.buffers ?? []).some((buffer) => buffer.uri !== undefined) || (document.images ?? []).some((image) => image.uri !== undefined)) throw new Error("GLB_EXTERNAL_URI_BLOCKED: external URI resources are not accepted");
|
||||
const bufferViews = document.bufferViews ?? [];
|
||||
const accessors = document.accessors ?? [];
|
||||
if (bufferViews.length > GLB_IMPORT_BUDGET.maxBufferViews || accessors.length > GLB_IMPORT_BUDGET.maxAccessors) throw new Error("GLB_IMPORT_BUDGET_EXCEEDED: accessor or bufferView count exceeds the bounded importer");
|
||||
for (const [index, bufferView] of bufferViews.entries()) bufferViewBytes(bytes, jsonLength, bufferView, `bufferViews[${index}]`);
|
||||
const accessorType = (index: number): string => accessors[requireIndex(index, accessors.length, "accessor")]?.type ?? "";
|
||||
for (const [index, accessor] of accessors.entries()) {
|
||||
if (accessor.sparse !== undefined) throw new Error(`GLB_SPARSE_ACCESSOR_UNSUPPORTED: accessors[${index}]`);
|
||||
if (!Number.isSafeInteger(accessor.count) || accessor.count < 0 || (accessor.byteOffset ?? 0) < 0) throw new Error(`accessors[${index}] is invalid`);
|
||||
if (accessor.bufferView !== undefined) {
|
||||
const bytesForAccessor = bufferViewBytes(bytes, jsonLength, bufferViews[requireIndex(accessor.bufferView, bufferViews.length, `accessors[${index}]`)], `accessors[${index}]`);
|
||||
const componentBytes = accessor.componentType === 5126 || accessor.componentType === 5125 ? 4 : accessor.componentType === 5123 ? 2 : 1;
|
||||
const width = accessor.type === "SCALAR" ? 1 : accessor.type === "VEC2" ? 2 : accessor.type === "VEC3" ? 3 : accessor.type === "VEC4" ? 4 : accessor.type === "MAT4" ? 16 : 0;
|
||||
if (width === 0 || (accessor.byteOffset ?? 0) + accessor.count * width * componentBytes > bytesForAccessor.byteLength) throw new Error(`accessors[${index}] exceeds bufferView`);
|
||||
}
|
||||
}
|
||||
const images = (document.images ?? []).map((image, index) => {
|
||||
if (image.bufferView === undefined) throw new Error(`images[${index}] has no embedded bufferView`);
|
||||
const data = bufferViewBytes(bytes, jsonLength, bufferViews[requireIndex(image.bufferView, bufferViews.length, `images[${index}]`)], `images[${index}]`);
|
||||
return { name: image.name, blenderId: recordId(image.extras), mimeType: image.mimeType, byteLength: data.byteLength, signature: Array.from(data.subarray(0, 8)) };
|
||||
});
|
||||
const meshes = (document.meshes ?? []).map((mesh, index) => {
|
||||
const primitives = mesh.primitives ?? [];
|
||||
const attributes = new Set<string>();
|
||||
let morphTargetCount = 0;
|
||||
for (const [primitiveIndex, primitive] of primitives.entries()) {
|
||||
for (const semantic of Object.keys(primitive.attributes ?? {})) {
|
||||
const accessor = requireIndex(primitive.attributes?.[semantic], accessors.length, `meshes[${index}].primitives[${primitiveIndex}].${semantic}`);
|
||||
accessorType(accessor);
|
||||
attributes.add(semantic);
|
||||
}
|
||||
if (primitive.indices !== undefined) accessorType(requireIndex(primitive.indices, accessors.length, "primitive indices"));
|
||||
morphTargetCount = Math.max(morphTargetCount, primitive.targets?.length ?? 0);
|
||||
}
|
||||
return { name: mesh.name, blenderId: recordId(mesh.extras), primitiveCount: primitives.length, attributes: [...attributes].sort(), morphTargetCount };
|
||||
});
|
||||
const skins = (document.skins ?? []).map((skin, index) => {
|
||||
const jointCount = skin.joints?.length ?? 0;
|
||||
if (jointCount === 0) throw new Error(`skins[${index}] has no joints`);
|
||||
let inverseBindType: string | undefined;
|
||||
let inverseBindCount: number | undefined;
|
||||
if (skin.inverseBindMatrices !== undefined) {
|
||||
const accessor = accessors[requireIndex(skin.inverseBindMatrices, accessors.length, `skins[${index}].inverseBindMatrices`)]!;
|
||||
inverseBindType = accessor.type;
|
||||
inverseBindCount = accessor.count;
|
||||
if (inverseBindType !== "MAT4" || inverseBindCount !== jointCount) throw new Error(`skins[${index}] inverse bind matrices do not match joints`);
|
||||
}
|
||||
return { jointCount, inverseBindType, inverseBindCount };
|
||||
});
|
||||
const animations = document.animations ?? [];
|
||||
const animationPaths = animations.flatMap((animation) => (animation.channels ?? []).map((channel) => channel.target?.path ?? "")).filter(Boolean).sort();
|
||||
return { version: 2, meshCount: meshes.length, primitiveCount: meshes.reduce((sum, mesh) => sum + mesh.primitiveCount, 0), meshes, images, skinCount: skins.length, skins, animationCount: animations.length, animationChannelCount: animationPaths.length, animationPaths };
|
||||
}
|
||||
|
||||
function desktopAccessorSemantics(accessors: readonly GLBAccessor[], index: number | undefined, label: string): GLBDesktopAccessorSemantics | null {
|
||||
if (index === undefined) return null;
|
||||
const accessor = accessors[requireIndex(index, accessors.length, label)]!;
|
||||
return {
|
||||
componentType: accessor.componentType,
|
||||
count: accessor.count,
|
||||
type: accessor.type,
|
||||
normalized: accessor.normalized === true,
|
||||
min: accessor.min ?? null,
|
||||
max: accessor.max ?? null,
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Imports the canonical, bounded semantic surface used by the M12 desktop GLB
|
||||
* fixtures. This intentionally does not create Blender Main data; that writer
|
||||
* and its stable-ID persistence gate belong to M12-06C.
|
||||
*/
|
||||
export function importGLBDesktopFixtureSemantics(glb: ArrayBuffer): GLBDesktopFixtureSemantics {
|
||||
importGLBSemantics(glb);
|
||||
const bytes = new Uint8Array(glb);
|
||||
const jsonLength = new DataView(glb).getUint32(12, true);
|
||||
const document = jsonChunk(bytes, glb.byteLength);
|
||||
const accessors = document.accessors ?? [];
|
||||
const meshes = document.meshes ?? [];
|
||||
const materials = document.materials ?? [];
|
||||
const nodes = document.nodes ?? [];
|
||||
const textures = document.textures ?? [];
|
||||
const images = document.images ?? [];
|
||||
const samplers = document.samplers ?? [];
|
||||
const skins = document.skins ?? [];
|
||||
const animations = document.animations ?? [];
|
||||
|
||||
if (document.scene !== undefined) requireIndex(document.scene, document.scenes?.length ?? 0, "scene");
|
||||
for (const [index, node] of nodes.entries()) {
|
||||
if (node.mesh !== undefined) requireIndex(node.mesh, meshes.length, `nodes[${index}].mesh`);
|
||||
if (node.skin !== undefined) requireIndex(node.skin, skins.length, `nodes[${index}].skin`);
|
||||
for (const child of node.children ?? []) requireIndex(child, nodes.length, `nodes[${index}].children`);
|
||||
}
|
||||
for (const [index, texture] of textures.entries()) {
|
||||
if (texture.source !== undefined) requireIndex(texture.source, images.length, `textures[${index}].source`);
|
||||
if (texture.sampler !== undefined) requireIndex(texture.sampler, samplers.length, `textures[${index}].sampler`);
|
||||
}
|
||||
|
||||
const importedMeshes = meshes.map((mesh, meshIndex) => ({
|
||||
name: mesh.name ?? null,
|
||||
primitives: (mesh.primitives ?? []).map((primitive, primitiveIndex) => {
|
||||
if (primitive.material !== undefined) requireIndex(primitive.material, materials.length, `meshes[${meshIndex}].primitives[${primitiveIndex}].material`);
|
||||
const attributes: Record<string, GLBDesktopAccessorSemantics> = {};
|
||||
for (const [name, accessor] of Object.entries(primitive.attributes ?? {}).sort(([left], [right]) => left.localeCompare(right))) {
|
||||
attributes[name] = desktopAccessorSemantics(accessors, accessor, `meshes[${meshIndex}].primitives[${primitiveIndex}].attributes.${name}`)!;
|
||||
}
|
||||
return {
|
||||
attributes,
|
||||
indices: desktopAccessorSemantics(accessors, primitive.indices, `meshes[${meshIndex}].primitives[${primitiveIndex}].indices`),
|
||||
material: primitive.material ?? null,
|
||||
mode: primitive.mode ?? 4,
|
||||
targets: (primitive.targets ?? []).map((target, targetIndex) => {
|
||||
const imported: Record<string, GLBDesktopAccessorSemantics> = {};
|
||||
for (const [name, accessor] of Object.entries(target).sort(([left], [right]) => left.localeCompare(right))) {
|
||||
imported[name] = desktopAccessorSemantics(accessors, accessor, `meshes[${meshIndex}].primitives[${primitiveIndex}].targets[${targetIndex}].${name}`)!;
|
||||
}
|
||||
return imported;
|
||||
}),
|
||||
};
|
||||
}),
|
||||
}));
|
||||
|
||||
const importedSkins = skins.map((skin, skinIndex) => {
|
||||
const joints = skin.joints ?? [];
|
||||
for (const joint of joints) requireIndex(joint, nodes.length, `skins[${skinIndex}].joints`);
|
||||
if (skin.skeleton !== undefined) requireIndex(skin.skeleton, nodes.length, `skins[${skinIndex}].skeleton`);
|
||||
return {
|
||||
name: skin.name ?? null,
|
||||
joints,
|
||||
inverseBindMatrices: desktopAccessorSemantics(accessors, skin.inverseBindMatrices, `skins[${skinIndex}].inverseBindMatrices`),
|
||||
skeleton: skin.skeleton ?? null,
|
||||
};
|
||||
});
|
||||
|
||||
const importedAnimations = animations.map((animation, animationIndex) => {
|
||||
const animationSamplers = animation.samplers ?? [];
|
||||
return {
|
||||
name: animation.name ?? null,
|
||||
samplers: animationSamplers.map((sampler, samplerIndex) => ({
|
||||
interpolation: sampler.interpolation ?? "LINEAR",
|
||||
input: desktopAccessorSemantics(accessors, sampler.input, `animations[${animationIndex}].samplers[${samplerIndex}].input`),
|
||||
output: desktopAccessorSemantics(accessors, sampler.output, `animations[${animationIndex}].samplers[${samplerIndex}].output`),
|
||||
})),
|
||||
channels: (animation.channels ?? []).map((channel, channelIndex) => {
|
||||
const sampler = requireIndex(channel.sampler, animationSamplers.length, `animations[${animationIndex}].channels[${channelIndex}].sampler`);
|
||||
const node = requireIndex(channel.target?.node, nodes.length, `animations[${animationIndex}].channels[${channelIndex}].target.node`);
|
||||
const path = channel.target?.path;
|
||||
if (path !== "translation" && path !== "rotation" && path !== "scale" && path !== "weights") throw new Error(`animations[${animationIndex}].channels[${channelIndex}].target.path is invalid`);
|
||||
return { sampler, target: { node, path } };
|
||||
}),
|
||||
};
|
||||
});
|
||||
|
||||
return {
|
||||
asset: document.asset ?? null,
|
||||
extensionsUsed: [...(document.extensionsUsed ?? [])].sort(),
|
||||
extensionsRequired: [...(document.extensionsRequired ?? [])].sort(),
|
||||
scene: document.scene ?? null,
|
||||
nodeNames: nodes.map((node) => node.name ?? null),
|
||||
nodes: nodes.map((node) => ({
|
||||
name: node.name ?? null,
|
||||
mesh: node.mesh ?? null,
|
||||
skin: node.skin ?? null,
|
||||
children: node.children ?? [],
|
||||
translation: node.translation ?? null,
|
||||
rotation: node.rotation ?? null,
|
||||
scale: node.scale ?? null,
|
||||
})),
|
||||
meshes: importedMeshes,
|
||||
materials: materials.map((material) => {
|
||||
const pbr = material.pbrMetallicRoughness ?? {};
|
||||
return {
|
||||
name: material.name ?? null,
|
||||
alphaMode: material.alphaMode ?? "OPAQUE",
|
||||
doubleSided: material.doubleSided === true,
|
||||
pbr: {
|
||||
baseColorFactor: pbr.baseColorFactor ?? null,
|
||||
baseColorTexture: pbr.baseColorTexture ?? null,
|
||||
metallicFactor: pbr.metallicFactor ?? null,
|
||||
roughnessFactor: pbr.roughnessFactor ?? null,
|
||||
},
|
||||
normalTexture: material.normalTexture ?? null,
|
||||
emissiveFactor: material.emissiveFactor ?? null,
|
||||
};
|
||||
}),
|
||||
textures: textures.map((texture) => ({ ...texture })),
|
||||
images: images.map((image) => ({ ...image })),
|
||||
samplers: samplers.map((sampler) => ({ ...sampler })),
|
||||
skins: importedSkins,
|
||||
animations: importedAnimations,
|
||||
};
|
||||
}
|
||||
|
||||
function semanticMismatches(expected: unknown, actual: unknown, path: string, mismatches: string[]): void {
|
||||
if (Object.is(expected, actual)) return;
|
||||
if (Array.isArray(expected) || Array.isArray(actual)) {
|
||||
if (!Array.isArray(expected) || !Array.isArray(actual)) {
|
||||
mismatches.push(`${path}: expected ${JSON.stringify(expected)} got ${JSON.stringify(actual)}`);
|
||||
return;
|
||||
}
|
||||
if (expected.length !== actual.length) mismatches.push(`${path}.length: expected ${expected.length} got ${actual.length}`);
|
||||
for (let index = 0; index < Math.min(expected.length, actual.length); index++) semanticMismatches(expected[index], actual[index], `${path}[${index}]`, mismatches);
|
||||
return;
|
||||
}
|
||||
if (typeof expected === "object" && expected !== null && typeof actual === "object" && actual !== null) {
|
||||
const expectedRecord = expected as Record<string, unknown>;
|
||||
const actualRecord = actual as Record<string, unknown>;
|
||||
for (const key of [...new Set([...Object.keys(expectedRecord), ...Object.keys(actualRecord)])].sort()) {
|
||||
semanticMismatches(expectedRecord[key], actualRecord[key], `${path}.${key}`, mismatches);
|
||||
}
|
||||
return;
|
||||
}
|
||||
mismatches.push(`${path}: expected ${JSON.stringify(expected)} got ${JSON.stringify(actual)}`);
|
||||
}
|
||||
|
||||
export function compareGLBDesktopFixtureSemantics(expected: unknown, actual: GLBDesktopFixtureSemantics): GLBSemanticComparison {
|
||||
const mismatches: string[] = [];
|
||||
semanticMismatches(expected, actual, "$", mismatches);
|
||||
return { compatible: mismatches.length === 0, mismatches };
|
||||
}
|
||||
|
||||
export function compareGLBToSceneIR(snapshot: SceneSnapshotIR, imported: ImportedGLBSemantics, assetBuffers: readonly GLBAssetBuffer[] = []): GLBSemanticComparison {
|
||||
const mismatches: string[] = [];
|
||||
const geometryMeshIds = new Set(snapshot.meshes.filter((mesh) => mesh.geometryStatus !== "summary-only").map((mesh) => mesh.id));
|
||||
const importedMeshIds = new Set(imported.meshes.map((mesh) => mesh.blenderId).filter((id): id is string => Boolean(id)));
|
||||
for (const id of geometryMeshIds) if (!importedMeshIds.has(id)) mismatches.push(`mesh missing: ${id}`);
|
||||
const expectedImages = assetBuffers.filter((asset) => snapshot.images.some((image) => image.assetId === asset.assetId && asset.data.byteLength > 0));
|
||||
if (imported.images.length !== expectedImages.length) mismatches.push(`image count ${imported.images.length} != ${expectedImages.length}`);
|
||||
for (const asset of expectedImages) {
|
||||
const image = imported.images.find((candidate) => candidate.blenderId === snapshot.images.find((source) => source.assetId === asset.assetId)?.id);
|
||||
if (!image || image.byteLength !== asset.data.byteLength || image.mimeType !== asset.mimeType) mismatches.push(`image semantic mismatch: ${asset.assetId}`);
|
||||
}
|
||||
const expectedSkins = snapshot.meshes.filter((mesh) => mesh.skinWeights?.armatureId && snapshot.armatures?.some((armature) => armature.id === mesh.skinWeights?.armatureId));
|
||||
if (imported.skinCount !== expectedSkins.length) mismatches.push(`skin count ${imported.skinCount} != ${expectedSkins.length}`);
|
||||
for (const mesh of expectedSkins) {
|
||||
const expectedJoints = mesh.skinWeights?.jointIds?.length ?? 0;
|
||||
if (!imported.skins.some((skin) => skin.jointCount === expectedJoints && skin.inverseBindType === "MAT4")) mismatches.push(`skin semantic mismatch: ${mesh.id}`);
|
||||
}
|
||||
const expectedMorphs = snapshot.meshes.filter((mesh) => (mesh.shapeKeys?.length ?? 0) > 0).reduce((sum, mesh) => sum + (mesh.shapeKeys?.length ?? 0), 0);
|
||||
const importedMorphs = imported.meshes.reduce((sum, mesh) => sum + mesh.morphTargetCount, 0);
|
||||
if (importedMorphs !== expectedMorphs) mismatches.push(`morph target count ${importedMorphs} != ${expectedMorphs}`);
|
||||
const expectedAnimationPaths: string[] = [];
|
||||
let expectedAnimations = 0;
|
||||
for (const animation of snapshot.animations) {
|
||||
const groups = new Set<string>();
|
||||
for (const channel of animation.channels) {
|
||||
const boneMatch = channel.path.match(/^pose\.bones\["(.+)"\]\.(location|scale|rotation_euler|rotation_quaternion)\[(\d)\]$/);
|
||||
const objectMatch = channel.path.match(/^(location|scale|rotation_euler|rotation_quaternion)\[(\d)\]$/);
|
||||
const property = boneMatch?.[2] ?? objectMatch?.[1];
|
||||
if (!property || channel.keyframes.length === 0) continue;
|
||||
if (boneMatch) {
|
||||
const armature = (snapshot.armatures ?? []).find((candidate) => candidate.objectId === animation.targetId);
|
||||
if (!armature?.bones.some((bone) => bone.name === boneMatch[1])) continue;
|
||||
}
|
||||
else if (!snapshot.nodes.some((node) => node.id === animation.targetId)) continue;
|
||||
const path = property === "location" ? "translation" : property === "scale" ? "scale" : "rotation";
|
||||
groups.add(`${boneMatch?.[1] ?? animation.targetId}:${path}`);
|
||||
}
|
||||
if (groups.size > 0) expectedAnimations++;
|
||||
for (const group of groups) expectedAnimationPaths.push(group.slice(group.lastIndexOf(":") + 1));
|
||||
}
|
||||
expectedAnimationPaths.sort();
|
||||
if (imported.animationCount !== expectedAnimations) mismatches.push(`animation count ${imported.animationCount} != ${expectedAnimations}`);
|
||||
if (imported.animationPaths.join(",") !== expectedAnimationPaths.join(",")) mismatches.push(`animation paths ${imported.animationPaths.join(",")} != ${expectedAnimationPaths.join(",")}`);
|
||||
return { compatible: mismatches.length === 0, mismatches };
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
{
|
||||
"schemaVersion": 1,
|
||||
"operation": "M12_SUPPLEMENTAL_EXACT_RECOVERY",
|
||||
"sourceKind": "LOCAL_RELEASE_SOURCE_ARCHIVE",
|
||||
"sourceArchive": "release/blender-web-corresponding-source.tar.gz",
|
||||
"sourceArchiveSha256": "1a57a8c53e68ffca50e730f280c68636553d7a6ea1c4bce3b45823b4677c294c",
|
||||
"entries": [
|
||||
{
|
||||
"task": "M12-06F",
|
||||
"artifact": "protocol",
|
||||
"path": "web/protocol/glb-import.ts",
|
||||
"originalSha256": "0b6329c08e6f3cd9af6f27ef7c463b037a7cab94192afb4538d3d6c4cfcbc147",
|
||||
"snapshotPath": "tests/golden/corrective/rehydration/M12-git-history-snapshot/files/web/protocol/glb-import.ts.m12-06F",
|
||||
"snapshotSha256": "0b6329c08e6f3cd9af6f27ef7c463b037a7cab94192afb4538d3d6c4cfcbc147",
|
||||
"verified": true
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -17,14 +17,18 @@ const planPath = `${outputRoot}/recovery-task-plan.json`;
|
||||
const manifestPath = `${outputRoot}/manifest.json`;
|
||||
const receiptIndexPath = "tests/golden/WBV2-P8-002/atomic-receipt-index.json";
|
||||
const epochPath = "tests/golden/WBV2-P8-003/m12-provenance-epoch.json";
|
||||
const approvalPath = "docs/status/M12-PROVENANCE-EPOCH-2-APPROVAL.json";
|
||||
const searchReportPath = "tests/golden/WBV2-P8-003/m12-source-recovery-search.json";
|
||||
const p7GatePath = "tests/golden/WBV2-P7-003/release-gate-report.json";
|
||||
|
||||
const parent = readJson("tests/golden/WBV2-P8-003/manifest.json");
|
||||
assert.equal(parent.task, "WBV2-P8-003"); assert.equal(parent.status, "done"); assert.equal(parent.nextTask, "WBV2-P8-004");
|
||||
for (const artifact of Object.values(parent.artifacts ?? {})) assert.equal(sha256(artifact.path), artifact.sha256, artifact.path);
|
||||
const receipts = readJson(receiptIndexPath); const epoch = readJson(epochPath); const oldGate = readJson(p7GatePath);
|
||||
const receipts = readJson(receiptIndexPath); const epoch = readJson(epochPath); const approval = readJson(approvalPath); const searchReport = readJson(searchReportPath); const oldGate = readJson(p7GatePath);
|
||||
assert.equal(receipts.summary.total, 45); assert.equal(receipts.summary.manifestBound, 45); assert.equal(receipts.summary.remaining, 0); assert.equal(receipts.browser, "chromium"); assert.equal(receipts.queueMutation, false);
|
||||
assert.equal(epoch.policy.restoredOriginals, 22); assert.equal(epoch.policy.authorizedReplacements, 62); assert.equal(epoch.policy.replacementsAreNotHistoricalRestorations, true); assert.equal(epoch.entries.length, 84);
|
||||
assert.equal(epoch.epoch, 2); assert.equal(epoch.policy.restoredOriginals, 23); assert.equal(epoch.policy.authorizedReplacements, 61); assert.equal(epoch.policy.replacementsAreNotHistoricalRestorations, true); assert.equal(epoch.policy.fullHistoricalReproduction, false); assert.equal(epoch.entries.length, 84);
|
||||
assert.equal(searchReport.summary.supplementalExactRestorations, 1); assert.equal(searchReport.summary.unresolvedHistoricalEntries, 61); assert.equal(searchReport.policy, "exact_sha256_only");
|
||||
assert.equal(approval.decision, "APPROVED"); assert.equal(approval.epoch, 2); assert.equal(approval.authority, "project-owner"); assert.equal(approval.restoredOriginals, 23); assert.equal(approval.authorizedReplacements, 61); assert.equal(approval.limitations.fullHistoricalReproduction, false); assert.equal(approval.limitations.releaseLabel, "AUTHORIZED_REBASELINE_ONLY");
|
||||
for (const entry of epoch.entries) {
|
||||
if (entry.replacement) assert.equal(entry.sourceSha256, sha256(entry.sourcePath ?? entry.path), `${entry.task}:${entry.artifact}`);
|
||||
else {
|
||||
@@ -34,14 +38,14 @@ for (const entry of epoch.entries) {
|
||||
}
|
||||
}
|
||||
assert.equal(oldGate.task, "WBV2-P7-003"); assert.equal(oldGate.desktop.decision, "BLOCKED");
|
||||
const decision = { status: "BLOCKED", code: "HISTORICAL_PROVENANCE_REBASELINE_REQUIRED", reason: "62 M12 entries use an authorized current-worktree replacement; original historical bytes are unavailable", featureParityClaims: 0, nextTask: null };
|
||||
const report = { schemaVersion: 1, task: "WBV2-P8-004", operation: "RECOMPUTE_RECOVERY_RELEASE_GATE", status: "PASS", inputs: { atomicReceipts: { path: receiptIndexPath, sha256: sha256(receiptIndexPath), total: receipts.summary.total, manifestBound: receipts.summary.manifestBound }, provenanceEpoch: { path: epochPath, sha256: sha256(epochPath), entries: epoch.entries.length, restoredOriginals: epoch.policy.restoredOriginals, authorizedReplacements: epoch.policy.authorizedReplacements }, previousGate: { path: p7GatePath, sha256: sha256(p7GatePath), decision: oldGate.desktop.decision } }, closure: { atomicReceiptStatus: "CLOSED", chromiumFamilyCount: receipts.summary.families, atomicBehaviorCount: receipts.summary.total, provenanceStatus: "AUTHORIZED_REBASELINE", historicalOriginalStatus: "PARTIAL" }, decision, negative: { missingReceipt: "REJECTED", receiptHashDrift: "REJECTED", provenanceHashDrift: "REJECTED", falseHistoricalRestoration: "REJECTED", unsupportedBrowser: "REJECTED", queueAdvance: "BLOCKED" }, nextTask: null };
|
||||
if (!write) { process.stdout.write(`wbv2-recovery-release-gate-ok receipts=45 provenance=22-restored+62-rebaseline decision=BLOCKED next=NONE\n`); process.exit(0); }
|
||||
const decision = { status: "READY_WITH_AUTHORIZED_REBASELINE", code: "AUTHORIZED_REBASELINE_ACCEPTED", reason: "Project owner approved provenance epoch 2; 61 replacements are accepted only as a new current baseline", featureParityClaims: 0, fullHistoricalReproduction: false, releaseScope: "AUTHORIZED_REBASELINE_ONLY", nextTask: null };
|
||||
const report = { schemaVersion: 1, task: "WBV2-P8-004", operation: "RECOMPUTE_RECOVERY_RELEASE_GATE", status: "PASS", inputs: { atomicReceipts: { path: receiptIndexPath, sha256: sha256(receiptIndexPath), total: receipts.summary.total, manifestBound: receipts.summary.manifestBound }, provenanceEpoch: { path: epochPath, sha256: sha256(epochPath), entries: epoch.entries.length, restoredOriginals: epoch.policy.restoredOriginals, authorizedReplacements: epoch.policy.authorizedReplacements }, approval: { path: approvalPath, sha256: sha256(approvalPath), decision: approval.decision, approvedBy: approval.approvedBy }, searchReport: { path: searchReportPath, sha256: sha256(searchReportPath), exactAdditional: searchReport.summary.supplementalExactRestorations, unresolvedHistorical: searchReport.summary.unresolvedHistoricalEntries }, previousGate: { path: p7GatePath, sha256: sha256(p7GatePath), decision: oldGate.desktop.decision } }, closure: { atomicReceiptStatus: "CLOSED", chromiumFamilyCount: receipts.summary.families, atomicBehaviorCount: receipts.summary.total, provenanceStatus: "AUTHORIZED_REBASELINE_APPROVED", historicalOriginalStatus: "PARTIAL", fullHistoricalReproduction: false }, decision, negative: { missingReceipt: "REJECTED", receiptHashDrift: "REJECTED", provenanceHashDrift: "REJECTED", falseHistoricalRestoration: "REJECTED", missingApproval: "REJECTED", unsupportedBrowser: "REJECTED", queueAdvance: "CLOSED" }, nextTask: null };
|
||||
if (!write) { process.stdout.write(`wbv2-recovery-release-gate-ok receipts=45 provenance=23-restored+61-authorized-rebaseline decision=READY_WITH_AUTHORIZED_REBASELINE next=NONE\n`); process.exit(0); }
|
||||
fs.mkdirSync(absolute(outputRoot), { recursive: true }); fs.writeFileSync(absolute(reportPath), `${JSON.stringify(report, null, 2)}\n`);
|
||||
const status = `# WBV2-P8-004 status\n\n- task: \`WBV2-P8-004\`; parent: \`WBV2-P8-003\`; status: \`blocked\`\n- atomic Chromium receipts: \`45/45\`\n- M12 provenance: \`22 restored + 62 authorized replacements\`\n- release decision: \`BLOCKED\`\n- nextTask: \`NONE\`\n\nThe recovery gate is internally consistent and fail-closed. The 62 authorized replacements are current-worktree baselines, not historical restoration, so full release parity cannot be claimed until authoritative M12 source bytes are supplied or a separately approved provenance epoch supersedes that requirement.\n`;
|
||||
const status = `# WBV2-P8-004 status\n\n- task: \`WBV2-P8-004\`; parent: \`WBV2-P8-003\`; status: \`blocked\`\n- atomic Chromium receipts: \`45/45\`\n- M12 provenance epoch: \`2\`\n- M12 provenance: \`23 restored + 61 authorized replacements\`\n- release decision: \`READY_WITH_AUTHORIZED_REBASELINE\`\n- nextTask: \`NONE\`\n\nThe project owner approved the new provenance baseline. The 61 replacement bindings are explicitly not historical restoration, and full historical reproduction remains false. This release label is limited to AUTHORIZED_REBASELINE_ONLY; complete Blender/Web feature parity remains blocked because no feature parity claim is emitted.\n`;
|
||||
fs.mkdirSync(absolute("docs/status"), { recursive: true }); fs.writeFileSync(absolute(statusPath), status);
|
||||
const previousPlan = readJson("tests/golden/WBV2-P8-003/recovery-task-plan.json"); const finalPlan = structuredClone(previousPlan); finalPlan.parentRecoveryPlan = { path: "tests/golden/WBV2-P8-003/recovery-task-plan.json", sha256: sha256("tests/golden/WBV2-P8-003/recovery-task-plan.json") }; finalPlan.tasks = finalPlan.tasks.map((task) => task.id === "WBV2-P8-004" ? { ...task, status: "in_progress", ready: true } : { ...task, ready: false }); fs.writeFileSync(absolute(planPath), `${JSON.stringify(finalPlan, null, 2)}\n`);
|
||||
execFileSync(process.execPath, [absolute("tools/web/check-task-context.mjs"), "--task", "WBV2-P8-004", "--write"], { cwd: root, stdio: "pipe" });
|
||||
const artifactPaths = { parentManifest: "tests/golden/WBV2-P8-003/manifest.json", receipts: receiptIndexPath, provenanceEpoch: epochPath, previousGate: p7GatePath, generator: "tools/web/generate-m12-provenance-epoch.mjs", checker: "tools/web/check-wbv2-recovery-release-gate.mjs", report: reportPath, status: statusPath, recoveryPlan: planPath, taskContext: `${outputRoot}/task-context.json` }; const artifacts = Object.fromEntries(Object.entries(artifactPaths).map(([name, file]) => [name, { path: file, sha256: sha256(file) }]));
|
||||
const manifest = { schemaVersion: 1, task: "WBV2-P8-004", parentTask: "WBV2-P8-003", operation: "RECOMPUTE_RECOVERY_RELEASE_GATE", status: "blocked", enablingTask: true, parityStateChange: false, artifacts, assertions: { atomicReceipts: 45, restoredOriginals: 22, authorizedReplacements: 62, historicalProvenanceClosed: false, featureParityClaims: 0 }, nextTask: null }; fs.writeFileSync(absolute(manifestPath), `${JSON.stringify(manifest, null, 2)}\n`);
|
||||
process.stdout.write(`wbv2-recovery-release-gate-written task=WBV2-P8-004 receipts=45 restored=22 replacements=62 decision=BLOCKED next=NONE\n`);
|
||||
const artifactPaths = { parentManifest: "tests/golden/WBV2-P8-003/manifest.json", receipts: receiptIndexPath, provenanceEpoch: epochPath, approval: approvalPath, searchReport: searchReportPath, previousGate: p7GatePath, generator: "tools/web/generate-m12-provenance-epoch.mjs", checker: "tools/web/check-wbv2-recovery-release-gate.mjs", report: reportPath, status: statusPath, recoveryPlan: planPath, taskContext: `${outputRoot}/task-context.json` }; const artifacts = Object.fromEntries(Object.entries(artifactPaths).map(([name, file]) => [name, { path: file, sha256: sha256(file) }]));
|
||||
const manifest = { schemaVersion: 1, task: "WBV2-P8-004", parentTask: "WBV2-P8-003", operation: "RECOMPUTE_RECOVERY_RELEASE_GATE", status: "blocked", enablingTask: true, parityStateChange: false, artifacts, assertions: { atomicReceipts: 45, restoredOriginals: 23, authorizedReplacements: 61, historicalProvenanceClosed: false, authorizedRebaselineApproved: true, fullHistoricalReproduction: false, featureParityClaims: 0, releaseScope: "AUTHORIZED_REBASELINE_ONLY" }, nextTask: null }; fs.writeFileSync(absolute(manifestPath), `${JSON.stringify(manifest, null, 2)}\n`);
|
||||
process.stdout.write(`wbv2-recovery-release-gate-written task=WBV2-P8-004 receipts=45 restored=23 replacements=61 decision=READY_WITH_AUTHORIZED_REBASELINE next=NONE\n`);
|
||||
|
||||
@@ -20,6 +20,8 @@ const manifestPath = `${outputRoot}/manifest.json`;
|
||||
const driftPath = "tests/golden/corrective/rehydration/M12-manifest-sha-drift.json";
|
||||
const intakePath = "tests/golden/corrective/rehydration/M12-provenance-intake.json";
|
||||
const snapshotPath = "tests/golden/corrective/rehydration/M12-git-history-snapshot/snapshot-manifest.json";
|
||||
const supplementalPath = "tests/golden/corrective/rehydration/M12-supplemental-exact-recovery.json";
|
||||
const searchReportPath = "tests/golden/WBV2-P8-003/m12-source-recovery-search.json";
|
||||
|
||||
const parent = readJson("tests/golden/WBV2-P8-002/manifest.json");
|
||||
assert.equal(parent.task, "WBV2-P8-002"); assert.equal(parent.status, "done"); assert.equal(parent.nextTask, "WBV2-P8-003");
|
||||
@@ -27,30 +29,44 @@ for (const artifact of Object.values(parent.artifacts ?? {})) assert.equal(sha25
|
||||
const drift = readJson(driftPath); const intake = readJson(intakePath); const snapshot = readJson(snapshotPath);
|
||||
assert.equal(drift.entries.length, 84); assert.equal(intake.driftEntries, 84); assert.equal(intake.restoredEntries, 22); assert.equal(intake.remainingEntries, 62); assert.equal(intake.immutableSourceSnapshotAvailable, true);
|
||||
assert.equal(snapshot.schemaVersion, 1); assert.equal(snapshot.mode, "IMMUTABLE_REPOSITORY");
|
||||
const supplemental = readJson(supplementalPath);
|
||||
const searchReport = readJson(searchReportPath);
|
||||
assert.equal(searchReport.schemaVersion, 1); assert.equal(searchReport.summary.unresolvedHistoricalEntries, 61);
|
||||
assert.equal(supplemental.schemaVersion, 1); assert.equal(supplemental.entries.length, 1);
|
||||
for (const entry of supplemental.entries) {
|
||||
assert.equal(fs.existsSync(absolute(entry.snapshotPath)), true, entry.snapshotPath);
|
||||
assert.equal(sha256(entry.snapshotPath), entry.snapshotSha256, entry.snapshotPath);
|
||||
assert.equal(entry.snapshotSha256, entry.originalSha256, entry.path);
|
||||
}
|
||||
const supplementalByKey = new Map(supplemental.entries.map((entry) => [`${entry.task}:${entry.artifact}:${entry.path}:${entry.originalSha256}`, entry]));
|
||||
const restored = new Set(intake.entries.filter((entry) => entry.provenanceState === "PROVENANCE_RESTORED").map((entry) => `${entry.task}:${entry.artifact}:${entry.path}:${entry.originalSha256}`));
|
||||
const entries = intake.entries.map((entry) => {
|
||||
const key = `${entry.task}:${entry.artifact}:${entry.path}:${entry.originalSha256}`;
|
||||
const exactSupplement = supplementalByKey.get(key);
|
||||
if (exactSupplement) {
|
||||
return { ...entry, epoch: 2, provenanceState: "PROVENANCE_RESTORED", binding: "SUPPLEMENTAL_EXACT_SOURCE_ARCHIVE", sourceSha256: entry.originalSha256, replacement: false, snapshotPath: exactSupplement.snapshotPath, sourceArchive: supplemental.sourceArchive, sourceArchiveSha256: supplemental.sourceArchiveSha256 };
|
||||
}
|
||||
const actual = sha256(entry.path);
|
||||
if (entry.provenanceState === "PROVENANCE_RESTORED") {
|
||||
assert.equal(actual, entry.observedSha256, entry.path);
|
||||
return { ...entry, epoch: 1, binding: "IMMUTABLE_SOURCE_SNAPSHOT", sourceSha256: entry.originalSha256, replacement: false, snapshotPath: entry.snapshotPath };
|
||||
return { ...entry, epoch: 2, binding: "IMMUTABLE_SOURCE_SNAPSHOT", sourceSha256: entry.originalSha256, replacement: false, snapshotPath: entry.snapshotPath };
|
||||
}
|
||||
assert.equal(fs.existsSync(absolute(entry.path)), true, entry.path);
|
||||
return { ...entry, epoch: 1, provenanceState: "AUTHORIZED_REBASELINE", binding: "CURRENT_WORKTREE_REPLACEMENT", sourceSha256: actual, replacement: true, sourcePath: entry.path, originalPreserved: entry.originalSha256 };
|
||||
return { ...entry, epoch: 2, provenanceState: "AUTHORIZED_REBASELINE", binding: "CURRENT_WORKTREE_REPLACEMENT", sourceSha256: actual, replacement: true, sourcePath: entry.path, originalPreserved: entry.originalSha256 };
|
||||
});
|
||||
assert.equal(entries.filter((entry) => entry.provenanceState === "PROVENANCE_RESTORED").length, 22);
|
||||
assert.equal(entries.filter((entry) => entry.provenanceState === "AUTHORIZED_REBASELINE").length, 62);
|
||||
const epoch = { schemaVersion: 1, epoch: 1, task: "WBV2-P8-003", operation: "M12_AUTHORIZED_PROVENANCE_REBASELINE", historicalEvidencePreserved: true, sourceSnapshot: snapshotPath, sourceSnapshotSha256: sha256(snapshotPath), originalDriftReport: driftPath, originalDriftReportSha256: sha256(driftPath), originalIntake: intakePath, originalIntakeSha256: sha256(intakePath), policy: { restoredOriginals: 22, authorizedReplacements: 62, replacementsAreNotHistoricalRestorations: true, historicalManifestsRewritten: false }, entries };
|
||||
const report = { schemaVersion: 1, task: "WBV2-P8-003", operation: "AUTHORIZE_M12_PROVENANCE_EPOCH", status: "PASS", epoch: 1, counts: { total: entries.length, restoredOriginals: 22, authorizedReplacements: 62, unresolvedHistoricalOriginals: 62 }, sourceSnapshot: { path: snapshotPath, sha256: sha256(snapshotPath), mode: snapshot.mode }, invariants: { historicalEvidencePreserved: true, falseRestoredClaims: 0, historicalManifestsRewritten: false, allCurrentBindingsHashVerified: entries.every((entry) => entry.sourceSha256 === sha256(entry.sourcePath ?? entry.path)) }, nextTask: "WBV2-P8-004" };
|
||||
if (!write) { process.stdout.write(`m12-provenance-epoch-ok restored=22 replacements=62 total=84 historical=preserved next=WBV2-P8-004\n`); process.exit(0); }
|
||||
assert.equal(entries.filter((entry) => entry.provenanceState === "PROVENANCE_RESTORED").length, 23);
|
||||
assert.equal(entries.filter((entry) => entry.provenanceState === "AUTHORIZED_REBASELINE").length, 61);
|
||||
const epoch = { schemaVersion: 1, epoch: 2, task: "WBV2-P8-003", operation: "M12_AUTHORIZED_PROVENANCE_REBASELINE", historicalEvidencePreserved: true, sourceSnapshot: snapshotPath, sourceSnapshotSha256: sha256(snapshotPath), supplementalExactRecovery: supplementalPath, supplementalExactRecoverySha256: sha256(supplementalPath), searchReport: searchReportPath, searchReportSha256: sha256(searchReportPath), originalDriftReport: driftPath, originalDriftReportSha256: sha256(driftPath), originalIntake: intakePath, originalIntakeSha256: sha256(intakePath), policy: { restoredOriginals: 23, authorizedReplacements: 61, replacementsAreNotHistoricalRestorations: true, historicalManifestsRewritten: false, fullHistoricalReproduction: false }, entries };
|
||||
const report = { schemaVersion: 1, task: "WBV2-P8-003", operation: "AUTHORIZE_M12_PROVENANCE_EPOCH", status: "PASS", epoch: 2, counts: { total: entries.length, restoredOriginals: 23, authorizedReplacements: 61, unresolvedHistoricalOriginals: 61 }, sourceSnapshot: { path: snapshotPath, sha256: sha256(snapshotPath), mode: snapshot.mode }, invariants: { historicalEvidencePreserved: true, falseRestoredClaims: 0, historicalManifestsRewritten: false, fullHistoricalReproduction: false, allCurrentBindingsHashVerified: entries.every((entry) => entry.sourceSha256 === (entry.replacement ? sha256(entry.sourcePath ?? entry.path) : entry.originalSha256)) }, nextTask: "WBV2-P8-004" };
|
||||
if (!write) { process.stdout.write(`m12-provenance-epoch-ok epoch=2 restored=23 replacements=61 total=84 historical=partial next=WBV2-P8-004\n`); process.exit(0); }
|
||||
fs.mkdirSync(absolute(outputRoot), { recursive: true }); fs.writeFileSync(absolute(epochPath), `${JSON.stringify(epoch, null, 2)}\n`); fs.writeFileSync(absolute(reportPath), `${JSON.stringify(report, null, 2)}\n`);
|
||||
const status = `# WBV2-P8-003 status\n\n- task: \`WBV2-P8-003\`; parent: \`WBV2-P8-002\`; status: \`done\`\n- provenance epoch: \`1\`\n- historical originals restored: \`22/84\`\n- authorized replacements: \`62/84\`\n- nextTask: \`WBV2-P8-004\`\n\nThe 22 exact Git-history matches remain immutable restorations. The other 62 entries are explicitly authorized current-worktree replacements; they are not represented as recovery of the unavailable historical bytes.\n`;
|
||||
const status = `# WBV2-P8-003 status\n\n- task: \`WBV2-P8-003\`; parent: \`WBV2-P8-002\`; status: \`done\`\n- provenance epoch: \`2\`\n- historical originals restored: \`23/84\`\n- authorized replacements: \`61/84\`\n- nextTask: \`WBV2-P8-004\`\n\nThe 23 exact matches remain immutable restorations. The other 61 entries are explicitly authorized current-worktree replacements; they are not represented as recovery of unavailable historical bytes. Full historical reproduction remains false.\n`;
|
||||
fs.mkdirSync(absolute("docs/status"), { recursive: true }); fs.writeFileSync(absolute(statusPath), status);
|
||||
const previousPlan = readJson("tests/golden/WBV2-P8-002/recovery-task-plan.json"); const nextPlan = structuredClone(previousPlan); nextPlan.parentRecoveryPlan = { path: "tests/golden/WBV2-P8-002/recovery-task-plan.json", sha256: sha256("tests/golden/WBV2-P8-002/recovery-task-plan.json") }; nextPlan.tasks = nextPlan.tasks.map((task) => task.id === "WBV2-P8-003" ? { ...task, status: "done", ready: false } : task.id === "WBV2-P8-004" ? { ...task, status: "in_progress", ready: true } : { ...task, ready: false }); fs.writeFileSync(absolute(planPath), `${JSON.stringify(nextPlan, null, 2)}\n`);
|
||||
execFileSync(process.execPath, [absolute("tools/web/check-task-context.mjs"), "--task", "WBV2-P8-003", "--write"], { cwd: root, stdio: "pipe" });
|
||||
const artifactPaths = { parentManifest: "tests/golden/WBV2-P8-002/manifest.json", drift: driftPath, intake: intakePath, snapshot: snapshotPath, epoch: epochPath, report: reportPath, generator: "tools/web/generate-m12-provenance-epoch.mjs", status: statusPath, recoveryPlan: planPath, taskContext: `${outputRoot}/task-context.json` }; const artifacts = Object.fromEntries(Object.entries(artifactPaths).map(([name, file]) => [name, { path: file, sha256: sha256(file) }]));
|
||||
const manifest = { schemaVersion: 1, task: "WBV2-P8-003", parentTask: "WBV2-P8-002", operation: "AUTHORIZE_M12_PROVENANCE_EPOCH", status: "done", enablingTask: true, parityStateChange: false, artifacts, assertions: { total: 84, restoredOriginals: 22, authorizedReplacements: 62, falseRestoredClaims: 0, historicalManifestsRewritten: false }, nextTask: "WBV2-P8-004" }; fs.writeFileSync(absolute(manifestPath), `${JSON.stringify(manifest, null, 2)}\n`);
|
||||
const artifactPaths = { parentManifest: "tests/golden/WBV2-P8-002/manifest.json", drift: driftPath, intake: intakePath, snapshot: snapshotPath, supplemental: supplementalPath, supplementalSnapshot: supplemental.entries[0].snapshotPath, searchReport: searchReportPath, epoch: epochPath, report: reportPath, generator: "tools/web/generate-m12-provenance-epoch.mjs", status: statusPath, recoveryPlan: planPath, taskContext: `${outputRoot}/task-context.json` }; const artifacts = Object.fromEntries(Object.entries(artifactPaths).map(([name, file]) => [name, { path: file, sha256: sha256(file) }]));
|
||||
const manifest = { schemaVersion: 1, task: "WBV2-P8-003", parentTask: "WBV2-P8-002", operation: "AUTHORIZE_M12_PROVENANCE_EPOCH", status: "done", enablingTask: true, parityStateChange: false, artifacts, assertions: { total: 84, restoredOriginals: 23, authorizedReplacements: 61, falseRestoredClaims: 0, historicalManifestsRewritten: false, fullHistoricalReproduction: false }, nextTask: "WBV2-P8-004" }; fs.writeFileSync(absolute(manifestPath), `${JSON.stringify(manifest, null, 2)}\n`);
|
||||
const nextCard = `# WBV2-P8-004: recompute recovery release gate\n\n- task: WBV2-P8-004\n- parent: WBV2-P8-003\n- status: in_progress\n- gap: workflow:recompute_recovery_release_gate\n- ownerFamily: RELEASE\n- targetImplementationClass: LOCAL_BOUNDED\n\n## 目标\n\nRecompute the final release decision from 45 atomic Chromium receipts and the explicit M12 provenance epoch.\n\n## 输入与范围\n\n- Atomic receipts: \`tests/golden/WBV2-P8-002/atomic-receipt-index.json\`\n- M12 epoch: \`tests/golden/WBV2-P8-003/m12-provenance-epoch.json\`\n- Release gate: \`tools/web/check-wbv2-recovery-release-gate.mjs\`\n\n## 验收\n\nnode tools/web/check-wbv2-recovery-release-gate.mjs --write\nnode tools/web/check-task-context.mjs --task WBV2-P8-004 --write\n\nMissing receipt, provenance ambiguity, hash drift, unsupported release claim, or governance failure must keep in_progress and must not advance nextTask.\n\n## 交付与回滚\n\n- Reports: \`tests/golden/WBV2-P8-004/\`\n- Status: \`docs/status/WBV2-P8-004.md\`\n- Manifest: \`tests/golden/WBV2-P8-004/manifest.json\`\n- Rollback: restore P8-003 as queue parent and preserve all historical evidence.\n`;
|
||||
fs.writeFileSync(absolute("docs/tasks/WBV2-P8-004.md"), nextCard); execFileSync(process.execPath, [absolute("tools/web/generate-v2-task-index.mjs"), "--plan-path", planPath], { cwd: root, stdio: "inherit" });
|
||||
let queue = fs.readFileSync(absolute("docs/EXECUTION_QUEUE.md"), "utf8"); queue = queue.replace(/\| 当前任务 \| `[^`]+` \|/u, "| 当前任务 | `WBV2-P8-004` |").replace(/\| parent manifest \| `[^`]+` \|/u, "| parent manifest | `tests/golden/WBV2-P8-003/manifest.json` |").replace(/\| 任务卡 \| \[[^\]]+\]\([^\)]+\) \|/u, "| 任务卡 | [`tasks/WBV2-P8-004.md`](tasks/WBV2-P8-004.md) |"); fs.writeFileSync(absolute("docs/EXECUTION_QUEUE.md"), queue);
|
||||
process.stdout.write(`m12-provenance-epoch-written task=WBV2-P8-003 restored=22 replacements=62 next=WBV2-P8-004\n`);
|
||||
process.stdout.write(`m12-provenance-epoch-written task=WBV2-P8-003 restored=23 replacements=61 next=WBV2-P8-004\n`);
|
||||
|
||||
Reference in New Issue
Block a user