@ceralive/modem-control 0.2.0 → 1.1.0

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 (464) hide show
  1. package/README.md +317 -0
  2. package/dist/backend/at-lease.d.ts +57 -0
  3. package/dist/backend/at-lease.js +109 -0
  4. package/dist/backend/cell-info.d.ts +46 -0
  5. package/dist/backend/cell-info.js +124 -0
  6. package/dist/backend/constants.d.ts +24 -0
  7. package/{src/backend/constants.ts → dist/backend/constants.js} +4 -9
  8. package/dist/backend/device-classifier.d.ts +46 -0
  9. package/dist/backend/device-classifier.js +258 -0
  10. package/dist/backend/enrichment.d.ts +28 -0
  11. package/dist/backend/enrichment.js +59 -0
  12. package/dist/backend/features.d.ts +61 -0
  13. package/dist/backend/features.js +109 -0
  14. package/dist/backend/identity-ladder.d.ts +57 -0
  15. package/dist/backend/identity-ladder.js +158 -0
  16. package/dist/backend/identity-registry.d.ts +51 -0
  17. package/dist/backend/identity-registry.js +101 -0
  18. package/dist/backend/index.d.ts +30 -0
  19. package/dist/backend/index.js +35 -0
  20. package/dist/backend/lifecycle-interlock.d.ts +25 -0
  21. package/dist/backend/lifecycle-interlock.js +18 -0
  22. package/dist/backend/managed-objects.d.ts +39 -0
  23. package/dist/backend/managed-objects.js +82 -0
  24. package/dist/backend/mapping.d.ts +11 -0
  25. package/dist/backend/mapping.js +148 -0
  26. package/dist/backend/mm-backend.d.ts +44 -0
  27. package/dist/backend/mm-backend.js +154 -0
  28. package/dist/backend/mm-location.d.ts +21 -0
  29. package/dist/backend/mm-location.js +237 -0
  30. package/dist/backend/mm-mutations.d.ts +42 -0
  31. package/dist/backend/mm-mutations.js +259 -0
  32. package/dist/backend/modem-actor.d.ts +41 -0
  33. package/dist/backend/modem-actor.js +78 -0
  34. package/dist/backend/nm-auto-apn.d.ts +54 -0
  35. package/dist/backend/nm-auto-apn.js +124 -0
  36. package/dist/backend/nm-gsm-fields.d.ts +23 -0
  37. package/dist/backend/nm-gsm-fields.js +107 -0
  38. package/dist/backend/nmcli-nm-port.d.ts +28 -0
  39. package/dist/backend/nmcli-nm-port.js +173 -0
  40. package/dist/backend/nmcli-runner.d.ts +24 -0
  41. package/dist/backend/nmcli-runner.js +35 -0
  42. package/dist/backend/observer.d.ts +37 -0
  43. package/dist/backend/observer.js +219 -0
  44. package/dist/backend/power-contract.d.ts +49 -0
  45. package/dist/backend/power-contract.js +34 -0
  46. package/dist/backend/recovery-attribution.d.ts +32 -0
  47. package/dist/backend/recovery-attribution.js +57 -0
  48. package/dist/backend/recovery-budget.d.ts +45 -0
  49. package/dist/backend/recovery-budget.js +44 -0
  50. package/dist/backend/recovery-ladder.d.ts +94 -0
  51. package/dist/backend/recovery-ladder.js +116 -0
  52. package/dist/backend/router-ethernet.d.ts +19 -0
  53. package/dist/backend/router-ethernet.js +66 -0
  54. package/dist/backend/row-store.d.ts +13 -0
  55. package/dist/backend/row-store.js +82 -0
  56. package/dist/backend/signal-setup.d.ts +30 -0
  57. package/dist/backend/signal-setup.js +92 -0
  58. package/dist/backend/sim-unlock.d.ts +13 -0
  59. package/dist/backend/sim-unlock.js +153 -0
  60. package/dist/backend/transition-preconditions.d.ts +76 -0
  61. package/dist/backend/transition-preconditions.js +64 -0
  62. package/dist/backend/usage/accounting.d.ts +39 -0
  63. package/dist/backend/usage/accounting.js +73 -0
  64. package/dist/backend/usage/billing-cycle.d.ts +11 -0
  65. package/dist/backend/usage/billing-cycle.js +39 -0
  66. package/dist/backend/usage/boot-id.d.ts +6 -0
  67. package/{src/backend/usage/boot-id.ts → dist/backend/usage/boot-id.js} +7 -7
  68. package/dist/backend/usage/index.d.ts +8 -0
  69. package/dist/backend/usage/index.js +11 -0
  70. package/dist/backend/usage/policy-store.d.ts +50 -0
  71. package/dist/backend/usage/policy-store.js +161 -0
  72. package/dist/backend/usage/policy-write.d.ts +65 -0
  73. package/dist/backend/usage/policy-write.js +112 -0
  74. package/dist/backend/usage/proc-net-dev.d.ts +18 -0
  75. package/{src/backend/usage/proc-net-dev.ts → dist/backend/usage/proc-net-dev.js} +39 -47
  76. package/dist/backend/usage/sampler.d.ts +75 -0
  77. package/dist/backend/usage/sampler.js +211 -0
  78. package/dist/backend/usage/store.d.ts +38 -0
  79. package/dist/backend/usage/store.js +126 -0
  80. package/dist/backend/usb-device-snapshot.d.ts +31 -0
  81. package/dist/backend/usb-device-snapshot.js +1 -0
  82. package/dist/backend/usb-enumerator.d.ts +21 -0
  83. package/dist/backend/usb-enumerator.js +153 -0
  84. package/dist/backend/usb-mode-transition.d.ts +29 -0
  85. package/dist/backend/usb-mode-transition.js +196 -0
  86. package/dist/band/band-names.d.ts +42 -0
  87. package/dist/band/band-names.js +150 -0
  88. package/dist/band/certification.d.ts +84 -0
  89. package/dist/band/certification.js +127 -0
  90. package/dist/band/certified-bands.json +4 -0
  91. package/dist/band/index.d.ts +2 -0
  92. package/dist/band/index.js +8 -0
  93. package/dist/capability/detect.d.ts +52 -0
  94. package/dist/capability/detect.js +86 -0
  95. package/dist/capability/five-g-preference.d.ts +104 -0
  96. package/dist/capability/five-g-preference.js +171 -0
  97. package/dist/capability/index.d.ts +3 -0
  98. package/dist/capability/index.js +10 -0
  99. package/dist/capability/support-claim.d.ts +39 -0
  100. package/dist/capability/support-claim.js +81 -0
  101. package/dist/domain/brand.d.ts +10 -0
  102. package/dist/domain/brand.js +21 -0
  103. package/dist/domain/errors.d.ts +32 -0
  104. package/dist/domain/errors.js +48 -0
  105. package/dist/domain/generation.d.ts +8 -0
  106. package/dist/domain/generation.js +12 -0
  107. package/dist/domain/guards.d.ts +6 -0
  108. package/dist/domain/guards.js +127 -0
  109. package/dist/domain/identity.d.ts +109 -0
  110. package/dist/domain/identity.js +86 -0
  111. package/dist/domain/index.d.ts +14 -0
  112. package/dist/domain/index.js +18 -0
  113. package/dist/domain/mm-enums.d.ts +12 -0
  114. package/dist/domain/mm-enums.js +139 -0
  115. package/dist/domain/modem-presentation.d.ts +10 -0
  116. package/dist/domain/modem-presentation.js +39 -0
  117. package/dist/domain/observation.d.ts +39 -0
  118. package/dist/domain/observation.js +4 -0
  119. package/dist/domain/operation.d.ts +118 -0
  120. package/dist/domain/operation.js +85 -0
  121. package/dist/domain/physical-identity.d.ts +43 -0
  122. package/dist/domain/physical-identity.js +113 -0
  123. package/{src/domain/policy.ts → dist/domain/policy.d.ts} +34 -69
  124. package/dist/domain/policy.js +38 -0
  125. package/dist/domain/shadow-divergence.d.ts +27 -0
  126. package/dist/domain/shadow-divergence.js +70 -0
  127. package/dist/domain/snapshot.d.ts +53 -0
  128. package/dist/domain/snapshot.js +75 -0
  129. package/{src/domain/state.ts → dist/domain/state.d.ts} +23 -122
  130. package/dist/domain/state.js +38 -0
  131. package/dist/fcc/coverage.d.ts +63 -0
  132. package/dist/fcc/coverage.js +102 -0
  133. package/dist/fcc/index.d.ts +3 -0
  134. package/dist/fcc/index.js +12 -0
  135. package/dist/fcc/policy-store.d.ts +40 -0
  136. package/dist/fcc/policy-store.js +146 -0
  137. package/dist/fcc/policy-write.d.ts +32 -0
  138. package/dist/fcc/policy-write.js +37 -0
  139. package/dist/hardware/hilink-protocol.d.ts +39 -0
  140. package/dist/hardware/hilink-protocol.js +58 -0
  141. package/dist/hardware/index.d.ts +3 -0
  142. package/dist/hardware/index.js +15 -0
  143. package/dist/hardware/router-parsers.d.ts +89 -0
  144. package/dist/hardware/router-parsers.js +234 -0
  145. package/dist/index.d.ts +19 -0
  146. package/dist/index.js +26 -0
  147. package/dist/journal/codec.d.ts +44 -0
  148. package/dist/journal/codec.js +198 -0
  149. package/dist/journal/engine.d.ts +28 -0
  150. package/dist/journal/engine.js +68 -0
  151. package/dist/journal/entry.d.ts +74 -0
  152. package/dist/journal/entry.js +56 -0
  153. package/dist/journal/index.d.ts +6 -0
  154. package/dist/journal/index.js +6 -0
  155. package/dist/journal/legacy-ceraui.d.ts +73 -0
  156. package/dist/journal/legacy-ceraui.js +227 -0
  157. package/dist/journal/recovery.d.ts +58 -0
  158. package/dist/journal/recovery.js +117 -0
  159. package/dist/journal/store.d.ts +55 -0
  160. package/dist/journal/store.js +150 -0
  161. package/dist/location/fix-state.d.ts +53 -0
  162. package/dist/location/fix-state.js +75 -0
  163. package/dist/location/index.d.ts +2 -0
  164. package/dist/location/index.js +8 -0
  165. package/dist/location/nmea.d.ts +10 -0
  166. package/dist/location/nmea.js +89 -0
  167. package/dist/observations/envelope.d.ts +63 -0
  168. package/dist/observations/envelope.js +77 -0
  169. package/dist/observations/freshness.d.ts +28 -0
  170. package/dist/observations/freshness.js +76 -0
  171. package/dist/observations/index.d.ts +13 -0
  172. package/dist/observations/index.js +24 -0
  173. package/dist/observations/metric.d.ts +47 -0
  174. package/dist/observations/metric.js +73 -0
  175. package/dist/observations/model.d.ts +80 -0
  176. package/dist/observations/model.js +11 -0
  177. package/dist/observations/provenance.d.ts +94 -0
  178. package/dist/observations/provenance.js +67 -0
  179. package/dist/observations/raw.d.ts +42 -0
  180. package/dist/observations/raw.js +146 -0
  181. package/dist/observations/reading.d.ts +51 -0
  182. package/dist/observations/reading.js +65 -0
  183. package/dist/observations/sources/hilink.d.ts +10 -0
  184. package/dist/observations/sources/hilink.js +84 -0
  185. package/dist/observations/sources/modemmanager.d.ts +18 -0
  186. package/dist/observations/sources/modemmanager.js +239 -0
  187. package/dist/observations/sources/router-shared.d.ts +29 -0
  188. package/dist/observations/sources/router-shared.js +68 -0
  189. package/dist/observations/sources/ufi.d.ts +10 -0
  190. package/dist/observations/sources/ufi.js +111 -0
  191. package/dist/observations/sources/zte.d.ts +7 -0
  192. package/dist/observations/sources/zte.js +71 -0
  193. package/dist/observations/state-separation.d.ts +64 -0
  194. package/dist/observations/state-separation.js +52 -0
  195. package/dist/operations/contracts.d.ts +72 -0
  196. package/dist/operations/contracts.js +1 -0
  197. package/dist/operations/index.d.ts +1 -0
  198. package/dist/operations/index.js +1 -0
  199. package/dist/operations/operation-engine.d.ts +16 -0
  200. package/dist/operations/operation-engine.js +194 -0
  201. package/dist/ports/index.d.ts +12 -0
  202. package/{src/ports/index.ts → dist/ports/index.js} +12 -8
  203. package/dist/ports/location.d.ts +87 -0
  204. package/dist/ports/location.js +36 -0
  205. package/dist/ports/modem-manager.d.ts +89 -0
  206. package/dist/ports/modem-manager.js +9 -0
  207. package/dist/ports/mutation-admission.d.ts +27 -0
  208. package/dist/ports/mutation-admission.js +9 -0
  209. package/dist/ports/network-manager.d.ts +68 -0
  210. package/dist/ports/network-manager.js +13 -0
  211. package/{src/ports/observation.ts → dist/ports/observation.d.ts} +16 -27
  212. package/dist/ports/observation.js +7 -0
  213. package/dist/ports/ops.d.ts +44 -0
  214. package/dist/ports/ops.js +16 -0
  215. package/{src/ports/receipts.ts → dist/ports/receipts.d.ts} +5 -27
  216. package/dist/ports/receipts.js +9 -0
  217. package/dist/ports/reconcile.d.ts +33 -0
  218. package/dist/ports/reconcile.js +200 -0
  219. package/dist/ports/resource-ownership.d.ts +29 -0
  220. package/dist/ports/resource-ownership.js +1 -0
  221. package/dist/ports/router.d.ts +19 -0
  222. package/dist/ports/router.js +7 -0
  223. package/dist/ports/sms.d.ts +64 -0
  224. package/dist/ports/sms.js +24 -0
  225. package/dist/ports/uhubctl.d.ts +6 -0
  226. package/dist/ports/uhubctl.js +1 -0
  227. package/dist/providers/contracts.d.ts +124 -0
  228. package/dist/providers/contracts.js +10 -0
  229. package/dist/providers/huawei-hilink/index.d.ts +2 -0
  230. package/dist/providers/huawei-hilink/index.js +2 -0
  231. package/dist/providers/huawei-hilink/operations.d.ts +20 -0
  232. package/dist/providers/huawei-hilink/operations.js +56 -0
  233. package/dist/providers/huawei-hilink/provider.d.ts +52 -0
  234. package/dist/providers/huawei-hilink/provider.js +76 -0
  235. package/dist/providers/huawei-hilink/runtime.d.ts +22 -0
  236. package/dist/providers/huawei-hilink/runtime.js +171 -0
  237. package/dist/providers/huawei-hilink/session.d.ts +28 -0
  238. package/dist/providers/huawei-hilink/session.js +120 -0
  239. package/dist/providers/huawei-hilink/transport.d.ts +19 -0
  240. package/dist/providers/huawei-hilink/transport.js +1 -0
  241. package/dist/providers/index.d.ts +8 -0
  242. package/dist/providers/index.js +8 -0
  243. package/dist/providers/matcher.d.ts +3 -0
  244. package/dist/providers/matcher.js +205 -0
  245. package/dist/providers/modem-manager/errors.d.ts +7 -0
  246. package/dist/providers/modem-manager/errors.js +37 -0
  247. package/dist/providers/modem-manager/generic-operations.d.ts +8 -0
  248. package/dist/providers/modem-manager/generic-operations.js +207 -0
  249. package/dist/providers/modem-manager/index.d.ts +3 -0
  250. package/dist/providers/modem-manager/index.js +3 -0
  251. package/dist/providers/modem-manager/module-operations.d.ts +21 -0
  252. package/dist/providers/modem-manager/module-operations.js +118 -0
  253. package/dist/providers/modem-manager/provider.d.ts +39 -0
  254. package/dist/providers/modem-manager/provider.js +152 -0
  255. package/dist/providers/modem-manager/snapshot.d.ts +5 -0
  256. package/dist/providers/modem-manager/snapshot.js +204 -0
  257. package/dist/providers/modem-manager/types.d.ts +135 -0
  258. package/dist/providers/modem-manager/types.js +1 -0
  259. package/dist/providers/network-manager/adapter.d.ts +71 -0
  260. package/dist/providers/network-manager/adapter.js +348 -0
  261. package/dist/providers/network-manager/index.d.ts +2 -0
  262. package/dist/providers/network-manager/index.js +2 -0
  263. package/dist/providers/network-manager/types.d.ts +163 -0
  264. package/dist/providers/network-manager/types.js +77 -0
  265. package/dist/providers/registry.d.ts +13 -0
  266. package/dist/providers/registry.js +33 -0
  267. package/dist/providers/ufi-himi/index.d.ts +6 -0
  268. package/dist/providers/ufi-himi/index.js +6 -0
  269. package/dist/providers/ufi-himi/operations.d.ts +41 -0
  270. package/dist/providers/ufi-himi/operations.js +66 -0
  271. package/dist/providers/ufi-himi/prohibitions.d.ts +62 -0
  272. package/dist/providers/ufi-himi/prohibitions.js +88 -0
  273. package/dist/providers/ufi-himi/provider.d.ts +41 -0
  274. package/dist/providers/ufi-himi/provider.js +204 -0
  275. package/dist/providers/ufi-himi/qualcomm-evidence.d.ts +32 -0
  276. package/dist/providers/ufi-himi/qualcomm-evidence.js +51 -0
  277. package/dist/providers/ufi-himi/session.d.ts +46 -0
  278. package/dist/providers/ufi-himi/session.js +92 -0
  279. package/dist/providers/ufi-himi/transport.d.ts +29 -0
  280. package/dist/providers/ufi-himi/transport.js +25 -0
  281. package/dist/providers/zte-goform/index.d.ts +2 -0
  282. package/dist/providers/zte-goform/index.js +2 -0
  283. package/dist/providers/zte-goform/provider.d.ts +51 -0
  284. package/dist/providers/zte-goform/provider.js +101 -0
  285. package/dist/providers/zte-goform/session.d.ts +17 -0
  286. package/dist/providers/zte-goform/session.js +133 -0
  287. package/dist/providers/zte-goform/transport.d.ts +16 -0
  288. package/dist/providers/zte-goform/transport.js +1 -0
  289. package/dist/radio/band-truth.d.ts +50 -0
  290. package/dist/radio/band-truth.js +92 -0
  291. package/dist/radio/index.d.ts +3 -0
  292. package/dist/radio/index.js +10 -0
  293. package/dist/radio/mode-combinations.d.ts +78 -0
  294. package/dist/radio/mode-combinations.js +198 -0
  295. package/dist/radio/mode-truth.d.ts +67 -0
  296. package/dist/radio/mode-truth.js +112 -0
  297. package/dist/redact.d.ts +15 -0
  298. package/dist/redact.js +189 -0
  299. package/dist/safety/composition-root.d.ts +28 -0
  300. package/dist/safety/composition-root.js +65 -0
  301. package/dist/safety/flock-resource-ownership.d.ts +11 -0
  302. package/dist/safety/flock-resource-ownership.js +151 -0
  303. package/dist/safety/index.d.ts +2 -0
  304. package/dist/safety/index.js +2 -0
  305. package/dist/sms/dbus-messaging.d.ts +17 -0
  306. package/dist/sms/dbus-messaging.js +185 -0
  307. package/dist/sms/inbox-store.d.ts +10 -0
  308. package/dist/sms/inbox-store.js +82 -0
  309. package/dist/sms/index.d.ts +4 -0
  310. package/dist/sms/index.js +10 -0
  311. package/dist/sms/mmcli-parse.d.ts +54 -0
  312. package/dist/sms/mmcli-parse.js +224 -0
  313. package/dist/sms/normalize.d.ts +42 -0
  314. package/dist/sms/normalize.js +95 -0
  315. package/dist/testing/domain-fakes.d.ts +58 -0
  316. package/dist/testing/domain-fakes.js +98 -0
  317. package/dist/testing/index.d.ts +2 -0
  318. package/dist/testing/index.js +17 -0
  319. package/dist/testing/provider-fakes.d.ts +45 -0
  320. package/dist/testing/provider-fakes.js +64 -0
  321. package/dist/transport/calls.d.ts +9 -0
  322. package/dist/transport/calls.js +88 -0
  323. package/dist/transport/codec.d.ts +3 -0
  324. package/dist/transport/codec.js +207 -0
  325. package/dist/transport/dbus-native.d.ts +57 -0
  326. package/dist/transport/dbus-native.js +17 -0
  327. package/dist/transport/errors.d.ts +21 -0
  328. package/{src/transport/errors.ts → dist/transport/errors.js} +34 -46
  329. package/dist/transport/index.d.ts +4 -0
  330. package/dist/transport/index.js +9 -0
  331. package/dist/transport/signals.d.ts +15 -0
  332. package/dist/transport/signals.js +123 -0
  333. package/dist/transport/signature.d.ts +7 -0
  334. package/dist/transport/signature.js +94 -0
  335. package/dist/transport/transport.d.ts +2 -0
  336. package/dist/transport/transport.js +202 -0
  337. package/dist/transport/types.d.ts +61 -0
  338. package/dist/transport/types.js +19 -0
  339. package/dist/usb-mode/catalog-schema.d.ts +139 -0
  340. package/dist/usb-mode/catalog-schema.js +97 -0
  341. package/dist/usb-mode/catalog.d.ts +21 -0
  342. package/{src/usb-mode/catalog.ts → dist/usb-mode/catalog.js} +10 -32
  343. package/dist/usb-mode/certified-catalog.json +67 -0
  344. package/dist/usb-mode/index.d.ts +5 -0
  345. package/dist/usb-mode/index.js +15 -0
  346. package/dist/usb-mode/ingestion.d.ts +111 -0
  347. package/dist/usb-mode/ingestion.js +187 -0
  348. package/dist/usb-mode/promotion-review.d.ts +21 -0
  349. package/dist/usb-mode/promotion-review.js +87 -0
  350. package/dist/usb-mode/usb-devices-parse.d.ts +36 -0
  351. package/dist/usb-mode/usb-devices-parse.js +157 -0
  352. package/dist/ussd/calls.d.ts +32 -0
  353. package/dist/ussd/calls.js +96 -0
  354. package/dist/ussd/index.d.ts +5 -0
  355. package/dist/ussd/index.js +12 -0
  356. package/dist/ussd/mm-ussd.d.ts +37 -0
  357. package/dist/ussd/mm-ussd.js +205 -0
  358. package/dist/ussd/refusal.d.ts +53 -0
  359. package/dist/ussd/refusal.js +154 -0
  360. package/dist/ussd/registration.d.ts +20 -0
  361. package/dist/ussd/registration.js +101 -0
  362. package/dist/ussd/session.d.ts +84 -0
  363. package/dist/ussd/session.js +163 -0
  364. package/package.json +38 -4
  365. package/src/backend/at-lease.test.ts +0 -106
  366. package/src/backend/at-lease.ts +0 -158
  367. package/src/backend/cell-info.test.ts +0 -154
  368. package/src/backend/cell-info.ts +0 -160
  369. package/src/backend/device-classifier.test.ts +0 -168
  370. package/src/backend/device-classifier.ts +0 -248
  371. package/src/backend/enrichment.ts +0 -96
  372. package/src/backend/features.test.ts +0 -162
  373. package/src/backend/features.ts +0 -179
  374. package/src/backend/identity-ladder.test.ts +0 -117
  375. package/src/backend/identity-ladder.ts +0 -221
  376. package/src/backend/identity-registry.test.ts +0 -89
  377. package/src/backend/identity-registry.ts +0 -151
  378. package/src/backend/index.ts +0 -221
  379. package/src/backend/lifecycle-interlock.ts +0 -38
  380. package/src/backend/managed-objects.ts +0 -108
  381. package/src/backend/mapping.ts +0 -160
  382. package/src/backend/mm-backend.ts +0 -191
  383. package/src/backend/mm-mutations.ts +0 -228
  384. package/src/backend/modem-actor.test.ts +0 -95
  385. package/src/backend/modem-actor.ts +0 -112
  386. package/src/backend/nm-auto-apn.ts +0 -161
  387. package/src/backend/nm-gsm-fields.ts +0 -122
  388. package/src/backend/nmcli-nm-port.ts +0 -228
  389. package/src/backend/nmcli-runner.ts +0 -52
  390. package/src/backend/observer.ts +0 -297
  391. package/src/backend/power-contract.test.ts +0 -40
  392. package/src/backend/power-contract.ts +0 -83
  393. package/src/backend/recovery-attribution.test.ts +0 -102
  394. package/src/backend/recovery-attribution.ts +0 -86
  395. package/src/backend/recovery-budget.test.ts +0 -64
  396. package/src/backend/recovery-budget.ts +0 -84
  397. package/src/backend/recovery-ladder.test.ts +0 -257
  398. package/src/backend/recovery-ladder.ts +0 -249
  399. package/src/backend/router-ethernet.test.ts +0 -71
  400. package/src/backend/router-ethernet.ts +0 -90
  401. package/src/backend/row-store.ts +0 -105
  402. package/src/backend/signal-setup.ts +0 -112
  403. package/src/backend/sim-unlock.ts +0 -193
  404. package/src/backend/transition-preconditions.ts +0 -149
  405. package/src/backend/usage/accounting.test.ts +0 -147
  406. package/src/backend/usage/accounting.ts +0 -123
  407. package/src/backend/usage/billing-cycle.test.ts +0 -62
  408. package/src/backend/usage/billing-cycle.ts +0 -45
  409. package/src/backend/usage/index.ts +0 -37
  410. package/src/backend/usage/proc-net-dev.test.ts +0 -56
  411. package/src/backend/usage/sampler.test.ts +0 -219
  412. package/src/backend/usage/sampler.ts +0 -228
  413. package/src/backend/usage/store.test.ts +0 -148
  414. package/src/backend/usage/store.ts +0 -177
  415. package/src/backend/usb-enumerator.test.ts +0 -87
  416. package/src/backend/usb-enumerator.ts +0 -181
  417. package/src/backend/usb-mode-transition.test.ts +0 -323
  418. package/src/backend/usb-mode-transition.ts +0 -253
  419. package/src/domain/brand.ts +0 -29
  420. package/src/domain/errors.ts +0 -77
  421. package/src/domain/guards.test.ts +0 -218
  422. package/src/domain/guards.ts +0 -144
  423. package/src/domain/identity.test.ts +0 -83
  424. package/src/domain/identity.ts +0 -165
  425. package/src/domain/index.ts +0 -12
  426. package/src/domain/snapshot.test.ts +0 -266
  427. package/src/domain/snapshot.ts +0 -120
  428. package/src/index.test.ts +0 -6
  429. package/src/index.ts +0 -15
  430. package/src/ports/README.md +0 -61
  431. package/src/ports/forbidden-surface.test.ts +0 -241
  432. package/src/ports/modem-manager.ts +0 -72
  433. package/src/ports/network-manager.ts +0 -87
  434. package/src/ports/ops.ts +0 -60
  435. package/src/ports/ops.type-test.ts +0 -39
  436. package/src/ports/receipts.test.ts +0 -153
  437. package/src/ports/reconcile.test.ts +0 -152
  438. package/src/ports/reconcile.ts +0 -338
  439. package/src/ports/router.ts +0 -29
  440. package/src/redact.test.ts +0 -82
  441. package/src/redact.ts +0 -73
  442. package/src/transport/README.md +0 -65
  443. package/src/transport/calls.ts +0 -113
  444. package/src/transport/characterization.test.ts +0 -260
  445. package/src/transport/codec.test.ts +0 -118
  446. package/src/transport/codec.ts +0 -240
  447. package/src/transport/conformance-python.test.ts +0 -152
  448. package/src/transport/conformance-same-lib.test.ts +0 -115
  449. package/src/transport/dbus-native-lib.d.ts +0 -19
  450. package/src/transport/dbus-native.ts +0 -85
  451. package/src/transport/index.ts +0 -30
  452. package/src/transport/no-library-leak.test.ts +0 -61
  453. package/src/transport/reliability.test.ts +0 -173
  454. package/src/transport/signals.ts +0 -150
  455. package/src/transport/signature.ts +0 -110
  456. package/src/transport/test-support/fake-service.ts +0 -168
  457. package/src/transport/test-support/independent-producer.py +0 -110
  458. package/src/transport/test-support/private-bus.ts +0 -66
  459. package/src/transport/transport.ts +0 -250
  460. package/src/transport/types.ts +0 -118
  461. package/src/usb-mode/catalog-schema.test.ts +0 -181
  462. package/src/usb-mode/catalog-schema.ts +0 -113
  463. package/src/usb-mode/certified-catalog.json +0 -67
  464. package/src/usb-mode/index.ts +0 -27
@@ -1,147 +0,0 @@
1
- // The adversarial accounting matrix — pure, deterministic proofs that per-slot usage
2
- // is attributed correctly across remaps, swaps, reuse, resets, pauses, and rollovers.
3
-
4
- import { describe, expect, test } from 'bun:test';
5
- import { type IdentityConfidence, logicalSlotId } from '../../domain';
6
- import { applySample, type BaselineKey, type SlotAccount } from './accounting';
7
-
8
- const SLOT_A = logicalSlotId('slot-a');
9
- const SLOT_B = logicalSlotId('slot-b');
10
- const SLOT_C = logicalSlotId('slot-c');
11
- const BOOT = 'boot-uuid-1';
12
-
13
- interface Step {
14
- readonly slot: string;
15
- readonly gen: number;
16
- readonly ifname: string;
17
- readonly current: number;
18
- readonly confidence?: IdentityConfidence;
19
- readonly cycleStartMs?: number;
20
- }
21
-
22
- function key(slot: string, gen: number, ifname: string): BaselineKey {
23
- return { logicalSlotId: slot, mappingGeneration: gen, ifname, bootId: BOOT };
24
- }
25
-
26
- function step(prior: SlotAccount | undefined, s: Step): SlotAccount {
27
- return applySample(prior, {
28
- key: key(s.slot, s.gen, s.ifname),
29
- current: s.current,
30
- confidence: s.confidence ?? 'high',
31
- cycleStartMs: s.cycleStartMs ?? 1000,
32
- });
33
- }
34
-
35
- describe('applySample — two modems tracked independently', () => {
36
- test('separate slots never cross-contaminate', () => {
37
- let a = step(undefined, { slot: SLOT_A, gen: 0, ifname: 'wwan0', current: 100 });
38
- let b = step(undefined, { slot: SLOT_B, gen: 0, ifname: 'wwan1', current: 5000 });
39
- a = step(a, { slot: SLOT_A, gen: 0, ifname: 'wwan0', current: 300 });
40
- b = step(b, { slot: SLOT_B, gen: 0, ifname: 'wwan1', current: 5001 });
41
- expect(a.cycleBytes).toBe(200);
42
- expect(b.cycleBytes).toBe(1);
43
- });
44
- });
45
-
46
- describe('applySample — A/B ifname swap follows the slot, not the interface', () => {
47
- test('each slot keeps its own total across a swap and re-baselines zero-delta', () => {
48
- // Prime: A on wwan0, B on wwan1.
49
- let a = step(undefined, { slot: SLOT_A, gen: 0, ifname: 'wwan0', current: 100 });
50
- let b = step(undefined, { slot: SLOT_B, gen: 0, ifname: 'wwan1', current: 1000 });
51
- a = step(a, { slot: SLOT_A, gen: 0, ifname: 'wwan0', current: 200 });
52
- b = step(b, { slot: SLOT_B, gen: 0, ifname: 'wwan1', current: 1100 });
53
- expect(a.cycleBytes).toBe(100);
54
- expect(b.cycleBytes).toBe(100);
55
-
56
- // Swap: A now maps to wwan1, B to wwan0 (mapping generation bumps for both).
57
- // First post-swap sample must be zero-delta despite the large counter change.
58
- a = step(a, { slot: SLOT_A, gen: 1, ifname: 'wwan1', current: 1100 });
59
- b = step(b, { slot: SLOT_B, gen: 1, ifname: 'wwan0', current: 200 });
60
- expect(a.cycleBytes).toBe(100);
61
- expect(b.cycleBytes).toBe(100);
62
-
63
- // Subsequent growth attributes to the correct slot on its new interface.
64
- a = step(a, { slot: SLOT_A, gen: 1, ifname: 'wwan1', current: 1150 });
65
- b = step(b, { slot: SLOT_B, gen: 1, ifname: 'wwan0', current: 260 });
66
- expect(a.cycleBytes).toBe(150);
67
- expect(b.cycleBytes).toBe(160);
68
- });
69
- });
70
-
71
- describe('applySample — old ifname reused by a different slot (no bleed)', () => {
72
- test('a new slot inheriting an old interface starts from zero', () => {
73
- let a = step(undefined, { slot: SLOT_A, gen: 0, ifname: 'wwan0', current: 100 });
74
- a = step(a, { slot: SLOT_A, gen: 0, ifname: 'wwan0', current: 500 });
75
- expect(a.cycleBytes).toBe(400);
76
-
77
- // Slot C now occupies wwan0. Its own account starts fresh (zero-delta baseline).
78
- let c = step(undefined, { slot: SLOT_C, gen: 0, ifname: 'wwan0', current: 500 });
79
- c = step(c, { slot: SLOT_C, gen: 0, ifname: 'wwan0', current: 700 });
80
- expect(c.cycleBytes).toBe(200);
81
- // A's total is untouched — no bleed either direction.
82
- expect(a.cycleBytes).toBe(400);
83
- });
84
- });
85
-
86
- describe('applySample — rename-first-sample is zero-delta', () => {
87
- test('the first sample after a remap never reports a spurious jump', () => {
88
- let s = step(undefined, { slot: SLOT_A, gen: 0, ifname: 'wwan0', current: 100 });
89
- s = step(s, { slot: SLOT_A, gen: 0, ifname: 'wwan0', current: 200 });
90
- expect(s.cycleBytes).toBe(100);
91
- // Rename wwan0 → wwan5 with a huge counter: must NOT attribute 9M.
92
- s = step(s, { slot: SLOT_A, gen: 1, ifname: 'wwan5', current: 9_000_000 });
93
- expect(s.cycleBytes).toBe(100);
94
- });
95
- });
96
-
97
- describe('applySample — reset-then-positive', () => {
98
- test('a counter reset clamps to zero, then normal increases resume', () => {
99
- let s = step(undefined, { slot: SLOT_A, gen: 0, ifname: 'wwan0', current: 1000 });
100
- s = step(s, { slot: SLOT_A, gen: 0, ifname: 'wwan0', current: 1500 });
101
- expect(s.cycleBytes).toBe(500);
102
- // Interface recreated: counter drops to 50 (decrease) → clamp + rebase.
103
- s = step(s, { slot: SLOT_A, gen: 0, ifname: 'wwan0', current: 50 });
104
- expect(s.cycleBytes).toBe(500);
105
- // Growth from the rebased baseline is tracked again.
106
- s = step(s, { slot: SLOT_A, gen: 0, ifname: 'wwan0', current: 250 });
107
- expect(s.cycleBytes).toBe(700);
108
- });
109
-
110
- test('a decrease never produces a negative delta', () => {
111
- let s = step(undefined, { slot: SLOT_A, gen: 0, ifname: 'wwan0', current: 800 });
112
- s = step(s, { slot: SLOT_A, gen: 0, ifname: 'wwan0', current: 300 });
113
- expect(s.cycleBytes).toBe(0);
114
- expect(s.cycleBytes).toBeGreaterThanOrEqual(0);
115
- });
116
- });
117
-
118
- describe('applySample — ambiguous identity pauses sampling', () => {
119
- test('low confidence attributes nothing and re-baselines zero-delta on resume', () => {
120
- let s = step(undefined, { slot: SLOT_A, gen: 0, ifname: 'wwan0', current: 100 });
121
- s = step(s, { slot: SLOT_A, gen: 0, ifname: 'wwan0', current: 300 });
122
- expect(s.cycleBytes).toBe(200);
123
- // Identity turns ambiguous → paused; the counter keeps climbing unattributed.
124
- s = step(s, { slot: SLOT_A, gen: 0, ifname: 'wwan0', current: 9999, confidence: 'low' });
125
- expect(s.paused).toBe(true);
126
- expect(s.cycleBytes).toBe(200);
127
- // Confidence returns: resume is zero-delta, so the paused-window bytes are NOT
128
- // back-attributed; only growth after resume counts.
129
- s = step(s, { slot: SLOT_A, gen: 0, ifname: 'wwan0', current: 9999 });
130
- expect(s.paused).toBe(false);
131
- expect(s.cycleBytes).toBe(200);
132
- s = step(s, { slot: SLOT_A, gen: 0, ifname: 'wwan0', current: 10_099 });
133
- expect(s.cycleBytes).toBe(300);
134
- });
135
- });
136
-
137
- describe('applySample — cycle rollover resets the per-cycle total', () => {
138
- test('crossing into a newer cycle zeroes cycleBytes but keeps the baseline', () => {
139
- let s = step(undefined, { slot: SLOT_A, gen: 0, ifname: 'wwan0', current: 100 });
140
- s = step(s, { slot: SLOT_A, gen: 0, ifname: 'wwan0', current: 600 });
141
- expect(s.cycleBytes).toBe(500);
142
- // New cycle boundary — cycleBytes resets, counter continuity preserved.
143
- s = step(s, { slot: SLOT_A, gen: 0, ifname: 'wwan0', current: 650, cycleStartMs: 2000 });
144
- expect(s.cycleStartMs).toBe(2000);
145
- expect(s.cycleBytes).toBe(50);
146
- });
147
- });
@@ -1,123 +0,0 @@
1
- // The pure usage-accounting reducer — the heart of the sampler.
2
- //
3
- // For each logical slot we keep a per-cycle byte total plus a BASELINE: the last
4
- // observed cumulative counter value under a specific key. The key is the composite
5
- // `{logicalSlotId, mappingGeneration, ifname, bootId}`. The rules, all encoded here
6
- // with zero I/O so they can be exhaustively unit-tested:
7
- //
8
- // - REMAP (any key field changes — e.g. the ifname-to-slot mapping bumped
9
- // `mappingGeneration`, or a reboot changed `bootId`): rebaseline with a
10
- // ZERO-DELTA sample. We start counting fresh from the current cumulative value
11
- // and attribute nothing for that first sample — never a spurious jump.
12
- // - SAME-KEY DECREASE (the cumulative counter went DOWN — interface re-created /
13
- // counter reset without a reported remap): CLAMP the negative delta to zero and
14
- // REBASE the baseline to the new lower value. Never report negative usage.
15
- // - LOW CONFIDENCE (ambiguous identity, A3.2 ladder): sampling is PAUSED. We drop
16
- // the baseline and attribute nothing; on resume the next sample is zero-delta so
17
- // bytes moved during the ambiguous window are never mis-attributed.
18
- // - CYCLE ROLLOVER (`now` crossed into a new billing cycle): the per-cycle total
19
- // resets to zero. The baseline is kept — the kernel counter is continuous across
20
- // a billing boundary; only OUR accounting window resets.
21
-
22
- import type { IdentityConfidence, LogicalSlotId } from '../../domain';
23
-
24
- /** The composite baseline key. A change in ANY field is a remap (zero-delta rebase). */
25
- export interface BaselineKey {
26
- readonly logicalSlotId: string;
27
- readonly mappingGeneration: number;
28
- readonly ifname: string;
29
- readonly bootId: string;
30
- }
31
-
32
- /** Per-slot accounting state. `key`/`lastObserved` are unset before the first sample. */
33
- export interface SlotAccount {
34
- /** Bytes attributed to this slot within the current cycle. */
35
- readonly cycleBytes: number;
36
- /** UTC start of the cycle `cycleBytes` is accruing into. */
37
- readonly cycleStartMs: number;
38
- /** True when the last observation was low-confidence and sampling is paused. */
39
- readonly paused: boolean;
40
- /** The key the baseline was captured under (undefined = no baseline yet). */
41
- readonly key?: BaselineKey;
42
- /** The cumulative counter value at the last accepted sample. */
43
- readonly lastObserved?: number;
44
- }
45
-
46
- /** One observation fed to the reducer for a single slot in one sampling pass. */
47
- export interface SampleInput {
48
- readonly key: BaselineKey;
49
- /** The current cumulative rx+tx counter for the slot's interface. */
50
- readonly current: number;
51
- readonly confidence: IdentityConfidence;
52
- /** The UTC start of the slot's active cycle (from `cycleStart`). */
53
- readonly cycleStartMs: number;
54
- }
55
-
56
- /** A fresh account for a slot first seen in `cycleStartMs`. */
57
- export function initialAccount(cycleStartMs: number): SlotAccount {
58
- return { cycleBytes: 0, cycleStartMs, paused: false };
59
- }
60
-
61
- function sameKey(a: BaselineKey, b: BaselineKey): boolean {
62
- return (
63
- a.logicalSlotId === b.logicalSlotId &&
64
- a.mappingGeneration === b.mappingGeneration &&
65
- a.ifname === b.ifname &&
66
- a.bootId === b.bootId
67
- );
68
- }
69
-
70
- /** Apply a cycle rollover: if we crossed into a newer cycle, zero the per-cycle total. */
71
- function rollCycle(account: SlotAccount, cycleStartMs: number): SlotAccount {
72
- if (cycleStartMs > account.cycleStartMs) {
73
- return { ...account, cycleBytes: 0, cycleStartMs };
74
- }
75
- return account;
76
- }
77
-
78
- /**
79
- * Fold one observation into a slot's account, returning the NEXT account. Pure —
80
- * no clock, no I/O; the caller supplies `current`, `confidence` and `cycleStartMs`.
81
- */
82
- export function applySample(prior: SlotAccount | undefined, input: SampleInput): SlotAccount {
83
- const base = rollCycle(prior ?? initialAccount(input.cycleStartMs), input.cycleStartMs);
84
-
85
- // Ambiguous identity → pause: attribute nothing and drop the baseline so the
86
- // next confident sample re-baselines zero-delta (no back-attribution).
87
- if (input.confidence === 'low') {
88
- return { cycleBytes: base.cycleBytes, cycleStartMs: base.cycleStartMs, paused: true };
89
- }
90
-
91
- // Remap, first-ever sample, or resuming from a pause → zero-delta rebaseline.
92
- if (base.paused || base.key === undefined || base.lastObserved === undefined) {
93
- return { ...base, paused: false, key: input.key, lastObserved: input.current };
94
- }
95
- if (!sameKey(base.key, input.key)) {
96
- return { ...base, paused: false, key: input.key, lastObserved: input.current };
97
- }
98
-
99
- // Same key: a decrease is a counter reset → clamp the negative delta and rebase.
100
- if (input.current < base.lastObserved) {
101
- return { ...base, paused: false, key: input.key, lastObserved: input.current };
102
- }
103
-
104
- // Normal case: attribute the non-negative delta and advance the baseline.
105
- const delta = input.current - base.lastObserved;
106
- return {
107
- ...base,
108
- paused: false,
109
- key: input.key,
110
- lastObserved: input.current,
111
- cycleBytes: base.cycleBytes + delta,
112
- };
113
- }
114
-
115
- /** Convenience constructor for a `BaselineKey` from its parts. */
116
- export function baselineKey(
117
- logicalSlotId: LogicalSlotId,
118
- mappingGeneration: number,
119
- ifname: string,
120
- bootId: string,
121
- ): BaselineKey {
122
- return { logicalSlotId, mappingGeneration, ifname, bootId };
123
- }
@@ -1,62 +0,0 @@
1
- // UTC billing-cycle math — month-length clamping (cycleDay 31 → Feb 28/29) and the
2
- // before/after-boundary cycle-start selection.
3
-
4
- import { describe, expect, test } from 'bun:test';
5
- import { type EpochMillis, epochMillis } from '../../domain';
6
- import { clampCycleDay, cycleStart, daysInMonth } from './billing-cycle';
7
-
8
- const utc = (y: number, m: number, d: number, h = 0): EpochMillis =>
9
- epochMillis(Date.UTC(y, m, d, h));
10
-
11
- describe('daysInMonth', () => {
12
- test('February is 28 days in a common year, 29 in a leap year', () => {
13
- expect(daysInMonth(2023, 1)).toBe(28);
14
- expect(daysInMonth(2024, 1)).toBe(29); // 2024 is a leap year
15
- expect(daysInMonth(2100, 1)).toBe(28); // century non-leap
16
- expect(daysInMonth(2000, 1)).toBe(29); // 400-divisible leap
17
- });
18
-
19
- test('30- and 31-day months', () => {
20
- expect(daysInMonth(2024, 3)).toBe(30); // April
21
- expect(daysInMonth(2024, 0)).toBe(31); // January
22
- });
23
- });
24
-
25
- describe('clampCycleDay', () => {
26
- test('cycleDay 31 clamps to the last day of a short month', () => {
27
- expect(clampCycleDay(31, 2023, 1)).toBe(28); // Feb non-leap
28
- expect(clampCycleDay(31, 2024, 1)).toBe(29); // Feb leap
29
- expect(clampCycleDay(31, 2024, 3)).toBe(30); // April
30
- expect(clampCycleDay(31, 2024, 0)).toBe(31); // January — no clamp
31
- });
32
-
33
- test('a valid in-range day is unchanged; a floor of 1 is enforced', () => {
34
- expect(clampCycleDay(15, 2024, 5)).toBe(15);
35
- expect(clampCycleDay(0, 2024, 5)).toBe(1);
36
- });
37
- });
38
-
39
- describe('cycleStart — month-length clamp with before/after selection', () => {
40
- test('cycleDay 31 in February resolves to the clamped Feb boundary', () => {
41
- // 2023-02-15 with cycleDay 31 → cycle started 2023-01-31 (Feb boundary Feb 28
42
- // is still ahead of the 15th).
43
- expect(cycleStart(epochMillis(utc(2023, 1, 15)), 31)).toBe(utc(2023, 0, 31));
44
- // 2023-03-01 with cycleDay 31 → the active cycle began at clamped Feb 28.
45
- expect(cycleStart(epochMillis(utc(2023, 2, 1)), 31)).toBe(utc(2023, 1, 28));
46
- // Leap year: 2024-03-01 → Feb 29.
47
- expect(cycleStart(epochMillis(utc(2024, 2, 1)), 31)).toBe(utc(2024, 1, 29));
48
- });
49
-
50
- test('now exactly on the boundary starts a new cycle', () => {
51
- expect(cycleStart(epochMillis(utc(2024, 5, 10)), 10)).toBe(utc(2024, 5, 10));
52
- });
53
-
54
- test('now before this month boundary rolls back to the previous month', () => {
55
- // cycleDay 20, now is the 5th → cycle began on the 20th of the prior month.
56
- expect(cycleStart(epochMillis(utc(2024, 6, 5)), 20)).toBe(utc(2024, 5, 20));
57
- });
58
-
59
- test('January rollback wraps to December of the prior year', () => {
60
- expect(cycleStart(epochMillis(utc(2024, 0, 5)), 20)).toBe(utc(2023, 11, 20));
61
- });
62
- });
@@ -1,45 +0,0 @@
1
- // UTC billing-cycle computation with month-length clamping.
2
- //
3
- // A usage cycle resets on a configured day of the month (`cycleDay`, 1–31) in UTC.
4
- // Months are not all the same length, so a `cycleDay` past the end of a short month
5
- // must clamp to that month's LAST day rather than rolling into the next month or
6
- // throwing: `cycleDay: 31` resolves to Feb 28 (or Feb 29 in a leap year), Apr 30,
7
- // etc. All arithmetic is UTC — the device clock's local zone never shifts a cycle.
8
-
9
- import type { EpochMillis } from '../../domain';
10
-
11
- /** Days in a given UTC month. `month` is 0-based (0 = January). Handles leap Feb. */
12
- export function daysInMonth(year: number, month: number): number {
13
- // Day 0 of the next month is the last day of this month; UTC avoids DST drift.
14
- return new Date(Date.UTC(year, month + 1, 0)).getUTCDate();
15
- }
16
-
17
- /** Clamp a requested cycle day to the last valid day of the given month. */
18
- export function clampCycleDay(cycleDay: number, year: number, month: number): number {
19
- const floor = Math.max(1, Math.trunc(cycleDay));
20
- return Math.min(floor, daysInMonth(year, month));
21
- }
22
-
23
- /** The UTC epoch-ms of the cycle boundary in a specific month (clamped). */
24
- function boundaryFor(cycleDay: number, year: number, month: number): number {
25
- return Date.UTC(year, month, clampCycleDay(cycleDay, year, month));
26
- }
27
-
28
- /**
29
- * The UTC start (`EpochMillis`) of the cycle that `now` falls in for a given
30
- * `cycleDay`. If `now` is before this month's (clamped) boundary the active cycle
31
- * began on the previous month's boundary; otherwise it began on this month's.
32
- */
33
- export function cycleStart(now: EpochMillis, cycleDay: number): EpochMillis {
34
- const at = new Date(now);
35
- const year = at.getUTCFullYear();
36
- const month = at.getUTCMonth();
37
- const thisBoundary = boundaryFor(cycleDay, year, month);
38
- if (now >= thisBoundary) {
39
- return thisBoundary as EpochMillis;
40
- }
41
- // Roll back one month (December wraps to the prior year), re-clamping there.
42
- const prevMonth = month === 0 ? 11 : month - 1;
43
- const prevYear = month === 0 ? year - 1 : year;
44
- return boundaryFor(cycleDay, prevYear, prevMonth) as EpochMillis;
45
- }
@@ -1,37 +0,0 @@
1
- // Data-usage sampler — internal all-interface sampler over `/proc/net/dev`
2
- // CUMULATIVE counters (A4.3). Public surface consumed by the A6.1 bench CLI `usage`
3
- // command (via `UsageSnapshot`) and the composition root that wires the sampler.
4
-
5
- export {
6
- applySample,
7
- type BaselineKey,
8
- baselineKey,
9
- initialAccount,
10
- type SampleInput,
11
- type SlotAccount,
12
- } from './accounting';
13
- export { clampCycleDay, cycleStart, daysInMonth } from './billing-cycle';
14
- export { readBootId } from './boot-id';
15
- export {
16
- type CounterSource,
17
- parseProcNetDev,
18
- procNetDevCounterSource,
19
- } from './proc-net-dev';
20
- export {
21
- createUsageSampler,
22
- type SlotUsageSnapshot,
23
- type UsageObservation,
24
- UsageSampler,
25
- type UsageSamplerOptions,
26
- type UsageSnapshot,
27
- } from './sampler';
28
- export {
29
- createUsageFileStore,
30
- type PersistedSlot,
31
- type PersistedUsage,
32
- USAGE_SCHEMA_VERSION,
33
- type UsageFileStoreOptions,
34
- type UsageLogEvent,
35
- type UsageLogger,
36
- type UsageStore,
37
- } from './store';
@@ -1,56 +0,0 @@
1
- // `/proc/net/dev` parser — proves rx+tx cumulative totals over the real fixed-column
2
- // format, header skipping, and fail-soft handling of malformed rows.
3
-
4
- import { describe, expect, test } from 'bun:test';
5
- import { parseProcNetDev } from './proc-net-dev';
6
-
7
- // A real capture (columns: rx bytes packets errs drop fifo frame compressed multicast
8
- // | tx bytes packets errs drop fifo colls carrier compressed).
9
- const REAL = `Inter-| Receive | Transmit
10
- face |bytes packets errs drop fifo frame compressed multicast|bytes packets errs drop fifo colls carrier compressed
11
- lo: 160183007830 18519510 0 0 0 0 0 0 160183007830 18519510 0 0 0 0 0 0
12
- eno2: 88166142004 86575608 0 0 48 0 0 146660 25843393633 48414413 0 3 0 0 0 0
13
- wlan0: 44865976 194892 0 0 0 0 0 0 5698312 36057 0 23 0 0 0 0
14
- `;
15
-
16
- describe('parseProcNetDev', () => {
17
- test('reads rx+tx cumulative bytes for each interface, skipping the 2-line header', () => {
18
- const counters = parseProcNetDev(REAL);
19
- expect(counters.size).toBe(3);
20
- // lo: 160183007830 (rx) + 160183007830 (tx).
21
- expect(counters.get('lo')).toBe(160183007830 + 160183007830);
22
- // eno2: rx 88166142004 + tx 25843393633.
23
- expect(counters.get('eno2')).toBe(88166142004 + 25843393633);
24
- // wlan0: rx 44865976 + tx 5698312.
25
- expect(counters.get('wlan0')).toBe(44865976 + 5698312);
26
- });
27
-
28
- test('handles bridge-style names with no leading space and long names', () => {
29
- const text = `h1
30
- h2
31
- br-d739ee545df1: 575402021 542380 0 0 0 0 0 0 450821722 810015 0 4 0 0 0 0
32
- docker0: 1750867165 1097738 0 0 0 0 0 0 5810268898 1237921 0 12223 0 0 0 0
33
- `;
34
- const counters = parseProcNetDev(text);
35
- expect(counters.get('br-d739ee545df1')).toBe(575402021 + 450821722);
36
- expect(counters.get('docker0')).toBe(1750867165 + 5810268898);
37
- });
38
-
39
- test('ignores malformed / short rows without throwing', () => {
40
- const text = `h1
41
- h2
42
- lo: 100 1 0 0 0 0 0 0 200 2 0 0 0 0 0 0
43
- garbage-without-colon 1 2 3
44
- short: 1 2 3
45
- nan: x 1 0 0 0 0 0 0 y 2 0 0 0 0 0 0
46
- `;
47
- const counters = parseProcNetDev(text);
48
- // Only the well-formed `lo` row survives.
49
- expect(counters.size).toBe(1);
50
- expect(counters.get('lo')).toBe(300);
51
- });
52
-
53
- test('empty input yields an empty map', () => {
54
- expect(parseProcNetDev('').size).toBe(0);
55
- });
56
- });