blun-king-cli 9.1.602 → 9.1.604

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (124) hide show
  1. package/CHANGELOG.md +118 -99
  2. package/LIESMICH.txt +74 -57
  3. package/README.md +119 -76
  4. package/bin/agentspine-king-goal-inbox.mjs +127 -127
  5. package/bin/agentspine-king-goal-intake.mjs +106 -106
  6. package/bin/agentspine-king-host-runner.mjs +109 -109
  7. package/bin/agentspine-king-snapshot-policy.cjs +80 -80
  8. package/bin/agentspine-king-status-policy.mjs +226 -226
  9. package/bin/agentspine-king-worker-host.mjs +160 -160
  10. package/bin/core-bootstrap.js +77 -77
  11. package/bin/launcher-mode.js +93 -93
  12. package/bin/launcher-restart-policy.cjs +131 -131
  13. package/bin/launcher-runtime.js +491 -491
  14. package/bin/managed-node.js +186 -186
  15. package/bin/managed-plugin-selection.cjs +115 -115
  16. package/bin/native-module-repair.js +201 -201
  17. package/bin/node-runtime.js +34 -34
  18. package/bin/node-version.js +49 -49
  19. package/bin/plugin-bootstrap.js +162 -162
  20. package/bin/private-paths.js +1606 -1606
  21. package/bin/runtime-exit-ledger.cjs +144 -144
  22. package/bin/runtime-exit-ledger.d.cts +23 -23
  23. package/bin/standard-tools-bootstrap.js +272 -272
  24. package/bin/turn-thinking-policy.cjs +82 -82
  25. package/bin/update-copy.js +200 -200
  26. package/bin/update-lease.js +597 -597
  27. package/bin/update-notice.js +1568 -1568
  28. package/bin/verify-agent-behavior.cjs +122 -122
  29. package/bin/verify-agent-components.cjs +104 -104
  30. package/bin/verify-bundled-agent-sources.cjs +98 -76
  31. package/bin/windows-node-crash-dump.cjs +289 -289
  32. package/blun.mjs +8041 -6407
  33. package/codebase-index/codebase_index.py +470 -470
  34. package/dist-web/assets/{CodeBlockNode-CXnTLMNr.js → CodeBlockNode-TKKkJX8L.js} +1 -1
  35. package/dist-web/assets/{CodeBlockShell.vue_vue_type_style_index_0_lang-CCF8Ntnq.js → CodeBlockShell.vue_vue_type_style_index_0_lang-CUj2Ds5x.js} +1 -1
  36. package/dist-web/assets/DesignSystemView-DwK1aQMo.js +12 -0
  37. package/dist-web/assets/DesignSystemView-szjTj7ns.css +1 -0
  38. package/dist-web/assets/{Tooltip-CFQEzqC-.js → Tooltip-CTWv7WCU.js} +1 -1
  39. package/dist-web/assets/{abnfDiagram-N423BO3Z-Z1APZG5m.js → abnfDiagram-N423BO3Z-DA8V8Zjh.js} +1 -1
  40. package/dist-web/assets/{arc-C4VyWloT.js → arc-YtddKbdY.js} +1 -1
  41. package/dist-web/assets/{architectureDiagram-T3A2C74G-DpddbUcM.js → architectureDiagram-T3A2C74G-CGEiObmo.js} +1 -1
  42. package/dist-web/assets/{blockDiagram-VBNYF7ZC-BqccOSMr.js → blockDiagram-VBNYF7ZC-Bd5Vt50e.js} +1 -1
  43. package/dist-web/assets/{c4Diagram-5PPSVZJV-OHAcJrTy.js → c4Diagram-5PPSVZJV-D2ApPM54.js} +1 -1
  44. package/dist-web/assets/channel-BnluexuN.js +1 -0
  45. package/dist-web/assets/{chunk-2GRJ4B5K-DqJHs8Fw.js → chunk-2GRJ4B5K-BDcIEZSl.js} +1 -1
  46. package/dist-web/assets/{chunk-2Q5K7J3B-B1nCd91o.js → chunk-2Q5K7J3B-6aSabCX7.js} +1 -1
  47. package/dist-web/assets/{chunk-5RXB4S5H-neG70kZx.js → chunk-5RXB4S5H-BFRQvIJS.js} +1 -1
  48. package/dist-web/assets/{chunk-5VM5RSS4-l7biGqeH.js → chunk-5VM5RSS4-ChAa-DNY.js} +1 -1
  49. package/dist-web/assets/{chunk-6Q2QTUOP-BO-F11Gs.js → chunk-6Q2QTUOP-BIfrb2Jc.js} +1 -1
  50. package/dist-web/assets/{chunk-GF5L2VYU-BtC69fw0.js → chunk-GF5L2VYU-BR0gvtWI.js} +1 -1
  51. package/dist-web/assets/{chunk-JWPE2WC7-DIOubEqr.js → chunk-JWPE2WC7-BgXKsx5E.js} +1 -1
  52. package/dist-web/assets/{chunk-KBJHAD2P-DDUeH_Ba.js → chunk-KBJHAD2P-I8mrZhpz.js} +1 -1
  53. package/dist-web/assets/{chunk-RYQCIY6F-B9gFMVbS.js → chunk-RYQCIY6F-BMPaem92.js} +1 -1
  54. package/dist-web/assets/{chunk-XXDRQBXY-Bn1Xz6TQ.js → chunk-XXDRQBXY-COy0J-0j.js} +1 -1
  55. package/dist-web/assets/classDiagram-JCYQIIEL-BliFdSD9.js +1 -0
  56. package/dist-web/assets/classDiagram-v2-OCEON4UE-BliFdSD9.js +1 -0
  57. package/dist-web/assets/{cose-bilkent-JH36ORCC-DqigO3T4.js → cose-bilkent-JH36ORCC-MosTTRdo.js} +1 -1
  58. package/dist-web/assets/{cynefin-VYW2F7L2-rpD93tQ-.js → cynefin-VYW2F7L2-5tjPgrkP.js} +1 -1
  59. package/dist-web/assets/{cynefinDiagram-MW4NZA55-DbTqnkVJ.js → cynefinDiagram-MW4NZA55-CbDcdInR.js} +1 -1
  60. package/dist-web/assets/{dagre-VZM6K2ZE-DcM8aEVY.js → dagre-VZM6K2ZE-YaBom1ZH.js} +1 -1
  61. package/dist-web/assets/{diagram-7IWD3JNH-UymgsBNa.js → diagram-7IWD3JNH-Da4m-Hgz.js} +1 -1
  62. package/dist-web/assets/{diagram-B4RE2ZJO-BiYu5WPF.js → diagram-B4RE2ZJO-CAUUegxg.js} +1 -1
  63. package/dist-web/assets/{diagram-LBJQPF4R-BD3kkgOO.js → diagram-LBJQPF4R-o21mWKG4.js} +1 -1
  64. package/dist-web/assets/{diagram-Q27KOJAE-D1mYQ_cI.js → diagram-Q27KOJAE-BA3z3sXf.js} +1 -1
  65. package/dist-web/assets/{diagram-UB23O5K3-BtX8u6HG.js → diagram-UB23O5K3-CGRdSSDK.js} +1 -1
  66. package/dist-web/assets/{ebnfDiagram-BXEA7PRR-CBAnFkRF.js → ebnfDiagram-BXEA7PRR-Bw-iU9FP.js} +1 -1
  67. package/dist-web/assets/{erDiagram-JOGREHBK-3vKcWsxm.js → erDiagram-JOGREHBK-BwM1yiR0.js} +1 -1
  68. package/dist-web/assets/{flowDiagram-UKHOOZJN-D9wBbHm2.js → flowDiagram-UKHOOZJN-z05eOR1Q.js} +1 -1
  69. package/dist-web/assets/{ganttDiagram-PKOTCBZU-Cd_dViF-.js → ganttDiagram-PKOTCBZU-BMUubNTl.js} +1 -1
  70. package/dist-web/assets/{gitGraphDiagram-DS77QQ5N-BiEEtTo7.js → gitGraphDiagram-DS77QQ5N-Dccbi1wU.js} +1 -1
  71. package/dist-web/assets/{index-DdEakFJM.js → index-BBbC5LRF.js} +1 -1
  72. package/dist-web/assets/{index-BmKj7CB1.css → index-C9eDH3u-.css} +1 -1
  73. package/dist-web/assets/{index-Ba1OvLjf.js → index-D48p0M2S.js} +2 -2
  74. package/dist-web/assets/{index-CiPA8Kex.js → index-h0KEOmkU.js} +14 -14
  75. package/dist-web/assets/{index10-CNr4U-Nw.js → index10-Qbuw1N6u.js} +1 -1
  76. package/dist-web/assets/{index11-Dto_yZNz.js → index11-g8v025wN.js} +1 -1
  77. package/dist-web/assets/{index5-B2PldaO2.js → index5-BYNcV8BY.js} +1 -1
  78. package/dist-web/assets/{index6-CBdZmmyx.js → index6-BetANtnV.js} +1 -1
  79. package/dist-web/assets/{index7-Dz9oCsUF.js → index7-BcPbgCKN.js} +1 -1
  80. package/dist-web/assets/{index8-B6k25jtU.js → index8-B1lp-RvF.js} +2 -2
  81. package/dist-web/assets/{infoDiagram-6WML65LV-D4ph2sIH.js → infoDiagram-6WML65LV-BF_pbUnN.js} +1 -1
  82. package/dist-web/assets/{ishikawaDiagram-WSZJBQD7-DjKjbMm9.js → ishikawaDiagram-WSZJBQD7-Dedv4urS.js} +1 -1
  83. package/dist-web/assets/{journeyDiagram-NVQOT4AX-DttHDfPQ.js → journeyDiagram-NVQOT4AX-B1Ex3b6o.js} +1 -1
  84. package/dist-web/assets/{kanban-definition-27J2QSJJ-C5gB-W0d.js → kanban-definition-27J2QSJJ-BtCGliBH.js} +1 -1
  85. package/dist-web/assets/{linear-BRGe4-d6.js → linear-ByItc8Qr.js} +1 -1
  86. package/dist-web/assets/{mermaid.core-D-9Sx1No.js → mermaid.core-B1M2O7nN.js} +4 -4
  87. package/dist-web/assets/{mindmap-definition-FAOFIHXS-Cg_hoVIq.js → mindmap-definition-FAOFIHXS-D0UHKUyj.js} +1 -1
  88. package/dist-web/assets/{pegDiagram-VL7TDLO6-CSX9hitD.js → pegDiagram-VL7TDLO6-D7zYCVmG.js} +1 -1
  89. package/dist-web/assets/{pieDiagram-7S7Q4E2Y-0L0mxahZ.js → pieDiagram-7S7Q4E2Y-Bd0i9CHa.js} +1 -1
  90. package/dist-web/assets/{quadrantDiagram-CIZ2JOQS-U483z0er.js → quadrantDiagram-CIZ2JOQS-MG-Ug47d.js} +1 -1
  91. package/dist-web/assets/{railroadDiagram-AXF67PYL-D80a2_DJ.js → railroadDiagram-AXF67PYL-AZdl90Gj.js} +1 -1
  92. package/dist-web/assets/{requirementDiagram-LRYGKXZP-CeyHfq8t.js → requirementDiagram-LRYGKXZP-DjplF9kt.js} +1 -1
  93. package/dist-web/assets/{sankeyDiagram-W5VNT64P-CCISkkrR.js → sankeyDiagram-W5VNT64P-Bi9Zgfjs.js} +1 -1
  94. package/dist-web/assets/{sequenceDiagram-SI44F4Z6-jQfm2XS7.js → sequenceDiagram-SI44F4Z6-ChEpdCvb.js} +1 -1
  95. package/dist-web/assets/{sizeCapture-X5ZJPWSS-lRZsmCoS.js → sizeCapture-X5ZJPWSS-B5RFUdaa.js} +1 -1
  96. package/dist-web/assets/{stateDiagram-OKZ733FA-ClCgTdUm.js → stateDiagram-OKZ733FA-BkRblSKp.js} +1 -1
  97. package/dist-web/assets/stateDiagram-v2-UEYNNEHI-fVkQcACW.js +1 -0
  98. package/dist-web/assets/{swimlanes-SLNWSIFB-BCdOUN05.js → swimlanes-SLNWSIFB-DLXH6Zhc.js} +2 -2
  99. package/dist-web/assets/swimlanesDiagram-ULZ7WXOC-Bg-BiZJQ.js +8 -0
  100. package/dist-web/assets/{timeline-definition-Z64GVDOM-DpWutSKa.js → timeline-definition-Z64GVDOM-C_N88siO.js} +1 -1
  101. package/dist-web/assets/{vennDiagram-T6HMQDX7-DVC5JVsc.js → vennDiagram-T6HMQDX7-DMsnvDt0.js} +1 -1
  102. package/dist-web/assets/{vue.runtime.esm-bundler-BwwRtQwQ.js → vue.runtime.esm-bundler-B-3uIy85.js} +1 -1
  103. package/dist-web/assets/{wardleyDiagram-T6FBY63Y-BK2mrq7L.js → wardleyDiagram-T6FBY63Y-C9SJIPzq.js} +1 -1
  104. package/dist-web/assets/{xychartDiagram-ELKLHX3M-DUJu9F7-.js → xychartDiagram-ELKLHX3M-DZLWA6Go.js} +1 -1
  105. package/dist-web/index.html +32 -32
  106. package/dist-web/vis/index.html.gz +0 -0
  107. package/package.json +1 -1
  108. package/scripts/fix-node-pty-perms.js +53 -53
  109. package/standard-skills/blun-app-design-system/SKILL.md +30 -30
  110. package/standard-skills/blun-app-design-system/provenance.json +17 -17
  111. package/standard-skills/blun-app-design-system/references/tokens.md +48 -48
  112. package/standard-skills/blun-app-design-system/scripts/check-blun-design.mjs +49 -49
  113. package/telegram-plugin/blun.plugin.json +20 -20
  114. package/telegram-plugin/commands/access.md +37 -37
  115. package/telegram-plugin/dist/bridge.mjs +117 -100
  116. package/telegram-plugin/dist/mcp-server.mjs +185 -161
  117. package/worker-host.mjs +1458 -1022
  118. package/dist-web/assets/DesignSystemView-6HgAUEmC.css +0 -1
  119. package/dist-web/assets/DesignSystemView-BbMOu-XO.js +0 -12
  120. package/dist-web/assets/channel-B2VOQOI-.js +0 -1
  121. package/dist-web/assets/classDiagram-JCYQIIEL-BA1TjAxj.js +0 -1
  122. package/dist-web/assets/classDiagram-v2-OCEON4UE-BA1TjAxj.js +0 -1
  123. package/dist-web/assets/stateDiagram-v2-UEYNNEHI-fi_lrTAx.js +0 -1
  124. package/dist-web/assets/swimlanesDiagram-ULZ7WXOC-BUd_uYK3.js +0 -8
@@ -1,83 +1,105 @@
1
- 'use strict';
2
- const fs = require('node:fs');
3
- const path = require('node:path');
4
- const { createHash } = require('node:crypto');
5
- const RECEIPT = 'bundled-agent-sources.json';
6
- const SCHEMA = 'blun.bundled-agent-sources/v1';
7
- const PREFIXES = ['agent-spine-plugin/', 'standard-skills/translate-native/', 'standard-tools/language-guard/'];
8
- const GUARD_RESPONSE_PROFILE = Object.freeze({
9
- schema: 'blun.language-guard-response-profile/v1',
10
- file: 'translate-native/scripts/blun_language_guard.py',
11
- beforeSha256: '837361690535ded4251ca23fbab313f5c3a7005472c259aa8fc51ebf7ecb9cb9',
12
- afterSha256: '1e21b570259de0145ace2abf55fb82bf8896c90aaae93839c97fff36a01731f2',
13
- });
14
- const GUARD_RESPONSE_PAYLOADS = Object.freeze([
15
- 'standard-skills/translate-native/scripts/blun_language_guard.py',
16
- 'standard-tools/language-guard/blun_language_guard.py',
17
- ]);
1
+ 'use strict';
2
+ const fs = require('node:fs');
3
+ const path = require('node:path');
4
+ const { createHash } = require('node:crypto');
5
+ const RECEIPT = 'bundled-agent-sources.json';
6
+ const SCHEMA = 'blun.bundled-agent-sources/v1';
7
+ const PREFIXES = ['agent-spine-plugin/', 'standard-skills/translate-native/', 'standard-tools/language-guard/'];
8
+ const GUARD_RESPONSE_PROFILE = Object.freeze({
9
+ schema: 'blun.language-guard-response-profile/v1',
10
+ file: 'translate-native/scripts/blun_language_guard.py',
11
+ beforeSha256: '837361690535ded4251ca23fbab313f5c3a7005472c259aa8fc51ebf7ecb9cb9',
12
+ afterSha256: '1e21b570259de0145ace2abf55fb82bf8896c90aaae93839c97fff36a01731f2',
13
+ });
14
+ const GUARD_RESPONSE_PAYLOADS = Object.freeze([
15
+ 'standard-skills/translate-native/scripts/blun_language_guard.py',
16
+ 'standard-tools/language-guard/blun_language_guard.py',
17
+ ]);
18
18
  const REQUIRED = [
19
- 'agent-spine-plugin/blun.plugin.json', 'agent-spine-plugin/src/hook.js',
20
- 'agent-spine-plugin/src/mcp.js', 'agent-spine-plugin/skills/agent-spine/SKILL.md',
21
- 'standard-skills/translate-native/SKILL.md', ...GUARD_RESPONSE_PAYLOADS,
22
- 'standard-tools/language-guard/check_diacritics.py', 'standard-tools/language-guard/language_quality.py',
23
- 'standard-tools/language-guard/guard_service_client.py', 'standard-tools/language-guard/translation_guard.py',
24
- ];
25
- const sha256 = bytes => createHash('sha256').update(bytes).digest('hex');
26
-
27
- function payloadInventory(root, prefix = '') {
28
- const files = {};
29
- for (const name of fs.readdirSync(root).sort()) {
30
- const target = path.join(root, name), relative = prefix + name;
31
- const stat = fs.lstatSync(target);
32
- if (stat.isSymbolicLink()) throw new Error('Linked bundled component: ' + relative);
33
- if (stat.isDirectory()) Object.assign(files, payloadInventory(target, relative + '/'));
34
- else if (stat.isFile()) files[relative] = sha256(fs.readFileSync(target));
35
- else throw new Error('Unsupported bundled component: ' + relative);
36
- }
37
- return files;
38
- }
39
-
40
- function verifyBundledAgentSources(root, pins) {
41
- const receipt = JSON.parse(fs.readFileSync(path.join(root, RECEIPT), 'utf8'));
42
- if (receipt.schema !== SCHEMA || !receipt.files || Array.isArray(receipt.files)) throw new Error('Invalid bundled source receipt');
43
- for (const name of ['agentSpine', 'translateNative']) {
44
- if (!/^[a-f0-9]{40}$/.test(receipt.sources?.[name]?.commit || '')) throw new Error('Missing bundled source commit: ' + name);
45
- if (pins && JSON.stringify(receipt.sources[name]) !== JSON.stringify(pins[name])) throw new Error('Stale bundled source: ' + name);
46
- }
47
- for (const file of REQUIRED) if (!Object.hasOwn(receipt.files, file)) throw new Error('Missing required bundled source: ' + file);
48
- const actual = {};
49
- for (const prefix of PREFIXES) {
50
- const target = path.join(root, prefix);
51
- if (fs.lstatSync(target).isSymbolicLink()) throw new Error('Linked component directory');
52
- Object.assign(actual, payloadInventory(target, prefix));
53
- }
54
- const expectedNames = Object.keys(receipt.files).sort();
55
- if (JSON.stringify(Object.keys(actual).sort()) !== JSON.stringify(expectedNames)) throw new Error('Bundled source inventory mismatch');
19
+ 'agent-spine-plugin/package.json',
20
+ 'standard-skills/translate-native/VERSION', 'standard-skills/translate-native/provenance.json',
21
+ 'standard-tools/language-guard/VERSION', 'standard-tools/language-guard/provenance.json',
22
+ 'agent-spine-plugin/blun.plugin.json', 'agent-spine-plugin/src/hook.js',
23
+ 'agent-spine-plugin/src/mcp.js', 'agent-spine-plugin/skills/agent-spine/SKILL.md',
24
+ 'standard-skills/translate-native/SKILL.md', ...GUARD_RESPONSE_PAYLOADS,
25
+ 'standard-tools/language-guard/check_diacritics.py', 'standard-tools/language-guard/language_quality.py',
26
+ 'standard-tools/language-guard/guard_service_client.py', 'standard-tools/language-guard/translation_guard.py',
27
+ ];
28
+ const sha256 = bytes => createHash('sha256').update(bytes).digest('hex');
29
+
30
+ function payloadInventory(root, prefix = '') {
31
+ const files = {};
32
+ for (const name of fs.readdirSync(root).sort()) {
33
+ const target = path.join(root, name), relative = prefix + name;
34
+ const stat = fs.lstatSync(target);
35
+ if (stat.isSymbolicLink()) throw new Error('Linked bundled component: ' + relative);
36
+ if (stat.isDirectory()) Object.assign(files, payloadInventory(target, relative + '/'));
37
+ else if (stat.isFile()) files[relative] = sha256(fs.readFileSync(target));
38
+ else throw new Error('Unsupported bundled component: ' + relative);
39
+ }
40
+ return files;
41
+ }
42
+
43
+ function verifyBundledAgentSources(root, pins) {
44
+ const receipt = JSON.parse(fs.readFileSync(path.join(root, RECEIPT), 'utf8'));
45
+ if (receipt.schema !== SCHEMA || !receipt.files || Array.isArray(receipt.files)) throw new Error('Invalid bundled source receipt');
46
+ for (const name of ['agentSpine', 'translateNative']) {
47
+ if (!/^[a-f0-9]{40}$/.test(receipt.sources?.[name]?.commit || '')) throw new Error('Missing bundled source commit: ' + name);
48
+ if (pins && JSON.stringify(receipt.sources[name]) !== JSON.stringify(pins[name])) throw new Error('Stale bundled source: ' + name);
49
+ }
50
+ for (const file of REQUIRED) if (!Object.hasOwn(receipt.files, file)) throw new Error('Missing required bundled source: ' + file);
51
+ const actual = {};
52
+ for (const prefix of PREFIXES) {
53
+ const target = path.join(root, prefix);
54
+ if (fs.lstatSync(target).isSymbolicLink()) throw new Error('Linked component directory');
55
+ Object.assign(actual, payloadInventory(target, prefix));
56
+ }
57
+ const expectedNames = Object.keys(receipt.files).sort();
58
+ if (JSON.stringify(Object.keys(actual).sort()) !== JSON.stringify(expectedNames)) throw new Error('Bundled source inventory mismatch');
56
59
  for (const file of expectedNames) {
57
60
  if (!/^[a-f0-9]{64}$/.test(receipt.files[file]) || actual[file] !== receipt.files[file]) throw new Error('Bundled source digest mismatch: ' + file);
58
61
  }
59
- // Bind the semantic repair independently of the self-reported file inventory.
60
- const patch = receipt.localPatches?.guardResponseProfile;
61
- if (!patch || typeof patch !== 'object' || Array.isArray(patch)
62
- || Object.keys(patch).length !== Object.keys(GUARD_RESPONSE_PROFILE).length
63
- || Object.entries(GUARD_RESPONSE_PROFILE).some(([key, value]) => patch[key] !== value)) {
64
- throw new Error('Invalid language guard response profile repair receipt');
65
- }
66
- if (receipt.sourceDigests?.translateNative?.[GUARD_RESPONSE_PROFILE.file] !== GUARD_RESPONSE_PROFILE.beforeSha256) {
67
- throw new Error('Invalid language guard response profile source digest');
62
+ for (const name of ['agentSpine', 'translateNative']) {
63
+ const version = receipt.versions?.[name];
64
+ if (typeof version !== 'string' || !version || version.trim() !== version) {
65
+ throw new Error('Invalid bundled component version: ' + name);
66
+ }
68
67
  }
69
- for (const file of GUARD_RESPONSE_PAYLOADS) {
70
- if (actual[file] !== GUARD_RESPONSE_PROFILE.afterSha256) {
71
- throw new Error('Invalid language guard response profile payload: ' + file);
68
+ const spine = JSON.parse(fs.readFileSync(path.join(root, 'agent-spine-plugin/package.json'), 'utf8'));
69
+ if (spine.version !== receipt.versions.agentSpine) throw new Error('Bundled component version mismatch: agentSpine');
70
+ for (const prefix of ['standard-skills/translate-native/', 'standard-tools/language-guard/']) {
71
+ if (fs.readFileSync(path.join(root, prefix, 'VERSION'), 'utf8').trim() !== receipt.versions.translateNative) {
72
+ throw new Error('Bundled component version mismatch: ' + prefix);
73
+ }
74
+ const provenance = JSON.parse(fs.readFileSync(path.join(root, prefix, 'provenance.json'), 'utf8'));
75
+ if (provenance?.name !== 'translate-native' || provenance.version !== receipt.versions.translateNative
76
+ || provenance.sourceCommit !== receipt.sources.translateNative.commit
77
+ || provenance.sourceRepository !== receipt.sources.translateNative.repository) {
78
+ throw new Error('Bundled component provenance mismatch: ' + prefix);
72
79
  }
73
80
  }
74
- return receipt;
75
- }
76
-
77
- if (require.main === module) {
78
- try { const receipt = verifyBundledAgentSources(path.resolve(__dirname, '..'));
79
- console.log(JSON.stringify({ verified: true, sources: receipt.sources, files: Object.keys(receipt.files).length }));
80
- } catch (error) { console.error(error.message); process.exitCode = 1; }
81
- }
82
- module.exports = { verifyBundledAgentSources, payloadInventory, sha256, RECEIPT, SCHEMA, PREFIXES, REQUIRED,
83
- GUARD_RESPONSE_PROFILE, GUARD_RESPONSE_PAYLOADS };
81
+ // Bind the semantic repair independently of the self-reported file inventory.
82
+ const patch = receipt.localPatches?.guardResponseProfile;
83
+ if (!patch || typeof patch !== 'object' || Array.isArray(patch)
84
+ || Object.keys(patch).length !== Object.keys(GUARD_RESPONSE_PROFILE).length
85
+ || Object.entries(GUARD_RESPONSE_PROFILE).some(([key, value]) => patch[key] !== value)) {
86
+ throw new Error('Invalid language guard response profile repair receipt');
87
+ }
88
+ if (receipt.sourceDigests?.translateNative?.[GUARD_RESPONSE_PROFILE.file] !== GUARD_RESPONSE_PROFILE.beforeSha256) {
89
+ throw new Error('Invalid language guard response profile source digest');
90
+ }
91
+ for (const file of GUARD_RESPONSE_PAYLOADS) {
92
+ if (actual[file] !== GUARD_RESPONSE_PROFILE.afterSha256) {
93
+ throw new Error('Invalid language guard response profile payload: ' + file);
94
+ }
95
+ }
96
+ return receipt;
97
+ }
98
+
99
+ if (require.main === module) {
100
+ try { const receipt = verifyBundledAgentSources(path.resolve(__dirname, '..'));
101
+ console.log(JSON.stringify({ verified: true, sources: receipt.sources, files: Object.keys(receipt.files).length }));
102
+ } catch (error) { console.error(error.message); process.exitCode = 1; }
103
+ }
104
+ module.exports = { verifyBundledAgentSources, payloadInventory, sha256, RECEIPT, SCHEMA, PREFIXES, REQUIRED,
105
+ GUARD_RESPONSE_PROFILE, GUARD_RESPONSE_PAYLOADS };