@blamejs/exceptd-skills 0.15.49 → 0.15.51

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.
package/sbom.cdx.json CHANGED
@@ -1,22 +1,22 @@
1
1
  {
2
2
  "bomFormat": "CycloneDX",
3
3
  "specVersion": "1.6",
4
- "serialNumber": "urn:uuid:13afd3b0-bf06-4674-9bdc-0e8f5b1bc649",
4
+ "serialNumber": "urn:uuid:9acfa07c-b6cd-4814-91c7-1c28fa9036c5",
5
5
  "version": 1,
6
6
  "metadata": {
7
- "timestamp": "2036-06-19T19:14:56.000Z",
7
+ "timestamp": "2108-04-22T07:45:00.000Z",
8
8
  "tools": [
9
9
  {
10
10
  "vendor": "blamejs",
11
11
  "name": "scripts/refresh-sbom.js",
12
- "version": "0.15.49"
12
+ "version": "0.15.51"
13
13
  }
14
14
  ],
15
15
  "component": {
16
- "bom-ref": "pkg:npm/@blamejs/exceptd-skills@0.15.49",
16
+ "bom-ref": "pkg:npm/@blamejs/exceptd-skills@0.15.51",
17
17
  "type": "application",
18
18
  "name": "@blamejs/exceptd-skills",
19
- "version": "0.15.49",
19
+ "version": "0.15.51",
20
20
  "description": "AI security skills grounded in mid-2026 threat reality, not stale framework documentation. 42 skills, 11 catalogs (427 CVEs / 173 CWEs / 805 ATT&CK + ICS / 170 ATLAS / 468 D3FEND / 8888 RFCs), 35 jurisdictions, 10-class catalog gap detector + budget gate, real XML parser + canonical-form diff + content-pattern regression detection, Ed25519-signed.",
21
21
  "licenses": [
22
22
  {
@@ -25,17 +25,17 @@
25
25
  }
26
26
  }
27
27
  ],
28
- "purl": "pkg:npm/%40blamejs/exceptd-skills@0.15.49",
28
+ "purl": "pkg:npm/%40blamejs/exceptd-skills@0.15.51",
29
29
  "hashes": [
30
30
  {
31
31
  "alg": "SHA-256",
32
- "content": "8014d759783bbbd62f82a8b8bf67219a267c620648529f2a7b68c699c23ca9c0"
32
+ "content": "286ba553798e8b3455fe13a1541b186417e4a817f9c33575e26cf828a1c08d6e"
33
33
  }
34
34
  ],
35
35
  "externalReferences": [
36
36
  {
37
37
  "type": "distribution",
38
- "url": "https://www.npmjs.com/package/@blamejs/exceptd-skills/v/0.15.49"
38
+ "url": "https://www.npmjs.com/package/@blamejs/exceptd-skills/v/0.15.51"
39
39
  },
40
40
  {
41
41
  "type": "vcs",
@@ -70,7 +70,7 @@
70
70
  },
71
71
  {
72
72
  "name": "exceptd:vendor:count",
73
- "value": "2"
73
+ "value": "3"
74
74
  },
75
75
  {
76
76
  "name": "exceptd:vendor:pin",
@@ -116,11 +116,11 @@
116
116
  "hashes": [
117
117
  {
118
118
  "alg": "SHA-256",
119
- "content": "1d89e0faa87efd172ed0f37f4a78b9b1787cf3f673a4f9e344fa5a3183bffcd3"
119
+ "content": "dc00c4b9ab8c88da642c093ff93db1017413c78cc05b9018466be6631c71fec5"
120
120
  },
121
121
  {
122
122
  "alg": "SHA3-512",
123
- "content": "494715845aa5068286eadb8ee1edcb54f2bb8c58a76f825ad5bb1d8496a5a1de4c544256ae88e42fd7ee343c4d7c62f8b72823d841ff79ad2267fd85534d10bb"
123
+ "content": "b05cb2e274f890263a22f70998d287f96470f83443b891c4a2958a9e053af429d53556495b7e5e427f3892223c3f255917560a3610bdea991e058eaf7cf670de"
124
124
  }
125
125
  ]
126
126
  },
@@ -281,11 +281,11 @@
281
281
  "hashes": [
282
282
  {
283
283
  "alg": "SHA-256",
284
- "content": "ab60be520c0c63ac839fd1b2a9e09e76955542f9321c269b472dbeab67811d70"
284
+ "content": "cf9b74140298bdee14d4826d11ed9f7d6b1266db8a782d8dce48425e76ec9af5"
285
285
  },
286
286
  {
287
287
  "alg": "SHA3-512",
288
- "content": "982f692aa088e16845b34f767a1734351ee9c86205b40473563538932806a88f36208aca306b3d46ce2864cc41b10dc0dc1ebc5dfd3c611256bc707b395dc8a6"
288
+ "content": "0528bbd4277fe3b8f4cb99eeaf35d5e9f310cfd48a0164fa4e4edb03154f1c7302af7d44617d7b6f1d6ab52e301a7772042e4c609693c49b8ce6eb64991419b9"
289
289
  }
290
290
  ]
291
291
  },
@@ -311,11 +311,11 @@
311
311
  "hashes": [
312
312
  {
313
313
  "alg": "SHA-256",
314
- "content": "84fad74c8497cab922ed64b814752f54aa4620c2a938cb06642ff1510e1c5cb3"
314
+ "content": "318bf8e9c5aee1d0a4a1dc37c4b211f2fbc937bf332a401a22483cc7d0547252"
315
315
  },
316
316
  {
317
317
  "alg": "SHA3-512",
318
- "content": "bcb5bbab48f5374c4714cc324c10a65b5005e8a8ac6882f356427e2e3ad43d7e9a5320b156539d2dc14b1b4ee17c4e44a97d9109db9162718533202fd268af34"
318
+ "content": "d929874af7a8091416f2adc116fcfe98383325c83ece819a3e07320e29b4d8645b27256a662a6fff3267156ff70cfe2f53d7b0a82b5f249902c495f5d668b962"
319
319
  }
320
320
  ]
321
321
  },
@@ -326,11 +326,11 @@
326
326
  "hashes": [
327
327
  {
328
328
  "alg": "SHA-256",
329
- "content": "7a5f4e31401505e53330cdc4b54b39f8a8b04459d6b9411676d291c583ae535f"
329
+ "content": "cb5e305b5488a2a02e177f10e913d22f602d6016109f152903093e9614e0b470"
330
330
  },
331
331
  {
332
332
  "alg": "SHA3-512",
333
- "content": "b4f57d7819e255a3754d0fc758198df5f1ac4f69c6d9bdee8696987bb6ab15ffe03a461c509e832f706e46e50b4755d5d1f1b06e0442d50ff55d8439bacadfa7"
333
+ "content": "a7abc804efd7dfd46056a857ee13e19b8d99cdd46db7390845f4036b1e4b97bce0e00ec3f677322716f6c74b071340561fdf8cfda9b2f5ff3b502353eaf4d135"
334
334
  }
335
335
  ]
336
336
  },
@@ -341,11 +341,11 @@
341
341
  "hashes": [
342
342
  {
343
343
  "alg": "SHA-256",
344
- "content": "0fd275c2a61754958d68cea03a92794a67cf1c1d4d609f81a5728334df013ee3"
344
+ "content": "b0e4d8f90b655b2b35b1e91c682ee66f2aa51ae5d38efb14f0e1b77f75ec5f7b"
345
345
  },
346
346
  {
347
347
  "alg": "SHA3-512",
348
- "content": "f6ca0b0e10d8b5d9d45ed43fd3b80d95ecd6ecb99a0241daa7e08695de2c02c7532d720cd4e61b6c3e9a138dfb9306ccefab43715d2a1c2b16cc34784e6d34ce"
348
+ "content": "ac9ca3b420093c62dd5a53b0349f1d5e9f10f90c958d0ab921654bd0bcf674d3aef478fc5bc3d359a224b03cd26b32578fe162f55ba2423c37c0061aaa80c862"
349
349
  }
350
350
  ]
351
351
  },
@@ -401,11 +401,11 @@
401
401
  "hashes": [
402
402
  {
403
403
  "alg": "SHA-256",
404
- "content": "29e7b6aa841ddf2530ca5971bdb60d7a715684b2f6264141ad49f0de9a039d78"
404
+ "content": "49cfbcaf0f27662db7e12340839c29f05d4ae31bc255dc9fa49ad1b4a45d0fa3"
405
405
  },
406
406
  {
407
407
  "alg": "SHA3-512",
408
- "content": "db18692914f44c8cbc9a853fe43865a5547058b5b0dc656e45e83da322072a323fa08b40479ecb8dbb2d1aac1997dccff05be3c26351098806b41a750248c43e"
408
+ "content": "677e753faee573812cfcb3b33e351b36430b38d36c409149a471b0561139ba1dccc23f1a15c9b836f0c5c7384abaa5dc7a56b3f0d8c747fc7d5f216f03911028"
409
409
  }
410
410
  ]
411
411
  },
@@ -731,11 +731,11 @@
731
731
  "hashes": [
732
732
  {
733
733
  "alg": "SHA-256",
734
- "content": "d9dd7f88dca3f91bc143cb3abdb5e90ae6109b7c4b6fc8253802b9776bc9102e"
734
+ "content": "c5e35e621cfd1702bd048dca73f0a309323b537aa73680967295a4176da7368b"
735
735
  },
736
736
  {
737
737
  "alg": "SHA3-512",
738
- "content": "117d523bb04163dceba8f2ca1ba6b487244c15d5e1b206721687411dab4c3c5265b91c224c513dafc9971087d49aed96b171dac74e15bd49030e2e8375a24f20"
738
+ "content": "919da50a7973dd8f64cd1088ebbc12ae11800b57dc2a65704d29aa373e63db841d392eee45da2a1cd2cfe6df605252bbbe06e303586ba9ebb6bad7a613031dad"
739
739
  }
740
740
  ]
741
741
  },
@@ -806,11 +806,11 @@
806
806
  "hashes": [
807
807
  {
808
808
  "alg": "SHA-256",
809
- "content": "acf9b2b001844dd2cacf1d29c7175d60db49b103847c9fddd242d2a98087541d"
809
+ "content": "c7419ef8265a8385ab29e37e3f3237f120dd2fa448692f9dc1aa2fd79339fc76"
810
810
  },
811
811
  {
812
812
  "alg": "SHA3-512",
813
- "content": "ea633dba87756ee5346ca8cbdc75d2f5d773c421cbe483792804266eea94fa9cd7e952955b43b43a93da76663c65236e36ab1a76c8bce09e9c3bb7da86df8c24"
813
+ "content": "7aea30cb368c94ff5e9fa3d1d6e60a71f81a1c36d5b358310b372b99d1e448ff5c19c34f2fb33316841906e3f988bc305a8c9c158d9fb33c62b91538a56fcde5"
814
814
  }
815
815
  ]
816
816
  },
@@ -1106,11 +1106,11 @@
1106
1106
  "hashes": [
1107
1107
  {
1108
1108
  "alg": "SHA-256",
1109
- "content": "a39b8a03b89093ad02faa3d106bb65f6a42e959297add8ee4d72c1f0254aaad9"
1109
+ "content": "17c8544a8043fd8a24aa22c1b5c061806983bc896a51b120f1976dea1c770a3d"
1110
1110
  },
1111
1111
  {
1112
1112
  "alg": "SHA3-512",
1113
- "content": "9229f5a214596e323a6c9a6984acf77e281414723558652677334d1d6d95f5f30250d110c6089425deb487dcbd3dcd29b66422dfd76444f79fbcc87bcb68a3dc"
1113
+ "content": "fdca23d1585d169fa2dad9be3f840de556b2673fefc6406c4ad0fb6cdf4e85a98103afc125f725c2fb3146fead224e444f963c17e031d6c64581a8552da96eca"
1114
1114
  }
1115
1115
  ]
1116
1116
  },
@@ -1316,11 +1316,11 @@
1316
1316
  "hashes": [
1317
1317
  {
1318
1318
  "alg": "SHA-256",
1319
- "content": "90b3c15de2da89e06ba82cad044bebcfcc7827ac612240e7a9f66a57d4bed696"
1319
+ "content": "f9452a58e4916a512b61ac8c6179dff6162f3634cf766b129d521233daec3c0e"
1320
1320
  },
1321
1321
  {
1322
1322
  "alg": "SHA3-512",
1323
- "content": "e8a3b82152c6e213a074037193a4030bb0e1a16e07c301e30ebdfc3c939866a3d1db2fa0a2c23dbe6c9af44100ba3f01a1d7e2714f68fda942fa1865a19c84bf"
1323
+ "content": "d6ebf5ffca3fee2398034f411eb477d393e8ee8a7f12ed576e72f0e785c42b37e760fb743bf47d0a4c704c71f726ba56e373fbd4149e2750c00ee89e8af74efe"
1324
1324
  }
1325
1325
  ]
1326
1326
  },
@@ -1661,11 +1661,11 @@
1661
1661
  "hashes": [
1662
1662
  {
1663
1663
  "alg": "SHA-256",
1664
- "content": "07ba1b6db0880e09b35b6e70129807d1c77aeb273b75e81024582e58932f17ca"
1664
+ "content": "484c2c4747699b7a32658126ade2fb498656cde204a8a30efde0730c04305a48"
1665
1665
  },
1666
1666
  {
1667
1667
  "alg": "SHA3-512",
1668
- "content": "e3c5f78c50845d7727d4c5aaf49f1e8b6d7cf6d4de5d9ae6930f3ae42f7a23df719e0169a595d55067a9d036e9248ba0bc057ac17b095bec63edab1c5513e024"
1668
+ "content": "b9162623770ee4a9879f501417f123fe02d819cfac322ca9fde4ca86c0319a4785a6a2bd719a2b9248e531cd8eac0a79c98b5f627c69b4dfb0d5e62f69f600d5"
1669
1669
  }
1670
1670
  ]
1671
1671
  },
@@ -1751,11 +1751,11 @@
1751
1751
  "hashes": [
1752
1752
  {
1753
1753
  "alg": "SHA-256",
1754
- "content": "b2d79207d42e38d82a76c13b827623baa3e951b16cfbcc05250572070eb76aed"
1754
+ "content": "26f77d56ab70b31946f08cd83c8cd5fc43e807c77955a0e9d4ae9450d32e29c9"
1755
1755
  },
1756
1756
  {
1757
1757
  "alg": "SHA3-512",
1758
- "content": "aacaf080aa59ced61686aef2fec87514b5ae34bfcbedd03614da053f0ed40cabf604b649519e75abf78df2e10892f3dd7b4241e7c5394110527f8ee6f9be4a6a"
1758
+ "content": "b2bfaea029b51a059fb31a734fa65e73366bf075e38af76723fda119fe9202a17a286b3e20b8e7d12b16e7eed9ef68e13e7b652ddb989d3c5cab30077e7748d2"
1759
1759
  }
1760
1760
  ]
1761
1761
  },
@@ -2201,11 +2201,11 @@
2201
2201
  "hashes": [
2202
2202
  {
2203
2203
  "alg": "SHA-256",
2204
- "content": "43be3a85bb57b5ee47a0e567e6fe252ca8d41ee5e01e5614886553a473df2609"
2204
+ "content": "576480c2ad29550a06e5a3e48b7dae04aadc1b505d76e3a5b1db9179d61263c4"
2205
2205
  },
2206
2206
  {
2207
2207
  "alg": "SHA3-512",
2208
- "content": "45a6856042bb6eed57a703c96129b31e92ad1f5b9625ca8e033e01ea8d237fa97fbdf5ccd5f661205f03adc3e28817aa93251eac8de659aa2c03d83e829cf612"
2208
+ "content": "e3370698400f8b807680cebda861e73acedbf1602c9a7c2a8372c2285b2f88650a9d6e2931ebdb2cb229ad23e7c592787dea15a91adea5b4a854c6fc6842d38a"
2209
2209
  }
2210
2210
  ]
2211
2211
  },
@@ -2321,11 +2321,11 @@
2321
2321
  "hashes": [
2322
2322
  {
2323
2323
  "alg": "SHA-256",
2324
- "content": "fa4411b9995749454427cdde051da0567ec48df5eeba7f23410e8cbd1590d69d"
2324
+ "content": "4622fd121015535bb0a1b47a7bf57abe3a195b02e42a0be99dfadc9d67a72160"
2325
2325
  },
2326
2326
  {
2327
2327
  "alg": "SHA3-512",
2328
- "content": "d16b768360c2553375b2ff183270ac89d3504cfa151d1178aebf8bd76f000fb17fa143ab719c2d43cfb0ec0f74969eb465e90162b55efe713296508e13f2f119"
2328
+ "content": "85f755a9228afe24b704d39d58ee11436c8dd663df47e8c7c84da9454c5bad1cf9f166c833a9648517f9c2689730103617b41bec0739c637d91fafb041f7db63"
2329
2329
  }
2330
2330
  ]
2331
2331
  },
@@ -2471,11 +2471,11 @@
2471
2471
  "hashes": [
2472
2472
  {
2473
2473
  "alg": "SHA-256",
2474
- "content": "d01f579279f7cdc0ab9bac6e1cd50f61a37a72f768ce656eb3f53737b76b58a3"
2474
+ "content": "a5a43d931bcc09f0e5866e5860efd373943e5ce797ff368dc009ea4161d03cd6"
2475
2475
  },
2476
2476
  {
2477
2477
  "alg": "SHA3-512",
2478
- "content": "6e990e7c3303f73cb71d98f565f2523e8e18dfbfd7ea0acced6233c7bab19e4206c3116e233c2dca97f7d33d144cb3c6794aec6c81a3a9a6aa7b546f79fb4b49"
2478
+ "content": "dff963f00485e37546f605542d94d5e8730be9b888d98dd9bc9d256f38b4820d3c3346b1bfdbacedefc4b47d7b07afffdd1b3d7a77ba4cf71593efdd5530b9af"
2479
2479
  }
2480
2480
  ]
2481
2481
  },
@@ -3101,11 +3101,11 @@
3101
3101
  "hashes": [
3102
3102
  {
3103
3103
  "alg": "SHA-256",
3104
- "content": "7c568ee9805f4c822c16c266348e35fa6f2d7a3c76135fa34b0cfa77f003a878"
3104
+ "content": "23d15c234afedec011d9c3e588334132373a22d09ef33cd2d943e479c88fcb43"
3105
3105
  },
3106
3106
  {
3107
3107
  "alg": "SHA3-512",
3108
- "content": "135e7723a95b7e3cc929e6074bf572d10e31100e3362730784a94273d7db0a85aa06bb6946207e56a3ee45adf3431a8d8cffadad9571fec3a4a98f6e2ca879e7"
3108
+ "content": "d4da986f67c1b537431731f28ac048bdca8bba2269896fe674aecc91d5da99d4963624e62309c60ec4c8a2422e0ed3899290a1f951db0eaf0fe46b43a90ebc74"
3109
3109
  }
3110
3110
  ]
3111
3111
  },
@@ -3266,11 +3266,11 @@
3266
3266
  "hashes": [
3267
3267
  {
3268
3268
  "alg": "SHA-256",
3269
- "content": "dc9e8a14d5ec7268c45b4c02d5489515c6f571f120aec56847a89eb69c912f17"
3269
+ "content": "bb7cb7e49f82a7bb2a75ebcacc0b673d564384c0382ee7b271c32dd46fde8928"
3270
3270
  },
3271
3271
  {
3272
3272
  "alg": "SHA3-512",
3273
- "content": "202f14c7f50493a44ff3bf386cea8398035587e70a11a95f0901d659570b2ff2969ff4ef4b2c63e14bbc369e40fff53b7b1d740511828cc61fc469604a5c509a"
3273
+ "content": "49cd6309d13cfde3a266a7a499bce75849e61b562eaba579b814bd2d553f0dc192fd987eba449e86691645a22459b3579bd32dac8bd1a50697d3bb2a2045d6a0"
3274
3274
  }
3275
3275
  ]
3276
3276
  },
@@ -3281,11 +3281,26 @@
3281
3281
  "hashes": [
3282
3282
  {
3283
3283
  "alg": "SHA-256",
3284
- "content": "a44aa473f7ea7f8353ad921cf198ac4bf1ff4ac9cde43aee8c79b52160436cf1"
3284
+ "content": "31a30c4d7ea405ad1799322c02334993f7985bf922246e621b3d3e8a402654f5"
3285
3285
  },
3286
3286
  {
3287
3287
  "alg": "SHA3-512",
3288
- "content": "617266e7ee99432abb4403fa9acfa7f8d4dcbacf0ba62a8e96be7bfb2bbd9c9a44185bdf46976766077f4a5f26558491478e91c6cde0b0d044e53ea9968caea5"
3288
+ "content": "1a33019f5533ecff0b7e97ce9d2433e83e054afd2ef3cd3902428037a4b34590820b064deeffcc4cfb92724e67f9e035fd2f2bc7f70e99128c2c7baf8d82070e"
3289
+ }
3290
+ ]
3291
+ },
3292
+ {
3293
+ "bom-ref": "file:vendor/blamejs/codepoint-class.js",
3294
+ "type": "file",
3295
+ "name": "vendor/blamejs/codepoint-class.js",
3296
+ "hashes": [
3297
+ {
3298
+ "alg": "SHA-256",
3299
+ "content": "2be79cf25de87f46b608aec98ee790f4cf1035ffee48fe70ff082d3cf6f324ba"
3300
+ },
3301
+ {
3302
+ "alg": "SHA3-512",
3303
+ "content": "8e243451500312f0836651525e31150f649b39ec34caa662bfff86f65975af91e479fd7b74a971ddb4a1fc30a379dc958b0407f7c5193c4e28a215a56a8e2bd4"
3289
3304
  }
3290
3305
  ]
3291
3306
  },
@@ -3319,6 +3334,46 @@
3319
3334
  }
3320
3335
  ]
3321
3336
  },
3337
+ {
3338
+ "bom-ref": "vendor:blamejs:codepoint-class.js",
3339
+ "type": "library",
3340
+ "name": "blamejs/codepoint-class.js",
3341
+ "version": "1442f17758a4",
3342
+ "description": "Vendored from blamejs/lib/codepoint-class.js (flattened + stripped). See vendor/blamejs/README.md.",
3343
+ "licenses": [
3344
+ {
3345
+ "license": {
3346
+ "id": "Apache-2.0"
3347
+ }
3348
+ }
3349
+ ],
3350
+ "hashes": [
3351
+ {
3352
+ "alg": "SHA-256",
3353
+ "content": "2be79cf25de87f46b608aec98ee790f4cf1035ffee48fe70ff082d3cf6f324ba"
3354
+ }
3355
+ ],
3356
+ "externalReferences": [
3357
+ {
3358
+ "type": "vcs",
3359
+ "url": "https://github.com/blamejs/blamejs"
3360
+ },
3361
+ {
3362
+ "type": "distribution",
3363
+ "url": "https://github.com/blamejs/blamejs/blob/1442f17758a4bd511c63877561c0ffa759f66a87/lib/codepoint-class.js"
3364
+ }
3365
+ ],
3366
+ "properties": [
3367
+ {
3368
+ "name": "exceptd:vendor:upstream_sha256_at_pin",
3369
+ "value": "2be79cf25de87f46b608aec98ee790f4cf1035ffee48fe70ff082d3cf6f324ba"
3370
+ },
3371
+ {
3372
+ "name": "exceptd:vendor:strip_summary",
3373
+ "value": ""
3374
+ }
3375
+ ]
3376
+ },
3322
3377
  {
3323
3378
  "bom-ref": "vendor:blamejs:retry.js",
3324
3379
  "type": "library",
@@ -41,6 +41,7 @@ const ROOT = path.resolve(__dirname, "..");
41
41
  const VALID_ALLOW_CLASSES = Object.freeze({
42
42
  "process-exit-after-stdout-write": true,
43
43
  "dynamic-regex": true,
44
+ "bidi-codepoint-literal": true,
44
45
  });
45
46
 
46
47
  const EXCLUDE_DIRS = new Set([
@@ -205,6 +206,39 @@ function detectDynamicRegex(files) {
205
206
  return filterMarkers(hits, "dynamic-regex");
206
207
  }
207
208
 
209
+ // Raw bidi-override / zero-width / invisible / null codepoints embedded as
210
+ // literals in source — the Trojan-Source class (CVE-2021-42574). A literal
211
+ // such codepoint is invisible in review and can reorder or hide code. Source
212
+ // should emit them programmatically (via vendor/blamejs/codepoint-class) or
213
+ // escape them (\uXXXX), never type them literally. The range table holds only
214
+ // numeric codepoints + the regex is built from escapes, so this detector's own
215
+ // source is clean (and the file self-skips below regardless).
216
+ const _BIDI_LITERAL_RANGES = [
217
+ [0x202A, 0x202E], [0x2066, 0x2069], 0x200E, 0x200F, 0x061C, // bidi overrides + isolates
218
+ 0x200B, 0x200C, 0x200D, 0x00AD, 0x2060, 0xFEFF, // zero-width / invisible
219
+ 0x0000, // null
220
+ ];
221
+ function _bidiLiteralRe() {
222
+ const body = _BIDI_LITERAL_RANGES.map((r) =>
223
+ Array.isArray(r)
224
+ ? "\\u" + r[0].toString(16).padStart(4, "0") + "-\\u" + r[1].toString(16).padStart(4, "0")
225
+ : "\\u" + r.toString(16).padStart(4, "0")
226
+ ).join("");
227
+ return new RegExp("[" + body + "]"); // allow:dynamic-regex — codepoints from a static literal range table, not operator input
228
+ }
229
+ function detectBidiCodepointLiteral(files) {
230
+ const re = _bidiLiteralRe();
231
+ const hits = [];
232
+ for (const rel of (files || filesUnder(["bin/exceptd.js", "lib", "orchestrator", "scripts"]))) {
233
+ if (rel === "scripts/check-codebase-patterns.js") continue; // holds the range table itself
234
+ const lines = readLines(rel);
235
+ for (let i = 0; i < lines.length; i++) {
236
+ if (re.test(lines[i])) hits.push({ file: rel, line: i + 1, content: lines[i].trim() });
237
+ }
238
+ }
239
+ return filterMarkers(hits, "bidi-codepoint-literal");
240
+ }
241
+
208
242
  function detectOrphanAllowClass(files) {
209
243
  const hits = [];
210
244
  for (const rel of (files || filesUnder(["bin/exceptd.js", "lib", "orchestrator", "scripts"]))) {
@@ -251,6 +285,12 @@ const CLASSES = [
251
285
  warnOnly: true, // flip to false next release once the known sites carry markers
252
286
  hint: "RegExp from operator input is a ReDoS sink — anchor + length-cap, or `// allow:dynamic-regex — <reason>` when the pattern is a trusted bundled schema",
253
287
  },
288
+ {
289
+ id: "bidi-codepoint-literal",
290
+ run: detectBidiCodepointLiteral,
291
+ warnOnly: false,
292
+ hint: "raw bidi/zero-width/null codepoint in source — emit it via vendor/blamejs/codepoint-class tables or a \\uXXXX escape, or `// allow:bidi-codepoint-literal — <reason>` if the literal is load-bearing test/illustrative data",
293
+ },
254
294
  {
255
295
  id: "orphan-allow-class",
256
296
  run: detectOrphanAllowClass,
@@ -289,6 +329,7 @@ module.exports = {
289
329
  CLASSES,
290
330
  detectProcessExitAfterStdout,
291
331
  detectDynamicRegex,
332
+ detectBidiCodepointLiteral,
292
333
  detectOrphanAllowClass,
293
334
  filesUnder,
294
335
  };
@@ -244,7 +244,7 @@ const GATES = [
244
244
  // dynamic-RegExp construction is surfaced warn-only this release. The
245
245
  // exception mechanism + the "owned elsewhere" boundary are documented in
246
246
  // the script header.
247
- name: "Codebase-pattern gates (process-exit-after-stdout-write, dynamic RegExp)",
247
+ name: "Codebase-pattern gates (stdout-flush, dynamic RegExp, bidi codepoints, orphan markers)",
248
248
  command: process.execPath,
249
249
  args: [path.join(ROOT, "scripts", "check-codebase-patterns.js")],
250
250
  ciJobName: "Data integrity (catalog + manifest snapshot)",
@@ -375,6 +375,22 @@ function cmdWatch() {
375
375
  // run doesn't throw before we get to inspect + rerun it.
376
376
  _run("gh", ["pr", "checks", prNum, "--watch"], { allowFail: true });
377
377
 
378
+ // Gate on check CONCLUSIONS, not only review threads. A red required check
379
+ // leaves the PR BLOCKED at merge, so surfacing failures here (the whole
380
+ // point of the watch phase) beats advancing to "next: merge" and letting
381
+ // cmdMerge reject it. Bucket is gh's normalized verdict: pass / fail /
382
+ // pending / skipping / cancel.
383
+ var checksRaw = _capture("gh", ["pr", "checks", prNum, "--json", "name,bucket,link"]).stdout;
384
+ var checks = [];
385
+ try { checks = JSON.parse(checksRaw || "[]"); } catch (_e) { checks = []; }
386
+ var failed = checks.filter(function (c) { return c.bucket === "fail" || c.bucket === "cancel"; });
387
+ if (failed.length > 0) {
388
+ console.log("\nfailed checks (" + failed.length + "):");
389
+ failed.forEach(function (c) { console.log(" ✗ " + c.name + " " + (c.link || "")); });
390
+ console.log("\nFix in code, push, then re-run: node scripts/release.js watch");
391
+ process.exit(3);
392
+ }
393
+
378
394
  var unresolved = _unresolvedThreads(prNum);
379
395
  if (unresolved.length > 0) {
380
396
  console.log("\nunresolved review threads (" + unresolved.length + "):");
@@ -85,6 +85,8 @@ The defining incidents driving this expansion:
85
85
  - **Typosquat campaigns target the MCP, Hugging Face, npm `@modelcontextprotocol/*`, and PyPI ML namespaces.** The MITRE ATLAS technique AML.T0010 (ML Supply Chain Compromise) is the umbrella class; AML.T0018 (compromised model weight) is the specific artifact.
86
86
  - **The XZ Utils backdoor (2024, CVE-2024-3094)** remains the canonical example of a maintainer-position long-game supply-chain compromise that no SBOM-only program detects. The defense is in-toto attestation chain plus reproducible builds plus maintainer-key transparency — none of which are mandated by current compliance frameworks.
87
87
 
88
+ **Capability surface is a CVE-independent screening lens.** Beyond matching dependencies against catalogued CVEs, classify every package by the capabilities it actually exercises — network egress, filesystem write, shell/process spawn, environment and credential access, dynamic `eval`, install-lifecycle scripts, telemetry, and native-binary builds. A package with zero catalogued CVEs can still carry the supply-chain delivery primitive: an install-script that spawns a shell, opens the network, and reads environment variables is the credential-harvesting shape shared by the node-ipc protestware wiper (CVE-2022-23812), the TrapDoor cross-ecosystem stealer, the MOIKA dependency-confusion campaign, and the XZ backdoor — independent of whether any of them is yet in a vulnerability feed. Two deltas matter most: a capability surface disproportionate to a package's stated function (a date-formatting utility that opens the network and reads env), and a capability *gained across a version bump* the dependent never opted into when it first selected the package — the in-the-wild signature of a maintainer-account takeover or protestware injection before any CVE is assigned. Build-tooling and native-addon packages (node-gyp, esbuild, sharp, prebuild-install) legitimately carry install-script and native-binary capability, so treat the lens as a high-recall screen that routes to adjudication against publisher provenance and changelog evidence — not an auto-verdict.
89
+
88
90
  Mid-2026 baseline expectations have shifted to: SLSA Build L3 minimum on every release pipeline; in-toto attestations for every step in the build graph; Sigstore keyless signing (cosign + Fulcio + Rekor) for container images, packages, and model weights; CycloneDX 1.6 or SPDX 3.0 SBOM at build time and re-verification at deploy time; CSAF 2.0 VEX statements published by vendors and consumed by operators to filter false-positive vulnerability noise. Adoption is uneven — security-mature orgs and open-source foundations (Kubernetes, Sigstore, Linux Foundation projects) are at or near this baseline; most enterprise pipelines are between SLSA L1 and L2 with no attestation chain and no VEX consumption.
89
91
 
90
92
  This project itself uses Ed25519 (RFC 8032) signing for skill integrity (`lib/sign.js`, `lib/verify.js`, public key at `keys/public.pem`). That is the smallest-scale living example of the broader pattern this skill defines: artifacts are signed by an identified key, signatures are verified before load, tampered artifacts are rejected, and the signing key is operationally separated from the artifact registry. The same pattern scales to every layer of the build pipeline — exceptd is just the scoped-to-one-repo version.
@@ -9,6 +9,7 @@ upstream commit [`1442f17`](https://github.com/blamejs/blamejs/commit/1442f17758
9
9
  |---|---|---|
10
10
  | `retry.js` | `lib/retry.js` | Battle-tested exponential backoff + crypto jitter + AbortSignal + circuit-breaker. Used by `lib/job-queue.js` and `lib/refresh-external.js` for HTTP retry semantics on KEV/EPSS/NVD/IETF/GitHub fetches. |
11
11
  | `worker-pool.js` | `lib/worker-pool.js` | Generic worker_threads pool with bounded queue, per-task timeout, worker recycle. Used by `scripts/build-indexes.js --parallel` and any future CPU-bound fan-out work. |
12
+ | `codepoint-class.js` | `lib/codepoint-class.js` | Trojan-Source (CVE-2021-42574) codepoint threat tables — bidi-override / C0-control / zero-width / null ranges + compiled regexes + `applyCharStripPolicies`. Used by the `--operator` reject path (`bin/exceptd.js`) and `sanitizeOperatorText` (`lib/playbook-runner.js`) to classify which family an offending codepoint belongs to; `\p{C}` remains the category backstop. |
12
13
  | `LICENSE` | `LICENSE` | Apache-2.0 license text (identical to exceptd's). |
13
14
  | `_PROVENANCE.json` | — | sha256 of each vendored file + upstream file at pin, plus the strip rules applied. `lib/validate-vendor.js` re-hashes on every predeploy run. |
14
15
 
@@ -52,6 +52,22 @@
52
52
  "exceptd_deltas": [
53
53
  "scriptPath validator rejects Windows UNC + extended-path prefixes (\\\\?\\, \\\\.\\, \\\\<server>\\) — defense-in-depth against worker-spawn from network shares on win32 platforms"
54
54
  ]
55
+ },
56
+ "codepoint-class.js": {
57
+ "vendored_path": "vendor/blamejs/codepoint-class.js",
58
+ "vendored_sha256": "2be79cf25de87f46b608aec98ee790f4cf1035ffee48fe70ff082d3cf6f324ba",
59
+ "upstream_path": "lib/codepoint-class.js",
60
+ "upstream_sha256_at_pin": "2be79cf25de87f46b608aec98ee790f4cf1035ffee48fe70ff082d3cf6f324ba",
61
+ "stripped": [],
62
+ "surface_preserved": [
63
+ "BIDI_RE / C0_CTRL_RE / ZERO_WIDTH_RE / NULL_BYTE (classification regexes)",
64
+ "BIDI_RE_G / C0_CTRL_RE_G / ZW_RE_G / NULL_RE_G (global strip regexes)",
65
+ "applyCharStripPolicies(text, opts)",
66
+ "hex4 / charClass / fromCp / range tables"
67
+ ],
68
+ "exceptd_deltas": [
69
+ "Used for codepoint-family CLASSIFICATION + family-strip only. The BIDI|C0|ZERO_WIDTH|NULL union is a strict subset of Unicode General Category C, so \\p{C} remains the reject/strip backstop at both consumer sites (bin/exceptd.js --operator validation, lib/playbook-runner.js sanitizeOperatorText) — it catches the divergent remainder (U+007F, U+0080-009F, U+FFF9-FFFB, private-use, unassigned) the named-family regexes miss."
70
+ ]
55
71
  }
56
72
  }
57
73
  }