From eb6328312795ff243d0a7adc277fb75da16a87b7 Mon Sep 17 00:00:00 2001 From: eimyroot Date: Sun, 6 Sep 2026 13:21:29 +0200 Subject: [PATCH 1/3] R2: add canonical webforge-reference product spec --- config/products/webforge-reference.json | 28 +++++++++++++++++++++++++ 1 file changed, 28 insertions(+) create mode 100644 config/products/webforge-reference.json diff --git a/config/products/webforge-reference.json b/config/products/webforge-reference.json new file mode 100644 index 0000000..d2b81f7 --- /dev/null +++ b/config/products/webforge-reference.json @@ -0,0 +1,28 @@ +{ + "schema": "webforge.product-spec.v1", + "status": "CANONICAL", + "specVersion": 1, + "productKey": "webforge-reference", + "productPurpose": "reference-demo", + "canonicalInput": { + "kind": "brief", + "encoding": "utf-8", + "normalization": "none", + "value": "Premium techno club in Prague with events, artists, tickets and gallery.", + "sha256": "b3f1110814999d1ec1e648e6378f1d71758fc0c1d3983031794335491d901d30" + }, + "identityConstraints": { + "generationRunIdIsProductIdentity": false, + "vantaIsProductionProduct": false, + "customerProduct": false, + "platformControlRoomProduct": false + }, + "authority": { + "decision": "PROMOTED", + "scope": [ + "product-identity", + "canonical-product-input" + ], + "deploymentAuthorized": false + } +} From 6fbdec58608bd3f4e02559b59e8e850adfe23829 Mon Sep 17 00:00:00 2001 From: eimyroot Date: Sun, 6 Sep 2026 13:21:37 +0200 Subject: [PATCH 2/3] R2: bind webforge-reference to canonical Vercel target --- .../webforge-reference.json | 29 +++++++++++++++++++ 1 file changed, 29 insertions(+) create mode 100644 config/product-target-bindings/webforge-reference.json diff --git a/config/product-target-bindings/webforge-reference.json b/config/product-target-bindings/webforge-reference.json new file mode 100644 index 0000000..216cf0e --- /dev/null +++ b/config/product-target-bindings/webforge-reference.json @@ -0,0 +1,29 @@ +{ + "schema": "webforge.product-target-binding.v1", + "status": "CANONICAL", + "bindingVersion": 1, + "productKey": "webforge-reference", + "productPurpose": "reference-demo", + "artifactClass": "generated-web-product", + "target": { + "provider": "vercel", + "teamId": "team_P8cB47XVLz6mGykUGFdfh0ki", + "projectId": "prj_At8RZceUAND02Y5Bxsu4lV6066Y5", + "targetPurpose": "reference-demo", + "permanentReferenceSlot": true + }, + "contracts": { + "productSpec": "config/products/webforge-reference.json", + "hostingTarget": "config/production-target.json" + }, + "constraints": { + "deploymentAuthorized": false, + "vantaProductPromotion": false, + "platformControlRoomTarget": false, + "customerProductsCovered": false, + "branchGovernanceChangesAuthorized": false, + "deletionAuthorized": false, + "permissionExpansionAuthorized": false, + "crossProjectPromotionAuthorized": false + } +} From c6a1fe080aeb5c9df08ed1166cd6f13eef97a2bc Mon Sep 17 00:00:00 2001 From: eimyroot Date: Sun, 6 Sep 2026 13:21:48 +0200 Subject: [PATCH 3/3] R2: verify canonical product target contracts --- tests/product-target-binding.test.mjs | 57 +++++++++++++++++++++++++++ 1 file changed, 57 insertions(+) create mode 100644 tests/product-target-binding.test.mjs diff --git a/tests/product-target-binding.test.mjs b/tests/product-target-binding.test.mjs new file mode 100644 index 0000000..8b5c341 --- /dev/null +++ b/tests/product-target-binding.test.mjs @@ -0,0 +1,57 @@ +import test from 'node:test'; +import assert from 'node:assert/strict'; +import crypto from 'node:crypto'; +import fs from 'node:fs'; + +const productSpec=JSON.parse(fs.readFileSync('config/products/webforge-reference.json','utf8')); +const binding=JSON.parse(fs.readFileSync('config/product-target-bindings/webforge-reference.json','utf8')); +const hostingTarget=JSON.parse(fs.readFileSync('config/production-target.json','utf8')); + +test('webforge-reference has stable canonical product identity and exact input',()=>{ + assert.equal(productSpec.schema,'webforge.product-spec.v1'); + assert.equal(productSpec.status,'CANONICAL'); + assert.equal(productSpec.productKey,'webforge-reference'); + assert.equal(productSpec.productPurpose,'reference-demo'); + assert.equal(productSpec.specVersion,1); + assert.equal(productSpec.identityConstraints.generationRunIdIsProductIdentity,false); + assert.equal(productSpec.identityConstraints.vantaIsProductionProduct,false); + assert.equal(productSpec.identityConstraints.customerProduct,false); + assert.equal(productSpec.identityConstraints.platformControlRoomProduct,false); + assert.equal(Object.hasOwn(productSpec,'projectId'),false); + assert.equal(Object.hasOwn(productSpec,'generationRunId'),false); + assert.equal(productSpec.canonicalInput.kind,'brief'); + assert.equal(productSpec.canonicalInput.encoding,'utf-8'); + assert.equal(productSpec.canonicalInput.normalization,'none'); + assert.equal(productSpec.canonicalInput.value.includes('VANTA'),false); + const digest=crypto.createHash('sha256').update(productSpec.canonicalInput.value,'utf8').digest('hex'); + assert.equal(digest,productSpec.canonicalInput.sha256); + assert.equal(productSpec.authority.deploymentAuthorized,false); +}); + +test('webforge-reference binding matches canonical hosting target and artifact class',()=>{ + assert.equal(binding.schema,'webforge.product-target-binding.v1'); + assert.equal(binding.status,'CANONICAL'); + assert.equal(binding.bindingVersion,1); + assert.equal(binding.productKey,productSpec.productKey); + assert.equal(binding.productPurpose,productSpec.productPurpose); + assert.equal(binding.artifactClass,'generated-web-product'); + assert.equal(binding.target.provider,hostingTarget.provider); + assert.equal(binding.target.teamId,hostingTarget.target.teamId); + assert.equal(binding.target.projectId,hostingTarget.target.projectId); + assert.equal(binding.target.targetPurpose,'reference-demo'); + assert.equal(binding.target.permanentReferenceSlot,true); + assert.equal(binding.constraints.deploymentAuthorized,false); + assert.equal(binding.constraints.vantaProductPromotion,false); + assert.equal(binding.constraints.platformControlRoomTarget,false); + assert.equal(binding.constraints.customerProductsCovered,false); +}); + +test('hosting target contract remains focused on hosting target identity',()=>{ + assert.equal(hostingTarget.schema,'webforge.production-target.v1'); + assert.equal(hostingTarget.status,'CANONICAL'); + assert.equal(hostingTarget.scope,'production-hosting-target-identity'); + assert.equal(Object.hasOwn(hostingTarget,'productKey'),false); + assert.equal(Object.hasOwn(hostingTarget,'productPurpose'),false); + assert.equal(Object.hasOwn(hostingTarget,'artifactClass'),false); + assert.equal(hostingTarget.authority.constraints.deploymentAuthorized,false); +});