@ceralive/modem-control 1.0.0 → 1.2.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 (480) hide show
  1. package/README.md +341 -0
  2. package/dist/backend/at-lease.d.ts +59 -0
  3. package/dist/backend/at-lease.js +118 -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 +101 -0
  61. package/dist/backend/transition-preconditions.js +132 -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 +216 -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 +20 -0
  146. package/dist/index.js +27 -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 +61 -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/operation-ids.d.ts +2 -0
  196. package/dist/operation-ids.js +26 -0
  197. package/dist/operations/contracts.d.ts +72 -0
  198. package/dist/operations/contracts.js +1 -0
  199. package/dist/operations/index.d.ts +1 -0
  200. package/dist/operations/index.js +1 -0
  201. package/dist/operations/operation-engine.d.ts +16 -0
  202. package/dist/operations/operation-engine.js +194 -0
  203. package/dist/ports/index.d.ts +12 -0
  204. package/{src/ports/index.ts → dist/ports/index.js} +12 -8
  205. package/dist/ports/location.d.ts +87 -0
  206. package/dist/ports/location.js +36 -0
  207. package/dist/ports/modem-manager.d.ts +89 -0
  208. package/dist/ports/modem-manager.js +9 -0
  209. package/dist/ports/mutation-admission.d.ts +27 -0
  210. package/dist/ports/mutation-admission.js +9 -0
  211. package/dist/ports/network-manager.d.ts +68 -0
  212. package/dist/ports/network-manager.js +13 -0
  213. package/{src/ports/observation.ts → dist/ports/observation.d.ts} +16 -27
  214. package/dist/ports/observation.js +7 -0
  215. package/dist/ports/ops.d.ts +44 -0
  216. package/dist/ports/ops.js +16 -0
  217. package/{src/ports/receipts.ts → dist/ports/receipts.d.ts} +5 -27
  218. package/dist/ports/receipts.js +9 -0
  219. package/dist/ports/reconcile.d.ts +33 -0
  220. package/dist/ports/reconcile.js +200 -0
  221. package/dist/ports/resource-ownership.d.ts +29 -0
  222. package/dist/ports/resource-ownership.js +1 -0
  223. package/dist/ports/router.d.ts +19 -0
  224. package/dist/ports/router.js +7 -0
  225. package/dist/ports/sms.d.ts +64 -0
  226. package/dist/ports/sms.js +24 -0
  227. package/dist/ports/uhubctl.d.ts +6 -0
  228. package/dist/ports/uhubctl.js +1 -0
  229. package/dist/providers/contracts.d.ts +124 -0
  230. package/dist/providers/contracts.js +10 -0
  231. package/dist/providers/huawei-hilink/index.d.ts +2 -0
  232. package/dist/providers/huawei-hilink/index.js +2 -0
  233. package/dist/providers/huawei-hilink/operations.d.ts +20 -0
  234. package/dist/providers/huawei-hilink/operations.js +56 -0
  235. package/dist/providers/huawei-hilink/provider.d.ts +52 -0
  236. package/dist/providers/huawei-hilink/provider.js +76 -0
  237. package/dist/providers/huawei-hilink/runtime.d.ts +22 -0
  238. package/dist/providers/huawei-hilink/runtime.js +171 -0
  239. package/dist/providers/huawei-hilink/session.d.ts +28 -0
  240. package/dist/providers/huawei-hilink/session.js +120 -0
  241. package/dist/providers/huawei-hilink/transport.d.ts +19 -0
  242. package/dist/providers/huawei-hilink/transport.js +1 -0
  243. package/dist/providers/index.d.ts +8 -0
  244. package/dist/providers/index.js +8 -0
  245. package/dist/providers/matcher.d.ts +3 -0
  246. package/dist/providers/matcher.js +205 -0
  247. package/dist/providers/modem-manager/errors.d.ts +7 -0
  248. package/dist/providers/modem-manager/errors.js +37 -0
  249. package/dist/providers/modem-manager/generic-operations.d.ts +10 -0
  250. package/dist/providers/modem-manager/generic-operations.js +209 -0
  251. package/dist/providers/modem-manager/index.d.ts +4 -0
  252. package/dist/providers/modem-manager/index.js +4 -0
  253. package/dist/providers/modem-manager/module-operations.d.ts +21 -0
  254. package/dist/providers/modem-manager/module-operations.js +118 -0
  255. package/dist/providers/modem-manager/provider.d.ts +41 -0
  256. package/dist/providers/modem-manager/provider.js +155 -0
  257. package/dist/providers/modem-manager/runtime-composition-operation.d.ts +32 -0
  258. package/dist/providers/modem-manager/runtime-composition-operation.js +151 -0
  259. package/dist/providers/modem-manager/snapshot.d.ts +5 -0
  260. package/dist/providers/modem-manager/snapshot.js +204 -0
  261. package/dist/providers/modem-manager/types.d.ts +137 -0
  262. package/dist/providers/modem-manager/types.js +1 -0
  263. package/dist/providers/network-manager/adapter.d.ts +71 -0
  264. package/dist/providers/network-manager/adapter.js +348 -0
  265. package/dist/providers/network-manager/index.d.ts +2 -0
  266. package/dist/providers/network-manager/index.js +2 -0
  267. package/dist/providers/network-manager/types.d.ts +171 -0
  268. package/dist/providers/network-manager/types.js +77 -0
  269. package/dist/providers/registry.d.ts +13 -0
  270. package/dist/providers/registry.js +33 -0
  271. package/dist/providers/ufi-himi/index.d.ts +6 -0
  272. package/dist/providers/ufi-himi/index.js +6 -0
  273. package/dist/providers/ufi-himi/operations.d.ts +41 -0
  274. package/dist/providers/ufi-himi/operations.js +66 -0
  275. package/dist/providers/ufi-himi/prohibitions.d.ts +62 -0
  276. package/dist/providers/ufi-himi/prohibitions.js +88 -0
  277. package/dist/providers/ufi-himi/provider.d.ts +41 -0
  278. package/dist/providers/ufi-himi/provider.js +204 -0
  279. package/dist/providers/ufi-himi/qualcomm-evidence.d.ts +32 -0
  280. package/dist/providers/ufi-himi/qualcomm-evidence.js +51 -0
  281. package/dist/providers/ufi-himi/session.d.ts +46 -0
  282. package/dist/providers/ufi-himi/session.js +92 -0
  283. package/dist/providers/ufi-himi/transport.d.ts +29 -0
  284. package/dist/providers/ufi-himi/transport.js +25 -0
  285. package/dist/providers/zte-goform/index.d.ts +2 -0
  286. package/dist/providers/zte-goform/index.js +2 -0
  287. package/dist/providers/zte-goform/provider.d.ts +56 -0
  288. package/dist/providers/zte-goform/provider.js +101 -0
  289. package/dist/providers/zte-goform/session.d.ts +23 -0
  290. package/dist/providers/zte-goform/session.js +197 -0
  291. package/dist/providers/zte-goform/transport.d.ts +16 -0
  292. package/dist/providers/zte-goform/transport.js +1 -0
  293. package/dist/radio/band-truth.d.ts +50 -0
  294. package/dist/radio/band-truth.js +92 -0
  295. package/dist/radio/index.d.ts +3 -0
  296. package/dist/radio/index.js +10 -0
  297. package/dist/radio/mode-combinations.d.ts +88 -0
  298. package/dist/radio/mode-combinations.js +198 -0
  299. package/dist/radio/mode-truth.d.ts +67 -0
  300. package/dist/radio/mode-truth.js +112 -0
  301. package/dist/redact.d.ts +15 -0
  302. package/dist/redact.js +189 -0
  303. package/dist/safety/composition-root.d.ts +28 -0
  304. package/dist/safety/composition-root.js +65 -0
  305. package/dist/safety/flock-resource-ownership.d.ts +11 -0
  306. package/dist/safety/flock-resource-ownership.js +138 -0
  307. package/dist/safety/index.d.ts +2 -0
  308. package/dist/safety/index.js +2 -0
  309. package/dist/sms/dbus-messaging.d.ts +17 -0
  310. package/dist/sms/dbus-messaging.js +185 -0
  311. package/dist/sms/inbox-store.d.ts +10 -0
  312. package/dist/sms/inbox-store.js +82 -0
  313. package/dist/sms/index.d.ts +4 -0
  314. package/dist/sms/index.js +10 -0
  315. package/dist/sms/mmcli-parse.d.ts +54 -0
  316. package/dist/sms/mmcli-parse.js +224 -0
  317. package/dist/sms/normalize.d.ts +42 -0
  318. package/dist/sms/normalize.js +95 -0
  319. package/dist/testing/domain-fakes.d.ts +58 -0
  320. package/dist/testing/domain-fakes.js +98 -0
  321. package/dist/testing/index.d.ts +2 -0
  322. package/dist/testing/index.js +17 -0
  323. package/dist/testing/provider-fakes.d.ts +45 -0
  324. package/dist/testing/provider-fakes.js +64 -0
  325. package/dist/transport/calls.d.ts +9 -0
  326. package/dist/transport/calls.js +88 -0
  327. package/dist/transport/codec.d.ts +3 -0
  328. package/dist/transport/codec.js +207 -0
  329. package/dist/transport/dbus-native.d.ts +57 -0
  330. package/dist/transport/dbus-native.js +17 -0
  331. package/dist/transport/errors.d.ts +21 -0
  332. package/{src/transport/errors.ts → dist/transport/errors.js} +34 -46
  333. package/dist/transport/index.d.ts +4 -0
  334. package/dist/transport/index.js +9 -0
  335. package/dist/transport/signals.d.ts +15 -0
  336. package/dist/transport/signals.js +123 -0
  337. package/dist/transport/signature.d.ts +7 -0
  338. package/dist/transport/signature.js +94 -0
  339. package/dist/transport/transport.d.ts +2 -0
  340. package/dist/transport/transport.js +202 -0
  341. package/dist/transport/types.d.ts +61 -0
  342. package/dist/transport/types.js +19 -0
  343. package/dist/usb-mode/catalog-schema.d.ts +139 -0
  344. package/dist/usb-mode/catalog-schema.js +97 -0
  345. package/dist/usb-mode/catalog.d.ts +21 -0
  346. package/{src/usb-mode/catalog.ts → dist/usb-mode/catalog.js} +10 -32
  347. package/dist/usb-mode/certified-catalog.json +67 -0
  348. package/dist/usb-mode/index.d.ts +6 -0
  349. package/dist/usb-mode/index.js +16 -0
  350. package/dist/usb-mode/ingestion.d.ts +111 -0
  351. package/dist/usb-mode/ingestion.js +187 -0
  352. package/dist/usb-mode/promotion-review.d.ts +21 -0
  353. package/dist/usb-mode/promotion-review.js +87 -0
  354. package/dist/usb-mode/runtime-capability.d.ts +59 -0
  355. package/dist/usb-mode/runtime-capability.js +157 -0
  356. package/dist/usb-mode/usb-devices-parse.d.ts +36 -0
  357. package/dist/usb-mode/usb-devices-parse.js +157 -0
  358. package/dist/ussd/calls.d.ts +32 -0
  359. package/dist/ussd/calls.js +96 -0
  360. package/dist/ussd/index.d.ts +5 -0
  361. package/dist/ussd/index.js +12 -0
  362. package/dist/ussd/mm-ussd.d.ts +37 -0
  363. package/dist/ussd/mm-ussd.js +205 -0
  364. package/dist/ussd/refusal.d.ts +53 -0
  365. package/dist/ussd/refusal.js +154 -0
  366. package/dist/ussd/registration.d.ts +20 -0
  367. package/dist/ussd/registration.js +101 -0
  368. package/dist/ussd/session.d.ts +106 -0
  369. package/dist/ussd/session.js +163 -0
  370. package/package.json +38 -4
  371. package/src/backend/at-lease.test.ts +0 -106
  372. package/src/backend/at-lease.ts +0 -158
  373. package/src/backend/cell-info.test.ts +0 -154
  374. package/src/backend/cell-info.ts +0 -160
  375. package/src/backend/device-classifier.test.ts +0 -168
  376. package/src/backend/device-classifier.ts +0 -248
  377. package/src/backend/enrichment.ts +0 -96
  378. package/src/backend/features.test.ts +0 -162
  379. package/src/backend/features.ts +0 -179
  380. package/src/backend/identity-ladder.test.ts +0 -117
  381. package/src/backend/identity-ladder.ts +0 -221
  382. package/src/backend/identity-registry.test.ts +0 -89
  383. package/src/backend/identity-registry.ts +0 -151
  384. package/src/backend/index.ts +0 -236
  385. package/src/backend/lifecycle-interlock.ts +0 -38
  386. package/src/backend/managed-objects.ts +0 -108
  387. package/src/backend/mapping.ts +0 -160
  388. package/src/backend/mm-backend.ts +0 -191
  389. package/src/backend/mm-mutations.ts +0 -228
  390. package/src/backend/modem-actor.test.ts +0 -95
  391. package/src/backend/modem-actor.ts +0 -112
  392. package/src/backend/nm-auto-apn.ts +0 -161
  393. package/src/backend/nm-gsm-fields.ts +0 -122
  394. package/src/backend/nmcli-nm-port.ts +0 -228
  395. package/src/backend/nmcli-runner.ts +0 -52
  396. package/src/backend/observer.ts +0 -297
  397. package/src/backend/power-contract.test.ts +0 -40
  398. package/src/backend/power-contract.ts +0 -83
  399. package/src/backend/recovery-attribution.test.ts +0 -102
  400. package/src/backend/recovery-attribution.ts +0 -86
  401. package/src/backend/recovery-budget.test.ts +0 -64
  402. package/src/backend/recovery-budget.ts +0 -84
  403. package/src/backend/recovery-ladder.test.ts +0 -257
  404. package/src/backend/recovery-ladder.ts +0 -249
  405. package/src/backend/router-ethernet.test.ts +0 -71
  406. package/src/backend/router-ethernet.ts +0 -90
  407. package/src/backend/row-store.ts +0 -105
  408. package/src/backend/signal-setup.ts +0 -112
  409. package/src/backend/sim-unlock.ts +0 -193
  410. package/src/backend/transition-preconditions.ts +0 -149
  411. package/src/backend/uhubctl-power-hook.test.ts +0 -274
  412. package/src/backend/uhubctl-power-hook.ts +0 -377
  413. package/src/backend/usage/accounting.test.ts +0 -147
  414. package/src/backend/usage/accounting.ts +0 -123
  415. package/src/backend/usage/billing-cycle.test.ts +0 -62
  416. package/src/backend/usage/billing-cycle.ts +0 -45
  417. package/src/backend/usage/index.ts +0 -60
  418. package/src/backend/usage/policy-store.test.ts +0 -164
  419. package/src/backend/usage/policy-store.ts +0 -216
  420. package/src/backend/usage/policy-write.test.ts +0 -198
  421. package/src/backend/usage/policy-write.ts +0 -207
  422. package/src/backend/usage/proc-net-dev.test.ts +0 -56
  423. package/src/backend/usage/sampler.test.ts +0 -327
  424. package/src/backend/usage/sampler.ts +0 -282
  425. package/src/backend/usage/store.test.ts +0 -148
  426. package/src/backend/usage/store.ts +0 -177
  427. package/src/backend/usb-enumerator.test.ts +0 -87
  428. package/src/backend/usb-enumerator.ts +0 -181
  429. package/src/backend/usb-mode-transition.test.ts +0 -323
  430. package/src/backend/usb-mode-transition.ts +0 -253
  431. package/src/domain/brand.ts +0 -29
  432. package/src/domain/errors.ts +0 -77
  433. package/src/domain/guards.test.ts +0 -218
  434. package/src/domain/guards.ts +0 -144
  435. package/src/domain/identity.test.ts +0 -83
  436. package/src/domain/identity.ts +0 -165
  437. package/src/domain/index.ts +0 -12
  438. package/src/domain/snapshot.test.ts +0 -266
  439. package/src/domain/snapshot.ts +0 -120
  440. package/src/index.test.ts +0 -6
  441. package/src/index.ts +0 -15
  442. package/src/ports/README.md +0 -61
  443. package/src/ports/forbidden-surface.test.ts +0 -241
  444. package/src/ports/modem-manager.ts +0 -72
  445. package/src/ports/network-manager.ts +0 -87
  446. package/src/ports/ops.ts +0 -60
  447. package/src/ports/ops.type-test.ts +0 -39
  448. package/src/ports/receipts.test.ts +0 -153
  449. package/src/ports/reconcile.test.ts +0 -152
  450. package/src/ports/reconcile.ts +0 -338
  451. package/src/ports/router.ts +0 -29
  452. package/src/redact.test.ts +0 -82
  453. package/src/redact.ts +0 -73
  454. package/src/transport/README.md +0 -65
  455. package/src/transport/calls.ts +0 -113
  456. package/src/transport/characterization.test.ts +0 -260
  457. package/src/transport/codec.test.ts +0 -118
  458. package/src/transport/codec.ts +0 -240
  459. package/src/transport/conformance-python.test.ts +0 -152
  460. package/src/transport/conformance-same-lib.test.ts +0 -115
  461. package/src/transport/dbus-native-lib.d.ts +0 -19
  462. package/src/transport/dbus-native.ts +0 -85
  463. package/src/transport/index.ts +0 -30
  464. package/src/transport/no-library-leak.test.ts +0 -61
  465. package/src/transport/reliability.test.ts +0 -173
  466. package/src/transport/signals.ts +0 -150
  467. package/src/transport/signature.ts +0 -110
  468. package/src/transport/test-support/fake-service.ts +0 -168
  469. package/src/transport/test-support/independent-producer.py +0 -110
  470. package/src/transport/test-support/private-bus.ts +0 -66
  471. package/src/transport/transport.ts +0 -250
  472. package/src/transport/types.ts +0 -118
  473. package/src/usb-mode/catalog-schema.test.ts +0 -181
  474. package/src/usb-mode/catalog-schema.ts +0 -113
  475. package/src/usb-mode/certified-catalog.json +0 -67
  476. package/src/usb-mode/index.ts +0 -58
  477. package/src/usb-mode/ingestion.test.ts +0 -268
  478. package/src/usb-mode/ingestion.ts +0 -297
  479. package/src/usb-mode/promotion-review.ts +0 -117
  480. package/src/usb-mode/usb-devices-parse.ts +0 -196
@@ -1,89 +0,0 @@
1
- import { describe, expect, test } from 'bun:test';
2
- import { imeiEquipmentId, logicalSlotId, runtimePath } from '../domain';
3
- import { type ModemIdentityFacts, resolveModemIdentity } from './identity-ladder';
4
- import { IdentityRegistry } from './identity-registry';
5
-
6
- const IMEI_A = '490154203237518';
7
- const IMEI_B = '356938035643809';
8
-
9
- function resolvedAt(
10
- device: string,
11
- imei: string,
12
- path: string,
13
- extra: Partial<ModemIdentityFacts> = {},
14
- ) {
15
- return resolveModemIdentity({
16
- runtimePath: path,
17
- device,
18
- equipmentId: imeiEquipmentId(imei),
19
- ...extra,
20
- });
21
- }
22
-
23
- describe('IdentityRegistry transitions', () => {
24
- test('a fresh stable key attaches a new row', () => {
25
- const registry = new IdentityRegistry();
26
- const transition = registry.apply(resolvedAt('slot-a', IMEI_A, '/Modem/0'));
27
- expect(transition.kind).toBe('attached');
28
- expect(registry.rows).toHaveLength(1);
29
- });
30
-
31
- test('replug into the SAME slot keeps ONE row and updates the path', () => {
32
- const registry = new IdentityRegistry();
33
- registry.apply(resolvedAt('slot-a', IMEI_A, '/Modem/0'));
34
- const transition = registry.apply(resolvedAt('slot-a', IMEI_A, '/Modem/7'));
35
-
36
- expect(transition.kind).toBe('replugged');
37
- expect(registry.rows).toHaveLength(1);
38
- expect(registry.rows[0]?.runtimePath).toBe(runtimePath('/Modem/7'));
39
- if (transition.kind === 'replugged') {
40
- expect(transition.previousPath).toBe(runtimePath('/Modem/0'));
41
- }
42
- });
43
-
44
- test('a different modem in the SAME slot is an equipment-swap (slot inherits policy)', () => {
45
- const registry = new IdentityRegistry();
46
- registry.apply(resolvedAt('slot-a', IMEI_A, '/Modem/0'));
47
- const transition = registry.apply(resolvedAt('slot-a', IMEI_B, '/Modem/1'));
48
-
49
- expect(transition.kind).toBe('equipment-swapped-in-slot');
50
- expect(registry.rows).toHaveLength(1);
51
- expect(registry.rows[0]?.logicalSlotId).toBe(logicalSlotId('slot-a'));
52
- expect(
53
- registry.rows[0]?.equipmentId.provenance === 'imei' && registry.rows[0]?.equipmentId.value,
54
- ).toBe(IMEI_B);
55
- if (transition.kind === 'equipment-swapped-in-slot') {
56
- expect(
57
- transition.previousEquipment.provenance === 'imei' && transition.previousEquipment.value,
58
- ).toBe(IMEI_A);
59
- }
60
- });
61
-
62
- test('the SAME equipment in a different slot is an equipment-move', () => {
63
- const registry = new IdentityRegistry();
64
- registry.apply(resolvedAt('slot-a', IMEI_A, '/Modem/0'));
65
- const transition = registry.apply(resolvedAt('slot-b', IMEI_A, '/Modem/2'));
66
-
67
- expect(transition.kind).toBe('equipment-moved');
68
- expect(registry.rows).toHaveLength(1);
69
- expect(registry.rows[0]?.logicalSlotId).toBe(logicalSlotId('slot-b'));
70
- if (transition.kind === 'equipment-moved') {
71
- expect(transition.previousKey).toBe('slot:slot-a');
72
- expect(transition.previousSlot).toBe(logicalSlotId('slot-a'));
73
- }
74
- });
75
-
76
- test('two distinct slots keep two independent rows', () => {
77
- const registry = new IdentityRegistry();
78
- registry.apply(resolvedAt('slot-a', IMEI_A, '/Modem/0'));
79
- registry.apply(resolvedAt('slot-b', IMEI_B, '/Modem/1'));
80
- expect(registry.rows).toHaveLength(2);
81
- });
82
-
83
- test('remove drops a row by stable key', () => {
84
- const registry = new IdentityRegistry();
85
- registry.apply(resolvedAt('slot-a', IMEI_A, '/Modem/0'));
86
- registry.remove('slot:slot-a');
87
- expect(registry.rows).toHaveLength(0);
88
- });
89
- });
@@ -1,151 +0,0 @@
1
- // The identity registry — ONE logical row per physical slot, across replugs.
2
- //
3
- // The epoch observer (A3.1) keys rows by the MM object path, which CHANGES on
4
- // replug and daemon restart. This registry sits above it and keys rows by the
5
- // STABLE identifier the ladder resolves (slot-UID / Physdev / sysfs / unique
6
- // equipment id), so a modem that disconnects and reconnects to the SAME slot
7
- // resolves to the SAME logical row instead of a duplicate.
8
- //
9
- // It also names the transitions the ladder can observe:
10
- //
11
- // - `attached` — a stable key we have not seen before.
12
- // - `replugged` — same stable key, same equipment: one row, new path.
13
- // - `equipment-swapped-in-slot` — same slot, DIFFERENT equipment. The slot keeps
14
- // its policy (slot-inherits-policy): unplug modem A,
15
- // plug modem B into the same slot, B adopts A's
16
- // slot-bound policy.
17
- // - `equipment-moved` — same equipment, DIFFERENT slot: the modem was
18
- // physically moved to another port.
19
-
20
- import type { EquipmentId, LogicalSlotId, RuntimePath } from '../domain';
21
- import type { ResolvedIdentity } from './identity-ladder';
22
-
23
- /** One durable logical row, keyed by the ladder's stable identifier. */
24
- export interface IdentityRow {
25
- /** The stable durable key (`slot:…` / `physdev:…` / `sysfs:…` / `equip:…`). */
26
- readonly stableKey: string;
27
- /** The resolved slot, when the row was slot-resolved (rungs 1-3). */
28
- readonly logicalSlotId?: LogicalSlotId;
29
- /** The equipment currently occupying this slot. */
30
- readonly equipmentId: EquipmentId;
31
- /** The live MM path — updated on every replug (never a durable key). */
32
- readonly runtimePath: RuntimePath;
33
- }
34
-
35
- /** A transition the registry detected while applying a resolved identity. */
36
- export type IdentityTransition =
37
- | { readonly kind: 'attached'; readonly row: IdentityRow }
38
- | { readonly kind: 'replugged'; readonly row: IdentityRow; readonly previousPath: RuntimePath }
39
- | {
40
- readonly kind: 'equipment-swapped-in-slot';
41
- readonly row: IdentityRow;
42
- readonly previousEquipment: EquipmentId;
43
- }
44
- | {
45
- readonly kind: 'equipment-moved';
46
- readonly row: IdentityRow;
47
- readonly previousKey: string;
48
- readonly previousSlot?: LogicalSlotId;
49
- };
50
-
51
- const equipmentValue = (equipment: EquipmentId): string | undefined =>
52
- equipment.provenance !== 'none' && equipment.value.trim().length > 0
53
- ? equipment.value
54
- : undefined;
55
-
56
- /**
57
- * Tracks logical modem rows across replug/swap/move. Stateful by design — it holds
58
- * the last-known row per stable key. `apply()` folds one resolved identity in and
59
- * reports the transition it produced.
60
- */
61
- export class IdentityRegistry {
62
- readonly #rows = new Map<string, IdentityRow>();
63
-
64
- /** A snapshot of the current logical rows, in insertion order. */
65
- get rows(): IdentityRow[] {
66
- return [...this.#rows.values()];
67
- }
68
-
69
- /** The row for a stable key, or `undefined`. */
70
- get(stableKey: string): IdentityRow | undefined {
71
- return this.#rows.get(stableKey);
72
- }
73
-
74
- /** Drop a row (e.g. after a current-epoch removal). */
75
- remove(stableKey: string): void {
76
- this.#rows.delete(stableKey);
77
- }
78
-
79
- /**
80
- * Fold one resolved identity into the registry and report the transition.
81
- * Keeps ONE row per stable key: a replug into the same slot updates the live
82
- * path in place rather than adding a duplicate.
83
- */
84
- apply(resolved: ResolvedIdentity): IdentityTransition {
85
- const row = this.#rowFrom(resolved);
86
- const existing = this.#rows.get(row.stableKey);
87
-
88
- if (existing !== undefined) {
89
- return this.#applyToExisting(existing, resolved, row);
90
- }
91
-
92
- // A unique equipment id at a NEW stable key that already lives elsewhere
93
- // means the modem physically moved to a different slot/port.
94
- const moved = this.#findByEquipment(row.equipmentId, row.stableKey);
95
- if (moved !== undefined) {
96
- this.#rows.delete(moved.stableKey);
97
- this.#rows.set(row.stableKey, row);
98
- return {
99
- kind: 'equipment-moved',
100
- row,
101
- previousKey: moved.stableKey,
102
- ...(moved.logicalSlotId !== undefined ? { previousSlot: moved.logicalSlotId } : {}),
103
- };
104
- }
105
-
106
- this.#rows.set(row.stableKey, row);
107
- return { kind: 'attached', row };
108
- }
109
-
110
- #applyToExisting(
111
- existing: IdentityRow,
112
- resolved: ResolvedIdentity,
113
- row: IdentityRow,
114
- ): IdentityTransition {
115
- const before = equipmentValue(existing.equipmentId);
116
- const after = equipmentValue(resolved.identity.equipmentId);
117
-
118
- if (before !== undefined && after !== undefined && before !== after) {
119
- // Same slot, different equipment — the slot keeps its policy binding.
120
- this.#rows.set(row.stableKey, row);
121
- return { kind: 'equipment-swapped-in-slot', row, previousEquipment: existing.equipmentId };
122
- }
123
-
124
- // Same slot, same (or unchanged) equipment — a replug: one row, new path.
125
- this.#rows.set(row.stableKey, row);
126
- return { kind: 'replugged', row, previousPath: existing.runtimePath };
127
- }
128
-
129
- #rowFrom(resolved: ResolvedIdentity): IdentityRow {
130
- const { identity, stableKey } = resolved;
131
- return {
132
- stableKey,
133
- equipmentId: identity.equipmentId,
134
- runtimePath: identity.runtimePath,
135
- ...(identity.logicalSlotId !== undefined ? { logicalSlotId: identity.logicalSlotId } : {}),
136
- };
137
- }
138
-
139
- #findByEquipment(equipment: EquipmentId, exceptKey: string): IdentityRow | undefined {
140
- const value = equipmentValue(equipment);
141
- if (value === undefined) {
142
- return undefined;
143
- }
144
- for (const row of this.#rows.values()) {
145
- if (row.stableKey !== exceptKey && equipmentValue(row.equipmentId) === value) {
146
- return row;
147
- }
148
- }
149
- return undefined;
150
- }
151
- }
@@ -1,236 +0,0 @@
1
- // Backend adapters — the concrete D-Bus implementations of the port contracts.
2
- //
3
- // A3.1 lands the epoch-scoped `MmDbusObserver` (the read side). A3.2 adds MM
4
- // feature detection + the stable identity ladder. Later A3 waves add mutations +
5
- // Signal.Setup (A3.3) and the recovery ladder (A3.4) here.
6
-
7
- export {
8
- AT_BASELINE_ALLOWLIST,
9
- type AtAuditEntry,
10
- type AtAuditSink,
11
- AtCommandLease,
12
- type AtCommandLeaseDeps,
13
- AtCommandNotAllowedError,
14
- type AtCommandSender,
15
- AtCommandTimeoutError,
16
- type AtResponse,
17
- computeAtAllowlist,
18
- } from './at-lease';
19
- export {
20
- type CellInfoProvenance,
21
- type CellReading,
22
- compareServing,
23
- normalizeCellInfo,
24
- normalizeCellReading,
25
- selectServingCell,
26
- } from './cell-info';
27
- export {
28
- MM_BUS_NAME,
29
- MM_MANAGER_IFACE,
30
- MM_ROOT_PATH,
31
- MODEM_IFACE,
32
- MODEM3GPP_IFACE,
33
- SIM_IFACE,
34
- } from './constants';
35
- export {
36
- classifyDevice,
37
- type DeviceClass,
38
- type DeviceClassification,
39
- descriptorsMatch,
40
- detectUsbMode,
41
- type UsbDeviceSnapshot,
42
- type UsbInterface,
43
- } from './device-classifier';
44
- export {
45
- buildEnrichment,
46
- type EsimInfo,
47
- type EsimStatus,
48
- type ModemEnrichment,
49
- readEsimInfo,
50
- readRevision,
51
- type SimType,
52
- } from './enrichment';
53
- export {
54
- detectMmFeatures,
55
- detectModemFeatures,
56
- type MmFeatures,
57
- type MmPropertyProbe,
58
- type MmVersion,
59
- parseMmVersion,
60
- probeModemProperties,
61
- } from './features';
62
- export {
63
- looksLikeSlotUid,
64
- type ModemIdentityFacts,
65
- modemIdentityFactsFromTree,
66
- type ResolvedIdentity,
67
- resolveModemIdentities,
68
- resolveModemIdentity,
69
- SLOT_UID_PREFIX,
70
- type SlotSource,
71
- } from './identity-ladder';
72
- export {
73
- IdentityRegistry,
74
- type IdentityRow,
75
- type IdentityTransition,
76
- } from './identity-registry';
77
- export {
78
- ALLOW_ALL_INTERLOCK,
79
- type InterlockDecision,
80
- type InterlockTarget,
81
- type LifecycleInterlock,
82
- } from './lifecycle-interlock';
83
- export {
84
- asManagedObjects,
85
- type DecodedInterfaces,
86
- type DecodedManagedObjects,
87
- type DecodedObject,
88
- type DecodedProps,
89
- fetchManagedObjects,
90
- findInterface,
91
- findObject,
92
- followObjectPath,
93
- hasInterface,
94
- numberProp,
95
- objectPaths,
96
- pathsWithInterface,
97
- propValue,
98
- stringProp,
99
- } from './managed-objects';
100
- export {
101
- createMmDbusBackend,
102
- MmDbusBackend,
103
- type MmDbusBackendOptions,
104
- } from './mm-backend';
105
- export { MmMutations, type MmMutationsDeps } from './mm-mutations';
106
- export {
107
- ModemActor,
108
- NO_OP_QUIESCE,
109
- type QuiesceHook,
110
- type QuiesceLeaseHandle,
111
- type QuiesceTarget,
112
- } from './modem-actor';
113
- export {
114
- AUTO_APN_ADVISORY,
115
- type AutoApnAdvisory,
116
- type AutoApnTransitionResult,
117
- autoApnCapableFromVersion,
118
- autoApnSupportedByVersion,
119
- classifyActivation,
120
- type ManualApn,
121
- parseNmVersion,
122
- probeAutoApnCapability,
123
- toAutoArgs,
124
- toManualArgs,
125
- } from './nm-auto-apn';
126
- export {
127
- buildProfile,
128
- cliArg,
129
- createGsmArgs,
130
- flattenPairs,
131
- gsmFieldPairs,
132
- passwordFlags,
133
- patchPairs,
134
- } from './nm-gsm-fields';
135
- export {
136
- NmcliNmPort,
137
- type NmcliNmPortOptions,
138
- } from './nmcli-nm-port';
139
- export {
140
- type NmcliResult,
141
- type NmcliRunner,
142
- parseTerse,
143
- runNmcli,
144
- SpawnNmcliRunner,
145
- } from './nmcli-runner';
146
- export {
147
- createMmDbusObserver,
148
- type EpochRefreshEvent,
149
- MmDbusObserver,
150
- type MmDbusObserverOptions,
151
- } from './observer';
152
- export {
153
- NONE_POWER_CAPABILITY,
154
- NONE_POWER_HOOK,
155
- type PowerCapability,
156
- type PowerCapabilityKind,
157
- type PowerCycleContext,
158
- type PowerCycleResult,
159
- type PowerHook,
160
- type PreferredUsbMode,
161
- unsupportedPowerHook,
162
- } from './power-contract';
163
- export {
164
- attributeFault,
165
- attributeSnapshot,
166
- type FaultAttribution,
167
- type FaultSymptoms,
168
- symptomsFromSnapshot,
169
- } from './recovery-attribution';
170
- export {
171
- type BudgetDecision,
172
- beginAttempt,
173
- DEFAULT_RECOVERY_BUDGET,
174
- INITIAL_BUDGET_STATE,
175
- markRecovered,
176
- type RecoveryBudget,
177
- type RecoveryBudgetState,
178
- } from './recovery-budget';
179
- export {
180
- DEFAULT_LADDER_CONFIG,
181
- LADDER_ORDER,
182
- RecoveryLadder,
183
- type RecoveryLadderConfig,
184
- type RecoveryLadderDeps,
185
- type RecoveryOutcome,
186
- type RecoveryOutcomeKind,
187
- type RecoveryRequest,
188
- type RecoveryRung,
189
- type RecoveryStepContext,
190
- type RecoveryStepGate,
191
- type RecoveryStepReport,
192
- type RecoverySteps,
193
- type StepOutcome,
194
- } from './recovery-ladder';
195
- export { createRouterEthernetProbe, type RouterEthernetProbeDeps } from './router-ethernet';
196
- export {
197
- DEFAULT_SIGNAL_INTERVAL_SECONDS,
198
- type SignalCadence,
199
- SignalSetupManager,
200
- type SignalSetupManagerOptions,
201
- } from './signal-setup';
202
- export { sendSimPin, sendSimPuk } from './sim-unlock';
203
- export {
204
- ALLOW_ALL_TRANSITION_INTERLOCK,
205
- checkTransitionPreconditions,
206
- type InterlockHold,
207
- type PreconditionResult,
208
- type TransitionInterlock,
209
- type TransitionReadiness,
210
- type UsbModeTransitionOutcome,
211
- type UsbModeTransitionRequest,
212
- } from './transition-preconditions';
213
- export {
214
- createUhubctlPowerHook,
215
- parseUhubctlPortMap,
216
- readUhubctlPortMap,
217
- SpawnUhubctlRunner,
218
- type UhubctlPortMap,
219
- type UhubctlPortMapping,
220
- type UhubctlPowerHookDeps,
221
- type UhubctlResult,
222
- type UhubctlRunner,
223
- type UsbEnumerationPoller,
224
- uhubctlCycleArgv,
225
- uhubctlPortMappingSchema,
226
- uhubctlPortMapSchema,
227
- } from './uhubctl-power-hook';
228
- export * from './usage';
229
- export {
230
- createUsbEnumerator,
231
- enumerateUsbDevices,
232
- parseUdevDatabase,
233
- type UsbEnumerator,
234
- type UsbEnumeratorDeps,
235
- } from './usb-enumerator';
236
- export { UsbModeTransition, type UsbModeTransitionDeps } from './usb-mode-transition';
@@ -1,38 +0,0 @@
1
- // The pluggable safety interlock the recovery ladder consults before disruption.
2
- //
3
- // A disruptive recovery step (deactivate NM, disable MM, Reset(), power-cycle) must
4
- // never fire while the modem is carrying a live stream. The ladder therefore asks a
5
- // `LifecycleInterlock` BEFORE every disruptive step. Phase A (CLI) injects the
6
- // always-allow stub below; Phase B wires CeraUI's real streaming-admission check
7
- // into this SAME interface — the ladder code does not change, only the injected
8
- // instance. A4.2's USB-mode transition reuses this exact interlock shape.
9
-
10
- /** What a disruptive step is about to act on — enough for an interlock to decide. */
11
- export interface InterlockTarget {
12
- readonly stableKey: string;
13
- }
14
-
15
- /** An interlock verdict. A denial ALWAYS carries a reason (why it is unsafe now). */
16
- export type InterlockDecision =
17
- | { readonly allow: true }
18
- | { readonly allow: false; readonly reason: string };
19
-
20
- /**
21
- * The safety interlock consulted before each disruptive recovery step. Returning
22
- * `{ allow: false, reason }` stops the ladder — the modem is left as-is rather than
23
- * disrupted mid-stream.
24
- */
25
- export interface LifecycleInterlock {
26
- canDisrupt(target: InterlockTarget): Promise<InterlockDecision>;
27
- }
28
-
29
- /**
30
- * The Phase-A interlock: always allows. There is no streaming-admission signal in
31
- * the CLI, so nothing to block against. Phase B replaces this instance with a
32
- * real streaming-aware interlock; no ladder code changes.
33
- */
34
- export const ALLOW_ALL_INTERLOCK: LifecycleInterlock = {
35
- canDisrupt(): Promise<InterlockDecision> {
36
- return Promise.resolve({ allow: true });
37
- },
38
- };
@@ -1,108 +0,0 @@
1
- // Walkers over a DECODED `GetManagedObjects` / `InterfacesAdded` tree.
2
- //
3
- // The transport decodes `a{oa{sa{sv}}}` into nested tuple arrays: a dict `a{sv}`
4
- // becomes `[key, variant][]` and a variant becomes `{ signature, value }`. These
5
- // accessors navigate that structure by object path and interface name. They live in
6
- // `src` (not the A2.3 test fake's `tree.ts`) because the observer that ships must not
7
- // import test-support — the published package would not contain it.
8
-
9
- import type { DbusTransport, DbusValue, DbusVariant } from '../transport';
10
- import { MM_ROOT_PATH, OBJECT_MANAGER_IFACE } from './constants';
11
-
12
- /** One interface's property entries: `[propertyName, variant][]`. */
13
- export type DecodedProps = ReadonlyArray<readonly [string, DbusVariant]>;
14
- /** One object's interfaces: `[interfaceName, props][]`. */
15
- export type DecodedInterfaces = ReadonlyArray<readonly [string, DecodedProps]>;
16
- /** One managed object: `[objectPath, interfaces]`. */
17
- export type DecodedObject = readonly [string, DecodedInterfaces];
18
- /** The whole `a{oa{sa{sv}}}` payload. */
19
- export type DecodedManagedObjects = readonly DecodedObject[];
20
-
21
- /** Treat a `GetManagedObjects` reply body value as the decoded tree. */
22
- export function asManagedObjects(value: DbusValue | undefined): DecodedManagedObjects {
23
- if (!Array.isArray(value)) {
24
- throw new TypeError('managed-objects payload is not an array');
25
- }
26
- return value as unknown as DecodedManagedObjects;
27
- }
28
-
29
- /** Call `ObjectManager.GetManagedObjects` on `destination` and decode the reply. */
30
- export async function fetchManagedObjects(
31
- transport: DbusTransport,
32
- destination: string,
33
- ): Promise<DecodedManagedObjects> {
34
- const reply = await transport.callMethod({
35
- destination,
36
- path: MM_ROOT_PATH,
37
- interface: OBJECT_MANAGER_IFACE,
38
- member: 'GetManagedObjects',
39
- });
40
- return asManagedObjects(reply.body[0]);
41
- }
42
-
43
- /** Treat an `InterfacesAdded` body (`[path, interfaces]`) as one decoded object. */
44
- export function asAddedObject(path: DbusValue, interfaces: DbusValue): DecodedObject {
45
- if (typeof path !== 'string' || !Array.isArray(interfaces)) {
46
- throw new TypeError('InterfacesAdded body is not [objectPath, interfaces]');
47
- }
48
- return [path, interfaces as unknown as DecodedInterfaces];
49
- }
50
-
51
- /** Every object path in the tree, in wire order. */
52
- export function objectPaths(tree: DecodedManagedObjects): string[] {
53
- return tree.map(([path]) => path);
54
- }
55
-
56
- /** The object at `path`, or `undefined`. */
57
- export function findObject(tree: DecodedManagedObjects, path: string): DecodedObject | undefined {
58
- return tree.find(([objectPath]) => objectPath === path);
59
- }
60
-
61
- /** The property entries of one interface on one object, or `undefined`. */
62
- export function findInterface(
63
- tree: DecodedManagedObjects,
64
- path: string,
65
- iface: string,
66
- ): DecodedProps | undefined {
67
- return findObject(tree, path)?.[1].find(([name]) => name === iface)?.[1];
68
- }
69
-
70
- /** Object paths that carry a given interface. */
71
- export function pathsWithInterface(tree: DecodedManagedObjects, iface: string): string[] {
72
- return tree
73
- .filter(([, interfaces]) => interfaces.some(([name]) => name === iface))
74
- .map(([path]) => path);
75
- }
76
-
77
- /** Whether an object exposes a given interface. */
78
- export function hasInterface(tree: DecodedManagedObjects, path: string, iface: string): boolean {
79
- return findInterface(tree, path, iface) !== undefined;
80
- }
81
-
82
- /** The inner value of a property (a variant's `.value`), or `undefined`. */
83
- export function propValue(props: DecodedProps | undefined, name: string): DbusValue | undefined {
84
- return props?.find(([key]) => key === name)?.[1]?.value;
85
- }
86
-
87
- /** A string-typed property, or `undefined` if absent / not a string. */
88
- export function stringProp(props: DecodedProps | undefined, name: string): string | undefined {
89
- const value = propValue(props, name);
90
- return typeof value === 'string' ? value : undefined;
91
- }
92
-
93
- /** A number-typed property, or `undefined` if absent / not a number. */
94
- export function numberProp(props: DecodedProps | undefined, name: string): number | undefined {
95
- const value = propValue(props, name);
96
- return typeof value === 'number' ? value : undefined;
97
- }
98
-
99
- /** Resolve an object-path property (e.g. a modem's `Sim`) to that object's props. */
100
- export function followObjectPath(
101
- tree: DecodedManagedObjects,
102
- props: DecodedProps | undefined,
103
- propName: string,
104
- iface: string,
105
- ): DecodedProps | undefined {
106
- const target = propValue(props, propName);
107
- return typeof target === 'string' ? findInterface(tree, target, iface) : undefined;
108
- }