messagefoundry 0.1.0__tar.gz → 0.2.0__tar.gz

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 (711) hide show
  1. messagefoundry-0.2.0/.dockerignore +45 -0
  2. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/.github/SECURITY.md +29 -0
  3. messagefoundry-0.2.0/.github/dependabot.yml +54 -0
  4. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/.github/workflows/benchmark.yml +3 -3
  5. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/.github/workflows/ci.yml +219 -36
  6. messagefoundry-0.2.0/.github/workflows/dependabot-auto-merge.yml +58 -0
  7. messagefoundry-0.2.0/.github/workflows/dependabot-lock-resync.yml +91 -0
  8. messagefoundry-0.2.0/.github/workflows/release-sync-check.yml +38 -0
  9. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/.github/workflows/release.yml +1 -1
  10. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/.github/workflows/security.yml +47 -13
  11. messagefoundry-0.2.0/.github/workflows/vuln-metrics.yml +40 -0
  12. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/.gitignore +12 -0
  13. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/CHANGELOG.md +30 -1
  14. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/CLAUDE.md +31 -8
  15. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/NOTICE +12 -0
  16. messagefoundry-0.1.0/README.md → messagefoundry-0.2.0/PKG-INFO +84 -11
  17. messagefoundry-0.1.0/PKG-INFO → messagefoundry-0.2.0/README.md +31 -49
  18. messagefoundry-0.2.0/docker/Dockerfile +121 -0
  19. messagefoundry-0.2.0/docker/README.md +125 -0
  20. messagefoundry-0.2.0/docker/compose.yaml +84 -0
  21. messagefoundry-0.2.0/docker/k8s/secret.example.yaml +27 -0
  22. messagefoundry-0.2.0/docker/k8s/statefulset.yaml +130 -0
  23. messagefoundry-0.2.0/docker/locks/requirements-core.lock +633 -0
  24. messagefoundry-0.2.0/docker/locks/requirements-sqlserver.lock +685 -0
  25. messagefoundry-0.2.0/docker/secrets.env.example +15 -0
  26. messagefoundry-0.2.0/docker/smoke/Dockerfile +20 -0
  27. messagefoundry-0.2.0/docker/smoke/config/IB_Test_ADT.py +29 -0
  28. messagefoundry-0.2.0/docker/smoke/send_adt.py +62 -0
  29. messagefoundry-0.2.0/docs/ADOPTER-CI.md +183 -0
  30. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/docs/AI.md +6 -5
  31. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/docs/ARCHITECTURE.md +15 -4
  32. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/docs/BACKLOG.md +930 -67
  33. messagefoundry-0.2.0/docs/CI-QUALITY.md +57 -0
  34. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/docs/CLUSTERING.md +47 -37
  35. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/docs/CONFIGURATION.md +38 -46
  36. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/docs/CONNECTIONS.md +312 -16
  37. messagefoundry-0.2.0/docs/CONTAINER-EXPOSURE-EVALUATION.md +344 -0
  38. messagefoundry-0.2.0/docs/COUNSEL-ENGAGEMENT-BRIEF.md +268 -0
  39. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/docs/DEPLOY-SERVER-DB.md +3 -4
  40. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/docs/DEPLOYMENT.md +60 -6
  41. messagefoundry-0.2.0/docs/DICOM.md +141 -0
  42. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/docs/EARLY-ADOPTER-GUIDE.md +134 -46
  43. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/docs/FEATURE-MAP.md +31 -14
  44. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/docs/INSTALL-GUIDE.md +27 -2
  45. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/docs/LOAD-TESTING.md +2 -2
  46. messagefoundry-0.2.0/docs/MENTAL-MODEL.md +494 -0
  47. messagefoundry-0.2.0/docs/MessageFoundry-Mental-Model.docx +0 -0
  48. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/docs/PHI.md +43 -8
  49. messagefoundry-0.2.0/docs/REMOTE-CONSOLE-CUSTOMER-GUIDE.md +176 -0
  50. messagefoundry-0.2.0/docs/REMOTE-CONSOLE.md +125 -0
  51. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/docs/SECURITY.md +1 -1
  52. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/docs/SERVICE.md +15 -0
  53. messagefoundry-0.2.0/docs/SUPPORT-POLICY.md +39 -0
  54. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/docs/SYSTEM-REQUIREMENTS.md +32 -24
  55. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/docs/Secure_AI_Development_Standards.md +26 -2
  56. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/docs/Secure_Development_Standards.md +169 -67
  57. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/docs/THROUGHPUT-IMPROVEMENTS.md +5 -4
  58. messagefoundry-0.2.0/docs/USER-GUIDE.md +582 -0
  59. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/docs/adr/0001-staged-pipeline-architecture.md +4 -0
  60. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/docs/adr/0004-payload-agnostic-ingress.md +6 -1
  61. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/docs/adr/0008-cluster-observability-api.md +14 -8
  62. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/docs/adr/0013-increment-2-reingress-design.md +12 -8
  63. messagefoundry-0.2.0/docs/adr/0021-inbound-ack-nak-capture-response-sent.md +172 -0
  64. messagefoundry-0.2.0/docs/adr/0022-fhir-resource-codec-rest-client.md +594 -0
  65. messagefoundry-0.2.0/docs/adr/0024-smart-backend-services-token-provider.md +296 -0
  66. messagefoundry-0.2.0/docs/adr/0025-dicom-codec-store-connectors.md +836 -0
  67. messagefoundry-0.2.0/docs/adr/0026-off-box-egress-update-check.md +122 -0
  68. messagefoundry-0.2.0/docs/adr/0028-base64-binary-carriage-codec.md +174 -0
  69. messagefoundry-0.2.0/docs/adr/0030-anonymization-test-harness-tee.md +399 -0
  70. messagefoundry-0.2.0/docs/adr/0031-startup-connection-fault-isolation.md +156 -0
  71. messagefoundry-0.2.0/docs/adr/0032-console-desktop-launch.md +86 -0
  72. messagefoundry-0.2.0/docs/adr/README.md +51 -0
  73. messagefoundry-0.2.0/docs/adr/TEMPLATE.md +51 -0
  74. messagefoundry-0.2.0/docs/releases/DOGFOOD-BACKLOG-MULTISESSION-PLAN.md +178 -0
  75. messagefoundry-0.2.0/docs/releases/MULTISESSION-PLAN-3.md +348 -0
  76. messagefoundry-0.2.0/docs/releases/MULTISESSION-PLAN-v0.2.md +526 -0
  77. messagefoundry-0.2.0/docs/releases/PLAN-3-LANE-HANDOFFS.md +145 -0
  78. messagefoundry-0.2.0/docs/releases/V0.2-LANE-HANDOFFS.md +116 -0
  79. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/docs/releases/v0.1-EXECUTION-PLAN.md +14 -7
  80. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/docs/releases/v0.1-PLAN.md +23 -13
  81. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/docs/releases/v0.1.0-PRETAG-CHECKLIST.md +14 -10
  82. messagefoundry-0.2.0/docs/research/cloud-deployment-research-2026-06.md +131 -0
  83. messagefoundry-0.2.0/docs/research/config-ux-review.md +235 -0
  84. messagefoundry-0.2.0/docs/research/non-hl7-transform-components.md +275 -0
  85. messagefoundry-0.2.0/docs/reviews/DEPENDENCY-INFOSEC-POSTURE-2026-06-23.md +175 -0
  86. messagefoundry-0.2.0/docs/security/ADVISORY-PROCESS.md +35 -0
  87. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/docs/security/ASVS-L2-PHASE0-CHANGES.md +1 -0
  88. messagefoundry-0.2.0/docs/security/DEP-CVE-RUNBOOK.md +96 -0
  89. messagefoundry-0.2.0/docs/security/DEPENDENCY-METRICS.md +47 -0
  90. messagefoundry-0.2.0/docs/security/MEFOR-Code-Review-Checklist.xlsx +0 -0
  91. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/docs/security/RELEASE-GATE.md +6 -2
  92. messagefoundry-0.2.0/docs/security/SECURITY-POSTURE.md +164 -0
  93. messagefoundry-0.2.0/docs/security/SOUP-DEPENDENCY-HANDLING.md +133 -0
  94. messagefoundry-0.2.0/docs/security/SOUP-REVIEW-2026-06-18.md +82 -0
  95. messagefoundry-0.2.0/docs/security/SOUP-REVIEW-PROCEDURE.md +231 -0
  96. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/docs/security/THREAT-MODEL.md +10 -6
  97. messagefoundry-0.2.0/docs/testing/VERIFY.md +66 -0
  98. messagefoundry-0.2.0/docs/testing/WIN2025-ACCEPTANCE.md +73 -0
  99. messagefoundry-0.2.0/docs/testing/WIN2025-TEST-MATRIX.md +109 -0
  100. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/environments/dev.toml +9 -0
  101. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/environments/prod.toml +9 -0
  102. messagefoundry-0.2.0/harness/acceptance/__init__.py +21 -0
  103. messagefoundry-0.2.0/harness/acceptance/__main__.py +93 -0
  104. messagefoundry-0.2.0/harness/acceptance/matrix.py +525 -0
  105. messagefoundry-0.2.0/harness/acceptance/probes.py +220 -0
  106. messagefoundry-0.2.0/harness/acceptance/report.py +147 -0
  107. messagefoundry-0.2.0/harness/acceptance/runner.py +176 -0
  108. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/harness/load/corpus.py +30 -0
  109. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/harness/reconcile/capture.py +17 -1
  110. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/ide/README.md +7 -4
  111. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/ide/package.json +23 -0
  112. messagefoundry-0.2.0/ide/src/alertEditor.ts +329 -0
  113. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/ide/src/chat.ts +59 -7
  114. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/ide/src/cli.ts +17 -0
  115. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/ide/src/extension.ts +3 -4
  116. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/ide/src/home.ts +3 -4
  117. messagefoundry-0.2.0/ide/src/test/suite/chat.test.ts +81 -0
  118. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/messagefoundry/__init__.py +7 -1
  119. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/messagefoundry/__main__.py +195 -0
  120. messagefoundry-0.2.0/messagefoundry/adr_analyze.py +216 -0
  121. messagefoundry-0.2.0/messagefoundry/anon/__init__.py +96 -0
  122. messagefoundry-0.2.0/messagefoundry/anon/_pools.py +36 -0
  123. messagefoundry-0.2.0/messagefoundry/anon/hl7.py +86 -0
  124. messagefoundry-0.2.0/messagefoundry/anon/keying.py +67 -0
  125. messagefoundry-0.2.0/messagefoundry/anon/leak.py +62 -0
  126. messagefoundry-0.2.0/messagefoundry/anon/rules.py +219 -0
  127. messagefoundry-0.2.0/messagefoundry/anon/surrogates.py +299 -0
  128. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/messagefoundry/api/app.py +102 -2
  129. messagefoundry-0.2.0/messagefoundry/api/metrics.py +320 -0
  130. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/messagefoundry/api/models.py +34 -1
  131. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/messagefoundry/api/tls.py +5 -1
  132. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/messagefoundry/checks.py +136 -6
  133. messagefoundry-0.2.0/messagefoundry/config/alerts_edit.py +170 -0
  134. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/messagefoundry/config/models.py +35 -6
  135. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/messagefoundry/config/settings.py +18 -18
  136. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/messagefoundry/config/wiring.py +204 -8
  137. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/messagefoundry/console/__main__.py +36 -0
  138. messagefoundry-0.2.0/messagefoundry/console/alerts_page.py +197 -0
  139. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/messagefoundry/console/client.py +72 -13
  140. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/messagefoundry/console/connections.py +35 -7
  141. messagefoundry-0.2.0/messagefoundry/console/dead_letters_page.py +232 -0
  142. messagefoundry-0.2.0/messagefoundry/console/delegates.py +69 -0
  143. messagefoundry-0.2.0/messagefoundry/console/icons/alerts.svg +4 -0
  144. messagefoundry-0.2.0/messagefoundry/console/icons/connections.svg +5 -0
  145. messagefoundry-0.2.0/messagefoundry/console/icons/dead-letters.svg +4 -0
  146. messagefoundry-0.2.0/messagefoundry/console/icons/engine-status.svg +3 -0
  147. messagefoundry-0.2.0/messagefoundry/console/icons/log-search.svg +4 -0
  148. messagefoundry-0.2.0/messagefoundry/console/icons/logo-lockup.svg +33 -0
  149. messagefoundry-0.2.0/messagefoundry/console/icons/users.svg +4 -0
  150. messagefoundry-0.2.0/messagefoundry/console/resources/README.md +23 -0
  151. messagefoundry-0.2.0/messagefoundry/console/resources/app.ico +0 -0
  152. messagefoundry-0.2.0/messagefoundry/console/resources/app.svg +8 -0
  153. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/messagefoundry/console/service_control.py +13 -1
  154. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/messagefoundry/console/shell.py +81 -11
  155. messagefoundry-0.2.0/messagefoundry/console/theme.py +266 -0
  156. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/messagefoundry/console/widgets.py +10 -1
  157. messagefoundry-0.2.0/messagefoundry/generators/documents.py +79 -0
  158. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/messagefoundry/parsing/__init__.py +22 -0
  159. messagefoundry-0.2.0/messagefoundry/parsing/binary.py +152 -0
  160. messagefoundry-0.2.0/messagefoundry/parsing/dicom/__init__.py +44 -0
  161. messagefoundry-0.2.0/messagefoundry/parsing/dicom/_deps.py +59 -0
  162. messagefoundry-0.2.0/messagefoundry/parsing/dicom/_util.py +64 -0
  163. messagefoundry-0.2.0/messagefoundry/parsing/dicom/dataset.py +181 -0
  164. messagefoundry-0.2.0/messagefoundry/parsing/dicom/errors.py +36 -0
  165. messagefoundry-0.2.0/messagefoundry/parsing/dicom/hl7_map.py +170 -0
  166. messagefoundry-0.2.0/messagefoundry/parsing/dicom/peek.py +110 -0
  167. messagefoundry-0.2.0/messagefoundry/parsing/fhir/__init__.py +39 -0
  168. messagefoundry-0.2.0/messagefoundry/parsing/fhir/_deps.py +56 -0
  169. messagefoundry-0.2.0/messagefoundry/parsing/fhir/errors.py +35 -0
  170. messagefoundry-0.2.0/messagefoundry/parsing/fhir/peek.py +149 -0
  171. messagefoundry-0.2.0/messagefoundry/parsing/fhir/resource.py +150 -0
  172. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/messagefoundry/parsing/message.py +52 -0
  173. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/messagefoundry/pipeline/cluster.py +66 -143
  174. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/messagefoundry/pipeline/cluster_sqlserver.py +5 -12
  175. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/messagefoundry/pipeline/engine.py +15 -14
  176. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/messagefoundry/pipeline/leader_tasks.py +6 -10
  177. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/messagefoundry/pipeline/wiring_runner.py +267 -77
  178. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/messagefoundry/scaffold.py +26 -0
  179. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/messagefoundry/store/base.py +17 -7
  180. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/messagefoundry/store/postgres.py +88 -166
  181. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/messagefoundry/store/sqlserver.py +41 -5
  182. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/messagefoundry/store/store.py +60 -4
  183. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/messagefoundry/transports/__init__.py +3 -0
  184. messagefoundry-0.2.0/messagefoundry/transports/dicom.py +541 -0
  185. messagefoundry-0.2.0/messagefoundry/transports/dicomweb.py +308 -0
  186. messagefoundry-0.2.0/messagefoundry/transports/fhir.py +437 -0
  187. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/messagefoundry/transports/mllp.py +14 -3
  188. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/messagefoundry/transports/rest.py +42 -6
  189. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/messagefoundry/transports/signing.py +106 -31
  190. messagefoundry-0.2.0/messagefoundry/transports/smart.py +307 -0
  191. messagefoundry-0.2.0/messagefoundry/verify/__init__.py +19 -0
  192. messagefoundry-0.2.0/messagefoundry/verify/checks.py +242 -0
  193. messagefoundry-0.2.0/messagefoundry/verify/model.py +33 -0
  194. messagefoundry-0.2.0/messagefoundry/verify/report.py +73 -0
  195. messagefoundry-0.2.0/messagefoundry/verify/runner.py +128 -0
  196. messagefoundry-0.2.0/messagefoundry/verify/smoke.py +175 -0
  197. messagefoundry-0.2.0/pyproject.toml +135 -0
  198. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/requirements.lock +294 -33
  199. messagefoundry-0.2.0/samples/config/IB_FHIR_INTAKE.py +56 -0
  200. messagefoundry-0.2.0/samples/config/IB_RADIOLOGY_SR.py +87 -0
  201. messagefoundry-0.2.0/samples/dicom/generate_sr_sample.py +118 -0
  202. messagefoundry-0.2.0/scripts/console/install-console-shortcut.ps1 +134 -0
  203. messagefoundry-0.2.0/scripts/console/pack_ico.py +55 -0
  204. messagefoundry-0.2.0/scripts/console/uninstall-console-shortcut.ps1 +47 -0
  205. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/scripts/dev/sqlserver-docker.ps1 +12 -5
  206. messagefoundry-0.2.0/scripts/publish/check_release_sync.py +258 -0
  207. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/scripts/publish/publish.ps1 +32 -0
  208. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/scripts/publish/scan_forbidden.py +52 -0
  209. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/scripts/security/crypto_inventory_check.py +16 -0
  210. messagefoundry-0.2.0/scripts/security/vuln_metrics.py +321 -0
  211. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/tee/__main__.py +96 -0
  212. messagefoundry-0.2.0/tee/anon/__init__.py +80 -0
  213. messagefoundry-0.2.0/tee/anon/_hl7data.py +428 -0
  214. messagefoundry-0.2.0/tee/anon/_pools.py +30 -0
  215. messagefoundry-0.2.0/tee/anon/hl7.py +71 -0
  216. messagefoundry-0.2.0/tee/anon/keying.py +67 -0
  217. messagefoundry-0.2.0/tee/anon/leak.py +97 -0
  218. messagefoundry-0.2.0/tee/anon/rules.py +219 -0
  219. messagefoundry-0.2.0/tee/anon/surrogates.py +299 -0
  220. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/tee/mefor_api.py +6 -1
  221. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/tee/relay.py +30 -3
  222. messagefoundry-0.2.0/tests/_dicom_sample.py +85 -0
  223. messagefoundry-0.2.0/tests/_fhir_fixtures.py +77 -0
  224. messagefoundry-0.2.0/tests/conftest.py +279 -0
  225. messagefoundry-0.2.0/tests/test_acceptance_framework.py +144 -0
  226. messagefoundry-0.2.0/tests/test_adr_analyze.py +104 -0
  227. messagefoundry-0.2.0/tests/test_alerts_edit.py +146 -0
  228. messagefoundry-0.2.0/tests/test_alerts_rules_api.py +255 -0
  229. messagefoundry-0.2.0/tests/test_anon_core.py +249 -0
  230. messagefoundry-0.2.0/tests/test_anon_integration.py +189 -0
  231. messagefoundry-0.2.0/tests/test_anon_parity.py +128 -0
  232. messagefoundry-0.2.0/tests/test_binary_carriage.py +307 -0
  233. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/tests/test_checks.py +167 -0
  234. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/tests/test_cli.py +4 -0
  235. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/tests/test_cluster.py +36 -73
  236. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/tests/test_cluster_failover_postgres.py +1 -1
  237. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/tests/test_cluster_graph_gating.py +4 -4
  238. messagefoundry-0.2.0/tests/test_connection_resilience.py +164 -0
  239. messagefoundry-0.2.0/tests/test_console_alerts.py +216 -0
  240. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/tests/test_console_client.py +148 -1
  241. messagefoundry-0.2.0/tests/test_console_dead_letters.py +276 -0
  242. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/tests/test_console_hardening.py +32 -7
  243. messagefoundry-0.2.0/tests/test_console_icon.py +76 -0
  244. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/tests/test_console_status.py +47 -0
  245. messagefoundry-0.2.0/tests/test_console_theme.py +86 -0
  246. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/tests/test_console_widgets.py +2 -2
  247. messagefoundry-0.2.0/tests/test_db_lookup_live_runner.py +278 -0
  248. messagefoundry-0.2.0/tests/test_dicom_codec.py +235 -0
  249. messagefoundry-0.2.0/tests/test_dicom_scp.py +172 -0
  250. messagefoundry-0.2.0/tests/test_dicom_scu.py +172 -0
  251. messagefoundry-0.2.0/tests/test_dicom_wiring.py +220 -0
  252. messagefoundry-0.2.0/tests/test_dicomweb.py +291 -0
  253. messagefoundry-0.2.0/tests/test_ed_documents.py +74 -0
  254. messagefoundry-0.2.0/tests/test_ed_documents_e2e.py +253 -0
  255. messagefoundry-0.2.0/tests/test_fhir_parsing.py +159 -0
  256. messagefoundry-0.2.0/tests/test_fhir_resource.py +96 -0
  257. messagefoundry-0.2.0/tests/test_fhir_transport.py +362 -0
  258. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/tests/test_harness_monitor.py +15 -1
  259. messagefoundry-0.2.0/tests/test_hl7_core_features.py +250 -0
  260. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/tests/test_leader_tasks.py +8 -18
  261. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/tests/test_load_config.py +19 -23
  262. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/tests/test_load_failover_postgres.py +0 -1
  263. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/tests/test_load_failover_sqlserver.py +0 -1
  264. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/tests/test_load_runner.py +7 -1
  265. messagefoundry-0.2.0/tests/test_metrics_exporter.py +288 -0
  266. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/tests/test_mllp_tls.py +94 -1
  267. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/tests/test_payload_agnostic_ingress.py +38 -0
  268. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/tests/test_postgres_store.py +62 -199
  269. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/tests/test_response_capture.py +13 -5
  270. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/tests/test_retention.py +0 -6
  271. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/tests/test_scaffold.py +9 -0
  272. messagefoundry-0.2.0/tests/test_service_control.py +53 -0
  273. messagefoundry-0.2.0/tests/test_smart_backend.py +395 -0
  274. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/tests/test_sqlserver_store.py +13 -0
  275. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/tests/test_staged_pipeline.py +14 -3
  276. messagefoundry-0.2.0/tests/test_startup_fault_isolation.py +243 -0
  277. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/tests/test_store.py +0 -14
  278. messagefoundry-0.2.0/tests/test_verify.py +218 -0
  279. messagefoundry-0.2.0/tests/test_win2025_acceptance.py +73 -0
  280. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/tests/test_wiring_engine.py +41 -11
  281. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/tests/test_wiring_serve.py +7 -2
  282. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/uv.lock +501 -39
  283. messagefoundry-0.1.0/.github/dependabot.yml +0 -17
  284. messagefoundry-0.1.0/docs/adr/0021-inbound-ack-nak-capture-response-sent.md +0 -86
  285. messagefoundry-0.1.0/docs/adr/README.md +0 -32
  286. messagefoundry-0.1.0/pyproject.toml +0 -85
  287. messagefoundry-0.1.0/tests/conftest.py +0 -41
  288. messagefoundry-0.1.0/tests/test_service_control.py +0 -29
  289. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/.claude/settings.json +0 -0
  290. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/.gitattributes +0 -0
  291. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/.github/CODEOWNERS +0 -0
  292. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
  293. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/.github/ISSUE_TEMPLATE/config.yml +0 -0
  294. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/.github/ISSUE_TEMPLATE/feature_request.md +0 -0
  295. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/.github/PULL_REQUEST_TEMPLATE.md +0 -0
  296. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/.github/workflows/cla.yml +0 -0
  297. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/.gitleaks.toml +0 -0
  298. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/.pre-commit-config.yaml +0 -0
  299. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/.semgrep/messagefoundry.yml +0 -0
  300. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/CLA.md +0 -0
  301. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/CODE_OF_CONDUCT.md +0 -0
  302. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/COMMERCIAL-LICENSE.md +0 -0
  303. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/CONTRIBUTING.md +0 -0
  304. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/GOVERNANCE.md +0 -0
  305. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/LICENSE +0 -0
  306. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/MAINTAINERS.md +0 -0
  307. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/docs/CONTRIBUTOR-FIRST-ISSUES.md +0 -0
  308. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/docs/CONTRIBUTOR-PROGRAM-PLAN.md +0 -0
  309. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/docs/DUAL_LICENSING_PLAN.md +0 -0
  310. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/docs/HL7-VALIDATION.md +0 -0
  311. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/docs/TEE-RELAY.md +0 -0
  312. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/docs/WORKTREES.md +0 -0
  313. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/docs/adr/0002-phase2-transport-security-and-strong-auth.md +0 -0
  314. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/docs/adr/0003-non-hl7-transports-database-rest-soap.md +0 -0
  315. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/docs/adr/0005-transform-accessible-state.md +0 -0
  316. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/docs/adr/0006-external-data-lookups.md +0 -0
  317. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/docs/adr/0007-gui-manageable-connections-toml.md +0 -0
  318. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/docs/adr/0009-run-scoped-context-providers.md +0 -0
  319. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/docs/adr/0010-handler-callable-db-lookup.md +0 -0
  320. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/docs/adr/0011-timer-scheduled-source.md +0 -0
  321. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/docs/adr/0012-x12-edi-codec.md +0 -0
  322. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/docs/adr/0013-query-response-orchestration.md +0 -0
  323. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/docs/adr/0014-alerting-rules-engine.md +0 -0
  324. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/docs/adr/0015-ws-soap-outbound-mtls-wssecurity.md +0 -0
  325. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/docs/adr/0016-synchronous-x12-request-response.md +0 -0
  326. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/docs/adr/0017-consumer-deployment-model.md +0 -0
  327. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/docs/adr/0018-per-message-signatures-accepted-risk.md +0 -0
  328. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/docs/adr/0019-pluggable-keyprovider-hsm-kms-vault.md +0 -0
  329. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/docs/adr/0020-protocol-diagnostic-capture.md +0 -0
  330. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/docs/architecture-components.png +0 -0
  331. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/docs/architecture-components.svg +0 -0
  332. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/docs/architecture-config-graph.png +0 -0
  333. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/docs/architecture-config-graph.svg +0 -0
  334. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/docs/architecture-diagram.md +0 -0
  335. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/docs/architecture-message-flow.png +0 -0
  336. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/docs/architecture-message-flow.svg +0 -0
  337. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/docs/architecture-topology.png +0 -0
  338. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/docs/architecture-topology.svg +0 -0
  339. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/docs/benchmarks/TUNING-BASELINE.md +0 -0
  340. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/docs/benchmarks/results/2026-06-16-ci-linux/environment.txt +0 -0
  341. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/docs/benchmarks/results/2026-06-16-ci-linux/failover-postgres.json +0 -0
  342. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/docs/benchmarks/results/2026-06-16-ci-linux/failover-sqlserver.json +0 -0
  343. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/docs/benchmarks/results/2026-06-16-ci-linux/reference-postgres.json +0 -0
  344. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/docs/benchmarks/results/2026-06-16-ci-linux/reference-sqlite.json +0 -0
  345. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/docs/benchmarks/results/2026-06-16-ci-linux/reference-sqlserver.json +0 -0
  346. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/docs/benchmarks/step-b-write-amplification.md +0 -0
  347. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/docs/hl7-message-ordering-reference.md +0 -0
  348. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/docs/message-ordering-design.md +0 -0
  349. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/docs/releases/ASVS-OPTION-A-MULTISESSION-PLAN.md +0 -0
  350. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/docs/releases/ASVS-PARTIALS-SWEEP-MULTISESSION-PLAN.md +0 -0
  351. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/docs/releases/MULTISESSION-PLAN.md +0 -0
  352. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/docs/reviews/FULL-REVIEW-2026-06-10.md +0 -0
  353. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/docs/security/ASVS-FAILS-REMEDIATION-PLAN.md +0 -0
  354. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/docs/security/ASVS-L2-REMEDIATION-PLAN.md +0 -0
  355. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/docs/security/ASVS-L3-ASSESSMENT.md +0 -0
  356. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/docs/security/ASVS-L3-REMEDIATION-PLAN.md +0 -0
  357. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/docs/security/ASVS-L3-STATUS.md +0 -0
  358. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/docs/security/BEYOND-ASVS-L3-ONEPAGE.md +0 -0
  359. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/docs/security/BEYOND-ASVS-L3-REMEDIATION-PLAN-ONEPAGE.md +0 -0
  360. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/docs/security/BEYOND-ASVS-L3-REMEDIATION-PLAN.md +0 -0
  361. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/docs/security/BEYOND-ASVS-L3.md +0 -0
  362. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/docs/security/PHASE-8C-RBAC.md +0 -0
  363. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/docs/security/PUBLISHING.md +0 -0
  364. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/docs/security/RCA-TEMPLATE.md +0 -0
  365. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/docs/security/REMEDIATION-PLAN.md +0 -0
  366. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/docs/security/REVIEW-2026-06-07.md +0 -0
  367. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/docs/security/SDS-CONFORMANCE-REVIEW-2026-06-12.md +0 -0
  368. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/docs/security/SDS-REMEDIATION-PLAN.md +0 -0
  369. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/harness/README.md +0 -0
  370. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/harness/__main__.py +0 -0
  371. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/harness/compose.py +0 -0
  372. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/harness/config/coverage.py +0 -0
  373. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/harness/config/load/_shape.py +0 -0
  374. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/harness/config/load/graph.py +0 -0
  375. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/harness/file_panel.py +0 -0
  376. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/harness/file_transport.py +0 -0
  377. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/harness/load/__init__.py +0 -0
  378. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/harness/load/correlator.py +0 -0
  379. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/harness/load/enginepoll.py +0 -0
  380. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/harness/load/failover.py +0 -0
  381. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/harness/load/failover_track.py +0 -0
  382. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/harness/load/governor.py +0 -0
  383. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/harness/load/ids.py +0 -0
  384. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/harness/load/metrics.py +0 -0
  385. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/harness/load/profile.py +0 -0
  386. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/harness/load/profiles/README.md +0 -0
  387. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/harness/load/profiles/closed-loop.toml +0 -0
  388. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/harness/load/profiles/failover.toml +0 -0
  389. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/harness/load/profiles/fanout-baseline.toml +0 -0
  390. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/harness/load/profiles/reference.toml +0 -0
  391. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/harness/load/profiles/smoke-sqlserver.toml +0 -0
  392. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/harness/load/profiles/smoke.toml +0 -0
  393. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/harness/load/profiles/soak.toml +0 -0
  394. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/harness/load/report.py +0 -0
  395. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/harness/load/runner.py +0 -0
  396. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/harness/load/sender.py +0 -0
  397. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/harness/load/sink.py +0 -0
  398. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/harness/mllp.py +0 -0
  399. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/harness/monitor.py +0 -0
  400. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/harness/receive.py +0 -0
  401. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/harness/reconcile/__init__.py +0 -0
  402. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/harness/reconcile/__main__.py +0 -0
  403. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/harness/reconcile/compare.py +0 -0
  404. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/harness/reconcile/normalize.py +0 -0
  405. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/harness/reconcile/report.py +0 -0
  406. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/harness/scenarios.py +0 -0
  407. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/harness/send.py +0 -0
  408. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/harness/window.py +0 -0
  409. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/ide/.gitignore +0 -0
  410. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/ide/.vscodeignore +0 -0
  411. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/ide/esbuild.js +0 -0
  412. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/ide/media/hl7schema.json +0 -0
  413. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/ide/media/icon.png +0 -0
  414. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/ide/media/icon.svg +0 -0
  415. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/ide/package-lock.json +0 -0
  416. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/ide/snippets/messagefoundry.code-snippets +0 -0
  417. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/ide/src/aiPolicy.ts +0 -0
  418. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/ide/src/auth.ts +0 -0
  419. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/ide/src/completion.ts +0 -0
  420. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/ide/src/connectionEditor.ts +0 -0
  421. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/ide/src/engineClient.ts +0 -0
  422. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/ide/src/generate.ts +0 -0
  423. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/ide/src/git.ts +0 -0
  424. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/ide/src/graphTree.ts +0 -0
  425. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/ide/src/newRoute.ts +0 -0
  426. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/ide/src/promote.ts +0 -0
  427. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/ide/src/sourceControl.ts +0 -0
  428. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/ide/src/test/runTest.ts +0 -0
  429. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/ide/src/test/suite/extension.test.ts +0 -0
  430. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/ide/src/test/suite/index.ts +0 -0
  431. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/ide/src/testBench.ts +0 -0
  432. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/ide/src/validate.ts +0 -0
  433. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/ide/tsconfig.json +0 -0
  434. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/ide/tsconfig.test.json +0 -0
  435. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/mefor.code-workspace +0 -0
  436. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/messagefoundry/api/__init__.py +0 -0
  437. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/messagefoundry/api/approvals.py +0 -0
  438. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/messagefoundry/api/auth_models.py +0 -0
  439. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/messagefoundry/api/auth_routes.py +0 -0
  440. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/messagefoundry/api/field_authz.py +0 -0
  441. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/messagefoundry/api/security.py +0 -0
  442. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/messagefoundry/auth/__init__.py +0 -0
  443. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/messagefoundry/auth/data/common_passwords.NOTICE +0 -0
  444. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/messagefoundry/auth/data/common_passwords.txt +0 -0
  445. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/messagefoundry/auth/identity.py +0 -0
  446. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/messagefoundry/auth/ldap.py +0 -0
  447. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/messagefoundry/auth/notifications.py +0 -0
  448. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/messagefoundry/auth/passwords.py +0 -0
  449. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/messagefoundry/auth/permissions.py +0 -0
  450. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/messagefoundry/auth/policy.py +0 -0
  451. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/messagefoundry/auth/ratelimit.py +0 -0
  452. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/messagefoundry/auth/service.py +0 -0
  453. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/messagefoundry/auth/tokens.py +0 -0
  454. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/messagefoundry/auth/totp.py +0 -0
  455. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/messagefoundry/config/__init__.py +0 -0
  456. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/messagefoundry/config/active_environment.py +0 -0
  457. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/messagefoundry/config/ai_policy.py +0 -0
  458. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/messagefoundry/config/code_sets.py +0 -0
  459. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/messagefoundry/config/connections_edit.py +0 -0
  460. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/messagefoundry/config/connections_file.py +0 -0
  461. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/messagefoundry/config/db_lookup.py +0 -0
  462. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/messagefoundry/config/environments.py +0 -0
  463. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/messagefoundry/config/ingest_time.py +0 -0
  464. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/messagefoundry/config/reference.py +0 -0
  465. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/messagefoundry/config/response.py +0 -0
  466. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/messagefoundry/config/run_context.py +0 -0
  467. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/messagefoundry/config/state.py +0 -0
  468. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/messagefoundry/config/tls_policy.py +0 -0
  469. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/messagefoundry/console/__init__.py +0 -0
  470. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/messagefoundry/console/_async.py +0 -0
  471. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/messagefoundry/console/change_password.py +0 -0
  472. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/messagefoundry/console/login.py +0 -0
  473. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/messagefoundry/console/mfa.py +0 -0
  474. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/messagefoundry/console/reauth.py +0 -0
  475. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/messagefoundry/console/search.py +0 -0
  476. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/messagefoundry/console/sessions.py +0 -0
  477. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/messagefoundry/console/status.py +0 -0
  478. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/messagefoundry/console/users_page.py +0 -0
  479. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/messagefoundry/generators/README.md +0 -0
  480. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/messagefoundry/generators/__init__.py +0 -0
  481. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/messagefoundry/generators/_core.py +0 -0
  482. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/messagefoundry/generators/_hl7data.py +0 -0
  483. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/messagefoundry/generators/adt.py +0 -0
  484. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/messagefoundry/generators/all_types.py +0 -0
  485. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/messagefoundry/generators/bar.py +0 -0
  486. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/messagefoundry/generators/dft.py +0 -0
  487. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/messagefoundry/generators/mdm.py +0 -0
  488. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/messagefoundry/generators/mfn.py +0 -0
  489. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/messagefoundry/generators/oml.py +0 -0
  490. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/messagefoundry/generators/orl.py +0 -0
  491. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/messagefoundry/generators/orm.py +0 -0
  492. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/messagefoundry/generators/oru.py +0 -0
  493. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/messagefoundry/generators/ras.py +0 -0
  494. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/messagefoundry/generators/rde.py +0 -0
  495. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/messagefoundry/generators/siu.py +0 -0
  496. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/messagefoundry/generators/vxu.py +0 -0
  497. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/messagefoundry/hl7schema.py +0 -0
  498. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/messagefoundry/last_resort.py +0 -0
  499. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/messagefoundry/logging_setup.py +0 -0
  500. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/messagefoundry/parsing/consistency.py +0 -0
  501. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/messagefoundry/parsing/groups.py +0 -0
  502. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/messagefoundry/parsing/peek.py +0 -0
  503. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/messagefoundry/parsing/split.py +0 -0
  504. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/messagefoundry/parsing/summary.py +0 -0
  505. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/messagefoundry/parsing/tree.py +0 -0
  506. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/messagefoundry/parsing/validate.py +0 -0
  507. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/messagefoundry/parsing/x12/__init__.py +0 -0
  508. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/messagefoundry/parsing/x12/delimiters.py +0 -0
  509. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/messagefoundry/parsing/x12/errors.py +0 -0
  510. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/messagefoundry/parsing/x12/interchange.py +0 -0
  511. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/messagefoundry/parsing/x12/message.py +0 -0
  512. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/messagefoundry/parsing/x12/peek.py +0 -0
  513. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/messagefoundry/pipeline/__init__.py +0 -0
  514. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/messagefoundry/pipeline/alert_sinks.py +0 -0
  515. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/messagefoundry/pipeline/alerts.py +0 -0
  516. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/messagefoundry/pipeline/cert_expiry.py +0 -0
  517. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/messagefoundry/pipeline/config_convergence.py +0 -0
  518. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/messagefoundry/pipeline/dryrun.py +0 -0
  519. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/messagefoundry/pipeline/reference_sync.py +0 -0
  520. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/messagefoundry/pipeline/retention.py +0 -0
  521. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/messagefoundry/pipeline/security_notify.py +0 -0
  522. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/messagefoundry/pipeline/state_convergence.py +0 -0
  523. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/messagefoundry/py.typed +0 -0
  524. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/messagefoundry/redaction.py +0 -0
  525. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/messagefoundry/secrets_dpapi.py +0 -0
  526. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/messagefoundry/store/__init__.py +0 -0
  527. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/messagefoundry/store/audit_tee.py +0 -0
  528. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/messagefoundry/store/crypto.py +0 -0
  529. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/messagefoundry/store/keyprovider.py +0 -0
  530. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/messagefoundry/timezone.py +0 -0
  531. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/messagefoundry/transports/base.py +0 -0
  532. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/messagefoundry/transports/database.py +0 -0
  533. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/messagefoundry/transports/file.py +0 -0
  534. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/messagefoundry/transports/framing.py +0 -0
  535. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/messagefoundry/transports/loopback.py +0 -0
  536. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/messagefoundry/transports/remotefile.py +0 -0
  537. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/messagefoundry/transports/soap.py +0 -0
  538. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/messagefoundry/transports/tcp.py +0 -0
  539. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/messagefoundry/transports/timer.py +0 -0
  540. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/messagefoundry/transports/x12.py +0 -0
  541. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/samples/config/IB_ACME_ADT.py +0 -0
  542. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/samples/config/IB_IMMUNIZATION_VXU.py +0 -0
  543. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/samples/config/IB_PARTNER_X12.py +0 -0
  544. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/samples/config/IB_RTE_ELIGIBILITY.py +0 -0
  545. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/samples/config/adt.py +0 -0
  546. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/samples/config/codesets/event_labels.csv +0 -0
  547. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/samples/config/codesets/facility_mnemonics.toml +0 -0
  548. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/samples/config/connections.toml +0 -0
  549. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/samples/consistency/validated_adt.py +0 -0
  550. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/samples/messages/adt_a01.hl7 +0 -0
  551. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/samples/messages/adt_batch.hl7 +0 -0
  552. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/samples/messages/hapi-hl7v2/.gitattributes +0 -0
  553. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/samples/messages/hapi-hl7v2/README.md +0 -0
  554. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/samples/messages/hapi-hl7v2/adt_a01.txt +0 -0
  555. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/samples/messages/hapi-hl7v2/adt_a03.txt +0 -0
  556. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/samples/messages/hapi-hl7v2/batch_18_messages.txt +0 -0
  557. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/samples/messages/hapi-hl7v2/erp_z99_v231.hl7 +0 -0
  558. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/samples/messages/hapi-hl7v2/omd_o03.txt +0 -0
  559. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/samples/messages/hapi-hl7v2/omd_o03_rep.txt +0 -0
  560. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/samples/messages/hapi-hl7v2/oml_o21.hl7 +0 -0
  561. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/samples/messages/x12_270_eligibility.edi +0 -0
  562. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/samples/results_relay/README.md +0 -0
  563. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/samples/results_relay/codesets/test_codes.csv +0 -0
  564. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/samples/results_relay/messages/oru_all_cancelled.hl7 +0 -0
  565. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/samples/results_relay/messages/oru_results.hl7 +0 -0
  566. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/samples/results_relay/results_relay.py +0 -0
  567. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/samples/send_mllp.py +0 -0
  568. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/scripts/dev/postgres.ps1 +0 -0
  569. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/scripts/dev/sqlserver.ps1 +0 -0
  570. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/scripts/hooks/block-blanket-git-stage.ps1 +0 -0
  571. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/scripts/publish/publish-denylist.txt +0 -0
  572. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/scripts/service/install-service.ps1 +0 -0
  573. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/scripts/service/uninstall-service.ps1 +0 -0
  574. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/scripts/soak/store_soak.py +0 -0
  575. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/scripts/trace_icon.py +0 -0
  576. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/scripts/worktree/new.ps1 +0 -0
  577. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/scripts/worktree/remove.ps1 +0 -0
  578. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/scripts/worktree/session-context.ps1 +0 -0
  579. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/scripts/worktree/spawn.ps1 +0 -0
  580. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/tee/__init__.py +0 -0
  581. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/tee/compare.py +0 -0
  582. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/tee/correlate.py +0 -0
  583. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/tee/hl7_fields.py +0 -0
  584. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/tee/mllp.py +0 -0
  585. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/tee/report.py +0 -0
  586. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/tee/store.py +0 -0
  587. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/tests/_failover_load_support.py +0 -0
  588. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/tests/test_active_environment.py +0 -0
  589. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/tests/test_ad_group_scope.py +0 -0
  590. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/tests/test_admin_new_ip.py +0 -0
  591. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/tests/test_ai_policy.py +0 -0
  592. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/tests/test_alert_rules.py +0 -0
  593. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/tests/test_alert_sinks.py +0 -0
  594. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/tests/test_api.py +0 -0
  595. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/tests/test_api_auth.py +0 -0
  596. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/tests/test_api_reload.py +0 -0
  597. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/tests/test_api_tls.py +0 -0
  598. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/tests/test_approvals.py +0 -0
  599. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/tests/test_asvs_phase0.py +0 -0
  600. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/tests/test_audit_integrity.py +0 -0
  601. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/tests/test_audit_offbox_tee.py +0 -0
  602. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/tests/test_auth_core.py +0 -0
  603. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/tests/test_auth_entry_hardening.py +0 -0
  604. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/tests/test_auth_hardening.py +0 -0
  605. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/tests/test_auth_service.py +0 -0
  606. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/tests/test_auth_session_lifecycle.py +0 -0
  607. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/tests/test_auth_store.py +0 -0
  608. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/tests/test_cert_expiry.py +0 -0
  609. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/tests/test_channel_rbac.py +0 -0
  610. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/tests/test_cluster_failover_sqlserver.py +0 -0
  611. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/tests/test_cluster_lease.py +0 -0
  612. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/tests/test_code_sets.py +0 -0
  613. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/tests/test_connection_api.py +0 -0
  614. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/tests/test_connections_cli.py +0 -0
  615. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/tests/test_connections_file.py +0 -0
  616. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/tests/test_consistency.py +0 -0
  617. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/tests/test_console_auth.py +0 -0
  618. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/tests/test_console_password.py +0 -0
  619. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/tests/test_console_sessions.py +0 -0
  620. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/tests/test_console_step_up.py +0 -0
  621. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/tests/test_console_users.py +0 -0
  622. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/tests/test_database_connector_integration.py +0 -0
  623. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/tests/test_database_transport.py +0 -0
  624. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/tests/test_db_lookup.py +0 -0
  625. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/tests/test_delivery_settings.py +0 -0
  626. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/tests/test_dependency_boundaries.py +0 -0
  627. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/tests/test_dryrun.py +0 -0
  628. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/tests/test_egress_allowlist.py +0 -0
  629. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/tests/test_environments.py +0 -0
  630. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/tests/test_field_authz.py +0 -0
  631. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/tests/test_fifo_ordering.py +0 -0
  632. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/tests/test_generate_cli.py +0 -0
  633. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/tests/test_generated_adt.py +0 -0
  634. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/tests/test_generators_core.py +0 -0
  635. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/tests/test_generators_types.py +0 -0
  636. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/tests/test_groups.py +0 -0
  637. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/tests/test_harness.py +0 -0
  638. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/tests/test_harness_compose.py +0 -0
  639. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/tests/test_harness_config.py +0 -0
  640. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/tests/test_harness_faults.py +0 -0
  641. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/tests/test_harness_file.py +0 -0
  642. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/tests/test_harness_scenarios.py +0 -0
  643. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/tests/test_hl7schema.py +0 -0
  644. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/tests/test_inbound_bind.py +0 -0
  645. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/tests/test_ingest_time.py +0 -0
  646. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/tests/test_keyprovider.py +0 -0
  647. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/tests/test_last_resort.py +0 -0
  648. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/tests/test_load_corpus.py +0 -0
  649. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/tests/test_load_failover_unit.py +0 -0
  650. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/tests/test_load_metrics.py +0 -0
  651. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/tests/test_load_profile.py +0 -0
  652. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/tests/test_load_report.py +0 -0
  653. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/tests/test_load_sender.py +0 -0
  654. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/tests/test_load_sink.py +0 -0
  655. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/tests/test_logging.py +0 -0
  656. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/tests/test_message.py +0 -0
  657. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/tests/test_message_split.py +0 -0
  658. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/tests/test_mfa.py +0 -0
  659. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/tests/test_mllp_encoding_override.py +0 -0
  660. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/tests/test_operability_config.py +0 -0
  661. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/tests/test_outbound_signing.py +0 -0
  662. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/tests/test_outbound_simulate.py +0 -0
  663. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/tests/test_packaging.py +0 -0
  664. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/tests/test_parse_tree.py +0 -0
  665. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/tests/test_parsing.py +0 -0
  666. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/tests/test_reconcile_capture.py +0 -0
  667. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/tests/test_reconcile_compare.py +0 -0
  668. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/tests/test_reconcile_harness.py +0 -0
  669. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/tests/test_redaction.py +0 -0
  670. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/tests/test_reference_sets.py +0 -0
  671. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/tests/test_reingress.py +0 -0
  672. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/tests/test_remotefile_transport.py +0 -0
  673. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/tests/test_rest_transport.py +0 -0
  674. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/tests/test_run_context.py +0 -0
  675. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/tests/test_scan_forbidden.py +0 -0
  676. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/tests/test_secrets_dpapi.py +0 -0
  677. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/tests/test_security_notify.py +0 -0
  678. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/tests/test_security_static.py +0 -0
  679. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/tests/test_settings.py +0 -0
  680. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/tests/test_soap_transport.py +0 -0
  681. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/tests/test_soap_wssecurity.py +0 -0
  682. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/tests/test_sqlserver_coordinator.py +0 -0
  683. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/tests/test_step_up.py +0 -0
  684. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/tests/test_store_backend.py +0 -0
  685. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/tests/test_store_encryption.py +0 -0
  686. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/tests/test_store_file_hardening.py +0 -0
  687. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/tests/test_store_read_pool.py +0 -0
  688. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/tests/test_summary.py +0 -0
  689. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/tests/test_task_resilience.py +0 -0
  690. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/tests/test_tcp_transport.py +0 -0
  691. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/tests/test_tee_cli.py +0 -0
  692. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/tests/test_tee_compare.py +0 -0
  693. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/tests/test_tee_correlate.py +0 -0
  694. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/tests/test_tee_hl7_fields.py +0 -0
  695. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/tests/test_tee_mefor_api.py +0 -0
  696. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/tests/test_tee_mllp.py +0 -0
  697. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/tests/test_tee_relay.py +0 -0
  698. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/tests/test_tee_report.py +0 -0
  699. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/tests/test_tee_store.py +0 -0
  700. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/tests/test_timer_source.py +0 -0
  701. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/tests/test_timezone.py +0 -0
  702. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/tests/test_tls_policy.py +0 -0
  703. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/tests/test_totp.py +0 -0
  704. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/tests/test_transform_state.py +0 -0
  705. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/tests/test_transports.py +0 -0
  706. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/tests/test_version.py +0 -0
  707. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/tests/test_wiring.py +0 -0
  708. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/tests/test_wiring_reload.py +0 -0
  709. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/tests/test_x12_parsing.py +0 -0
  710. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/tests/test_x12_rte.py +0 -0
  711. {messagefoundry-0.1.0 → messagefoundry-0.2.0}/tests/test_x12_transport.py +0 -0
@@ -0,0 +1,45 @@
1
+ # SPDX-License-Identifier: AGPL-3.0-or-later
2
+ # Copyright (C) 2026 MessageFoundry Organization and contributors
3
+ #
4
+ # Keep the engine image build context small and free of anything sensitive. docker/Dockerfile COPYs
5
+ # only: pyproject.toml, README.md, LICENSE, NOTICE, messagefoundry/, and docker/locks/. Everything
6
+ # else is excluded so it can never end up in an image layer (PHI, secrets, the console, dev tooling).
7
+
8
+ # VCS / editor / caches
9
+ **/.git
10
+ **/.gitignore
11
+ **/.venv
12
+ **/__pycache__
13
+ **/*.pyc
14
+ **/.pytest_cache
15
+ **/.mypy_cache
16
+ **/.ruff_cache
17
+ **/.DS_Store
18
+
19
+ # Local stores / logs / secrets — never in an image
20
+ *.db
21
+ *.db-wal
22
+ *.db-shm
23
+ *.log
24
+ *.env
25
+ .env
26
+ **/*.pem
27
+ **/*.key
28
+
29
+ # Not needed in the engine image (console is host-side; tests/docs/samples/harness are not shipped)
30
+ .claude/
31
+ .github/
32
+ docs/
33
+ tests/
34
+ harness/
35
+ samples/
36
+ scripts/
37
+ environments/
38
+ ide/
39
+ node_modules/
40
+ migration-local/
41
+ out/
42
+
43
+ # The console package is GUI-only and must not be baked into the headless engine image. (The wheel
44
+ # build needs the rest of messagefoundry/, so only the console subpackage is excluded.)
45
+ messagefoundry/console/
@@ -40,6 +40,35 @@ window to ship a fix before any public detail, and we publish details (and credi
40
40
  a fix is available**. We'll keep you updated on progress and agree the disclosure timing with you.
41
41
  These windows trace to the project's Secure Development Standards (§4.4 RV.2, Appendix A.5).
42
42
 
43
+ ## Dependency (third-party) vulnerabilities
44
+
45
+ The table above is for vulnerabilities in **MessageFoundry's own code**, clocked from our triage. A
46
+ vulnerability in a **third-party dependency** is a different clock and a different priority signal, so
47
+ it has its own targets (this is deliberately distinct — the dependency fast lane below is ≤72h, which
48
+ is *not* a contradiction of the ≤7-day own-code window above):
49
+
50
+ - **Clock starts at upstream-fix availability**, not our triage — we generally cannot patch someone
51
+ else's library, so the SLA measures how fast we adopt the fix once it exists.
52
+ - **Exploitation pressure sets priority, not CVSS alone.** We triage **KEV-first** (on CISA's
53
+ Known-Exploited-Vulnerabilities list → patch now), then **EPSS** (≥ 0.7 = imminent), with **CVSS only
54
+ as a tiebreaker**, and we weigh **reachability** (is the package installed in a shipped profile, wired
55
+ into a running graph, and egress-reachable? — see
56
+ [`docs/security/SOUP-DEPENDENCY-HANDLING.md`](../docs/security/SOUP-DEPENDENCY-HANDLING.md)).
57
+
58
+ | Class | Trigger | Target (from upstream-fix availability) |
59
+ |---|---|---|
60
+ | **Tier-0 fast lane** | CISA **KEV** *or* **EPSS ≥ 0.7**, and reachable in a shipped profile | **≤ 72 hours** |
61
+ | Critical | CVSS critical, reachable | ≤ 14 days |
62
+ | High | CVSS high, reachable | ≤ 30 days |
63
+ | Medium | CVSS medium | ≤ 60–90 days |
64
+ | Low / unreachable | — | Best-effort; recorded with rationale |
65
+
66
+ **No upstream fix yet?** We apply a documented **compensating control** — pin the transitive dep out,
67
+ leave the affected extra uninstalled, or tighten the egress allow-list — and track to the fix. Detection
68
+ feeds this lane automatically: blocking `pip-audit`/`npm-audit` against the hash-locked tree, a **daily**
69
+ `security.yml` cron (a CVE against an unchanged pin is caught in ~24h), and grouped Dependabot security
70
+ PRs. The step-by-step response is [`docs/security/DEP-CVE-RUNBOOK.md`](../docs/security/DEP-CVE-RUNBOOK.md).
71
+
43
72
  ## Scope notes
44
73
 
45
74
  - The engine binds `127.0.0.1` by default and requires authentication; the documented threat
@@ -0,0 +1,54 @@
1
+ # Dependabot: surface vulnerable / outdated dependencies and CI actions as PRs (CI-1 / DEP-1).
2
+ # Until a committed lockfile lands, this is the primary signal for a known-CVE dependency.
3
+ version: 2
4
+ updates:
5
+ # Python deps via the native "uv" ecosystem (was "pip"). The uv ecosystem resolves against
6
+ # pyproject.toml + uv.lock and REGENERATES uv.lock IN its PRs (version updates GA 2025-03,
7
+ # security updates GA 2025-12) — the old "pip" ecosystem updated requirements/pyproject but NOT
8
+ # uv.lock. It still does not re-derive the EXPORTED locks (requirements.lock + docker/locks/*),
9
+ # which the DEP-1 gate in security.yml byte-diffs; .github/workflows/dependabot-lock-resync.yml
10
+ # re-exports those on the Dependabot branch so the gate stays green.
11
+ - package-ecosystem: "uv"
12
+ directory: "/"
13
+ schedule:
14
+ interval: "weekly"
15
+ open-pull-requests-limit: 10
16
+ # Supply-chain cooldown: age a fresh release before opening a ROUTINE update PR, to dodge a
17
+ # package compromised shortly after publish. Security updates ignore cooldown (Dependabot
18
+ # behavior), so a real advisory fix still arrives immediately. Pairs with the auto-merge
19
+ # workflow: routine patches auto-merge AFTER aging; security patches auto-merge now.
20
+ cooldown:
21
+ default-days: 3
22
+ semver-major-days: 7
23
+ groups:
24
+ # Version-update grouping (applies-to defaults to version-updates).
25
+ python-deps:
26
+ patterns: ["*"]
27
+ # Security-update grouping: collapse multiple vulnerable-dep fixes into ONE PR so a single
28
+ # review/merge clears them — faster remediation when several CVEs land together.
29
+ python-security:
30
+ applies-to: security-updates
31
+ patterns: ["*"]
32
+
33
+ - package-ecosystem: "github-actions"
34
+ directory: "/"
35
+ schedule:
36
+ interval: "weekly"
37
+
38
+ # The VS Code extension's npm tree (build-time toolchain — the shipped artifact is the esbuild
39
+ # bundle). Surfaces a vulnerable/outdated npm dep as a PR, the same DEP-1 surveillance the uv
40
+ # ecosystem gets; the blocking npm-audit job in security.yml is the fail-closed companion.
41
+ - package-ecosystem: "npm"
42
+ directory: "/ide"
43
+ schedule:
44
+ interval: "weekly"
45
+ open-pull-requests-limit: 10
46
+ cooldown:
47
+ default-days: 3
48
+ semver-major-days: 7
49
+ groups:
50
+ ide-deps:
51
+ patterns: ["*"]
52
+ ide-security:
53
+ applies-to: security-updates
54
+ patterns: ["*"]
@@ -27,7 +27,7 @@ jobs:
27
27
  name: baseline (sqlite)
28
28
  runs-on: ubuntu-latest
29
29
  steps:
30
- - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6
30
+ - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
31
31
  - name: Set up Python
32
32
  uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6
33
33
  with:
@@ -88,7 +88,7 @@ jobs:
88
88
  MEFOR_STORE_ENCRYPT: "false" # plaintext to the container; the TLS-hardening guard needs the escape
89
89
  MEFOR_ALLOW_INSECURE_TLS: "1"
90
90
  steps:
91
- - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6
91
+ - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
92
92
  - name: Set up Python
93
93
  uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6
94
94
  with:
@@ -155,7 +155,7 @@ jobs:
155
155
  MEFOR_STORE_TRUST_SERVER_CERTIFICATE: "true"
156
156
  MEFOR_ALLOW_INSECURE_TLS: "1"
157
157
  steps:
158
- - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6
158
+ - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
159
159
  - name: Set up Python
160
160
  uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6
161
161
  with:
@@ -11,16 +11,26 @@ concurrency:
11
11
  cancel-in-progress: true
12
12
 
13
13
  jobs:
14
- # Lint + type-check + unit tests. The Python-version matrix runs on Linux
15
- # (cheap); Windows Server 2022 + 2025 are added for OS coverage on the exact
16
- # versions we deploy to (one Python each to keep Windows minutes down they
17
- # bill at 2x on a private repo).
14
+ # Lint + type-check + unit tests. Linux carries the cheap breadth — the 3.11
15
+ # floor plus a fast early-fail leg on the newest 3.14 (1x minutes). Windows
16
+ # Server 2022 + 2025 is the primary deployment target, so it covers BOTH the
17
+ # current (3.13) and the new (3.14) deploy Python on each Server SKU, even
18
+ # though Windows bills at 2x — testing the version we ship on the OS we ship it
19
+ # on is worth the minutes.
18
20
  test:
19
21
  name: test (${{ matrix.os }}, py${{ matrix.python-version }})
20
22
  runs-on: ${{ matrix.os }}
21
- # Backstop for the intermittent py3.11 pytest wedge (BACKLOG #17): bound the leg's wall-clock so a
22
- # hang fails in minutes, not the 6h default. The pytest-timeout watchdog (60s/test) should catch the
23
- # culprit first; this is the belt-and-suspenders cap if the whole process deadlocks below pytest.
23
+ # py3.11 is a REQUIRED gate again (BACKLOG #17 RESOLVED in PR #448). The intermittent py3.11-only hang
24
+ # was root-caused and reproduced on a Docker py3.11 box as a CPython 3.11 asyncio cancellation race:
25
+ # cancelling a task parked in asyncio.Queue.get() can intermittently never complete (fixed in CPython
26
+ # 3.12, hence py3.13 was always clean and production — one long-lived loop — never hit it). TeeRelay.stop()
27
+ # tripped it; fixed via a sentinel shutdown in tee/relay.py, validated at 0 hangs across 24 full-suite +
28
+ # 40 isolated runs in the repro container and green on CI. So the advisory `continue-on-error` is removed
29
+ # and a py3.11 failure reds the build again. (The dormant `MEFOR_PY311_QUARANTINE` conftest lever stays as
30
+ # an off-by-default safety net; it is no longer needed.)
31
+ # Wall-clock backstop: bound each leg so a hung test fails in minutes, not the 6h default. The
32
+ # pytest-timeout watchdog (60s/test) should catch a culprit first; this is the belt-and-suspenders cap
33
+ # if a whole process ever deadlocks below pytest (e.g. a future regression of BACKLOG #17).
24
34
  timeout-minutes: 15
25
35
  strategy:
26
36
  fail-fast: false
@@ -28,14 +38,17 @@ jobs:
28
38
  include:
29
39
  - { os: ubuntu-latest, python-version: "3.11" }
30
40
  - { os: ubuntu-latest, python-version: "3.13" }
41
+ - { os: ubuntu-latest, python-version: "3.14" }
31
42
  - { os: windows-2022, python-version: "3.13" }
43
+ - { os: windows-2022, python-version: "3.14" }
32
44
  - { os: windows-2025, python-version: "3.13" }
45
+ - { os: windows-2025, python-version: "3.14" }
33
46
  defaults:
34
47
  run:
35
48
  shell: bash # available on all runners (Git Bash on Windows) -> one set of commands
36
49
 
37
50
  steps:
38
- - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6
51
+ - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
39
52
 
40
53
  - name: Set up Python ${{ matrix.python-version }}
41
54
  uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6
@@ -52,10 +65,15 @@ jobs:
52
65
  sudo apt-get update
53
66
  sudo apt-get install -y libegl1 libgl1 libxkbcommon0 libdbus-1-3
54
67
 
55
- - name: Install project (dev + console extras)
68
+ - name: Install project (dev + console + fhir + dicom extras)
56
69
  run: |
57
70
  python -m pip install --upgrade pip
58
- pip install -e ".[dev,console]"
71
+ # [fhir] so the FHIR typed-tier tests (incl. the PHI-no-leak invariant, ADR 0022) actually
72
+ # run their assertions in CI rather than importorskip-skipping (extra-less local runs skip).
73
+ # [dicom] (pydicom + pynetdicom; ADR 0025) does the same for the DICOM codec + C-STORE SCP
74
+ # tests, and lets mypy type-check transports/dicom.py + parsing/dicom/ against the real
75
+ # (py.typed) libraries rather than treating them as Any.
76
+ pip install -e ".[dev,console,fhir,dicom]"
59
77
 
60
78
  - name: Lint (ruff)
61
79
  run: ruff check messagefoundry tests
@@ -82,7 +100,7 @@ jobs:
82
100
  runs-on: ubuntu-latest
83
101
  timeout-minutes: 10
84
102
  steps:
85
- - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6
103
+ - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
86
104
  - name: Set up Python 3.11
87
105
  uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6
88
106
  with:
@@ -119,7 +137,7 @@ jobs:
119
137
  run:
120
138
  working-directory: ide
121
139
  steps:
122
- - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6
140
+ - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
123
141
 
124
142
  - name: Set up Node
125
143
  uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6
@@ -150,18 +168,21 @@ jobs:
150
168
  # switch to an always-run job whose heavy steps are step-gated, since the service container starts
151
169
  # before steps.)
152
170
  changes:
153
- name: detect server-DB changes
171
+ name: detect server-DB + docker changes
154
172
  runs-on: ubuntu-latest
155
173
  outputs:
156
174
  serverdb: ${{ steps.f.outputs.serverdb }}
175
+ docker: ${{ steps.f.outputs.docker }}
157
176
  steps:
158
- - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6
177
+ - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
159
178
  with:
160
179
  fetch-depth: 0
161
180
  - id: f
162
181
  run: |
163
182
  if [ "${{ github.event_name }}" != "pull_request" ]; then
164
- echo "serverdb=true" >> "$GITHUB_OUTPUT"; exit 0
183
+ echo "serverdb=true" >> "$GITHUB_OUTPUT"
184
+ echo "docker=true" >> "$GITHUB_OUTPUT"
185
+ exit 0
165
186
  fi
166
187
  changed=$(git diff --name-only "${{ github.event.pull_request.base.sha }}...HEAD")
167
188
  if echo "$changed" | grep -qE '^(messagefoundry/store/|messagefoundry/pipeline/cluster|messagefoundry/transports/database|tests/test_(sqlserver|postgres|cluster|database_connector)|\.github/workflows/ci\.yml)'; then
@@ -169,6 +190,13 @@ jobs:
169
190
  else
170
191
  echo "serverdb=false" >> "$GITHUB_OUTPUT"
171
192
  fi
193
+ # The container image smoke runs on PRs that touch the image, the per-profile locks, packaging,
194
+ # or this workflow (engine-wide regressions are already covered by the `test` job + push-to-main).
195
+ if echo "$changed" | grep -qE '^(docker/|\.dockerignore|pyproject\.toml|requirements\.lock|\.github/workflows/ci\.yml)'; then
196
+ echo "docker=true" >> "$GITHUB_OUTPUT"
197
+ else
198
+ echo "docker=false" >> "$GITHUB_OUTPUT"
199
+ fi
172
200
 
173
201
  # SQL Server service-container leg: runs the gated suites that need a real SQL Server (Linux, so 1x
174
202
  # minutes) — the PRODUCTION store backend suite AND the PRODUCTION DATABASE connector round-trip
@@ -178,13 +206,23 @@ jobs:
178
206
  # in branch protection so a T-SQL regression can't merge. Exercises the T-SQL + the live aioodbc
179
207
  # round-trip the SQLite / faked-driver tests can't.
180
208
  sqlserver-store:
181
- name: sql server (store + connector)
209
+ name: sql server (store + connector) ${{ matrix.label }}
182
210
  needs: changes
183
211
  if: github.event_name != 'pull_request' || needs.changes.outputs.serverdb == 'true'
184
212
  runs-on: ubuntu-latest
213
+ # Matrix the gated suite across every supported SQL Server major (2022 = 16.x, 2025 = 17.x) so a
214
+ # version-specific T-SQL / engine regression can't merge. fail-fast: false keeps a 2025-only hiccup
215
+ # from cancelling the 2022 leg (and vice-versa). The `changes` path-filter still gates this on PRs, so
216
+ # matrixing only doubles the (rate-limited) mcr pulls on server-DB PRs + pushes to main.
217
+ strategy:
218
+ fail-fast: false
219
+ matrix:
220
+ include:
221
+ - { image: "mcr.microsoft.com/mssql/server:2022-latest", label: "2022" }
222
+ - { image: "mcr.microsoft.com/mssql/server:2025-latest", label: "2025" }
185
223
  services:
186
224
  mssql:
187
- image: mcr.microsoft.com/mssql/server:2022-latest
225
+ image: ${{ matrix.image }}
188
226
  env:
189
227
  ACCEPT_EULA: "Y"
190
228
  MSSQL_SA_PASSWORD: "Str0ng_P@ssw0rd!"
@@ -192,7 +230,7 @@ jobs:
192
230
  - 1433:1433
193
231
 
194
232
  steps:
195
- - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6
233
+ - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
196
234
 
197
235
  - name: Set up Python
198
236
  uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6
@@ -211,7 +249,7 @@ jobs:
211
249
  - name: Wait for SQL Server and create the database
212
250
  run: |
213
251
  sqlcmd=/opt/mssql-tools18/bin/sqlcmd
214
- for i in $(seq 1 40); do
252
+ for i in $(seq 1 60); do # ~120s cap: 2025's first boot can run slower than 2022's
215
253
  if "$sqlcmd" -S localhost -U sa -P 'Str0ng_P@ssw0rd!' -C -Q "SELECT 1" > /dev/null 2>&1; then
216
254
  echo "SQL Server is up"; break
217
255
  fi
@@ -336,7 +374,7 @@ jobs:
336
374
  --health-retries 5
337
375
 
338
376
  steps:
339
- - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6
377
+ - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
340
378
 
341
379
  - name: Set up Python
342
380
  uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6
@@ -394,7 +432,7 @@ jobs:
394
432
  if: github.event_name != 'pull_request'
395
433
  runs-on: ubuntu-latest
396
434
  steps:
397
- - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6
435
+ - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
398
436
 
399
437
  - name: Set up Python
400
438
  uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6
@@ -446,19 +484,27 @@ jobs:
446
484
  # profile (correctness SLOs strict; drain bound sized for a server DB). Skipped on PRs to save spend —
447
485
  # runs on push to main + on-demand (workflow_dispatch). Heavier SQL Server profiles run manually.
448
486
  load-test-sqlserver:
449
- name: load test (smoke, sqlserver)
487
+ name: load test (smoke, sqlserver) ${{ matrix.label }}
450
488
  if: github.event_name != 'pull_request'
451
489
  runs-on: ubuntu-latest
490
+ # Smoke the end-to-end SQL Server store path on every supported major (2022/2025). Push/dispatch-only,
491
+ # so no PR cost; fail-fast: false keeps the two legs independent.
492
+ strategy:
493
+ fail-fast: false
494
+ matrix:
495
+ include:
496
+ - { image: "mcr.microsoft.com/mssql/server:2022-latest", label: "2022" }
497
+ - { image: "mcr.microsoft.com/mssql/server:2025-latest", label: "2025" }
452
498
  services:
453
499
  mssql:
454
- image: mcr.microsoft.com/mssql/server:2022-latest
500
+ image: ${{ matrix.image }}
455
501
  env:
456
502
  ACCEPT_EULA: "Y"
457
503
  MSSQL_SA_PASSWORD: "Str0ng_P@ssw0rd!"
458
504
  ports:
459
505
  - 1433:1433
460
506
  steps:
461
- - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6
507
+ - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
462
508
 
463
509
  - name: Set up Python
464
510
  uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6
@@ -477,7 +523,7 @@ jobs:
477
523
  - name: Wait for SQL Server and create the database (RCSI on, like the store suite)
478
524
  run: |
479
525
  sqlcmd=/opt/mssql-tools18/bin/sqlcmd
480
- for i in $(seq 1 40); do
526
+ for i in $(seq 1 60); do # ~120s cap: 2025's first boot can run slower than 2022's
481
527
  if "$sqlcmd" -S localhost -U sa -P 'Str0ng_P@ssw0rd!' -C -Q "SELECT 1" > /dev/null 2>&1; then
482
528
  echo "SQL Server is up"; break
483
529
  fi
@@ -538,29 +584,41 @@ jobs:
538
584
  # confirm it was recorded -> stop -> uninstall. Skipped on PRs to save Windows
539
585
  # minutes; runs on push to main and on-demand (workflow_dispatch).
540
586
  windows-service-smoke:
541
- name: windows service smoke (${{ matrix.os }})
587
+ name: windows service smoke (${{ matrix.os }}, py${{ matrix.python-version }})
542
588
  if: github.event_name != 'pull_request'
543
589
  runs-on: ${{ matrix.os }}
544
590
  strategy:
545
591
  fail-fast: false
546
592
  matrix:
547
- os: [windows-2022, windows-2025]
593
+ # Windows Server 2022 + 2025 on the current deploy Python (3.13); plus the new 3.14 deploy
594
+ # target on 2025 (newest Server) so the real NSSM install->serve->MLLP path is validated on
595
+ # the version we will ship. This job is push/dispatch-only, so the extra leg costs no PR time.
596
+ include:
597
+ - { os: windows-2022, python-version: "3.13" }
598
+ - { os: windows-2025, python-version: "3.13" }
599
+ - { os: windows-2025, python-version: "3.14" }
548
600
  defaults:
549
601
  run:
550
602
  shell: pwsh
551
603
 
552
604
  steps:
553
- - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6
605
+ - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
554
606
 
555
607
  - name: Set up Python
556
608
  uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6
557
609
  with:
558
- python-version: "3.13"
610
+ python-version: ${{ matrix.python-version }}
559
611
 
560
- - name: Install the engine
612
+ - name: Install the engine (fhir + dicom extras)
561
613
  run: |
562
614
  python -m pip install --upgrade pip
563
- pip install -e .
615
+ # The samples/config graph this smoke serves uses the FHIR and DICOM connectors, and the
616
+ # DICOM inbound binds a DIMSE C-STORE SCP at startup (transports/dicom.py imports pynetdicom
617
+ # eagerly on start) — so a bare `pip install -e .` makes the engine fail-close at wiring with
618
+ # ModuleNotFoundError and /health never comes up. Install the connector extras the graph needs
619
+ # (the "real Windows service path" a user running this graph would install). Keep in sync with
620
+ # the connectors used in samples/config.
621
+ pip install -e ".[fhir,dicom]"
564
622
 
565
623
  # Run the install/uninstall scripts under Windows PowerShell 5.1 (shell: powershell) to
566
624
  # match what the console launches on an end-user machine — catches 5.1-only behaviour
@@ -602,17 +660,22 @@ jobs:
602
660
  # since no VXU is sent; the non-secret endpoints live in environments/prod.toml (selected by
603
661
  # the -Environment prod passed to install-service.ps1 above).
604
662
  # `prod` also FAIL-CLOSES on unrestricted egress (a transform could send PHI anywhere): lock it
605
- # down (deny_by_default) AND allowlist the samples/config graph's 6 outbound destinations, or the
663
+ # down (deny_by_default) AND allowlist the samples/config graph's 8 outbound destinations, or the
606
664
  # engine refuses to start at wiring. [egress] is SERVICE settings (MEFOR_EGRESS_*), NOT an
607
665
  # environments/<env>.toml value; lists are comma-separated host:port matching the resolved
608
- # prod.toml endpoints (MLLP->allowed_mllp; X12->allowed_tcp; SOAP->allowed_http; File->allowed_file_dirs).
666
+ # prod.toml endpoints (MLLP->allowed_mllp; X12->allowed_tcp; SOAP+FHIR->allowed_http; File->allowed_file_dirs).
667
+ # NOTE keep this list in sync with samples/config when an outbound is added (e.g. OB_FHIR_SERVER) —
668
+ # the egress check fails fast on the FIRST denied dest, so a missing entry wedges service start.
669
+ # fhir-prod.example.org is allowlisted HOST-ONLY: its prod URL (https://fhir-prod.example.org/fhir)
670
+ # has no explicit port, so urlsplit().port is None and a ":443" suffix would NOT match (see
671
+ # _http_egress_allowed). A bare host matches any port, which is what we want for a default-port URL.
609
672
  nssm set MessageFoundry AppEnvironmentExtra `
610
673
  "MEFOR_AUTH_ENABLED=false" `
611
674
  "MEFOR_STORE_ENCRYPTION_KEY=$storeKey" `
612
675
  "MEFOR_EGRESS_DENY_BY_DEFAULT=true" `
613
- "MEFOR_EGRESS_ALLOWED_MLLP=receiver-prod.example.org:6661" `
676
+ "MEFOR_EGRESS_ALLOWED_MLLP=receiver-prod.example.org:6661,powerscribe-prod.example.org:6665" `
614
677
  "MEFOR_EGRESS_ALLOWED_TCP=payer-prod.example.org:6662,rte-prod.example.org:6663,rte-result-prod.example.org:6664" `
615
- "MEFOR_EGRESS_ALLOWED_HTTP=iis-prod.example.org:8443" `
678
+ "MEFOR_EGRESS_ALLOWED_HTTP=iis-prod.example.org:8443,fhir-prod.example.org" `
616
679
  "MEFOR_EGRESS_ALLOWED_FILE_DIRS=out" `
617
680
  "MEFOR_VALUE_REGISTRY_CLIENT_CERT=$cert" `
618
681
  "MEFOR_VALUE_REGISTRY_CLIENT_KEY=$key" `
@@ -644,6 +707,7 @@ jobs:
644
707
  "messages.total = $($msgs.total)"
645
708
 
646
709
  - name: Stop the service (graceful)
710
+ if: always()
647
711
  run: nssm stop MessageFoundry
648
712
 
649
713
  - name: Show service logs
@@ -665,6 +729,125 @@ jobs:
665
729
  if: always()
666
730
  uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7
667
731
  with:
668
- name: service-logs-${{ matrix.os }}
732
+ name: service-logs-${{ matrix.os }}-py${{ matrix.python-version }}
669
733
  path: C:\ProgramData\MessageFoundry\logs\
670
734
  if-no-files-found: ignore
735
+
736
+ # Container image smoke (the engine's FIRST non-Windows runtime target — it is Windows-service/NSSM
737
+ # first today). Builds the slim engine image, builds a test-only image that bakes a minimal ADT->file
738
+ # config + a self-contained MLLP sender (config baked, not mounted, so it is owned by the engine's UID
739
+ # and not group/world-writable — _assert_safe_config_source refuses otherwise), serves it loopback +
740
+ # auth-off, sends one synthetic ADT^A01 over the in-container MLLP listener, and asserts it FINALIZES
741
+ # to PROCESSED (not merely RECEIVED — that distinguishes ACK-on-receipt from final disposition). Then
742
+ # it verifies a graceful `docker stop`: tini forwards SIGTERM -> uvicorn lifespan -> engine.stop().
743
+ # Runs on push to main + dispatch always; on PRs only when the image/locks/packaging/this workflow
744
+ # change (gated by `changes`), so docs/unrelated PRs don't pay the build.
745
+ docker-smoke:
746
+ name: docker image smoke (slim, linux)
747
+ needs: changes
748
+ if: github.event_name != 'pull_request' || needs.changes.outputs.docker == 'true'
749
+ runs-on: ubuntu-latest
750
+ steps:
751
+ - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
752
+
753
+ - name: Build the slim engine image
754
+ run: docker build -f docker/Dockerfile -t messagefoundry:ci .
755
+
756
+ - name: Build the -sqlserver variant (ODBC apt layer + sqlserver lock must resolve)
757
+ # Build-only: it pulls the Microsoft ODBC repo + installs from requirements-sqlserver.lock, so a
758
+ # broken hashed dep or the Debian/MS-key issue the Dockerfile warns about turns the job red here.
759
+ run: docker build -f docker/Dockerfile --target runtime-sqlserver -t messagefoundry:sqlserver-ci .
760
+
761
+ - name: Build the test smoke image (baked minimal config + MLLP sender)
762
+ run: docker build -f docker/smoke/Dockerfile --build-arg BASE=messagefoundry:ci -t messagefoundry:smoke .
763
+
764
+ - name: Serve (loopback, auth off) and assert an MLLP message reaches PROCESSED
765
+ run: |
766
+ set -euo pipefail
767
+ # Bind the API + MLLP to loopback INSIDE the container and drive the test from inside it
768
+ # (docker exec). A non-loopback bind without TLS would be refused by the startup bind guard
769
+ # (and auth-off is refused off-loopback regardless of --allow-insecure-bind), so loopback +
770
+ # in-container traffic is the correct posture for an auth-disabled smoke — no insecure override.
771
+ docker run -d --name mefor -e MEFOR_AUTH_ENABLED=false messagefoundry:smoke \
772
+ serve --config /config --env dev --host 127.0.0.1 --port 8765
773
+ # Readiness: /health is tokenless and always 200 once the listener is up.
774
+ for _ in $(seq 1 60); do
775
+ docker exec mefor curl -fsS http://127.0.0.1:8765/health >/dev/null 2>&1 && break || sleep 0.5
776
+ done
777
+ docker exec mefor curl -fsS http://127.0.0.1:8765/health
778
+ # Send one synthetic ADT^A01 over the in-container MLLP listener (loopback:2575); fails on a non-AA ACK.
779
+ docker exec mefor python /smoke/send_adt.py 127.0.0.1 2575
780
+ # Poll the disposition via the container's own python (stdlib urllib — no host python/jq needed).
781
+ total() { docker exec mefor python -c "import urllib.request,json;print(json.load(urllib.request.urlopen('http://127.0.0.1:8765/messages?status=$1'))['total'])"; }
782
+ processed=0
783
+ for _ in $(seq 1 60); do
784
+ # `|| processed=0`: a transient non-zero before the row finalizes must NOT abort the loop under set -e.
785
+ processed=$(total processed) || processed=0
786
+ [ "$processed" -ge 1 ] && break || sleep 0.5
787
+ done
788
+ received=$(total received) || received=0
789
+ echo "processed=$processed received=$received"
790
+ # The whole point of the assert: confirm it FINALIZED, not just that it was acknowledged-on-receipt.
791
+ if [ "$processed" -lt 1 ]; then
792
+ echo "FAIL: message did not finalize to PROCESSED (received=$received) — stuck at ACK-on-receipt"
793
+ exit 1
794
+ fi
795
+
796
+ - name: Verify graceful shutdown (tini -> SIGTERM -> engine.stop drains)
797
+ run: |
798
+ set -euo pipefail
799
+ docker stop --time 30 mefor
800
+ code=$(docker inspect -f '{{.State.ExitCode}}' mefor)
801
+ echo "container exit code: $code"
802
+ # A fully graceful shutdown exits 0 (uvicorn handles SIGTERM, runs the lifespan, returns); 143
803
+ # (128+SIGTERM) is acceptable too. 137 = SIGKILL after the grace expired = ungraceful.
804
+ if [ "$code" = "137" ]; then echo "FAIL: ungraceful shutdown (SIGKILL after grace)"; exit 1; fi
805
+ docker logs mefor 2>&1 | grep -q "Application shutdown complete" \
806
+ || { echo "FAIL: no clean-shutdown marker (lifespan shutdown did not complete)"; exit 1; }
807
+ echo "graceful shutdown verified"
808
+
809
+ - name: Engine log (always)
810
+ if: always()
811
+ run: docker logs mefor 2>&1 | tail -60 || true
812
+
813
+ - name: Tear down
814
+ if: always()
815
+ run: docker rm -f mefor || true
816
+
817
+ # Single STABLE required status check standing in for the conditional / matrix heavy legs (SQL
818
+ # Server, Postgres, load, Windows-service smoke). Those legs CANNOT be required directly:
819
+ # * the push-only legs (`postgres-store`, `load-test`, `load-test-sqlserver`,
820
+ # `windows-service-smoke`) report `skipped` on every PR — never the required context a PR waits
821
+ # on — so requiring them either no-ops or wedges; and
822
+ # * the matrix legs report an UNEXPANDED name when skipped (`... ${{ matrix.label }}`) but
823
+ # EXPANDED names when they run (`... 2022`/`2025`, `(windows-2022, py3.13)`), so no single
824
+ # context string matches both the skipped and the run state.
825
+ # This gate ALWAYS runs (if: always()), so it reports ONE fixed context ("CI gate") regardless of
826
+ # which legs ran, and fails iff a gated leg actually FAILED or was cancelled — a `skipped` leg
827
+ # counts as a pass. Require "CI gate" in branch protection INSTEAD of the individual legs; a leg
828
+ # that does run on a PR (e.g. `sqlserver-store` on a server-DB PR) thus still blocks the merge.
829
+ # NB: `docker-smoke` is intentionally NOT gated here (out of the named set) — add it to `needs`
830
+ # below to make a container-smoke failure block merge too.
831
+ ci-gate:
832
+ name: CI gate
833
+ if: always()
834
+ needs:
835
+ - changes
836
+ - sqlserver-store
837
+ - postgres-store
838
+ - load-test
839
+ - load-test-sqlserver
840
+ - windows-service-smoke
841
+ runs-on: ubuntu-latest
842
+ steps:
843
+ - name: Fail if any gated leg failed or was cancelled
844
+ if: >-
845
+ contains(needs.*.result, 'failure') ||
846
+ contains(needs.*.result, 'cancelled')
847
+ run: |
848
+ echo "::error::A gated CI leg failed or was cancelled."
849
+ echo '${{ toJSON(needs) }}'
850
+ exit 1
851
+
852
+ - name: Gated legs OK
853
+ run: echo "All gated CI legs succeeded or were skipped."
@@ -0,0 +1,58 @@
1
+ name: Dependabot auto-merge
2
+
3
+ # Scoped auto-merge for Dependabot PRs (A4 of the dependency fast-response plan).
4
+ #
5
+ # SAFE because main's required status checks are the gate: the full pytest suite, pip-audit, the
6
+ # DEP-1 lock-sync check (incl. the A3 lock-resync commit), bandit/semgrep/gitleaks all must pass
7
+ # before GitHub completes the merge. A bad bump turns CI red and never merges — auto-merge only
8
+ # removes the human-latency on the safe, common case, not the safety net.
9
+ #
10
+ # IN SCOPE (auto-merged):
11
+ # - any PATCH update (incl. security patches — most security fixes are patches)
12
+ # - MINOR updates of DEV-only dependencies
13
+ # OUT OF SCOPE (left for human review, surfaced same-day by the daily security cron + alerts):
14
+ # - MINOR/MAJOR updates of runtime deps, and ALL MAJOR updates
15
+ #
16
+ # Fresh-release supply-chain poisoning is handled upstream by the dependabot.yml `cooldown`
17
+ # (routine updates age before a PR opens); SECURITY updates bypass cooldown by design, so a real
18
+ # advisory fix still arrives immediately and (if a patch) auto-merges.
19
+ #
20
+ # Why `pull_request` (not pull_request_target): a Dependabot `pull_request` run gets a read-only
21
+ # GITHUB_TOKEN by default, which the `permissions:` block below elevates to exactly what the merge
22
+ # API needs — no untrusted-code-with-secrets exposure, no GitHub App required. This is the pattern
23
+ # GitHub documents for Dependabot auto-merge.
24
+
25
+ on: pull_request
26
+
27
+ permissions:
28
+ contents: write # complete the merge
29
+ pull-requests: write # enable auto-merge on the PR
30
+
31
+ concurrency:
32
+ group: dependabot-automerge-${{ github.event.pull_request.number }}
33
+ cancel-in-progress: false
34
+
35
+ jobs:
36
+ auto-merge:
37
+ runs-on: ubuntu-latest
38
+ # Only Dependabot's own PRs. pull_request.user.login is the immutable PR author, so an A3
39
+ # lock-resync `synchronize` (pushed by the App) still satisfies this — the author stays
40
+ # dependabot[bot] even though the triggering actor is the App.
41
+ if: github.event.pull_request.user.login == 'dependabot[bot]'
42
+ timeout-minutes: 10
43
+ steps:
44
+ - name: Fetch Dependabot metadata
45
+ id: meta
46
+ uses: dependabot/fetch-metadata@25dd0e34f4fe68f24cc83900b1fe3fe149efef98 # v3.1.0
47
+ with:
48
+ github-token: ${{ secrets.GITHUB_TOKEN }}
49
+
50
+ - name: Enable auto-merge for in-scope updates
51
+ if: >-
52
+ steps.meta.outputs.update-type == 'version-update:semver-patch' ||
53
+ (steps.meta.outputs.update-type == 'version-update:semver-minor' &&
54
+ steps.meta.outputs.dependency-type == 'direct:development')
55
+ run: gh pr merge --auto --squash "$PR_URL"
56
+ env:
57
+ PR_URL: ${{ github.event.pull_request.html_url }}
58
+ GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}