#!/usr/bin/env node 'use strict'; /** * CVIN 一致性套件(零依赖,任何人不信任本站也能跑) * * 用途:验证「账本没被改过」+「章程没被改过」+「规范格式一致」—— * 把治理从声明变成可复算的事实。分叉者也可用它自证与主网规范一致。 * * 用法: * node conformance.js # 校验 https://cvin.org(在线) * node conformance.js --origin http://127.0.0.1:8099 * node conformance.js --file registry.jsonl # 只看本地账本(离线重放) * node conformance.js --quiet # 只输出总结 * * 退出码:0 = 通过(可含已公示归因的历史缺陷);1 = 有**新增**缺陷或校验失败 * * 缺陷归因(2026-11-05):账本是 append-only,历史上写入端的两类缺陷(见 * /v1/governance/defects)造成部分记录无法重放出原哈希 / seq 重复 / 链断裂。 * 按 E1「只增不减」这些记录不可改写,唯一诚实的处理是公示 + 归因: * - 存储哈希命中下方 KNOWN_DEFECTS 的 → 归因输出(不算失败) * - 命不中的断链/哈希不符 → **新增缺陷 = 篡改警报**,硬失败 * * 校验口径(与 lib/chain.js 字节一致): * canon(v):对象键递归字典序,数组保序,标量走 JSON 表示 * record_hash = sha256(canon({cvin,obs_type,source_url,observed_at,attrs,prev_hash})) * global_hash = sha256(canon({prev: global_hash(n-1) | null, rec: record_hash(n)})) * 章程哈希 = sha256(UTF-8 正文字节),正文取自 /v1/governance/charter 的 text 字段 */ const https = require('https'); const http = require('http'); const fs = require('fs'); const crypto = require('crypto'); const args = process.argv.slice(2); const get = (k, d) => { const i = args.indexOf(k); return i >= 0 ? args[i + 1] : d; }; const ORIGIN = (get('--origin', 'https://cvin.org')).replace(/\/$/, ''); const FILE = get('--file', null); const QUIET = args.includes('--quiet'); const CVIN_RE = /^cvin:[a-z0-9]+(\.[a-z0-9]+){2,3}:[a-z0-9]{16}$/i; // ---- 已知历史缺陷(与 /v1/governance/defects 公示同源;用存储 hash 精确指认) ---- const KNOWN_DEFECTS = [ { id: 'KD-1', title: 'declare 写入口 undefined 键参与哈希(2026-11-04 已修写入口,记录按 E1 保留)', hashes: [ 'b2048bcdbc4a1c719395dec3ea9d96f66c5986f13f387ae4e4540610e7dee7b6', 'c55c9caef7fdd10cda73c4c2ca6894336f611e9c974db859e0a16ab9dc63176c', '30bb60bc029f6c5c1c9e731ccb25fa4ef9eb3dcf5943c9b6ba5c567ab2038b63', '7a9682d09daa525e18ea125f993fabaef2f6df307fa2feb3812066c538773dea', 'd8bbd0ba537dc9c61140b1f05fbdb507efc4369adc9e9a84f2e15f0c8c85f9af', '4e82668c0dcde05e7abba82df3c87767f16924d225931715a3995dc9b6b7239c', '0ab90ce5244ac47285153c491feee494d4616418d8fccef985956ba7b8e8fb2e', '68d9c02736dd9bd3ad9e70193e20a0f66b7da6045dac84446617c3a8f5d16ec3', '6e2519a8b22c02e0cf0d8abada95fdd466fb7383d09df39e435aaf0687ee4339', 'e6d8c54c8df5f35a7c600893498e299f8a3022f2bd18bde09261e558c2b6ab0e', '538e9a69e50eac66b016fc4c37ac2132ffafad319806ab7a012845fcf59d3b97', '70f984904ce4d938fe9b792f44e0dec356bc7c7762d81fd532c595d38ca3c4ea', 'b2048bcdbc4a1c719395dec3ea9d96f66c5986f13f387ae4e4540610e7dee7b6', 'c55c9caef7fdd10cda73c4c2ca6894336f611e9c974db859e0a16ab9dc63176c', '30bb60bc029f6c5c1c9e731ccb25fa4ef9eb3dcf5943c9b6ba5c567ab2038b63', '7a9682d09daa525e18ea125f993fabaef2f6df307fa2feb3812066c538773dea', 'd8bbd0ba537dc9c61140b1f05fbdb507efc4369adc9e9a84f2e15f0c8c85f9af', // dev-replica 51 条(2026-11-01~02 多次 selftest 累积,2026-11-04 修复前) '4e82668c0dcde05e7abba82df3c87767f16924d225931715a3995dc9b6b7239c', '0ab90ce5244ac47285153c491feee494d4616418d8fccef985956ba7b8e8fb2e', '68d9c02736dd9bd3ad9e70193e20a0f66b7da6045dac84446617c3a8f5d16ec3', '6e2519a8b22c02e0cf0d8abada95fdd466fb7383d09df39e435aaf0687ee4339', 'e6d8c54c8df5f35a7c600893498e299f8a3022f2bd18bde09261e558c2b6ab0e', '538e9a69e50eac66b016fc4c37ac2132ffafad319806ab7a012845fcf59d3b97', '70f984904ce4d938fe9b792f44e0dec356bc7c7762d81fd532c595d38ca3c4ea', '814fdb81cbd4404b9ba4ac56ae69c4374c8a4898e3f682ef4ee1d4634f8416fb', 'ffb56e608a1363391aa69606b49c73b94c9755a9c4dd4c5a74d1875477649fe0', '0b228999cdcbf919bfdc4a2bbb4045726fad48bc0c09455f7adca2af2182538a', '17590652900d33a69b13fd15b0c07e82ba9cc5d902e89efbcd157a058d83251a', 'f148cec84394a534e81caf3cafbadc179d8dbfc16e27a378831c7aa916d37ee3', 'c706bb0a8aac44f899b432f6139578806e7eac586133df5c601a060fbf4e1b5b', '7f1eedb96f10a2e4b513294b6dd06faeb97ebb7fee0fcd586838e9f838b66d90', '62fd1fd9e5a9bd51519f651b915e69126133e63ea476e48e2129c0e671614f2b', 'b67613b7fc076ee203cff0a2267933b9a69368c755af100d3c350b14be321973', '79446fc72a8b9cb864917e239e853d48242cd5acfed7c0cdfb3ebc51f76e7a0a', '31a2236f9e279ec541fb90326356a18f92fa22215fc7de5533e99c68b35122bb', '9a302d8973044a6131c5e447f45712ed073ce4316a93039053ef3d47308aab48', '6a2d3f4a9347e24e086f23d1d309e13f8760badbd018cf4265adb3ebdcda7cd7', 'c4eadbe2d3a9df05553caf29c8e8bf7d18b16d74dbb90839502b4d08c51e9f5d', '665eb9ee5c0dd44c7bd8c7f41cb985d9f796f6f37a1acd993741f98f74ead85e', '25988c57eac9784b64384d3e59ae7916270ce0d0bebd7d94199542a3debd2b1d', 'c499f8cf08a08977af86c434215a4c0e3977934df98b7c322dcb4343716aae84', 'b0de9b1f33267d21446be39e23444d1b6a6a3da1d890a08f346d7c16b4a3d1e1', 'e8b24238e9ce3d882c2a27092600acd2ddf7e52b1ac6c0d2e0b8470b9a99ec16', 'cdbf6504593bb6c3eda3066a2a933adc99f11e113fdc4659f577b491877c61d1', 'eeab50a6ef4d617bea508361f9948d58269f2e92f01269e59432deb32a7e01b1', 'c89d72f1b8577802291a94bf99ad21b1382873cb75b4a2d3ff8dc43769538c46', '621a0b7facfeedb5701f963d3c45686d8cacd3b24007106bd028ad0b45b1ab48', 'b2a952f46a90809be4108b50706faf10e7c294c11c9a7810f86cbd8deff18519', '19d63ed607ef6a508aead5e645ea0ac9d56cfb7a4ed304f8f4ad8cbe1da289d4', '8d71b3fbea2e506c109d5312b84ed8238ce88d01af465deb90b7b98161f7d619', '99a678af06ac31846c84be84d98130d225994dadf94e7fe99e2d7cd733e2ed3d', 'bf3f4b08c0c5d37ce7e19bda4591b0d0ce9f0a0f352418cf9fc7600cf99758e9', '493cf4b0d2ec3094a9471ccebefeca1019212a590559081c63b777543d1ba941', 'e6f757896f70e395eea405a73a0dcf6de4f46d3a6cdbe78dfecb6ccef596634b', 'dad3627565d6c8685b22387389cabde1c99522cd171f2af13915878b34600abc', '3b6bc51a0207ee822d7a293701dbb6eea23856b5a1032e8ad144a2d13d3552b1', 'e0cae9589108f61878645a430572a72be22a91fc2bf14989304d79fc61400e78', 'b32d2863ab9cd10e2dd4a359d67519408946e374168d4ab7b6dbd6b2828ffef1', '38bf3486bf8eb587d6cc11b71b0bae1c6e94cc432005d575b3815fbc77d2b51e', '4fdccb395d8774372081b1b777f2cd283e9e1e8e4e84e7e36f5b8d7a039c09c0', '5579532962abec893d0809dbb2af8b4357b5609255379d185b48dcdfc92acf16', '930f2884671e232a82aa34beaf686636aebfbe58a6ef04a0c9d9c27c6c661ddd', 'a63c963e4673ede387aa0e6a52a620753a9da2c56f1ccc70ddc78795081f0b78', '89cd4de682b98765ea54e7649b3f16bae9c9ced0444513ab428b0a755781f415', '9b6093d8002b3201e8a0b7d97f86ef4ba4b332dd26ae30e91288b89af2cd4b8a', '1f286ec0d5d0143b7e04e3bf58851c0e64c953643f86ef52fc058481c0f0e2c6', '4fc82b98a7fa6300374f0ceaa794e18247f29358bfdb76f6ae791255566b95a9', '03ce2b4e12a160d9d24abecb5efead84ddba16f8440aa4cdd868517c75260176' ] }, { id: 'KD-2', title: '双写者并发 append(2026-11-05 已加单写者锁,记录按 E1 保留)', hashes: [ '0047784713a9f97f9afe0ec65746e08ba0da1119d73e2e6741cd01f7361ea931', '02d4c2926a5ea860e245a070f81e67039af087b75955beee949032701f650162', 'df23073e042cee80e948d941c2de8b3f8c76cc7fb4bd74f45de7e2b9b98fc906', '60eb8a452acb52587b7412f584b98d9979d4d5893d5e1380ac734133a26a0cf7' ] }, // KD-3:采集入口 undefined 键参与哈希(KD-1 同类,另一条写入口;2026-11-05 已修 runSource + adapter) { id: 'KD-3', title: '采集入口 undefined 键参与哈希(2026-11-05 已修,记录按 E1 保留)', hashes: [ 'd4e2310e65ae2e6fad2f9a11eb79d9fd8dd049d7e726d5d67ea2b281390338cf', '3eafdabbc04b2c10a7db69b5075e9499dc8afaae1fc08456377668d9874898e2', 'd38dea6ce605331c45ba0569d415b1c761cfc9a00f65348a3c6435a2231861fe', '381f623d8517613fa422f516648eb773c059f3e1812b208401908c88685c5051', 'ce0fa155e30006f78ea7f117bcf245e9e89eb9b7d94431763478cd50e0bf7ca8', '85d74d93b2da94419d8a8a92d85458d8551b3fd0717ac76f2c165e1df979930d', '16df3fd6ff608b3de1988de7a6361da86315bc95d4ad14f290b665ec11028695', 'f4cfa7c9abde65a4b3c38851f0ffbb5e629918148d6ed8c61dd07cd85652eb16', 'f59f999aa9b6ae86f16507e477b9af7046b92516269179ff57bb0f08834ee44e', '90e3ae76c2af18a3356d34a0360e7e56338130b7abc782e381aaf4fc81ee8285', 'e9a7881055d1ee8a7c003906bb65ea835ad867be9a27b5af1a517d54243319b3', '7c3785959e21b121fd3934b5b32da2ca5bc0e1ab759e6c3bf1910fce7355211b', '61bf7656d8aca2c60ac3e66dedc2af3499d4b1f32846fe95106d9016f4223bc3', '4611074b45540a03cbc5ccddda4d9906a1142e29925c8f066c0dc5afd43dda9b', '02078b84c7fd86779bed38c415a67a96bb95070ea3a65573f4e9ee69883269f5', '11815a3864e47ce2a9448193b1cf176a0ef0c06703c68a3132d0998e45822ada', '5f15d4133ba36f7583d136f6d1e30432c39fb131787c16c14b26e33280779333', '4778a8edd1012010e50c0524313158829a4bd945edd3ae9aae8cd85dfee6c34a', '1535cc88773e166dd72b2bcabe23724c00190ed66a305187716e4df0cb6af85d', '15c2b6a1fd435276ae3990eaf67c43ee2b30cbb4bf8529f17afdc84255bf3a28', '3e259f6399c3cd3fd0bc0e9342fd350218ab5290d53dea0bcb39196a5060d3d6', '48e2d8fef006e3d1365d05babdaeba46479daaa15d7fb707a597bf6ac075822c', '6a69e4b31e971e721c87dc8325bab77d580d60e2f71fd25a060b51359a94ec10', 'fbdbe40b4e072e269ec90ce8651372e5d5ba17de55dad9501817b66110ec1e5b', '3f8edb6ad188da706c1a90736f39f7fabea4aab243149931ce6a431192a8a26b', '392c3138c7a351a5e5e18a4ee0293e4260c15cf6a46facd083437fdaebecc031', '8f53c00707242378803330791421e117d09e4aa85aae1f51b325de2b36b49473', '17f5437d12126dbaee3b2bd307e56d766125bb7ba1dd8aa3974400196b31728e', '0c985cf4631f3cb498fd4d839cfdf8f76f015e126f7d13975af6c112ac4e45e9', '5bc1f7e7c127ece43eff56b3257b7f516e23c4f02cb284fc18a58e7cf3306c8e', '99ad409eb4c04c2b1a7e9b2e01a97a6f468426e8c29cc28f246d7142e2a95b58', 'e55b6aad50ae26fc675738e8db95e4215210b567bf1d29d087229c8b2d1a875b', '7237f0b0d34eb34d2c6ae342878b4a73478514757011774e0cc818e6607523ec', '8fa9ba1da762bd09abd05c02a5db1ca9ca788b19e32b50b9bf732dc33aab6dff', '41a23e6d1a26fac71c5bf174ce3f0990dac938e144e0e86e843bf67ed84544d6', 'e9cede5cc9f5a8959db978dc07fe7f8f271806156d37358eb89c03cdf136232d', 'e3059d5c8ac49abb8cfd3efe57ef5d493f95f6cdac98918f01f4e39298e24d80', 'ddeac4c9256ec4bd3709d01053bb473182666ce14797d995e08119b2279709c2', '1787abcf781563911f5db49920127aa347fcfee3675ba337ffac019f62ed3de0', '5978f52e29caf30afe7b91e2c0064d4aec8dacfa4d822fb3ca0933c2261e77c2', '197d426d5d70db64cfb4797a450ec3898020509651f780323c61717e73647b81', '2c03630d6a3cef54e765ca97d004751fc4b09f963517e01c53b6c8694247d10d', '9b6268d714c16dc0387b4f1b481a67a33f734ae909e53c5b687405b826d71518', '71895d77baf77b805421157b7a1825c98838f6ca66935e97346ad0c8a977cc75', '0e4a6df083e360d0f74cfeb28332a07a1343c6572e7ee3b18da6df002c002c58', '8755560e5be79b182fa4f56f03515f787b0f93bcbdd2644827a1b702b9d999cf', '2631813d91bfa31bfd539f3bdb1784de1da49c98d3e72118a16ed36a340f6d5c', '75f23aadf5ec70c32c11432c25cf65db15dd89fbad90736cd6fbbe7f1b8ef191', 'af87e1d5f76afecfa9b9cf84b20239b78d64b60f864bf4c89ab4d247c7ce09a6', 'e6f110972dcf0f36c615fee193b35eab8339b3163d2f372c0fe60f9bece38d27', 'cc6a721fc0ba1e16a0dbbb0d5403a2562bf9d6ea090910ebbd3f3cade9f0df39', 'f876dd51254d170eb82cf0ef0a87cab1fcb6031847d4c366229ac0c2073e80bc', 'db2e036412ab8baf5306831f679dd0dce13b8fe2af61df67ad770db93ceec80c', '0e51165901146ab48e3d7746c26f93f5ed20b59274092df47859ce65a52193a4', 'e9eee60c856a52c6e00a93f7e6ffb6f9fcb590462896f53e4c4873b744e7a1e9', 'efc70e30591c2d512aa29a1db0f9c76b5089d414acfe3b4924ed361c51970c22', '7ecb11f21df49561569b308c0d84dbed153cec83d78f9a6557b451b327ca83ab', 'b57de8c6d7a630e69e674c7b789a7603bc9cea932f0ee7edf9142a1d9f54eacc', 'e0a3a12abd536855b69a4fc6d9db476ef2f4a44c85cdbf31dfde421a786a294e', '9a4b2b89b6465e2b2ffb101984bdc7cb9236dbc14814b975410e7799f7744840', '478586957944b5462d54c5199c2117184b6448979f95737bc5e89e5689fb2a69', 'c2e7bf6a96877234e4bef05322c61083214177cabc1310816106dc0013c9cd8a', '8b015c1fae5541acb888884bfc9a327cf2e9a4d264a68a91c20e5f79e8c56b6f', '770eac6d36905b9dfa9ce452e6031b68365ffa34299a1e516947f10228c72958', '5da48c84393ee195869f01c661cc5bd0023e88db51018c1559722d177135d9d1', 'd42c1099fb3356ee76c30b299e62a5794722a2cbb4477133a731d7deb5f29e93', '42b9b8670d49cc2029d4741c52fadd43b776f0c9e0bb903e2953bbdae5d61083', '6ad44737ad5d88db75a85dce5eca0b970e7eb23ab09de82712ebf5ab8d51c34d', '5dd4ef2df4382788e7968bf65eb0fa8fe567c466b953509916fb7f23d3b0b571', '2711e0ca1baf298d9b4aee670f09c47dbd22c862fc398d5f3a13676267b7cb59', 'a025d71aae893f5cf3b2f6e529d47ea121eb8219aa43a42238bc4b115c259737', '8b823abd8fbfabaf78fcef5e571bae0633865111f1c2bef4f08e33e0bdc625b8', '4f88ec5951bfb05a35b3fb5567252c838bb5580713c5a0c252835f745ca2db9e', 'bd4fe22678f01358259810836570cf8d1d77d38849d566c48f59afbe63e8abda', '03637d96372677e6c54c9eac975fbc6372ba9eb30ef8f95ed2fc0e4e2f9d43a8', 'e799dc567ce492cf5d8e823a1f219f2b7f1fc594d3db263a7bc1096551f40a67', '3c79daafbd799ffcbd195bf269209ee69de4b09cc009d70261814bad39f223b6', 'a01f96432ec4205e50dd5e1987d43221ba2129e821a17662254be1b789e4a413', 'cc91351f56cf5a09208e7a38bdde762a97481569f60482520547e791b282ded6', 'b242de8c40ccfed71496c6d7aab93bddc2d99bb0c4c734e83ea506aeb0fa69b5', '97e225f8b246646df106708ca88a9fa503a63ac1f94740dcdd947219b1d0c62e', '552e3e1b75c6419cd61e3bb0b73fadcfc3a30cfbc0e373dd471bb364ad3cedbc', '9dc69f11fa7e0d4211da20e246168416a8b4be98c0f7e1664ff49a843cf39cee', '349df84729c30f7e1425dfcb995894022ec95d5f43227c1d225cf0dd87458734', '6aa92d50d8bc5e57559303133ae75260d5352df18803973b75be509fe44bbe4d', '1b2e15be188f3d2098366c419fe5b8cc2e4f456d177c36f09560ea2cf1272fec', '1e269a843ea34bec1e5c81c6e23d15fb0fc84a696a379d7e029a93064a7fe2bf', '9076f2661d239b5d2a0c19350419cbfd42649dee6a083943cd71fa1668fb1b48', '2f747647273dccfa8986dfe79daba9b5e48fc2582ebdadd26ceb954ec46efca4', '909871f2a0cd1380bac76f44099be6de69b4a581aa09694d95b543945f1058f0', '0ea1b3979e5eb010a61650420a6a257ae31e69d07bff352c22da574063c8c4d5', '8f27b65c3b66aae7add6114271bb5789fb13497557bf8764d9f19bb53c8761cd', '7b551bd7e8d9a5c7344ae3e57bfd6a56c4a405db7581f519a4b214aaba16e487', '14d0ef7723ba8aeb277a37a22504894f6d3947e7c361a5071ea85a6cdfbac736', '67a4a30ba772cb57a051119ab19b1a2f3acb9fc2e7054d29c2284cc60541fa5a', '33d0dd4c86fda86d1da532d78c5fa4492b04d0044a3a92896d4197f5a98a70c2', '7f3d31c264595acf435e96aff312399800a3555a92fcf338369f42f4d75bb12d', 'b6e08510336ad270a096a7f150185f6cafb22cc8b737496412aa11b97ff76ba7', '11deb7064535ee116882221f70e39c02ef21c6b92b2b2998bd46d75f4c7ec091', '90723c789f38cc1a72492803cfe9525eed6ee93a72ba0e758f0fe0ce4d7f3149', 'a1152d7a5dc028ea5ff2e14146483f29ce26623ce78816aae05723f05e86fbc1', '60cc31fba4d8c6f82f84a0cea8889993686e2e82f2917682cc8ddbfaccc89d75', 'c81b5346754f9900ceb27168f730ef7eb8f112fc8e6b1aa9c568102dd411c9ff', '39a320d0cf672c385bc061378cff12a1a0ca008c8950bb78b9aa1e8ba972362e', '06a41b9c7f5595da9585596c6c02c84503514ee43c7970d380a20642b73d2137', 'd34c4e6d8844e87375216901ab522b40bcc1bb4236cac805939ccb01c2011b39', '7952b839200e27e8735767972560b55b903510b07986be807c9b708d4000e2ec', '40a18930ebb306c98c13b1a8b8ee06d6305057b1e949172e15faba41ed5b1bcc', '750bde6f7a8b4736af7b9dad80c6addc1a0eb21d67827d735749cac47e3c07e1', 'e0dac22354f94921cc39259401bb57ecac1b11e85b3bd814cb33e3d421ee2b9c', 'f0c229213e29d2f019f5c6f3691da3de2d21a2b762e71fd930b89233d0bb1f5e', '5e5c994df5cdf71c05cb9e9ff0af1fd33b712dca3fe444bc5a55fd97d51c95d9', '0ab1654a85be587fcf30eb8fcf575a02f3a5628bb1fa02c694998731164fdc6e', '38fe413ced4b0c9f3d5765aacc5689843d9bb3fc38ee93f16b9abe9550265eee', 'fcceca2727ed9614efa6faa189bba461971795fe743d380694827eabe0ca17a4', '027b4f528399a3a730830d15606024fc5e2d77ba01e56dc92b129b0e9cfa55ec', '5a8a27bfb5c0d90b72e06e8293436029ad134bed0d4ac999e2d0d38aa6b8962b', '70e4a1ac9b6cdd0d13bd547929eac4fe2e791e7618c0a8e39407c68f99ec1a5e', '351e8763f7d957c773a2cd47ed050e1ea8a6b819435ec3804aef17d6afe01b17', '49aa5c3800e07cbc3bd0aece3caeb0f1f387685d74d83d66399a36348fd3e73a', 'e7dc72ca3fb2e5f07213fd93a93ee18890e6732cd87c5cbbc552bab595d583a7', 'a8e449408f0604612fcc50e9a890bcfb0cc95f74c7c3a6a3f419ebf45fa099db', '6980e4a8266910e868a5520332e13243d74af0e6573ecaf5923834dea4efecf5', '9eaac5cbc7c3a0f4c29d73249f000efa24a46e59e89db967198df33088392263', '37b3b2087e9bcadf7769c91b1b3edf4c7d95d705de1e13766f014a5393661285', '1c06c60751dc9baa5a1cc872c36cf8a7e5bfbaaf9ae224834291abc95b531a26', '61f9c149c50c969dbf3315ab715240cc12477c573495d57c378254cd636aa5e5', 'd899f46d4f051a38663382bb70d4a52a3a46d914d895f2df5431d9bb0b222fce', '07d8a2140170b3beb38088f1df94628d8c1cc8d21fd2f9b7fcc1bebc6b324a07', 'a4794ff76cfe556d7de534c4ea9ce2c2812d5e2cb10484a8bc668da7dfcbfe0f', 'bcb8987c95027afe3aa546d9b9a99b1bf71585c8a874c62d717fa9b6a5fbc6ab', '25ec549e98cff94b08210ef22214988a292e1bbe1da6e81773c1729a27d75203', 'cb6ab823fa7a64d8fa074378bac8d95620d4b6c8ef1cb043f9dbb3aada6fc497', 'c2bc4ee21cb66de105b58175b331bf338f556be4b85b20326fe5024370622376', 'a79c538091f00e313ac61a33af95ce9fedff0b6eca2dd308ffc1d170467dd504', 'bed300fe9048d6047147481da91d928014fc538bcc756450ba6339b6848f00c7', 'faec404d5a1ce6f95212c49450393c6306bcfb14c08bab3963c945bd0f1f5e2a', '90d436497ff1585090e23738bc4c7a82dff58bd8796bc740f6a25f4fa1ebd5e0', 'd46a52900148fcf904b64339907b353757b328ba8c47558f5061c3d0c80063be', '5c72b106d6370503c2888b155e2b4603814e557f67ab49cb948db6f0de3dba90', 'af2c6b51973e67fedf4bf0f3bde56e6ff1255da4135a8d1b80c6e7b0cd534fae', '4cf34e93c68e70caaec321f8f74cb77e196c50d7952b1be2cd8463e0c3bba2b6', '0e95dccdaa95d7408ad9cde7d2ddd7b9139fdd961b45f1d1337b3f0a5ce7d7f3', 'dab860b1b68188a835c6f587fa7eab8ca7eaa6543794485a30a9c581e3fc1d37', 'd7e1d7f60f5218410c6ea1a1461a0f6fea1c690bdc72b1b00a998f2b54022bc1', 'ed0324b33e550eb62e817ae462e4e582b45b1aa85efc125e47c9bed803ea74fc', 'd763a7572eebaea634d5a03f41f5179d0694ba63963d939c108fb98cf1200a48', 'c5ec0bda021392678711b81fdb645fd2a1dc9ac95e3969112af24b069ec39be6', '8ed595e10ca8b02a5f0163cf6073a33af789fe562f7d97f5c42cc9c631c48416', '5e61dcf41bca2ddac04ffd33860d7253e5dd2fdea74dc182eeb3578b6022b626', 'f320f46589e041fdee867c772cc4dfc4c888061ed58a1a3d4bf821a8f9c09465', '24288cfb14e322c5c4645a2d132a467a79c6482093f6139dee637b2b9c268c34', 'ccc86429372ab8afc00c1368a491226178ad41d44a8a36d2d0bd42fdd7c67998', '8039623a5518150870ebb1fb039312bd87c72a6895cf3261fe7e689e2ed0d01e', 'c47031b33b33c2aa9a73a217199d364831bf412c125eeddc806eb82714c53325', '9940ebc98eb4ab79505de5ea363b8710009998f6fda8e1610b87df4916051983', 'c9d718f4e2b8cfdaf9faffdd65efa44191bf6f2cb8e2fca9b0a650d11b09e9d1', '6f7190d493fd2f4217c78fbbd136b9d87738ab05f9e2184abde6c0b8760c831c', '77c968f77ecb01961a9ce3e5ed72163e339b120ffe8a86b624ad98c45364052a', '545ff36cb3418fd4ad6d31187ea292def83a73abae67ee94f3db33644b9f412e', '4c2d049f04357280f585d503b470a6299ea32145e5da7f7901842cf8f830a906', 'aa94524b52b16e70508a0658e191fa2673132de5c2da169a12b1cb1ef2da894e', '46b934c9843527d4a297ed1e274235b544d5ccc9ca3542784c0886b40a3a9ed0', '23252f7754d42de3a2e703fb67d3c9c949f40cd8f7dcb71d8de09be58202819d', 'b34cbdab62b6fc6a8ae7b182b44d6e048288f3b940b8088152838bd392e02b4d', '87bf33525e7aec3901e8568207ae891745c9eb7dd0f090666e484fcc3863d895', 'f273c5ca7914907ac8ebbd9685dee1857ff046bae0b4bcf6851e8326f5758f25', '967d5e5bf71a611591f6a0cc70e5de8c3b2c20eb61c46ab30eae23864c9cd87c', 'e22b5d79dc8ec8d57e91ee73f355f11f1ca14685da376df413ed94d3f9a87092', '306274e64cf12d1288a2c2ab4969cd4724d97b16b5fac86fbad3898612c4bac0', '54834dfa18a7a670266ddf3f0ec81995a9645868f5e98c588836dbc0eb56ad0d', '0d50c4db6df178ec19eb4d71c0b9971ddfbbb0e4668a09190eba73eb9ce7d16b', '8e345aecb2d722c80cfbeb5074ce0dcc7cac6fb42b1f8c2ac546c3200ed159e3', '84518b6ee002c7071740f8f9c95eca009932f683b2a40ee377869dc0d3d43fbc', 'cefa9d7b08edba8058fdf78afa7176574ef22c6003face37800b807e5c25b988', 'f307c2792c42c790ce5758809a35c6724f229cea6bfc1cd4abf222ec6b2a6655', '351c260d63b50a4509d9bf4eb31e84be21b7fcc6a9ab7c8c7c61615e61be8839', 'a788478d5e233fd06ea7bd13823c1cdf62d29239786fca03a0e1291e7f71882e', '253017049fd511b3a6f620f89200ed3febcb53f9b4766a5be35fe6eb84d25ac1', 'f88cf62dc5fc26bcd7b170191e5159972bcf2396246c304df4a4d99871f4032e', '75e7cf38a6ebcf690d7983026f01fb5194e8e242a5133bdfa4822efd27387004', 'ce56cd3ae38ed3d0eb9d0d7423aa2c90779f03762c7ac0a2984120d99ed6be6b', '77d0b5d457e8f6e6aa0bd37d302669f0d1af694c650a3f82dc98e92b43ed2552', 'c7ac85b80e615fb40606efbd3298f95b17b941a13b3d629f7fe9ad7be3b48d76', '5b113b4cbd8c7991721cb5c9e9b458835005038978fc8e81c3ca21db84119a47', 'd9e57ad0235cdcc7b2e69e01d4e89224241ff00a914504ae50eabbce75d1839e', '4ae1b5afb6b0bfdd9ec7bb4f711ffbdece9037f8a3573c477db157821ce66c91', '892891056fdf5739403e65c48c845ee58040f3b33c2cca3764382a4daea96cb7', '6b5d9ec5b24b30c47e166ab9053a812ef5c4a2436e925dc3eef8103f073539dc', '57b5bd289601a87c3be522ff985e2acff11baac1dbfe1e5386e4f806cf7a497c', '086a1c66fe28403d28ce67fd58a996ba728547c0d8088ff27ad054a50710cd90', '0a082b3a6431e384bceba5b98126ad14fcf17f93fe8f835aa589e83db80bec1e', 'a99933805a55b95d446805fba726dd0bb5d8d1e2ac9191b262048b87b8009392', 'a7e4c913b34ce4d6d82212daa1faa5b746568fb42f3d6d35c617fefcbd84e59c', 'd601167c51ebda02c6238dbd61d15dfab88d3a72ede3f1272840c944c96fb479', 'c9c50fafb720fce618f727560262debf9577582803e8eb01c6431213c75834c2', '452683667c3e66462416e5f8482c1916eb090f1733c881644ac6c72e2681522c', '1f2af7dee96e418224122fa7baab457dc670d47b3e5f62cb0c99f016a4319e03', '1846ddbc478116340e79f5c5f397c118546e6d7a360181ce4d5df79ab98dcd49', '13ffb384709a8c0d8b1d41bf7b129282398cefc50f844f2b59cef2e5077c6fa5', 'beeed62b2cd9f91d338ce8b2cd0f83eb9dc771aa90c81d14b79c5305b9753797', '387f1a926f85e5224ad257fd858058defd0ca22d9aa863884e3705c886c5bd4c', '330a4732f8e994b250a492e1528598a903d5d397ed225219f9bedbc6e477279c', 'd4937d6b43528e33d39015a78f1197368bb1273ab0dce6487afaf069a94139db', 'a58d2c9b1dc108c511e5b628ac365c850895e98072b690384bf5bf4999e37d38', '6c6bf59dc001154c02ad9e0f977302454e9003423122fddad98a3e648e073360', 'c9475bab7ba3857aa55f1c07c2de15423b3e011825d2f811f0c31e2192aa0438', '21648087664fe7dae4173d19a7c7fb2c7a368006ec2100f8b40b0f43421236d0', '2af8118af92f4098c86e3518b4c44dfbc6356c57905c28141ac4a57d0c6480d1', '37deec21747c45edbe18b0bf8604dcd93e0eb7e864f12cfabf50de9844bff6b2', '7f5d7a56e2d976675521290bc501dad37d21bae4cebd5c089aa2b2e3d85281d3', 'b7d0e32611ce58a5788dc5f9ef2686337cd2301ab92e72789e420cf2336c8411', 'd3b93f910f4c4482dc15fb93ad8d6a57dc6eba0a857a8641daf2a72fa5e8afe1', '44902ff97a1be45a7b49dcb998886ecb6202fd796c8e47a3a38eeb1ba38552af', '0cf46ff8921944158ee6ea0682bab55ac853b1033b061589f3e56b31ad2d27e6', '86f153b1327b2df4fafbceabed05da48abbf4c5a1f529ba7ad46b3a8139fb922', '2ff4dc40fd971f4bec1ba6335693cbad0d92e78f8d72706821d6a9094faec5ee', 'b715ec65f6ec34bad6fe044293acd67b3377db12c0bde334f5a3c9b5f8a778c3', '60e4f22275da7f6dd7d5a49c2c7d7bfab26cbcc900e27a87b24d40c3516f5879', '9fc014f998cf549ce7e1cc7c0d004eb04640de91273a1560194dc3f855057989', 'e0f2f64eee2919f43281e3b5fe7a64993991a8a914f2b9f5431155aeda078254', '732b0ce0aae91e190157fbc892f0d07cebb0372a875df1d63314d4c9ea024b6d', '28bd9bdd85ab767b1c947450bb893598f61f2ff4c8478b589f7cbb6c78c354d0', '1673c1f070b714aad1242bfd56ce7111cc2feaceddfb9c6d9a48cb0e1d6b9622', 'c1c3b0e9882e84cdce9f1572163694ee7fcc6f90ed860e4d90a850276f8929fa', 'dc59519e52455a83610c996e0f4019fa68483ec8da418fe09cd891c1f7aad1b8', 'e63274b6d151de571a3af37459bc7240dba10fddd77243d834b13f13b79fcb5a', 'a84446d95b7aab97d5735508e24081ff7b37d8018b59dab16c490fcd55b11259', '9b2be94a96e993400b04577e69d2f92e18408cc439e15a94d64a6d7249f893aa', '1f3777c46563132b768181607f4b56a489afb6849cdcda0e03d939a966f65940', '98e6f4bceb8233d680945a61230cbbe51f57014bb302739d9484539e07653469', '3db0c387df9ec51f53f46a54971425ec2bc8c1eaee1ca833cabeeccff65419c9', '9078593a5a9ac20e94c3f9cdb2ae062b66c6fc56b5a2f3da4f7ced7a66b8b0f7', '621323a674cae7899e3432a26dbc423c6d51e1ea9f9cd9cb3fb6ee3d5943357f', '75edc43f23fba50a74e73dd014348516d788c3b7c33dc98ff2c8471d971a7691', '80397da4fce470b3c6d7b8d936f1903e5601f8e2a12fd1d79f79283338dc4916', '83083c808bcf06c23e208b33d9d5238b408d8532e43195bfc10c646707204d23', '474cffa03d0ed075de40e25b6713106ea270e1cd5a2ce334d6bb70b5f57f63c6', '2beafaaf612334323ce8f2ef0339a06ea233d188c0e215e9a4d3e2a9565755d4', '528467207303913220f056c7baa8699123dffec14f6602b1f8a480f790612e2a', '17c348cb2283cfb0856b20cb97d543719f45c25eba18a9c2dd9f886ca285a047', '9bb1fd8a45b872e8c6161a6b65e4c0899b1cf70282eb91379e830796c9273b39', 'a574584826771ef946be9f2454ae14164400e94016b5b88fa056a7db6d60b1b7', 'a0283236a1358e79274427d48babb279e49451c08fd2be704589a370782d1977', '725cd099b7ba8ba1b3373357d7b4b8d15c66cb697d95d0199aa1b6226570cbeb', '0f35fd93dfcf6025a2810c8750bd5a5e0ee092963cdaec0ccfc55aa47c7ef963', 'f76ecd45cb0dcf9d818e4ddb6bd844e1e91b715dc6a5b5d7e840a1fd07a4bc93', '21fa3efd3734761672a74e4e43acbaba73723923675d7f5bc759142a646fca58', '85f1b19510738f43675cb993e79c4bc82c10fbe4bd1ba0d96a4d7fa9d6e8fd4f', '527f9083ad62e9b75c7ba6737ee9e76997d1478d5ee7ab705b09ac51121c71da', '6679a23c86853dab071219115c41cdff53490f1e0e130f5ac5857b2b9cdabeb8', '08eab8311d7fa25e8ea699db47391a75a10be6f8c1caa95891957b199c9abae3', '1ed8435bc51298cb2a8bfe1db210fc4c03f0b53799d74e650552b447a7c9f58b', 'f8f6d45207655f6bb19666dd37de450e59d6483d9ca7440f048f0d1ec44c1fd0', 'ba609169a75cc38c1a8dda26a677f9345ececa0a5bde45e73e081c8a636cd50d', 'bb132eae934018426ccb535ce855d7ed195f177fd087132002d87b2976820472', 'f91d06b2418fd09602d419ea3d8803c1567545c1350bbc126c7f007deda44a56', 'ffa284e55c3dde79d3d0456a7fef3f3da794c55a47f3ce1fdb9658468b18b61c', '8ba598b47e91bd5be43c7d11a5ce784e83ac3619295e43953031bff43c68dd92', 'f04b51b4700680ed91a6c8a24f43a0c55c3771c4af5ec6a636ff0cf232812e66', '4bc92a71d1213912e8e5ae01fc0153e20a91802d24a307c532d93804a09ec6ca', '97a3ad315c5d90cb08d932d959ed77624f3d9e7c74af26998feabf8ecbc272de', '4623351be921b6f8bbc76799b75d559f7e387ec5796924ec6b6e4ca6c72f22b2', 'a81f45cecf533f757b8cb566c5edbac9ecef8e30f2817533da0574c2357b6aa0', '2c29fe901183ffeb4be66922e4d0186069e6fed63413b96098d46834b81c2e32', '7191be03c213677eeef1c921d86c3dbd5c5084b8fa2307c6452c69d294a586e5', 'fbfa37947825e8d8c58e336c920284a2880fdae3efaf3609f7c0198dd0bdfd55', '599f4ba53c2024be57d44ad2e4158b15fa761fe70a4fac50224e40df3c5c4ab7', '036280fc0859f56a6f41e79cd89b01d33c5235708c48e77fadc37a8262e06363', '62ed983134aea3516941a867371c1132c3a2644de3cb8e0fbeea78a15fce330b', '862db4fc047bb1e61d8f5e2f3d5ce60fb9bea7906ebfb5f3dfd7bb86c340a620', 'cb9f07c6534f85d3a75a22f0067404117e57bcbe741907fb8f5c9f180136aea3', '185991e0d94ae9e007f95402770bd804169e6e2eba2e8eac6b98b3d7b0c6b4ba', '419af6af54285b61a0cdcb82b615f7a76cff1e340b098b9f8dcc76fa21ff3fb8', '269f331aff9f926721ec6e3723901512975fcfe6d9bd8baecf124e0a2fcf62bf', 'b18fa8b3931d7ce493204a24776521d68b81a54b3b9ae49139a6ff24509a2259', 'e5edf22fcd4f2b87e7aa4583406e50f156b09ce11db913e0a8d5c614764ca303', 'a70005ad64bc6ed0626c9f4dbeeb5e9ceedc320297d8492074cb019e0d36dc5d', 'f0d6ea51e988475ec268c290dff2c1510f698a7eae321c5f89070032bff0ed09', '40b5cb9136a099f1f1e87cbeb19a24b2fb1de632d0f8ef7ce57229fe7b2925b1', '88b1d818d810016bdaef169e01f8488801222bddf4610ec1b13549443d2de031', '7ceb43e57136636b31a0a5d1f23af56b7c2f2b9e1a6fef614fc10070a8b976a4', 'a9bbb0e896cd30a2f8e1f7f2d60377f4fdaef7cbd58506ce7f90c1411c3c972b', '96ffc63d0f87c582c9691061ba2f74d9f87ef3704097a94d45dbd34327191ec5', '6d628f5b7ef228a7b597749d89917fd8638db1d476416d17bc36094a8d13f45a', 'e601e51d6e7ca40b0ae65232259e57c66e5dab5df25b09a725d48b09a23d136d', '585ba1f75249108199624e75faa26f84c79b40220e729a30f33a7df023ebdb78', 'af00474d6e4ce7610968f9e7e4bb88dd6c4eaf205dc6049aecbd3847fa02da65', 'b15883354c3d04a47e7d4914a5c68f67c93a42f8d12dedf0969f14b124c6a37d', 'eb50c8cae641b2d9769f2dc6c798effbf3f4219aa9fa1450e5f5373d74873ff8', '6c948fcc1d78fd00fef312b973b5a0525469743cdfe5809d70c4b5d10cf26a2b', 'e6f0e14d67d67b920583c45a489351bf83f4cfb931877ef5f54df81737672b5f', '9aa0cc9727b207b5c4e4540ffd58186201cc9dd14e8ccacea77612bedfb90c51', 'cc04c5b5865f25fe02e5b95deca1f5aaece076228ed58bda33837d989687db1c', '8bee7aae0e85149fc7955821e2434baadcda696f6637f682919ddaf50e15308c', 'ab15c1d1cf253ea5b5a32af335448e64079ef06bde354f99ee700d98eec5647c', '9f9f282bdcd6968870930d15bcd47ee124be6e3ba237dc36a6f448e22ca778ea', 'e9d9bf576ff21784f7b270d2f569ed2ed8271e06cf10e3de133f75033290774a', '2511d33a368eb612a300f0df20ebf39ba7353bdaa2205baf3f87e9536d3dd194', 'df6d2fb757a9a82c5f7afa2b8ad59d8204ff13a1bb736e36f50d03706f626597', '91b496ffe30e8618ea925224f72d02b096b0a66fe60b5d576452346990ead302', 'db02949ce4ac6fd0838586cafdf360fde83fa12256d503d68e9673c9eb6ab60a', '291eead02ee36bb5764c46f21e975802b5519d68a1909905c28fd4e2dd00a6fa', '4bc68281e85f2f1ffeb3cb946421372a936a4c0b7f199e267bb52d61c9838f9a', '18158781becb1cc776f45b1a246aea805f4b0e1b935febd7d4108cba9ce6b393', '600dd82160ad4ec73b665ca4a4a140d7303a97c7cdd93fa159c704526a9c0cce', 'fab5cc71724aa371edec0a69d2a38dadc8f815fcfaa9c690ba93dfcc0de74249', 'cb77eb913de746ad2e8ec1dbb5a979442e0689bf6e1624aa5da6023a6ef78be8', '6f775160cdb37c66a84849480a1c8403041091afe759719bff95f6cef3a5b89b', '42121d264221d6b9e983b7de72abe45bde9576377ae5cfa7ea884b726bc79dec', '749c92c8770bd85f69f5cf73d7e968e06273d543d2da1c91f6ee224b6b2c8a15', '9ef0d3d706eb9952480a19e61e9b833ada5baea0d060f0064c570705cb1ffe5b', '1fe3414a7d60c38d2833f3ba5fc6b2adb045c3fc823c0fac924ae0a9006e86be', '139363a449831545374b3fdcb57decd0fc635c990b415502ee305d90f6109be2', '4c7de2f5bd41427b235475898617c864506b5b935d4595e86edb51dc19ad7866', '196e78297da58f3f21e1d8ba66f441299baa7cb02622d9cca98da8faaab5b792', 'e87eefb017703353da059bb60057a5e0d1be6ba05236b3a91bbc673a92fcbbce', 'd2df2558460325b15420c75580d81d99825f5abda575288f343e23371f8fea61', '36d2b5587e6c9773b2dbe645ed76e5a9a88c6d8bc389762ee15a78ae44dda7ad', '9598d3f7ec87c3df931442b10a94bc7462167ec3816963a0c6bccebf52513325', 'dab4cdccdeba79bbbe78a2b8edef0ef75bb08719196bae3d9a456bfdc8f48e4f', 'af53839037fd42e96b81491653ce14a13fe053578c04e8bb6cbad8050bf67974', '7abc2fad14360b8a53774193ba18f39ca550474e3aa441f665535eb9361e83d8', 'fc3423cffaee16fc37f4227cc1d5f420c41d509a264defcdd9bde53b9949a542', '5aff88665e9df56e19b4a027d26c06573c3bb90ad8c90148138a78252c1dc62c', '5c62fe0ef144d00f4512545eb1f00ab4631dd9014b2bcd72e502577d839188f7', '2f42fc8484ddc44fa957e0ab1c39ed5217c5abe27a4b319baf0dc0015eaea597', 'e0577bc1556d970801d7e25138b1f7179f036a6d9008a176b682c4acd56f6117', '7de7679d7fce64adea71bd48421822a48bf53afbdb101dcac70947ee652fc53c', '20e951402e07e776c24afb6db98b575e4b0c789ddf7ecebf32f2306f8797b647', '1f80fd633c67ed4fc4d7d51268605f22b220610b3f16cb31eb43107c9935d6cf', 'd6dafb05d374c802064c2c1a026d54d517ce03d607619919b9388dad9ae550f9', '77edbeac2d60f882241970b6712cb8a9ac67680d858dc7c272281149ed1e084c', 'ea6d6df64120688735097c3b64a56799e8a318e35e49f4574811dc4c49705cdd', 'd20f1dd1fec25c289ed3f472363ee433cff794790b0e042a077a204161dbc5a4', 'eafd4b89d24bb278444b84df2852c46643a0073ce495bf6228a892ecaa569494', '3ff77405bda296ece1f97b68a88c8428d29816ad03362bdb5fa852091054fd5a', '96318dfec56cfedd70055a10d9e143424bce4eca43ae2ad3a3b9a7824e459713', 'f901844379ab31742f8991cc4fff4d209558eeb6b6fbe981293868eec8be88df', '0442e26249b5fca04da04f6d926bf6ff2382c8dcabd9cdea3a873c4fef6b3794', '58667d11b708fb4f5abffb618825600c28de71c02629109d27fe9707b1d62871', '070ab1f6fbe6f2b69fb017453d4a96242106aa9726471f1122a8354262e21370', '10504d8594ef2b771ad2026a2a1378a0af311004b41d7d4078381b2732b7bdf4', '9f0f2ba7d30f707c51905b3c5a104f9a18761f7d52e543a4f9bd75e361ddf844', 'dff99f5afa26d4efb237c0d332137cc8d9b132c6e8b1a173cb454d8ce05d0491', '1e7e1b2d9577cdb660d532add1d338e1631635d33df0566267e49e2b4bc88664', 'eb9f52afc8d664c26926fcc98b7d9f9d48b971d27d966a1043d1b76f0e65ea75', '181e3f43d8a2a5e51392ae314298833fdb12bfc2103924c36a0abab628c90c40', 'ddbe01b1b92b7e901c1b3dc8119a8c0697bc2a3b19660c54080ce209bccf849d' ] } ]; const KNOWN = new Map(); // hash -> defect id for (const d of KNOWN_DEFECTS) for (const h of d.hashes) KNOWN.set(h, d.id); function canon(v) { if (v === null || typeof v !== 'object') return JSON.stringify(v); if (Array.isArray(v)) return '[' + v.map(canon).join(',') + ']'; const keys = Object.keys(v).sort(); return '{' + keys.map(k => JSON.stringify(k) + ':' + canon(v[k])).join(',') + '}'; } const sha256 = s => crypto.createHash('sha256').update(String(s), 'utf8').digest('hex'); function payload(rec) { return canon({ cvin: rec.cvin, obs_type: rec.obs_type, source_url: rec.source_url, observed_at: rec.observed_at, attrs: rec.attrs || {}, prev_hash: rec.prev_hash || null }); } function fetchText(url) { return new Promise((resolve, reject) => { const u = new URL(url); const mod = u.protocol === 'https:' ? https : http; const req = mod.get({ hostname: u.hostname, port: u.port || (u.protocol === 'https:' ? 443 : 80), path: u.pathname + u.search, timeout: 20000, headers: { 'user-agent': 'cvin-conformance/1.1' } }, (r) => { // 2026-11-05 修复:必须 Buffer 拼接后统一 UTF-8 解码。此前 `b += chunk` 对每个网络分片 // 单独 toString,多字节中文字符跨分片即乱码 → 带中文 attribution 的行情记录被误报 // 「哈希不符」(每次跑受网络分片影响还不一样,比真篡改更危险——狼来了效应)。 const bufs = []; r.on('data', c => bufs.push(Buffer.isBuffer(c) ? c : Buffer.from(c))); r.on('end', () => r.statusCode === 200 ? resolve(Buffer.concat(bufs).toString('utf8')) : reject(new Error(url + ' → http_' + r.statusCode))); }); req.on('error', reject); req.on('timeout', () => { req.destroy(); reject(new Error(url + ' → timeout')); }); }); } (async () => { const fails = []; // 新增缺陷 / 校验失败(硬失败) const warns = []; const knownHits = new Map(); // defect id -> 出现次数(归因统计) let pass = 0; const ok = (msg) => { pass++; if (!QUIET) console.log(' ✓ ' + msg); }; const fail = (msg) => { fails.push(msg); console.log(' ✗ ' + msg); }; const warn = (msg) => { warns.push(msg); console.log(' ! ' + msg); }; const known = (id, msg) => { knownHits.set(id, (knownHits.get(id) || 0) + 1); if (!QUIET) console.log(' ◦ ' + msg + ' → 已归因 ' + id + '(公示于 /v1/governance/defects)'); }; console.log('CVIN conformance · ' + (FILE ? 'file:' + FILE : ORIGIN)); console.log('\n[1] 账本哈希链'); let raw; try { raw = FILE ? fs.readFileSync(FILE, 'utf8') : await fetchText(ORIGIN + '/registry.jsonl'); } catch (e) { fail('账本获取失败:' + e.message); } const recs = raw ? raw.split('\n').filter(Boolean).map(l => { try { return JSON.parse(l); } catch (e) { return null; } }).filter(Boolean) : []; if (!recs.length) fail('账本为空或无法解析'); else { ok('账本可解析:' + recs.length + ' 条'); let bad = 0, badLink = 0, badFmt = 0; const prevOf = new Map(); for (const r of recs) { const h = sha256(payload(r)); if (h !== r.hash) { if (KNOWN.has(r.hash)) known(KNOWN.get(r.hash), '记录 hash 不符:seq=' + r.seq + ' cvin=' + r.cvin); else { bad++; if (bad <= 5) fail('记录 hash 不符(新增缺陷):seq=' + r.seq + ' cvin=' + r.cvin); } } const expectPrev = prevOf.has(r.cvin) ? prevOf.get(r.cvin) : null; if ((r.prev_hash || null) !== expectPrev) { // 断裂两侧任一命中已知缺陷清单即归因(KD-2 的重复记录接的是过期视图) const side = KNOWN.get(r.hash) || (expectPrev ? KNOWN.get(expectPrev) : null); if (side) known(side, '设备链断裂:seq=' + r.seq + ' cvin=' + r.cvin); else { badLink++; if (badLink <= 5) fail('设备链断裂(新增缺陷):seq=' + r.seq + ' cvin=' + r.cvin); } } prevOf.set(r.cvin, r.hash); if (!CVIN_RE.test(String(r.cvin || ''))) { badFmt++; if (badFmt <= 3) fail('CVIN 格式不符:' + r.cvin); } if (!r.source_url || !r.observed_at || !r.obs_type) { badFmt++; if (badFmt <= 3) fail('必填字段缺失:seq=' + r.seq); } } if (!bad) ok('记录哈希重算:清单外全部一致' + (knownHits.size ? '(已公示缺陷另行归因)' : '(' + recs.length + ' 条)')); if (!badLink) ok('设备链 prev_hash:清单外全部连续'); if (!badFmt) ok('CVIN 格式与必填字段全部通过'); // seq 唯一性(KD-2 的直接症状:双写者各自计数) const seqSeen = new Map(); let dupBad = 0; for (const r of recs) { if (seqSeen.has(r.seq)) { if (KNOWN.has(r.hash) || KNOWN.has(seqSeen.get(r.seq).hash)) known('KD-2', 'seq 重复:seq=' + r.seq + '(cvin=' + r.cvin + ' 与 ' + seqSeen.get(r.seq).cvin + ')'); else { dupBad++; if (dupBad <= 5) fail('seq 重复(新增缺陷):seq=' + r.seq); } } else seqSeen.set(r.seq, r); } if (!dupBad) ok('seq 全库唯一(无新增重复)'); // 全局链(有则校验) const withG = recs.filter(r => r.global_hash); if (withG.length) { let g = 0; let prevG = null; for (const r of recs) { if (!r.global_hash) { prevG = null; continue; } const expect = sha256(canon({ prev: prevG || null, rec: r.hash })); if (expect !== r.global_hash) { if (KNOWN.has(r.hash)) known('KD-2', '全局链断裂:seq=' + r.seq + ' cvin=' + r.cvin); else g++; } prevG = r.global_hash; } if (!g) ok('全局链:清单外全部一致(' + withG.length + ' 条参与)'); else fail('全局链断裂(新增缺陷)' + g + ' 处'); } else warn('账本未含 global_hash(旧格式或分批写入),仅校验设备链'); // 已知弱点披露:synthetic 标记不在哈希内 const syn = recs.filter(r => r.synthetic).length; warn('synthetic 标记不在哈希计算范围内(' + syn + ' 条带标的记录):可被私下翻转而不破链,只能靠 /v1/provenance 的公开披露与历史快照交叉核对'); } if (!FILE) { console.log('\n[2] 章程哈希与锚点'); try { const j = JSON.parse(await fetchText(ORIGIN + '/v1/governance/charter')); const h = sha256(j.text || ''); if (h === j.sha256) ok('章程正文重算一致:' + h.slice(0, 16) + '…'); else fail('章程哈希不符:接口 ' + String(j.sha256).slice(0, 16) + '… / 重算 ' + h.slice(0, 16) + '…'); if (j.anchored && j.anchored.sha256_matches) ok('账本锚点与当前正文一致(锚点 #' + j.anchored.index + ')'); else fail('账本锚点缺失或与正文不一致 —— 章程可能被改过'); ok('不可修改条款 ' + j.entrenched.length + ' 条 · 授权 ' + j.licenses.data.id + ' / ' + j.licenses.spec.id + ' / ' + j.licenses.code.id); } catch (e) { fail('章程校验失败:' + e.message); } console.log('\n[2.5] 缺陷公示一致性'); try { const d = JSON.parse(await fetchText(ORIGIN + '/v1/governance/defects')); const remote = new Set(); for (const def of (d.defects || [])) for (const a of (def.affected || [])) { if (a.hash) remote.add(a.hash); for (const h of (a.hashes || [])) remote.add(h); } let missingHere = 0, extraHere = 0; for (const h of remote) if (!KNOWN.has(h)) missingHere++; for (const h of KNOWN.keys()) if (!remote.has(h)) extraHere++; ok('缺陷公示端点可用:' + (d.defects || []).length + ' 类 / ' + remote.size + ' 条受影响记录(' + (d.defects || []).map(x => x.id).join(', ') + ')'); if (missingHere) warn('线上公示有 ' + missingHere + ' 条记录不在本脚本清单内——请更新本脚本(已知缺陷若不归因会被误报为新增缺陷)'); if (extraHere) warn('本脚本清单有 ' + extraHere + ' 条记录不在当前线上公示内(可能是旧版公示,不影响校验)'); } catch (e) { warn('缺陷公示端点不可用(' + e.message + ')——归因仅依据脚本内置清单'); } console.log('\n[3] 服务可用性'); try { const h = JSON.parse(await fetchText(ORIGIN + '/health')); if (h.ok) ok('健康检查通过(' + h.observations + ' 条观测 / ' + h.assets + ' 个 ID)'); else fail('服务报告异常:' + JSON.stringify(h).slice(0, 120)); } catch (e) { fail('健康检查失败:' + e.message); } } else { console.log('\n[2] 章程与 [3] 健康检查:离线文件模式跳过(只重放账本)'); } console.log('\n' + '─'.repeat(48)); const knownTotal = [...knownHits.values()].reduce((a, b) => a + b, 0); console.log(`通过 ${pass} 项 · 警告 ${warns.length} 项 · 已公示缺陷归因 ${knownTotal} 处${knownTotal ? '(' + [...knownHits.entries()].map(([k, v]) => k + '×' + v).join(' / ') + ')' : ''} · 失败 ${fails.length} 项`); if (knownTotal && !QUIET) console.log('归因依据:/v1/governance/defects(成因 / 影响面 / 修复动作全公示,缺陷记录按 E1 只增不减原样保留)'); if (fails.length) { console.log('\n失败明细(新增缺陷 = 篡改警报):'); fails.forEach(f => console.log(' - ' + f)); process.exit(1); } console.log('结论:账本可按公开规则独立复算;断链处均为已公示归因的历史写入缺陷,无新增缺陷。'); })().catch(e => { console.error('致命错误:', e.message); process.exit(1); });