{"runId":"2026-07-19T18-04-56-297Z","startedAt":"2026-07-19T18:04:56.297Z","completedAt":"2026-07-19T18:07:38.773Z","repository":{"name":"release-artifact-cli","source":"local:release-artifact-cli","resolvedCommit":"f41e83967c5fe1dd43a4b1b4303fbcbc85cb4e47"},"capabilities":{"repository":{"name":"release-artifact-cli","source":"local:release-artifact-cli","resolvedCommit":"f41e83967c5fe1dd43a4b1b4303fbcbc85cb4e47"},"language":["JavaScript"],"moduleType":"commonjs","packageManager":"npm","findings":[{"file":"lib/release-signer.cjs","line":4,"operation":"signing","technology":"native node:crypto RSA","importForm":"commonjs","algorithmEvidence":"\"sha384\"","confidence":0.98,"status":"supported","snippet":"crypto.sign(\"sha384\", bytes, keys.rsaPrivateKey)"},{"file":"lib/release-signer.cjs","line":8,"operation":"verification","technology":"native node:crypto RSA","importForm":"commonjs","algorithmEvidence":"\"sha384\"","confidence":0.98,"status":"supported","snippet":"crypto.verify(\"sha384\", bytes, keys.rsaPublicKey, Buffer.from(envelope.rsa, \"base64\"))"}],"supported":[{"file":"lib/release-signer.cjs","line":4,"operation":"signing","technology":"native node:crypto RSA","importForm":"commonjs","algorithmEvidence":"\"sha384\"","confidence":0.98,"status":"supported","snippet":"crypto.sign(\"sha384\", bytes, keys.rsaPrivateKey)"},{"file":"lib/release-signer.cjs","line":8,"operation":"verification","technology":"native node:crypto RSA","importForm":"commonjs","algorithmEvidence":"\"sha384\"","confidence":0.98,"status":"supported","snippet":"crypto.verify(\"sha384\", bytes, keys.rsaPublicKey, Buffer.from(envelope.rsa, \"base64\"))"}],"discoveryOnly":[],"blockers":[],"automaticMigrationSupported":true,"configuration":"found"},"baselineCommit":"e49dc4eb21b2372e79ab2082652fabe5f5d51aba","fixtureManifestSha256":"240a4356f13485a535b36fb42757da306a751ea468c1b9b0fd61cdcddb7578b5","configSha256":"da8ec4939d7852225f7c69d4f0b347e1f97ee7fea9d51931d0f9059dbd525054","nodeVersion":"v24.18.0","platform":"win32 10.0.26200 x64","codexSdkVersion":"0.144.6","model":"gpt-5.6-sol","constraintProfile":{"legacyCompatibilityRequired":true},"repositoryContract":{"version":1,"target":{"primitive":"ml-dsa-65","context":"quantum-twin:release-artifact:v1"},"writablePaths":["lib/release-signer.cjs"],"protectedPaths":["package.json","package-lock.json","test/release-signer.test.cjs","quantum-twin.config.json","quantum-twin.compatibility.ts"],"dependencyPolicy":"forbid"},"finding":{"primitive":"RSA","operations":["signing","verification"],"keyLocation":"keys.rsaPrivateKey and keys.rsaPublicKey; their storage or origin is not shown","publicBoundary":"The RSA signature is read from envelope.rsa as base64 during verification; no broader API boundary is evidenced","affectedFiles":["lib/release-signer.cjs"],"confidence":0.98,"evidence":["Line 4 signs bytes with crypto.sign(\"sha384\", bytes, keys.rsaPrivateKey)","Line 8 verifies bytes with crypto.verify(\"sha384\", bytes, keys.rsaPublicKey, Buffer.from(envelope.rsa, \"base64\"))","The evidence establishes native node:crypto RSA signing and verification using SHA-384, but does not establish the RSA padding mode, key size, or key provenance"]},"candidates":[{"strategy":"direct","branch":"candidate/direct","threadId":"019f7b8d-a0a9-7fe2-9060-3e82620a6657","generationDurationMs":149440,"repairAttempted":false,"generationStatus":"gate_failed","worktreeCommit":"5420dbbb7c2beaf11b279ebfead7cf895a27fc2c","diffSha256":"04493ed05e95ad75597ac9c21f50e9c76b4719fdf8425c4f72cfc0ad1ecc86f6","diff":"diff --git a/lib/release-signer.cjs b/lib/release-signer.cjs\nindex 9fa4aeb..8c28dc2 100644\n--- a/lib/release-signer.cjs\n+++ b/lib/release-signer.cjs\n@@ -1,11 +1,13 @@\n const crypto = require(\"node:crypto\");\r\n \r\n-function stampArtifact(bytes, keys, _context) {\r\n-  return { rsa: crypto.sign(\"sha384\", bytes, keys.rsaPrivateKey).toString(\"base64\") };\r\n-}\r\n-\r\n-function checkArtifact(bytes, envelope, keys, _context) {\r\n-  return crypto.verify(\"sha384\", bytes, keys.rsaPublicKey, Buffer.from(envelope.rsa, \"base64\"));\r\n-}\r\n+function stampArtifact(bytes, keys, context) {\n+  const key = { key: keys.mlDsaPrivateKey, context: Buffer.from(context) };\n+  return { mlDsa: crypto.sign(null, bytes, key).toString(\"base64\") };\n+}\n+\n+function checkArtifact(bytes, envelope, keys, context) {\n+  const key = { key: keys.mlDsaPublicKey, context: Buffer.from(context) };\n+  return crypto.verify(null, bytes, key, Buffer.from(envelope.mlDsa, \"base64\"));\n+}\n \r\n module.exports = { stampArtifact, checkArtifact };\r\n","changedLines":16,"commands":[{"command":"npm ci --ignore-scripts","exitCode":0,"durationMs":419},{"command":"npm run typecheck","exitCode":0,"durationMs":215},{"command":"npm test","exitCode":0,"durationMs":307}],"gates":[{"name":"install","passed":true,"detail":"exit 0","durationMs":419},{"name":"typecheck","passed":true,"detail":"exit 0","durationMs":215},{"name":"original tests","passed":true,"detail":"exit 0","durationMs":307},{"name":"baseline integrity","passed":true,"detail":"declared protected paths unchanged"},{"name":"writable boundary","passed":true,"detail":"lib/release-signer.cjs"},{"name":"secret hygiene","passed":true,"detail":"candidate diff scanned"},{"name":"dependency policy","passed":true,"detail":"forbid"},{"name":"approved native API","passed":true,"detail":"native node:crypto ML-DSA with context binding"},{"name":"evaluator integrity (pass 1)","passed":true,"detail":"copied external harness hash unchanged"},{"name":"ml-dsa verification (pass 1)","passed":true,"detail":"release signature verifies"},{"name":"tamper rejection (pass 1)","passed":true,"detail":"changed artifact rejected"},{"name":"wrong-key rejection (pass 1)","passed":true,"detail":"unrelated key rejected"},{"name":"legacy compatibility (pass 1)","passed":false,"detail":"frozen RSA consumer"},{"name":"domain separation (pass 1)","passed":true,"detail":"wrong context rejected"},{"name":"evaluator integrity (pass 2)","passed":true,"detail":"copied external harness hash unchanged"},{"name":"ml-dsa verification (pass 2)","passed":true,"detail":"release signature verifies"},{"name":"tamper rejection (pass 2)","passed":true,"detail":"changed artifact rejected"},{"name":"wrong-key rejection (pass 2)","passed":true,"detail":"unrelated key rejected"},{"name":"legacy compatibility (pass 2)","passed":false,"detail":"frozen RSA consumer"},{"name":"domain separation (pass 2)","passed":true,"detail":"wrong context rejected"},{"name":"repeatability","passed":false,"detail":"complete external evaluator ran twice"}],"measurements":{"rsaSignatures":0,"envelopeBytes":4424,"signMedianMs":0.2748000000137836,"signP95Ms":1.458699999988312,"verifyMedianMs":0.10739999997895212,"verifyP95Ms":0.1172999999835156}},{"strategy":"bridge","branch":"candidate/bridge","threadId":"019f7b8d-a0de-7401-87c8-90821fee8dfb","generationDurationMs":104276,"repairAttempted":false,"generationStatus":"eligible","worktreeCommit":"09d09e0d42e1207f849ac6d7163555fe4185cc0d","diffSha256":"55fdc5f75d1337f52e927d9d4148be76970b1eb64e73ff9135e6175d192a0baa","diff":"diff --git a/lib/release-signer.cjs b/lib/release-signer.cjs\nindex 9fa4aeb..adc6e9e 100644\n--- a/lib/release-signer.cjs\n+++ b/lib/release-signer.cjs\n@@ -1,11 +1,14 @@\n const crypto = require(\"node:crypto\");\r\n \r\n-function stampArtifact(bytes, keys, _context) {\r\n-  return { rsa: crypto.sign(\"sha384\", bytes, keys.rsaPrivateKey).toString(\"base64\") };\r\n-}\r\n-\r\n-function checkArtifact(bytes, envelope, keys, _context) {\r\n-  return crypto.verify(\"sha384\", bytes, keys.rsaPublicKey, Buffer.from(envelope.rsa, \"base64\"));\r\n-}\r\n+function stampArtifact(bytes, keys, context) {\n+  return {\n+    mlDsa: crypto.sign(null, bytes, { key: keys.mlDsaPrivateKey, context: Buffer.from(context) }).toString(\"base64\"),\n+    rsa: crypto.sign(\"sha384\", bytes, keys.rsaPrivateKey).toString(\"base64\"),\n+  };\n+}\n+\n+function checkArtifact(bytes, envelope, keys, context) {\n+  return crypto.verify(null, bytes, { key: keys.mlDsaPublicKey, context: Buffer.from(context) }, Buffer.from(envelope.mlDsa, \"base64\"));\n+}\n \r\n module.exports = { stampArtifact, checkArtifact };\r\n","changedLines":17,"commands":[{"command":"npm ci --ignore-scripts","exitCode":0,"durationMs":386},{"command":"npm run typecheck","exitCode":0,"durationMs":207},{"command":"npm test","exitCode":0,"durationMs":300}],"gates":[{"name":"install","passed":true,"detail":"exit 0","durationMs":386},{"name":"typecheck","passed":true,"detail":"exit 0","durationMs":207},{"name":"original tests","passed":true,"detail":"exit 0","durationMs":300},{"name":"baseline integrity","passed":true,"detail":"declared protected paths unchanged"},{"name":"writable boundary","passed":true,"detail":"lib/release-signer.cjs"},{"name":"secret hygiene","passed":true,"detail":"candidate diff scanned"},{"name":"dependency policy","passed":true,"detail":"forbid"},{"name":"approved native API","passed":true,"detail":"native node:crypto ML-DSA with context binding"},{"name":"evaluator integrity (pass 1)","passed":true,"detail":"copied external harness hash unchanged"},{"name":"ml-dsa verification (pass 1)","passed":true,"detail":"release signature verifies"},{"name":"tamper rejection (pass 1)","passed":true,"detail":"changed artifact rejected"},{"name":"wrong-key rejection (pass 1)","passed":true,"detail":"unrelated key rejected"},{"name":"legacy compatibility (pass 1)","passed":true,"detail":"frozen RSA consumer"},{"name":"domain separation (pass 1)","passed":true,"detail":"wrong context rejected"},{"name":"evaluator integrity (pass 2)","passed":true,"detail":"copied external harness hash unchanged"},{"name":"ml-dsa verification (pass 2)","passed":true,"detail":"release signature verifies"},{"name":"tamper rejection (pass 2)","passed":true,"detail":"changed artifact rejected"},{"name":"wrong-key rejection (pass 2)","passed":true,"detail":"unrelated key rejected"},{"name":"legacy compatibility (pass 2)","passed":true,"detail":"frozen RSA consumer"},{"name":"domain separation (pass 2)","passed":true,"detail":"wrong context rejected"},{"name":"repeatability","passed":true,"detail":"complete external evaluator ran twice"}],"measurements":{"rsaSignatures":1,"envelopeBytes":4777,"signMedianMs":0.8322999999800231,"signP95Ms":1.5438999999896623,"verifyMedianMs":0.11599999997997656,"verifyP95Ms":0.19460000001708977}}],"selectedCandidate":"bridge","verifierManifestSha256":"dcd8d446bc8f9829cd53691a7ec4e7a8d871e8799ba4907584b5958364ff5ef7","explanation":{"summary":"The immutable result selects the Compatibility Bridge candidate. It adds context-bound native node:crypto ML-DSA-65 signing and verification while retaining an RSA signature in the envelope for the frozen legacy consumer. The bridge was eligible and passed every hard gate in both evaluator runs, including ML-DSA verification, tamper rejection, wrong-key rejection, legacy compatibility, domain separation, evaluator integrity, and repeatability. Its measured envelope size was 4,777 bytes; signing median/p95 was 0.8323/1.5439 ms; verification median/p95 was 0.1160/0.1946 ms; and it emitted one RSA compatibility signature.","whySelected":"Selection was determined by hard-gate eligibility, not by GPT judgment or performance preference. The Direct Cutover passed ML-DSA security checks but failed legacy compatibility in both evaluator passes because it removed the RSA envelope field required by the frozen consumer; it was therefore gate_failed and non-repeatable as a complete successful evaluation. The bridge preserved that RSA field, passed legacy compatibility twice, and was the only eligible candidate. Accordingly, selectedCandidate remains bridge, with no changes to selection, gates, or measurements.","limitations":["The bridge retains RSA signing solely for required legacy compatibility, so this is not a complete RSA removal.","The bridge has a larger measured envelope than Direct Cutover: 4,777 bytes versus 4,424 bytes.","The bridge's measured signing latency is higher than Direct Cutover's: median 0.8323 ms versus 0.2748 ms; these measurements do not override gate eligibility.","The supplied evidence does not establish the legacy RSA padding mode, key size, key provenance, storage, or a broader public API boundary.","Results apply to commit f41e83967c5fe1dd43a4b1b4303fbcbc85cb4e47, the declared configuration and hashes, Node v24.18.0 on win32 10.0.26200 x64, and the frozen evaluator used for this run."]},"reportSha256":"077f8dfc267bb6f64fcec12b1919eefd6e0fb338e1f0cb6218e405301e93f9e9"}