diff --git a/README.md b/README.md index 35cf204..84eb51b 100644 --- a/README.md +++ b/README.md @@ -1084,3 +1084,30 @@ Boundary: - No current production claim: true - No starship claim: true - No physical production instructions: true + +## Move 135 — Org profile binds CONTROL v0.2.65 + +This public surface binds the CONTROL v0.2.65 closure authority. + +Authority: + +- CONTROL release: https://github.com/ANTIMATTERIUM/CONTROL/releases/tag/v0.2.65-antimatterium-control-move133-surface-closure +- Verify CI: https://github.com/ANTIMATTERIUM/CONTROL/actions/runs/29362695665 +- Main SHA: bd3e4e02c1b923785607687b36bf1d082042c348 +- Closure ID: 0e5c9918ca4ba76f44577b62549888dadad5464cdc170e5ed7b7835b9107fbd0 + +Surface release: + +- https://github.com/ANTIMATTERIUM/.github/releases/tag/v0.0.74-antimatterium-org-profile-control-v0265-backlink + +Backlink ID: + +- 642a078b237d35fd2e8f15d79825890c23089aa415b15deb9d6718aebeff7f78 + +Boundary: + +- Short public tag required: true +- No local root required: true +- No current production claim: true +- No starship claim: true +- No physical production instructions: true diff --git a/package.json b/package.json index 4fa6acc..9d45235 100644 --- a/package.json +++ b/package.json @@ -123,8 +123,10 @@ "verify:move131-control-v0263-backlink": "node scripts/verify-org-profile-move131-control-v0263-backlink.mjs", "test:move131-control-v0263-backlink": "node --test tests/org-profile-move131-control-v0263-backlink.test.mjs", "verify:move133-control-v0264-backlink": "node scripts/verify-org-profile-move133-control-v0264-backlink.mjs", - "test:move133-control-v0264-backlink": "node --test tests/org-profile-move133-control-v0264-backlink.test.mjs" + "test:move133-control-v0264-backlink": "node --test tests/org-profile-move133-control-v0264-backlink.test.mjs", + "verify:move135-control-v0265-backlink": "node scripts/verify-org-profile-move135-control-v0265-backlink.mjs", + "test:move135-control-v0265-backlink": "node --test tests/org-profile-move135-control-v0265-backlink.test.mjs" }, "type": "module", - "version": "0.0.73" + "version": "0.0.74" } diff --git a/public/receipts/ANTIMATTERIUM_ORG_PROFILE_MOVE135_CONTROL_V0265_BACKLINK.json b/public/receipts/ANTIMATTERIUM_ORG_PROFILE_MOVE135_CONTROL_V0265_BACKLINK.json new file mode 100644 index 0000000..956cac3 --- /dev/null +++ b/public/receipts/ANTIMATTERIUM_ORG_PROFILE_MOVE135_CONTROL_V0265_BACKLINK.json @@ -0,0 +1,30 @@ +{ + "schema": "antimatterium.surface_control_backlink.v1", + "move": 123, + "surface": "org_profile", + "package": { + "version": "0.0.74", + "tag": "v0.0.74-antimatterium-org-profile-control-v0265-backlink", + "release": "https://github.com/ANTIMATTERIUM/.github/releases/tag/v0.0.74-antimatterium-org-profile-control-v0265-backlink" + }, + "authority": { + "control_version": "0.2.65", + "control_tag": "v0.2.65-antimatterium-control-move133-surface-closure", + "control_release": "https://github.com/ANTIMATTERIUM/CONTROL/releases/tag/v0.2.65-antimatterium-control-move133-surface-closure", + "verify_ci_run": "https://github.com/ANTIMATTERIUM/CONTROL/actions/runs/29362695665", + "main_sha": "bd3e4e02c1b923785607687b36bf1d082042c348", + "closure_id": "0e5c9918ca4ba76f44577b62549888dadad5464cdc170e5ed7b7835b9107fbd0" + }, + "membership": { + "member_of_move135_surface_fanout": true, + "control_v0265_release_bound": true, + "short_public_tag_required": true, + "no_local_root_required": true + }, + "safety": { + "no_current_production_claim": true, + "no_starship_claim": true, + "no_physical_production_instructions": true + }, + "backlink_id": "642a078b237d35fd2e8f15d79825890c23089aa415b15deb9d6718aebeff7f78" +} diff --git a/scripts/verify-org-profile-move135-control-v0265-backlink.mjs b/scripts/verify-org-profile-move135-control-v0265-backlink.mjs new file mode 100755 index 0000000..2119f23 --- /dev/null +++ b/scripts/verify-org-profile-move135-control-v0265-backlink.mjs @@ -0,0 +1,107 @@ +#!/usr/bin/env node +import fs from 'node:fs'; +import crypto from 'node:crypto'; + +function fail(message) { + console.error(message); + process.exit(1); +} + +function stable(value) { + if (Array.isArray(value)) { + return '[' + value.map(stable).join(',') + ']'; + } + + if (value && typeof value === 'object') { + return '{' + Object.keys(value) + .sort() + .map(key => JSON.stringify(key) + ':' + stable(value[key])) + .join(',') + '}'; + } + + return JSON.stringify(value); +} + +const receipt = JSON.parse( + fs.readFileSync("public/receipts/ANTIMATTERIUM_ORG_PROFILE_MOVE135_CONTROL_V0265_BACKLINK.json", 'utf8') +); + +const expected = { + "schema": "antimatterium.surface_control_backlink.v1", + "move": 123, + "surface": "org_profile", + "packageVersion": "0.0.74", + "packageTag": "v0.0.74-antimatterium-org-profile-control-v0265-backlink", + "packageRelease": "https://github.com/ANTIMATTERIUM/.github/releases/tag/v0.0.74-antimatterium-org-profile-control-v0265-backlink", + "controlVersion": "0.2.65", + "controlTag": "v0.2.65-antimatterium-control-move133-surface-closure", + "controlRelease": "https://github.com/ANTIMATTERIUM/CONTROL/releases/tag/v0.2.65-antimatterium-control-move133-surface-closure", + "controlCi": "https://github.com/ANTIMATTERIUM/CONTROL/actions/runs/29362695665", + "controlSha": "bd3e4e02c1b923785607687b36bf1d082042c348", + "controlClosureId": "0e5c9918ca4ba76f44577b62549888dadad5464cdc170e5ed7b7835b9107fbd0", + "backlinkId": "642a078b237d35fd2e8f15d79825890c23089aa415b15deb9d6718aebeff7f78" +}; +const outputPrefix = "ANTIMATTERIUM_ORG_PROFILE_MOVE135_CONTROL_V0265_BACKLINK"; + +const checks = [ + ['schema', receipt.schema, expected.schema], + ['move', receipt.move, expected.move], + ['surface', receipt.surface, expected.surface], + ['package.version', receipt.package?.version, expected.packageVersion], + ['package.tag', receipt.package?.tag, expected.packageTag], + ['package.release', receipt.package?.release, expected.packageRelease], + ['authority.control_version', receipt.authority?.control_version, expected.controlVersion], + ['authority.control_tag', receipt.authority?.control_tag, expected.controlTag], + ['authority.control_release', receipt.authority?.control_release, expected.controlRelease], + ['authority.verify_ci_run', receipt.authority?.verify_ci_run, expected.controlCi], + ['authority.main_sha', receipt.authority?.main_sha, expected.controlSha], + ['authority.closure_id', receipt.authority?.closure_id, expected.controlClosureId], + ['membership.member_of_move135_surface_fanout', receipt.membership?.member_of_move135_surface_fanout, true], + ['membership.control_v0265_release_bound', receipt.membership?.control_v0265_release_bound, true], + ['membership.short_public_tag_required', receipt.membership?.short_public_tag_required, true], + ['membership.no_local_root_required', receipt.membership?.no_local_root_required, true], + ['safety.no_current_production_claim', receipt.safety?.no_current_production_claim, true], + ['safety.no_starship_claim', receipt.safety?.no_starship_claim, true], + ['safety.no_physical_production_instructions', receipt.safety?.no_physical_production_instructions, true], + ['backlink_id', receipt.backlink_id, expected.backlinkId] +]; + +for (const [name, actual, wanted] of checks) { + if (actual !== wanted) { + fail( + 'MOVE135_CHECK_FAILED ' + + name + + ': expected ' + + wanted + + ', got ' + + actual + ); + } +} + +const canonical = structuredClone(receipt); +delete canonical.backlink_id; + +const recomputed = crypto + .createHash('sha256') + .update(stable(canonical)) + .digest('hex'); + +if (recomputed !== receipt.backlink_id) { + fail( + 'MOVE135_BACKLINK_ID_RECOMPUTE_FAILED expected ' + + receipt.backlink_id + + ', got ' + + recomputed + ); +} + +console.log(outputPrefix + '_VERIFY_PASS=true'); +console.log(outputPrefix + '_CONTROL_V0265_RELEASE_BOUND=true'); +console.log(outputPrefix + '_CONTROL_V0265_MEMBER=true'); +console.log('ANTIMATTERIUM_SHORT_PUBLIC_TAG_REQUIRED=true'); +console.log('ANTIMATTERIUM_NO_LOCAL_ROOT_REQUIRED=true'); +console.log(outputPrefix + '_ID=' + receipt.backlink_id); +console.log('NO_CURRENT_PRODUCTION_CLAIM=true'); +console.log('NO_STARSHIP_CLAIM=true'); +console.log('NO_PHYSICAL_PRODUCTION_INSTRUCTIONS=true'); diff --git a/tests/org-profile-move135-control-v0265-backlink.test.mjs b/tests/org-profile-move135-control-v0265-backlink.test.mjs new file mode 100644 index 0000000..014d971 --- /dev/null +++ b/tests/org-profile-move135-control-v0265-backlink.test.mjs @@ -0,0 +1,23 @@ +import test from 'node:test'; +import assert from 'node:assert/strict'; +import { spawnSync } from 'node:child_process'; + +test('Move 135 Org profile CONTROL v0.2.65 backlink verifier exits cleanly', () => { + const result = spawnSync( + 'npm', + ['run', "verify:move135-control-v0265-backlink"], + { encoding: 'utf8' } + ); + + assert.equal(result.status, 0, result.stderr || result.stdout); + + assert.match( + result.stdout, + new RegExp("ANTIMATTERIUM_ORG_PROFILE_MOVE135_CONTROL_V0265_BACKLINK_VERIFY_PASS=true") + ); + + assert.match( + result.stdout, + new RegExp("ANTIMATTERIUM_ORG_PROFILE_MOVE135_CONTROL_V0265_BACKLINK_ID=") + ); +});