messagefoundry 0.2.0__tar.gz → 0.2.1__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 (706) hide show
  1. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/.github/workflows/release-sync-check.yml +6 -0
  2. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/.github/workflows/security.yml +9 -2
  3. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/CHANGELOG.md +18 -1
  4. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/PKG-INFO +1 -1
  5. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/messagefoundry/__init__.py +1 -1
  6. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/messagefoundry/__main__.py +18 -3
  7. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/messagefoundry/api/app.py +57 -3
  8. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/messagefoundry/api/models.py +21 -1
  9. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/messagefoundry/console/__init__.py +16 -1
  10. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/messagefoundry/console/client.py +19 -1
  11. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/messagefoundry/console/connections.py +39 -1
  12. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/messagefoundry/pipeline/engine.py +88 -0
  13. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/messagefoundry/verify/checks.py +7 -1
  14. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/tests/test_anon_core.py +13 -0
  15. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/tests/test_anon_parity.py +5 -0
  16. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/tests/test_cli.py +18 -0
  17. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/tests/test_console_widgets.py +75 -0
  18. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/tests/test_load_config.py +7 -0
  19. messagefoundry-0.2.1/tests/test_stats_reset.py +238 -0
  20. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/tests/test_verify.py +39 -0
  21. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/.claude/settings.json +0 -0
  22. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/.dockerignore +0 -0
  23. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/.gitattributes +0 -0
  24. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/.github/CODEOWNERS +0 -0
  25. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
  26. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/.github/ISSUE_TEMPLATE/config.yml +0 -0
  27. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/.github/ISSUE_TEMPLATE/feature_request.md +0 -0
  28. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/.github/PULL_REQUEST_TEMPLATE.md +0 -0
  29. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/.github/SECURITY.md +0 -0
  30. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/.github/dependabot.yml +0 -0
  31. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/.github/workflows/benchmark.yml +0 -0
  32. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/.github/workflows/ci.yml +0 -0
  33. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/.github/workflows/cla.yml +0 -0
  34. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/.github/workflows/dependabot-auto-merge.yml +0 -0
  35. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/.github/workflows/dependabot-lock-resync.yml +0 -0
  36. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/.github/workflows/release.yml +0 -0
  37. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/.github/workflows/vuln-metrics.yml +0 -0
  38. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/.gitignore +0 -0
  39. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/.gitleaks.toml +0 -0
  40. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/.pre-commit-config.yaml +0 -0
  41. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/.semgrep/messagefoundry.yml +0 -0
  42. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/CLA.md +0 -0
  43. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/CLAUDE.md +0 -0
  44. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/CODE_OF_CONDUCT.md +0 -0
  45. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/COMMERCIAL-LICENSE.md +0 -0
  46. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/CONTRIBUTING.md +0 -0
  47. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/GOVERNANCE.md +0 -0
  48. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/LICENSE +0 -0
  49. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/MAINTAINERS.md +0 -0
  50. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/NOTICE +0 -0
  51. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/README.md +0 -0
  52. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/docker/Dockerfile +0 -0
  53. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/docker/README.md +0 -0
  54. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/docker/compose.yaml +0 -0
  55. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/docker/k8s/secret.example.yaml +0 -0
  56. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/docker/k8s/statefulset.yaml +0 -0
  57. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/docker/locks/requirements-core.lock +0 -0
  58. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/docker/locks/requirements-sqlserver.lock +0 -0
  59. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/docker/secrets.env.example +0 -0
  60. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/docker/smoke/Dockerfile +0 -0
  61. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/docker/smoke/config/IB_Test_ADT.py +0 -0
  62. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/docker/smoke/send_adt.py +0 -0
  63. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/docs/ADOPTER-CI.md +0 -0
  64. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/docs/AI.md +0 -0
  65. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/docs/ARCHITECTURE.md +0 -0
  66. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/docs/BACKLOG.md +0 -0
  67. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/docs/CI-QUALITY.md +0 -0
  68. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/docs/CLUSTERING.md +0 -0
  69. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/docs/CONFIGURATION.md +0 -0
  70. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/docs/CONNECTIONS.md +0 -0
  71. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/docs/CONTAINER-EXPOSURE-EVALUATION.md +0 -0
  72. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/docs/CONTRIBUTOR-FIRST-ISSUES.md +0 -0
  73. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/docs/CONTRIBUTOR-PROGRAM-PLAN.md +0 -0
  74. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/docs/COUNSEL-ENGAGEMENT-BRIEF.md +0 -0
  75. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/docs/DEPLOY-SERVER-DB.md +0 -0
  76. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/docs/DEPLOYMENT.md +0 -0
  77. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/docs/DICOM.md +0 -0
  78. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/docs/DUAL_LICENSING_PLAN.md +0 -0
  79. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/docs/EARLY-ADOPTER-GUIDE.md +0 -0
  80. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/docs/FEATURE-MAP.md +0 -0
  81. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/docs/HL7-VALIDATION.md +0 -0
  82. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/docs/INSTALL-GUIDE.md +0 -0
  83. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/docs/LOAD-TESTING.md +0 -0
  84. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/docs/MENTAL-MODEL.md +0 -0
  85. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/docs/MessageFoundry-Mental-Model.docx +0 -0
  86. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/docs/PHI.md +0 -0
  87. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/docs/REMOTE-CONSOLE-CUSTOMER-GUIDE.md +0 -0
  88. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/docs/REMOTE-CONSOLE.md +0 -0
  89. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/docs/SECURITY.md +0 -0
  90. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/docs/SERVICE.md +0 -0
  91. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/docs/SUPPORT-POLICY.md +0 -0
  92. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/docs/SYSTEM-REQUIREMENTS.md +0 -0
  93. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/docs/Secure_AI_Development_Standards.md +0 -0
  94. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/docs/Secure_Development_Standards.md +0 -0
  95. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/docs/TEE-RELAY.md +0 -0
  96. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/docs/THROUGHPUT-IMPROVEMENTS.md +0 -0
  97. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/docs/USER-GUIDE.md +0 -0
  98. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/docs/WORKTREES.md +0 -0
  99. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/docs/adr/0001-staged-pipeline-architecture.md +0 -0
  100. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/docs/adr/0002-phase2-transport-security-and-strong-auth.md +0 -0
  101. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/docs/adr/0003-non-hl7-transports-database-rest-soap.md +0 -0
  102. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/docs/adr/0004-payload-agnostic-ingress.md +0 -0
  103. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/docs/adr/0005-transform-accessible-state.md +0 -0
  104. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/docs/adr/0006-external-data-lookups.md +0 -0
  105. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/docs/adr/0007-gui-manageable-connections-toml.md +0 -0
  106. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/docs/adr/0008-cluster-observability-api.md +0 -0
  107. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/docs/adr/0009-run-scoped-context-providers.md +0 -0
  108. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/docs/adr/0010-handler-callable-db-lookup.md +0 -0
  109. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/docs/adr/0011-timer-scheduled-source.md +0 -0
  110. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/docs/adr/0012-x12-edi-codec.md +0 -0
  111. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/docs/adr/0013-increment-2-reingress-design.md +0 -0
  112. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/docs/adr/0013-query-response-orchestration.md +0 -0
  113. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/docs/adr/0014-alerting-rules-engine.md +0 -0
  114. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/docs/adr/0015-ws-soap-outbound-mtls-wssecurity.md +0 -0
  115. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/docs/adr/0016-synchronous-x12-request-response.md +0 -0
  116. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/docs/adr/0017-consumer-deployment-model.md +0 -0
  117. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/docs/adr/0018-per-message-signatures-accepted-risk.md +0 -0
  118. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/docs/adr/0019-pluggable-keyprovider-hsm-kms-vault.md +0 -0
  119. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/docs/adr/0020-protocol-diagnostic-capture.md +0 -0
  120. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/docs/adr/0021-inbound-ack-nak-capture-response-sent.md +0 -0
  121. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/docs/adr/0022-fhir-resource-codec-rest-client.md +0 -0
  122. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/docs/adr/0024-smart-backend-services-token-provider.md +0 -0
  123. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/docs/adr/0025-dicom-codec-store-connectors.md +0 -0
  124. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/docs/adr/0026-off-box-egress-update-check.md +0 -0
  125. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/docs/adr/0028-base64-binary-carriage-codec.md +0 -0
  126. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/docs/adr/0030-anonymization-test-harness-tee.md +0 -0
  127. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/docs/adr/0031-startup-connection-fault-isolation.md +0 -0
  128. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/docs/adr/0032-console-desktop-launch.md +0 -0
  129. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/docs/adr/README.md +0 -0
  130. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/docs/adr/TEMPLATE.md +0 -0
  131. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/docs/architecture-components.png +0 -0
  132. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/docs/architecture-components.svg +0 -0
  133. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/docs/architecture-config-graph.png +0 -0
  134. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/docs/architecture-config-graph.svg +0 -0
  135. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/docs/architecture-diagram.md +0 -0
  136. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/docs/architecture-message-flow.png +0 -0
  137. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/docs/architecture-message-flow.svg +0 -0
  138. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/docs/architecture-topology.png +0 -0
  139. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/docs/architecture-topology.svg +0 -0
  140. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/docs/benchmarks/TUNING-BASELINE.md +0 -0
  141. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/docs/benchmarks/results/2026-06-16-ci-linux/environment.txt +0 -0
  142. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/docs/benchmarks/results/2026-06-16-ci-linux/failover-postgres.json +0 -0
  143. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/docs/benchmarks/results/2026-06-16-ci-linux/failover-sqlserver.json +0 -0
  144. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/docs/benchmarks/results/2026-06-16-ci-linux/reference-postgres.json +0 -0
  145. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/docs/benchmarks/results/2026-06-16-ci-linux/reference-sqlite.json +0 -0
  146. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/docs/benchmarks/results/2026-06-16-ci-linux/reference-sqlserver.json +0 -0
  147. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/docs/benchmarks/step-b-write-amplification.md +0 -0
  148. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/docs/hl7-message-ordering-reference.md +0 -0
  149. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/docs/message-ordering-design.md +0 -0
  150. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/docs/releases/ASVS-OPTION-A-MULTISESSION-PLAN.md +0 -0
  151. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/docs/releases/ASVS-PARTIALS-SWEEP-MULTISESSION-PLAN.md +0 -0
  152. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/docs/releases/DOGFOOD-BACKLOG-MULTISESSION-PLAN.md +0 -0
  153. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/docs/releases/MULTISESSION-PLAN-3.md +0 -0
  154. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/docs/releases/MULTISESSION-PLAN-v0.2.md +0 -0
  155. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/docs/releases/MULTISESSION-PLAN.md +0 -0
  156. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/docs/releases/PLAN-3-LANE-HANDOFFS.md +0 -0
  157. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/docs/releases/V0.2-LANE-HANDOFFS.md +0 -0
  158. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/docs/releases/v0.1-EXECUTION-PLAN.md +0 -0
  159. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/docs/releases/v0.1-PLAN.md +0 -0
  160. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/docs/releases/v0.1.0-PRETAG-CHECKLIST.md +0 -0
  161. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/docs/research/cloud-deployment-research-2026-06.md +0 -0
  162. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/docs/research/config-ux-review.md +0 -0
  163. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/docs/research/non-hl7-transform-components.md +0 -0
  164. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/docs/reviews/DEPENDENCY-INFOSEC-POSTURE-2026-06-23.md +0 -0
  165. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/docs/reviews/FULL-REVIEW-2026-06-10.md +0 -0
  166. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/docs/security/ADVISORY-PROCESS.md +0 -0
  167. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/docs/security/ASVS-FAILS-REMEDIATION-PLAN.md +0 -0
  168. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/docs/security/ASVS-L2-PHASE0-CHANGES.md +0 -0
  169. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/docs/security/ASVS-L2-REMEDIATION-PLAN.md +0 -0
  170. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/docs/security/ASVS-L3-ASSESSMENT.md +0 -0
  171. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/docs/security/ASVS-L3-REMEDIATION-PLAN.md +0 -0
  172. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/docs/security/ASVS-L3-STATUS.md +0 -0
  173. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/docs/security/BEYOND-ASVS-L3-ONEPAGE.md +0 -0
  174. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/docs/security/BEYOND-ASVS-L3-REMEDIATION-PLAN-ONEPAGE.md +0 -0
  175. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/docs/security/BEYOND-ASVS-L3-REMEDIATION-PLAN.md +0 -0
  176. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/docs/security/BEYOND-ASVS-L3.md +0 -0
  177. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/docs/security/DEP-CVE-RUNBOOK.md +0 -0
  178. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/docs/security/DEPENDENCY-METRICS.md +0 -0
  179. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/docs/security/MEFOR-Code-Review-Checklist.xlsx +0 -0
  180. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/docs/security/PHASE-8C-RBAC.md +0 -0
  181. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/docs/security/PUBLISHING.md +0 -0
  182. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/docs/security/RCA-TEMPLATE.md +0 -0
  183. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/docs/security/RELEASE-GATE.md +0 -0
  184. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/docs/security/REMEDIATION-PLAN.md +0 -0
  185. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/docs/security/REVIEW-2026-06-07.md +0 -0
  186. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/docs/security/SDS-CONFORMANCE-REVIEW-2026-06-12.md +0 -0
  187. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/docs/security/SDS-REMEDIATION-PLAN.md +0 -0
  188. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/docs/security/SECURITY-POSTURE.md +0 -0
  189. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/docs/security/SOUP-DEPENDENCY-HANDLING.md +0 -0
  190. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/docs/security/SOUP-REVIEW-2026-06-18.md +0 -0
  191. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/docs/security/SOUP-REVIEW-PROCEDURE.md +0 -0
  192. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/docs/security/THREAT-MODEL.md +0 -0
  193. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/docs/testing/VERIFY.md +0 -0
  194. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/docs/testing/WIN2025-ACCEPTANCE.md +0 -0
  195. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/docs/testing/WIN2025-TEST-MATRIX.md +0 -0
  196. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/environments/dev.toml +0 -0
  197. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/environments/prod.toml +0 -0
  198. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/harness/README.md +0 -0
  199. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/harness/__main__.py +0 -0
  200. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/harness/acceptance/__init__.py +0 -0
  201. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/harness/acceptance/__main__.py +0 -0
  202. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/harness/acceptance/matrix.py +0 -0
  203. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/harness/acceptance/probes.py +0 -0
  204. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/harness/acceptance/report.py +0 -0
  205. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/harness/acceptance/runner.py +0 -0
  206. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/harness/compose.py +0 -0
  207. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/harness/config/coverage.py +0 -0
  208. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/harness/config/load/_shape.py +0 -0
  209. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/harness/config/load/graph.py +0 -0
  210. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/harness/file_panel.py +0 -0
  211. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/harness/file_transport.py +0 -0
  212. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/harness/load/__init__.py +0 -0
  213. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/harness/load/corpus.py +0 -0
  214. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/harness/load/correlator.py +0 -0
  215. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/harness/load/enginepoll.py +0 -0
  216. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/harness/load/failover.py +0 -0
  217. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/harness/load/failover_track.py +0 -0
  218. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/harness/load/governor.py +0 -0
  219. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/harness/load/ids.py +0 -0
  220. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/harness/load/metrics.py +0 -0
  221. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/harness/load/profile.py +0 -0
  222. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/harness/load/profiles/README.md +0 -0
  223. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/harness/load/profiles/closed-loop.toml +0 -0
  224. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/harness/load/profiles/failover.toml +0 -0
  225. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/harness/load/profiles/fanout-baseline.toml +0 -0
  226. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/harness/load/profiles/reference.toml +0 -0
  227. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/harness/load/profiles/smoke-sqlserver.toml +0 -0
  228. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/harness/load/profiles/smoke.toml +0 -0
  229. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/harness/load/profiles/soak.toml +0 -0
  230. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/harness/load/report.py +0 -0
  231. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/harness/load/runner.py +0 -0
  232. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/harness/load/sender.py +0 -0
  233. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/harness/load/sink.py +0 -0
  234. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/harness/mllp.py +0 -0
  235. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/harness/monitor.py +0 -0
  236. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/harness/receive.py +0 -0
  237. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/harness/reconcile/__init__.py +0 -0
  238. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/harness/reconcile/__main__.py +0 -0
  239. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/harness/reconcile/capture.py +0 -0
  240. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/harness/reconcile/compare.py +0 -0
  241. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/harness/reconcile/normalize.py +0 -0
  242. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/harness/reconcile/report.py +0 -0
  243. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/harness/scenarios.py +0 -0
  244. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/harness/send.py +0 -0
  245. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/harness/window.py +0 -0
  246. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/ide/.gitignore +0 -0
  247. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/ide/.vscodeignore +0 -0
  248. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/ide/README.md +0 -0
  249. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/ide/esbuild.js +0 -0
  250. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/ide/media/hl7schema.json +0 -0
  251. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/ide/media/icon.png +0 -0
  252. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/ide/media/icon.svg +0 -0
  253. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/ide/package-lock.json +0 -0
  254. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/ide/package.json +0 -0
  255. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/ide/snippets/messagefoundry.code-snippets +0 -0
  256. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/ide/src/aiPolicy.ts +0 -0
  257. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/ide/src/alertEditor.ts +0 -0
  258. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/ide/src/auth.ts +0 -0
  259. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/ide/src/chat.ts +0 -0
  260. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/ide/src/cli.ts +0 -0
  261. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/ide/src/completion.ts +0 -0
  262. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/ide/src/connectionEditor.ts +0 -0
  263. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/ide/src/engineClient.ts +0 -0
  264. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/ide/src/extension.ts +0 -0
  265. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/ide/src/generate.ts +0 -0
  266. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/ide/src/git.ts +0 -0
  267. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/ide/src/graphTree.ts +0 -0
  268. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/ide/src/home.ts +0 -0
  269. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/ide/src/newRoute.ts +0 -0
  270. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/ide/src/promote.ts +0 -0
  271. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/ide/src/sourceControl.ts +0 -0
  272. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/ide/src/test/runTest.ts +0 -0
  273. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/ide/src/test/suite/chat.test.ts +0 -0
  274. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/ide/src/test/suite/extension.test.ts +0 -0
  275. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/ide/src/test/suite/index.ts +0 -0
  276. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/ide/src/testBench.ts +0 -0
  277. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/ide/src/validate.ts +0 -0
  278. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/ide/tsconfig.json +0 -0
  279. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/ide/tsconfig.test.json +0 -0
  280. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/mefor.code-workspace +0 -0
  281. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/messagefoundry/adr_analyze.py +0 -0
  282. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/messagefoundry/anon/__init__.py +0 -0
  283. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/messagefoundry/anon/_pools.py +0 -0
  284. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/messagefoundry/anon/hl7.py +0 -0
  285. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/messagefoundry/anon/keying.py +0 -0
  286. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/messagefoundry/anon/leak.py +0 -0
  287. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/messagefoundry/anon/rules.py +0 -0
  288. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/messagefoundry/anon/surrogates.py +0 -0
  289. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/messagefoundry/api/__init__.py +0 -0
  290. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/messagefoundry/api/approvals.py +0 -0
  291. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/messagefoundry/api/auth_models.py +0 -0
  292. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/messagefoundry/api/auth_routes.py +0 -0
  293. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/messagefoundry/api/field_authz.py +0 -0
  294. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/messagefoundry/api/metrics.py +0 -0
  295. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/messagefoundry/api/security.py +0 -0
  296. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/messagefoundry/api/tls.py +0 -0
  297. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/messagefoundry/auth/__init__.py +0 -0
  298. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/messagefoundry/auth/data/common_passwords.NOTICE +0 -0
  299. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/messagefoundry/auth/data/common_passwords.txt +0 -0
  300. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/messagefoundry/auth/identity.py +0 -0
  301. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/messagefoundry/auth/ldap.py +0 -0
  302. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/messagefoundry/auth/notifications.py +0 -0
  303. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/messagefoundry/auth/passwords.py +0 -0
  304. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/messagefoundry/auth/permissions.py +0 -0
  305. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/messagefoundry/auth/policy.py +0 -0
  306. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/messagefoundry/auth/ratelimit.py +0 -0
  307. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/messagefoundry/auth/service.py +0 -0
  308. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/messagefoundry/auth/tokens.py +0 -0
  309. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/messagefoundry/auth/totp.py +0 -0
  310. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/messagefoundry/checks.py +0 -0
  311. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/messagefoundry/config/__init__.py +0 -0
  312. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/messagefoundry/config/active_environment.py +0 -0
  313. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/messagefoundry/config/ai_policy.py +0 -0
  314. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/messagefoundry/config/alerts_edit.py +0 -0
  315. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/messagefoundry/config/code_sets.py +0 -0
  316. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/messagefoundry/config/connections_edit.py +0 -0
  317. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/messagefoundry/config/connections_file.py +0 -0
  318. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/messagefoundry/config/db_lookup.py +0 -0
  319. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/messagefoundry/config/environments.py +0 -0
  320. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/messagefoundry/config/ingest_time.py +0 -0
  321. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/messagefoundry/config/models.py +0 -0
  322. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/messagefoundry/config/reference.py +0 -0
  323. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/messagefoundry/config/response.py +0 -0
  324. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/messagefoundry/config/run_context.py +0 -0
  325. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/messagefoundry/config/settings.py +0 -0
  326. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/messagefoundry/config/state.py +0 -0
  327. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/messagefoundry/config/tls_policy.py +0 -0
  328. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/messagefoundry/config/wiring.py +0 -0
  329. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/messagefoundry/console/__main__.py +0 -0
  330. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/messagefoundry/console/_async.py +0 -0
  331. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/messagefoundry/console/alerts_page.py +0 -0
  332. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/messagefoundry/console/change_password.py +0 -0
  333. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/messagefoundry/console/dead_letters_page.py +0 -0
  334. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/messagefoundry/console/delegates.py +0 -0
  335. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/messagefoundry/console/icons/alerts.svg +0 -0
  336. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/messagefoundry/console/icons/connections.svg +0 -0
  337. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/messagefoundry/console/icons/dead-letters.svg +0 -0
  338. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/messagefoundry/console/icons/engine-status.svg +0 -0
  339. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/messagefoundry/console/icons/log-search.svg +0 -0
  340. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/messagefoundry/console/icons/logo-lockup.svg +0 -0
  341. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/messagefoundry/console/icons/users.svg +0 -0
  342. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/messagefoundry/console/login.py +0 -0
  343. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/messagefoundry/console/mfa.py +0 -0
  344. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/messagefoundry/console/reauth.py +0 -0
  345. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/messagefoundry/console/resources/README.md +0 -0
  346. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/messagefoundry/console/resources/app.ico +0 -0
  347. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/messagefoundry/console/resources/app.svg +0 -0
  348. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/messagefoundry/console/search.py +0 -0
  349. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/messagefoundry/console/service_control.py +0 -0
  350. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/messagefoundry/console/sessions.py +0 -0
  351. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/messagefoundry/console/shell.py +0 -0
  352. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/messagefoundry/console/status.py +0 -0
  353. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/messagefoundry/console/theme.py +0 -0
  354. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/messagefoundry/console/users_page.py +0 -0
  355. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/messagefoundry/console/widgets.py +0 -0
  356. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/messagefoundry/generators/README.md +0 -0
  357. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/messagefoundry/generators/__init__.py +0 -0
  358. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/messagefoundry/generators/_core.py +0 -0
  359. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/messagefoundry/generators/_hl7data.py +0 -0
  360. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/messagefoundry/generators/adt.py +0 -0
  361. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/messagefoundry/generators/all_types.py +0 -0
  362. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/messagefoundry/generators/bar.py +0 -0
  363. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/messagefoundry/generators/dft.py +0 -0
  364. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/messagefoundry/generators/documents.py +0 -0
  365. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/messagefoundry/generators/mdm.py +0 -0
  366. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/messagefoundry/generators/mfn.py +0 -0
  367. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/messagefoundry/generators/oml.py +0 -0
  368. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/messagefoundry/generators/orl.py +0 -0
  369. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/messagefoundry/generators/orm.py +0 -0
  370. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/messagefoundry/generators/oru.py +0 -0
  371. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/messagefoundry/generators/ras.py +0 -0
  372. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/messagefoundry/generators/rde.py +0 -0
  373. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/messagefoundry/generators/siu.py +0 -0
  374. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/messagefoundry/generators/vxu.py +0 -0
  375. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/messagefoundry/hl7schema.py +0 -0
  376. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/messagefoundry/last_resort.py +0 -0
  377. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/messagefoundry/logging_setup.py +0 -0
  378. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/messagefoundry/parsing/__init__.py +0 -0
  379. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/messagefoundry/parsing/binary.py +0 -0
  380. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/messagefoundry/parsing/consistency.py +0 -0
  381. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/messagefoundry/parsing/dicom/__init__.py +0 -0
  382. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/messagefoundry/parsing/dicom/_deps.py +0 -0
  383. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/messagefoundry/parsing/dicom/_util.py +0 -0
  384. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/messagefoundry/parsing/dicom/dataset.py +0 -0
  385. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/messagefoundry/parsing/dicom/errors.py +0 -0
  386. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/messagefoundry/parsing/dicom/hl7_map.py +0 -0
  387. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/messagefoundry/parsing/dicom/peek.py +0 -0
  388. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/messagefoundry/parsing/fhir/__init__.py +0 -0
  389. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/messagefoundry/parsing/fhir/_deps.py +0 -0
  390. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/messagefoundry/parsing/fhir/errors.py +0 -0
  391. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/messagefoundry/parsing/fhir/peek.py +0 -0
  392. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/messagefoundry/parsing/fhir/resource.py +0 -0
  393. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/messagefoundry/parsing/groups.py +0 -0
  394. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/messagefoundry/parsing/message.py +0 -0
  395. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/messagefoundry/parsing/peek.py +0 -0
  396. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/messagefoundry/parsing/split.py +0 -0
  397. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/messagefoundry/parsing/summary.py +0 -0
  398. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/messagefoundry/parsing/tree.py +0 -0
  399. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/messagefoundry/parsing/validate.py +0 -0
  400. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/messagefoundry/parsing/x12/__init__.py +0 -0
  401. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/messagefoundry/parsing/x12/delimiters.py +0 -0
  402. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/messagefoundry/parsing/x12/errors.py +0 -0
  403. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/messagefoundry/parsing/x12/interchange.py +0 -0
  404. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/messagefoundry/parsing/x12/message.py +0 -0
  405. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/messagefoundry/parsing/x12/peek.py +0 -0
  406. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/messagefoundry/pipeline/__init__.py +0 -0
  407. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/messagefoundry/pipeline/alert_sinks.py +0 -0
  408. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/messagefoundry/pipeline/alerts.py +0 -0
  409. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/messagefoundry/pipeline/cert_expiry.py +0 -0
  410. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/messagefoundry/pipeline/cluster.py +0 -0
  411. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/messagefoundry/pipeline/cluster_sqlserver.py +0 -0
  412. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/messagefoundry/pipeline/config_convergence.py +0 -0
  413. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/messagefoundry/pipeline/dryrun.py +0 -0
  414. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/messagefoundry/pipeline/leader_tasks.py +0 -0
  415. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/messagefoundry/pipeline/reference_sync.py +0 -0
  416. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/messagefoundry/pipeline/retention.py +0 -0
  417. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/messagefoundry/pipeline/security_notify.py +0 -0
  418. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/messagefoundry/pipeline/state_convergence.py +0 -0
  419. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/messagefoundry/pipeline/wiring_runner.py +0 -0
  420. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/messagefoundry/py.typed +0 -0
  421. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/messagefoundry/redaction.py +0 -0
  422. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/messagefoundry/scaffold.py +0 -0
  423. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/messagefoundry/secrets_dpapi.py +0 -0
  424. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/messagefoundry/store/__init__.py +0 -0
  425. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/messagefoundry/store/audit_tee.py +0 -0
  426. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/messagefoundry/store/base.py +0 -0
  427. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/messagefoundry/store/crypto.py +0 -0
  428. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/messagefoundry/store/keyprovider.py +0 -0
  429. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/messagefoundry/store/postgres.py +0 -0
  430. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/messagefoundry/store/sqlserver.py +0 -0
  431. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/messagefoundry/store/store.py +0 -0
  432. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/messagefoundry/timezone.py +0 -0
  433. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/messagefoundry/transports/__init__.py +0 -0
  434. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/messagefoundry/transports/base.py +0 -0
  435. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/messagefoundry/transports/database.py +0 -0
  436. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/messagefoundry/transports/dicom.py +0 -0
  437. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/messagefoundry/transports/dicomweb.py +0 -0
  438. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/messagefoundry/transports/fhir.py +0 -0
  439. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/messagefoundry/transports/file.py +0 -0
  440. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/messagefoundry/transports/framing.py +0 -0
  441. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/messagefoundry/transports/loopback.py +0 -0
  442. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/messagefoundry/transports/mllp.py +0 -0
  443. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/messagefoundry/transports/remotefile.py +0 -0
  444. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/messagefoundry/transports/rest.py +0 -0
  445. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/messagefoundry/transports/signing.py +0 -0
  446. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/messagefoundry/transports/smart.py +0 -0
  447. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/messagefoundry/transports/soap.py +0 -0
  448. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/messagefoundry/transports/tcp.py +0 -0
  449. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/messagefoundry/transports/timer.py +0 -0
  450. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/messagefoundry/transports/x12.py +0 -0
  451. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/messagefoundry/verify/__init__.py +0 -0
  452. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/messagefoundry/verify/model.py +0 -0
  453. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/messagefoundry/verify/report.py +0 -0
  454. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/messagefoundry/verify/runner.py +0 -0
  455. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/messagefoundry/verify/smoke.py +0 -0
  456. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/pyproject.toml +0 -0
  457. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/requirements.lock +0 -0
  458. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/samples/config/IB_ACME_ADT.py +0 -0
  459. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/samples/config/IB_FHIR_INTAKE.py +0 -0
  460. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/samples/config/IB_IMMUNIZATION_VXU.py +0 -0
  461. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/samples/config/IB_PARTNER_X12.py +0 -0
  462. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/samples/config/IB_RADIOLOGY_SR.py +0 -0
  463. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/samples/config/IB_RTE_ELIGIBILITY.py +0 -0
  464. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/samples/config/adt.py +0 -0
  465. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/samples/config/codesets/event_labels.csv +0 -0
  466. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/samples/config/codesets/facility_mnemonics.toml +0 -0
  467. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/samples/config/connections.toml +0 -0
  468. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/samples/consistency/validated_adt.py +0 -0
  469. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/samples/dicom/generate_sr_sample.py +0 -0
  470. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/samples/messages/adt_a01.hl7 +0 -0
  471. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/samples/messages/adt_batch.hl7 +0 -0
  472. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/samples/messages/hapi-hl7v2/.gitattributes +0 -0
  473. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/samples/messages/hapi-hl7v2/README.md +0 -0
  474. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/samples/messages/hapi-hl7v2/adt_a01.txt +0 -0
  475. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/samples/messages/hapi-hl7v2/adt_a03.txt +0 -0
  476. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/samples/messages/hapi-hl7v2/batch_18_messages.txt +0 -0
  477. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/samples/messages/hapi-hl7v2/erp_z99_v231.hl7 +0 -0
  478. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/samples/messages/hapi-hl7v2/omd_o03.txt +0 -0
  479. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/samples/messages/hapi-hl7v2/omd_o03_rep.txt +0 -0
  480. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/samples/messages/hapi-hl7v2/oml_o21.hl7 +0 -0
  481. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/samples/messages/x12_270_eligibility.edi +0 -0
  482. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/samples/results_relay/README.md +0 -0
  483. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/samples/results_relay/codesets/test_codes.csv +0 -0
  484. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/samples/results_relay/messages/oru_all_cancelled.hl7 +0 -0
  485. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/samples/results_relay/messages/oru_results.hl7 +0 -0
  486. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/samples/results_relay/results_relay.py +0 -0
  487. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/samples/send_mllp.py +0 -0
  488. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/scripts/console/install-console-shortcut.ps1 +0 -0
  489. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/scripts/console/pack_ico.py +0 -0
  490. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/scripts/console/uninstall-console-shortcut.ps1 +0 -0
  491. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/scripts/dev/postgres.ps1 +0 -0
  492. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/scripts/dev/sqlserver-docker.ps1 +0 -0
  493. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/scripts/dev/sqlserver.ps1 +0 -0
  494. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/scripts/hooks/block-blanket-git-stage.ps1 +0 -0
  495. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/scripts/publish/check_release_sync.py +0 -0
  496. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/scripts/publish/publish-denylist.txt +0 -0
  497. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/scripts/publish/publish.ps1 +0 -0
  498. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/scripts/publish/scan_forbidden.py +0 -0
  499. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/scripts/security/crypto_inventory_check.py +0 -0
  500. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/scripts/security/vuln_metrics.py +0 -0
  501. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/scripts/service/install-service.ps1 +0 -0
  502. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/scripts/service/uninstall-service.ps1 +0 -0
  503. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/scripts/soak/store_soak.py +0 -0
  504. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/scripts/trace_icon.py +0 -0
  505. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/scripts/worktree/new.ps1 +0 -0
  506. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/scripts/worktree/remove.ps1 +0 -0
  507. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/scripts/worktree/session-context.ps1 +0 -0
  508. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/scripts/worktree/spawn.ps1 +0 -0
  509. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/tee/__init__.py +0 -0
  510. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/tee/__main__.py +0 -0
  511. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/tee/anon/__init__.py +0 -0
  512. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/tee/anon/_hl7data.py +0 -0
  513. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/tee/anon/_pools.py +0 -0
  514. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/tee/anon/hl7.py +0 -0
  515. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/tee/anon/keying.py +0 -0
  516. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/tee/anon/leak.py +0 -0
  517. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/tee/anon/rules.py +0 -0
  518. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/tee/anon/surrogates.py +0 -0
  519. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/tee/compare.py +0 -0
  520. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/tee/correlate.py +0 -0
  521. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/tee/hl7_fields.py +0 -0
  522. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/tee/mefor_api.py +0 -0
  523. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/tee/mllp.py +0 -0
  524. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/tee/relay.py +0 -0
  525. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/tee/report.py +0 -0
  526. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/tee/store.py +0 -0
  527. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/tests/_dicom_sample.py +0 -0
  528. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/tests/_failover_load_support.py +0 -0
  529. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/tests/_fhir_fixtures.py +0 -0
  530. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/tests/conftest.py +0 -0
  531. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/tests/test_acceptance_framework.py +0 -0
  532. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/tests/test_active_environment.py +0 -0
  533. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/tests/test_ad_group_scope.py +0 -0
  534. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/tests/test_admin_new_ip.py +0 -0
  535. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/tests/test_adr_analyze.py +0 -0
  536. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/tests/test_ai_policy.py +0 -0
  537. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/tests/test_alert_rules.py +0 -0
  538. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/tests/test_alert_sinks.py +0 -0
  539. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/tests/test_alerts_edit.py +0 -0
  540. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/tests/test_alerts_rules_api.py +0 -0
  541. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/tests/test_anon_integration.py +0 -0
  542. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/tests/test_api.py +0 -0
  543. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/tests/test_api_auth.py +0 -0
  544. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/tests/test_api_reload.py +0 -0
  545. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/tests/test_api_tls.py +0 -0
  546. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/tests/test_approvals.py +0 -0
  547. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/tests/test_asvs_phase0.py +0 -0
  548. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/tests/test_audit_integrity.py +0 -0
  549. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/tests/test_audit_offbox_tee.py +0 -0
  550. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/tests/test_auth_core.py +0 -0
  551. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/tests/test_auth_entry_hardening.py +0 -0
  552. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/tests/test_auth_hardening.py +0 -0
  553. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/tests/test_auth_service.py +0 -0
  554. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/tests/test_auth_session_lifecycle.py +0 -0
  555. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/tests/test_auth_store.py +0 -0
  556. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/tests/test_binary_carriage.py +0 -0
  557. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/tests/test_cert_expiry.py +0 -0
  558. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/tests/test_channel_rbac.py +0 -0
  559. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/tests/test_checks.py +0 -0
  560. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/tests/test_cluster.py +0 -0
  561. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/tests/test_cluster_failover_postgres.py +0 -0
  562. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/tests/test_cluster_failover_sqlserver.py +0 -0
  563. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/tests/test_cluster_graph_gating.py +0 -0
  564. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/tests/test_cluster_lease.py +0 -0
  565. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/tests/test_code_sets.py +0 -0
  566. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/tests/test_connection_api.py +0 -0
  567. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/tests/test_connection_resilience.py +0 -0
  568. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/tests/test_connections_cli.py +0 -0
  569. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/tests/test_connections_file.py +0 -0
  570. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/tests/test_consistency.py +0 -0
  571. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/tests/test_console_alerts.py +0 -0
  572. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/tests/test_console_auth.py +0 -0
  573. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/tests/test_console_client.py +0 -0
  574. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/tests/test_console_dead_letters.py +0 -0
  575. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/tests/test_console_hardening.py +0 -0
  576. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/tests/test_console_icon.py +0 -0
  577. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/tests/test_console_password.py +0 -0
  578. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/tests/test_console_sessions.py +0 -0
  579. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/tests/test_console_status.py +0 -0
  580. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/tests/test_console_step_up.py +0 -0
  581. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/tests/test_console_theme.py +0 -0
  582. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/tests/test_console_users.py +0 -0
  583. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/tests/test_database_connector_integration.py +0 -0
  584. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/tests/test_database_transport.py +0 -0
  585. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/tests/test_db_lookup.py +0 -0
  586. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/tests/test_db_lookup_live_runner.py +0 -0
  587. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/tests/test_delivery_settings.py +0 -0
  588. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/tests/test_dependency_boundaries.py +0 -0
  589. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/tests/test_dicom_codec.py +0 -0
  590. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/tests/test_dicom_scp.py +0 -0
  591. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/tests/test_dicom_scu.py +0 -0
  592. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/tests/test_dicom_wiring.py +0 -0
  593. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/tests/test_dicomweb.py +0 -0
  594. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/tests/test_dryrun.py +0 -0
  595. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/tests/test_ed_documents.py +0 -0
  596. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/tests/test_ed_documents_e2e.py +0 -0
  597. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/tests/test_egress_allowlist.py +0 -0
  598. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/tests/test_environments.py +0 -0
  599. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/tests/test_fhir_parsing.py +0 -0
  600. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/tests/test_fhir_resource.py +0 -0
  601. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/tests/test_fhir_transport.py +0 -0
  602. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/tests/test_field_authz.py +0 -0
  603. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/tests/test_fifo_ordering.py +0 -0
  604. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/tests/test_generate_cli.py +0 -0
  605. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/tests/test_generated_adt.py +0 -0
  606. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/tests/test_generators_core.py +0 -0
  607. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/tests/test_generators_types.py +0 -0
  608. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/tests/test_groups.py +0 -0
  609. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/tests/test_harness.py +0 -0
  610. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/tests/test_harness_compose.py +0 -0
  611. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/tests/test_harness_config.py +0 -0
  612. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/tests/test_harness_faults.py +0 -0
  613. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/tests/test_harness_file.py +0 -0
  614. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/tests/test_harness_monitor.py +0 -0
  615. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/tests/test_harness_scenarios.py +0 -0
  616. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/tests/test_hl7_core_features.py +0 -0
  617. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/tests/test_hl7schema.py +0 -0
  618. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/tests/test_inbound_bind.py +0 -0
  619. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/tests/test_ingest_time.py +0 -0
  620. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/tests/test_keyprovider.py +0 -0
  621. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/tests/test_last_resort.py +0 -0
  622. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/tests/test_leader_tasks.py +0 -0
  623. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/tests/test_load_corpus.py +0 -0
  624. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/tests/test_load_failover_postgres.py +0 -0
  625. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/tests/test_load_failover_sqlserver.py +0 -0
  626. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/tests/test_load_failover_unit.py +0 -0
  627. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/tests/test_load_metrics.py +0 -0
  628. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/tests/test_load_profile.py +0 -0
  629. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/tests/test_load_report.py +0 -0
  630. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/tests/test_load_runner.py +0 -0
  631. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/tests/test_load_sender.py +0 -0
  632. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/tests/test_load_sink.py +0 -0
  633. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/tests/test_logging.py +0 -0
  634. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/tests/test_message.py +0 -0
  635. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/tests/test_message_split.py +0 -0
  636. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/tests/test_metrics_exporter.py +0 -0
  637. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/tests/test_mfa.py +0 -0
  638. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/tests/test_mllp_encoding_override.py +0 -0
  639. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/tests/test_mllp_tls.py +0 -0
  640. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/tests/test_operability_config.py +0 -0
  641. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/tests/test_outbound_signing.py +0 -0
  642. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/tests/test_outbound_simulate.py +0 -0
  643. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/tests/test_packaging.py +0 -0
  644. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/tests/test_parse_tree.py +0 -0
  645. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/tests/test_parsing.py +0 -0
  646. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/tests/test_payload_agnostic_ingress.py +0 -0
  647. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/tests/test_postgres_store.py +0 -0
  648. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/tests/test_reconcile_capture.py +0 -0
  649. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/tests/test_reconcile_compare.py +0 -0
  650. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/tests/test_reconcile_harness.py +0 -0
  651. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/tests/test_redaction.py +0 -0
  652. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/tests/test_reference_sets.py +0 -0
  653. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/tests/test_reingress.py +0 -0
  654. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/tests/test_remotefile_transport.py +0 -0
  655. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/tests/test_response_capture.py +0 -0
  656. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/tests/test_rest_transport.py +0 -0
  657. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/tests/test_retention.py +0 -0
  658. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/tests/test_run_context.py +0 -0
  659. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/tests/test_scaffold.py +0 -0
  660. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/tests/test_scan_forbidden.py +0 -0
  661. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/tests/test_secrets_dpapi.py +0 -0
  662. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/tests/test_security_notify.py +0 -0
  663. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/tests/test_security_static.py +0 -0
  664. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/tests/test_service_control.py +0 -0
  665. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/tests/test_settings.py +0 -0
  666. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/tests/test_smart_backend.py +0 -0
  667. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/tests/test_soap_transport.py +0 -0
  668. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/tests/test_soap_wssecurity.py +0 -0
  669. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/tests/test_sqlserver_coordinator.py +0 -0
  670. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/tests/test_sqlserver_store.py +0 -0
  671. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/tests/test_staged_pipeline.py +0 -0
  672. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/tests/test_startup_fault_isolation.py +0 -0
  673. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/tests/test_step_up.py +0 -0
  674. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/tests/test_store.py +0 -0
  675. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/tests/test_store_backend.py +0 -0
  676. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/tests/test_store_encryption.py +0 -0
  677. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/tests/test_store_file_hardening.py +0 -0
  678. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/tests/test_store_read_pool.py +0 -0
  679. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/tests/test_summary.py +0 -0
  680. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/tests/test_task_resilience.py +0 -0
  681. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/tests/test_tcp_transport.py +0 -0
  682. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/tests/test_tee_cli.py +0 -0
  683. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/tests/test_tee_compare.py +0 -0
  684. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/tests/test_tee_correlate.py +0 -0
  685. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/tests/test_tee_hl7_fields.py +0 -0
  686. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/tests/test_tee_mefor_api.py +0 -0
  687. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/tests/test_tee_mllp.py +0 -0
  688. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/tests/test_tee_relay.py +0 -0
  689. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/tests/test_tee_report.py +0 -0
  690. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/tests/test_tee_store.py +0 -0
  691. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/tests/test_timer_source.py +0 -0
  692. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/tests/test_timezone.py +0 -0
  693. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/tests/test_tls_policy.py +0 -0
  694. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/tests/test_totp.py +0 -0
  695. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/tests/test_transform_state.py +0 -0
  696. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/tests/test_transports.py +0 -0
  697. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/tests/test_version.py +0 -0
  698. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/tests/test_win2025_acceptance.py +0 -0
  699. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/tests/test_wiring.py +0 -0
  700. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/tests/test_wiring_engine.py +0 -0
  701. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/tests/test_wiring_reload.py +0 -0
  702. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/tests/test_wiring_serve.py +0 -0
  703. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/tests/test_x12_parsing.py +0 -0
  704. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/tests/test_x12_rte.py +0 -0
  705. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/tests/test_x12_transport.py +0 -0
  706. {messagefoundry-0.2.0 → messagefoundry-0.2.1}/uv.lock +0 -0
@@ -32,6 +32,12 @@ jobs:
32
32
  python-version: "3.13"
33
33
  - name: Check tag / PyPI / mirror are in sync
34
34
  run: |
35
+ # The script lives under the deny-listed scripts/publish/, so it is ABSENT on the OSS mirror;
36
+ # the sync check only runs on the private repo (the publish source). Skip where it's absent.
37
+ if [ ! -f scripts/publish/check_release_sync.py ]; then
38
+ echo "scripts/publish/check_release_sync.py absent (OSS mirror) — skipping the release-sync check."
39
+ exit 0
40
+ fi
35
41
  # `packaging` gives canonical version normalization (so a "0.1.0-rc1" tag and PyPI's
36
42
  # "0.1.0rc1" compare equal); the script falls back to a naive form if it's absent.
37
43
  python -m pip install --upgrade pip packaging
@@ -202,5 +202,12 @@ jobs:
202
202
  with:
203
203
  python-version: "3.13"
204
204
  - name: Scan the publishable subset for forbidden content
205
- # Stdlib-only scanner (no install). Exits non-zero — failing the build — on any hit.
206
- run: python scripts/publish/scan_forbidden.py --published
205
+ # Stdlib-only scanner (no install). Exits non-zero — failing the build — on any hit. The scanner
206
+ # lives under the deny-listed scripts/publish/, so it is ABSENT on the OSS mirror — there's
207
+ # nothing to gate there (everything is already the published subset); skip rather than error.
208
+ run: |
209
+ if [ -f scripts/publish/scan_forbidden.py ]; then
210
+ python scripts/publish/scan_forbidden.py --published
211
+ else
212
+ echo "scripts/publish/scan_forbidden.py absent (OSS mirror) — skipping the publish leak-gate."
213
+ fi
@@ -6,6 +6,21 @@ All notable changes to MessageFoundry are documented here. The format follows
6
6
 
7
7
  ## [Unreleased]
8
8
 
9
+ ## [0.2.1] — 2026-06-23 — Early Access
10
+
11
+ ### Fixed
12
+ - **Windows: `messagefoundry --help` crashed on a legacy codepage** — the top-level help rendered a
13
+ non-cp1252 character (a `->` arrow in the `adr-analyze` subcommand help, new in 0.2.0), so `--help`
14
+ aborted with `UnicodeEncodeError` on a cp1252/charmap console (cmd, PowerShell, or any redirected
15
+ stdout). `main()` now reconfigures stdout/stderr with `errors="replace"` and the help text is ASCII;
16
+ the machine-read JSON introspection subcommands are unaffected (`json.dumps(ensure_ascii=True)`).
17
+ - **`verify --section host` crashed without the `[console]` extra** — `check_console_no_window()`
18
+ resolved a console submodule via `find_spec`, which imported the console package and its eager `httpx`
19
+ dependency, so a `[sqlserver]`-only install aborted with `ModuleNotFoundError: No module named 'httpx'`
20
+ instead of skipping the console check. The console package now imports its API client lazily (PEP 562
21
+ `__getattr__`), so resolving a submodule no longer requires `httpx`, and the check degrades to SKIP if a
22
+ console dependency is absent.
23
+
9
24
  ## [0.2.0] — 2026-06-23 — Early Access
10
25
 
11
26
  ### Added
@@ -75,5 +90,7 @@ tests, but the external code review + penetration test (the bar for a security-c
75
90
  - Releases are built, SBOM'd (CycloneDX), and signed with [Sigstore](https://www.sigstore.dev/) — see the
76
91
  `release` workflow.
77
92
 
78
- [Unreleased]: https://github.com/wshallwshall/MessageFoundry/compare/v0.1.0...HEAD
93
+ [Unreleased]: https://github.com/wshallwshall/MessageFoundry/compare/v0.2.1...HEAD
94
+ [0.2.1]: https://github.com/wshallwshall/MessageFoundry/compare/v0.2.0...v0.2.1
95
+ [0.2.0]: https://github.com/wshallwshall/MessageFoundry/compare/v0.1.0...v0.2.0
79
96
  [0.1.0]: https://github.com/wshallwshall/MessageFoundry/releases/tag/v0.1.0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: messagefoundry
3
- Version: 0.2.0
3
+ Version: 0.2.1
4
4
  Summary: Open-source healthcare integration engine — route, transform, and validate messages across many formats and connection types
5
5
  License-Expression: AGPL-3.0-or-later
6
6
  License-File: LICENSE
@@ -60,7 +60,7 @@ from messagefoundry.parsing.message import Message, RawMessage
60
60
  from messagefoundry.parsing.split import split_by_obr
61
61
  from messagefoundry.timezone import convert_hl7_timestamp, to_zone
62
62
 
63
- __version__ = "0.2.0"
63
+ __version__ = "0.2.1"
64
64
 
65
65
  __all__ = [
66
66
  "Message",
@@ -30,6 +30,21 @@ from messagefoundry.logging_setup import LOG_LEVELS, SyslogForward, configure_lo
30
30
 
31
31
 
32
32
  def main(argv: list[str] | None = None) -> int:
33
+ # Harden the human-facing streams for a legacy Windows codepage (cp1252/charmap): argparse's own
34
+ # --help/usage printer and runtime log/print() lines bypass _safe_print, so a non-cp1252 char
35
+ # (an arrow or other symbol in a help string or log line) would otherwise abort with
36
+ # UnicodeEncodeError. errors="replace" is lossy for such chars, but the machine-read JSON
37
+ # subcommands stay ASCII (json.dumps ensure_ascii=True). Guarded: some stream wrappers
38
+ # (PYTHONLEGACYWINDOWSSTDIO, pytest capture) lack reconfigure or reject it, and the hardening
39
+ # must never itself crash the CLI.
40
+ for _stream in (sys.stdout, sys.stderr):
41
+ _reconfigure = getattr(_stream, "reconfigure", None)
42
+ if _reconfigure is not None:
43
+ try:
44
+ _reconfigure(errors="replace")
45
+ except (ValueError, OSError):
46
+ pass
47
+
33
48
  parser = argparse.ArgumentParser(prog="messagefoundry", description=__doc__)
34
49
  parser.add_argument("--version", action="version", version=f"messagefoundry {__version__}")
35
50
  sub = parser.add_subparsers(dest="command", required=True)
@@ -111,8 +126,8 @@ def main(argv: list[str] | None = None) -> int:
111
126
 
112
127
  adr_analyze = sub.add_parser(
113
128
  "adr-analyze",
114
- help="advisory spec-driven ADR coverage: acceptance-criteriatest links, missing criteria, "
115
- "open clarifications (Secure Development Standards §5)",
129
+ help="advisory spec-driven ADR coverage: acceptance-criteria->test links, missing criteria, "
130
+ "open clarifications (Secure Development Standards section 5)",
116
131
  )
117
132
  adr_analyze.add_argument(
118
133
  "--adr-dir", default="docs/adr", help="ADR directory (default: docs/adr)"
@@ -458,7 +473,7 @@ def _serve(args: argparse.Namespace) -> int:
458
473
  # Only announce forwarding when configure_logging actually installed the handler — a TCP
459
474
  # collector that is down at startup is skipped (it warns), so this must not contradict it.
460
475
  logging.getLogger(__name__).info(
461
- "off-box log forwarding enabled %s:%d (%s, %s)",
476
+ "off-box log forwarding enabled -> %s:%d (%s, %s)",
462
477
  log_forward.host,
463
478
  log_forward.port,
464
479
  log_forward.protocol,
@@ -81,6 +81,8 @@ from messagefoundry.api.models import (
81
81
  ReloadRequest,
82
82
  ReloadResult,
83
83
  ReplayResult,
84
+ StatsResetRequest,
85
+ StatsResetResult,
84
86
  StatsResponse,
85
87
  SystemStatus,
86
88
  )
@@ -565,9 +567,9 @@ def create_app(
565
567
  _user: Identity = Depends(require(Permission.MONITORING_READ)),
566
568
  ) -> list[ConnectionRow]:
567
569
  now = time.time()
568
- metrics = await engine.store.connection_metrics(
569
- since=engine.started_at, now=now, rate_window=_RATE_WINDOW
570
- )
570
+ # Offset-adjusted: subtracts any operator stats-resets (in-memory baselines). Identical to the
571
+ # raw store metrics when nothing has been reset.
572
+ metrics = await engine.connection_metrics_view(now=now, rate_window=_RATE_WINDOW)
571
573
  rows: list[ConnectionRow] = []
572
574
 
573
575
  # A source row per inbound connection, and a destination row per (inbound → outbound)
@@ -855,6 +857,58 @@ def create_app(
855
857
  cancelled = await engine.store.cancel_queued(None, name, top_only=(scope == "top"))
856
858
  return PurgeResult(cancelled=cancelled)
857
859
 
860
+ @app.post("/statistics/reset", response_model=StatsResetResult)
861
+ async def reset_statistics(
862
+ req: StatsResetRequest,
863
+ engine: Engine = Depends(_get_engine),
864
+ identity: Identity = Depends(require(Permission.MONITORING_DIAGNOSE)),
865
+ ) -> StatsResetResult:
866
+ """Zero the connections-dashboard cumulative counters (inbound read/errored, outbound
867
+ written/dead) for the selected connections, or all of them. This moves an in-memory baseline —
868
+ message rows (the PHI/audit record) and the Prometheus ``/metrics`` counters are untouched, as
869
+ are live gauges (queue depth, ages)."""
870
+ inbound: list[str] = []
871
+ outbound: list[tuple[str, str]] = []
872
+ if req.all:
873
+ # "Reset all" spans every channel, so a channel-scoped user may not run it (mirror purge).
874
+ if identity.allowed_channels is not None:
875
+ await _audit_channel_denied(engine, identity, None)
876
+ raise HTTPException(403, "channel-scoped users cannot reset all statistics")
877
+ else:
878
+ for t in req.targets:
879
+ # Per-channel RBAC: a scoped user may reset only endpoints of their own inbound channels
880
+ # (a destination row is the channel_id->destination edge, so the same scope applies).
881
+ if identity.allowed_channels is not None and not identity.can_access_channel(
882
+ t.channel_id
883
+ ):
884
+ await _audit_channel_denied(engine, identity, t.channel_id)
885
+ raise HTTPException(403, "connection is outside your channel scope")
886
+ if t.role == "source":
887
+ if t.channel_id not in inbound:
888
+ inbound.append(t.channel_id)
889
+ else:
890
+ if t.destination is None:
891
+ raise HTTPException(422, "destination rows require a destination name")
892
+ key = (t.channel_id, t.destination)
893
+ if key not in outbound:
894
+ outbound.append(key)
895
+ count = await engine.reset_stats(
896
+ all_connections=req.all, inbound=inbound, outbound=outbound, now=time.time()
897
+ )
898
+ await engine.store.record_audit(
899
+ "stats_reset",
900
+ actor=identity.username,
901
+ detail=json.dumps(
902
+ {
903
+ "all": req.all,
904
+ "inbound": inbound,
905
+ "outbound": [list(k) for k in outbound],
906
+ "reset": count,
907
+ }
908
+ ),
909
+ )
910
+ return StatsResetResult(reset=count)
911
+
858
912
  # --- dead letters (verify + recover) -------------------------------------
859
913
 
860
914
  @app.get("/dead-letters", response_model=DeadLetterList)
@@ -10,7 +10,7 @@ body (PHI) appears only in the single-message detail view, which is audited.
10
10
 
11
11
  from __future__ import annotations
12
12
 
13
- from typing import Any
13
+ from typing import Any, Literal
14
14
 
15
15
  from pydantic import BaseModel, Field
16
16
 
@@ -243,6 +243,26 @@ class ConnectionRow(BaseModel):
243
243
  )
244
244
 
245
245
 
246
+ class StatsResetTarget(BaseModel):
247
+ """One connections-dashboard endpoint to reset, matching a row's (role, channel_id, destination).
248
+ For ``source`` rows ``destination`` is ignored; for ``destination`` rows it is required."""
249
+
250
+ role: Literal["source", "destination"]
251
+ channel_id: str = Field(min_length=1, max_length=256)
252
+ destination: str | None = Field(default=None, max_length=256)
253
+
254
+
255
+ class StatsResetRequest(BaseModel):
256
+ """Reset the dashboard's cumulative counters for ``targets``, or for every connection (``all``)."""
257
+
258
+ all: bool = False
259
+ targets: list[StatsResetTarget] = Field(default_factory=list)
260
+
261
+
262
+ class StatsResetResult(BaseModel):
263
+ reset: int # number of connection endpoints whose dashboard counters were reset
264
+
265
+
246
266
  class StatsResponse(BaseModel):
247
267
  outbox_by_status: dict[str, int]
248
268
  # NOT-DONE rows (pending|inflight) across every stage (ingress + routed + outbound) — a
@@ -15,6 +15,21 @@ PySide6 unless you actually open the GUI.
15
15
 
16
16
  from __future__ import annotations
17
17
 
18
- from messagefoundry.console.client import ApiError, EngineClient
18
+ from typing import TYPE_CHECKING
19
+
20
+ if TYPE_CHECKING:
21
+ # Static-only re-export: mypy --strict still resolves the names, but at runtime they load lazily
22
+ # via __getattr__ below, so importing this package (or find_spec'ing a sibling submodule like
23
+ # service_control) no longer hard-requires the [console] extra's httpx. Mirrors the
24
+ # lazy-truststore import already in client.py and the lazy-pydantic api/__init__ convention.
25
+ from messagefoundry.console.client import ApiError, EngineClient
19
26
 
20
27
  __all__ = ["EngineClient", "ApiError"]
28
+
29
+
30
+ def __getattr__(name: str) -> object:
31
+ if name in __all__:
32
+ from messagefoundry.console import client
33
+
34
+ return getattr(client, name)
35
+ raise AttributeError(f"module {__name__!r} has no attribute {name!r}")
@@ -15,7 +15,7 @@ from __future__ import annotations
15
15
 
16
16
  import logging
17
17
  import ssl
18
- from collections.abc import Callable
18
+ from collections.abc import Callable, Sequence
19
19
  from json import JSONDecodeError
20
20
  from types import TracebackType
21
21
  from typing import TypeVar
@@ -56,6 +56,7 @@ from messagefoundry.api.models import (
56
56
  PurgeResult,
57
57
  ReloadResult,
58
58
  ReplayResult,
59
+ StatsResetResult,
59
60
  StatsResponse,
60
61
  SystemStatus,
61
62
  )
@@ -375,6 +376,23 @@ class EngineClient:
375
376
  PurgeResult,
376
377
  )
377
378
 
379
+ def reset_stats(
380
+ self,
381
+ *,
382
+ all_connections: bool = False,
383
+ targets: Sequence[tuple[str, str, str | None]] = (),
384
+ ) -> StatsResetResult:
385
+ """Reset the connections-dashboard counters for ``targets`` (each ``(role, channel_id,
386
+ destination)``), or for every connection when ``all_connections`` is set."""
387
+ body = {
388
+ "all": all_connections,
389
+ "targets": [
390
+ {"role": role, "channel_id": channel_id, "destination": destination}
391
+ for (role, channel_id, destination) in targets
392
+ ],
393
+ }
394
+ return _decode(self._request("POST", "/statistics/reset", json=body), StatsResetResult)
395
+
378
396
  def list_messages(
379
397
  self,
380
398
  *,
@@ -127,6 +127,9 @@ class ConnectionsPage(QWidget):
127
127
  menu.addSeparator()
128
128
  act_purge_top = menu.addAction("Purge Top Message")
129
129
  act_purge_all = menu.addAction("Purge All Queued Messages")
130
+ menu.addSeparator()
131
+ act_reset_sel = menu.addAction("Reset Statistics (Selected)")
132
+ act_reset_all = menu.addAction("Reset All Statistics")
130
133
  self._actions.setMenu(menu)
131
134
 
132
135
  self._start.clicked.connect(lambda: self._inbound_action(self._client.start_connection))
@@ -134,6 +137,8 @@ class ConnectionsPage(QWidget):
134
137
  act_restart.triggered.connect(lambda: self._inbound_action(self._client.restart_connection))
135
138
  act_purge_top.triggered.connect(lambda: self._purge("top"))
136
139
  act_purge_all.triggered.connect(lambda: self._purge("all"))
140
+ act_reset_sel.triggered.connect(lambda: self._reset_stats(all_connections=False))
141
+ act_reset_all.triggered.connect(lambda: self._reset_stats(all_connections=True))
137
142
 
138
143
  toolbar = QHBoxLayout()
139
144
  toolbar.addWidget(QLabel("Connections"))
@@ -292,7 +297,10 @@ class ConnectionsPage(QWidget):
292
297
  has = bool(self._selected_keys())
293
298
  self._start.setEnabled(has)
294
299
  self._stop.setEnabled(has)
295
- self._actions.setEnabled(has)
300
+ # The Actions menu stays enabled even with no selection: "Reset All Statistics" needs none. The
301
+ # selection-dependent items (Restart / Purge / Reset Selected) guard themselves and report when
302
+ # nothing is selected.
303
+ self._actions.setEnabled(True)
296
304
 
297
305
  # --- actions -------------------------------------------------------------
298
306
 
@@ -343,6 +351,36 @@ class ConnectionsPage(QWidget):
343
351
  return
344
352
  self.refresh()
345
353
 
354
+ def _reset_stats(self, *, all_connections: bool) -> None:
355
+ """Zero the dashboard's cumulative counters (read / errored / written) for the selected rows,
356
+ or for every connection. Non-destructive: it moves a display baseline on the engine — messages
357
+ and history are untouched — so only "Reset All" is confirmed (it's broad)."""
358
+ targets: list[tuple[str, str, str | None]] = []
359
+ if all_connections:
360
+ answer = QMessageBox.question(
361
+ self,
362
+ "Reset all statistics",
363
+ "Reset the counters (read / errored / written) for ALL connections?\n\n"
364
+ "This only clears the dashboard tallies — messages and history are untouched.",
365
+ QMessageBox.StandardButton.Yes | QMessageBox.StandardButton.No,
366
+ QMessageBox.StandardButton.No,
367
+ )
368
+ if answer != QMessageBox.StandardButton.Yes:
369
+ return
370
+ else:
371
+ # Each row key is (role, channel_id, dest|""); "" (source rows) becomes None for the API.
372
+ for role, channel_id, dest in self._selected_keys():
373
+ targets.append((role, channel_id, dest or None))
374
+ if not targets:
375
+ self.error.emit("Select one or more rows to reset, or use Reset All Statistics.")
376
+ return
377
+ try:
378
+ self._client.reset_stats(all_connections=all_connections, targets=targets)
379
+ except ApiError as exc:
380
+ self.error.emit(str(exc))
381
+ return
382
+ self.refresh()
383
+
346
384
  def _on_cell_clicked(self, row: int, col: int) -> None:
347
385
  if col != _LOGS_COL:
348
386
  return
@@ -13,6 +13,7 @@ import asyncio
13
13
  import logging
14
14
  import time
15
15
  from collections.abc import Callable, Mapping, Sequence
16
+ from dataclasses import replace
16
17
  from pathlib import Path
17
18
  from typing import Any
18
19
 
@@ -42,6 +43,7 @@ from messagefoundry.pipeline.retention import RetentionRunner
42
43
  from messagefoundry.pipeline.state_convergence import StateConvergenceRunner
43
44
  from messagefoundry.pipeline.wiring_runner import RegistryRunner
44
45
  from messagefoundry.store import MessageStore, Store
46
+ from messagefoundry.store.store import ConnectionMetrics, DestinationMetrics, InboundMetrics
45
47
 
46
48
  __all__ = ["Engine", "ConfigReloadDenied"]
47
49
 
@@ -180,6 +182,15 @@ class Engine:
180
182
  self._graph_reconcile_interval = 1.0
181
183
  # Set when start() runs; the "since" for since-engine-start metric counts.
182
184
  self.started_at: float = 0.0
185
+ # Console stats-reset baselines (in-memory; dropped on restart, like the counts they offset).
186
+ # When an operator resets a connection's dashboard stats, we snapshot its current cumulative
187
+ # counters here; the connections view subtracts the snapshot so the visible read/errored/
188
+ # written/dead zero out without touching any message rows (the PHI/audit record). Keyed by
189
+ # channel_id (inbound) and (channel_id, destination) (outbound). See reset_stats().
190
+ self._inbound_stat_offsets: dict[str, tuple[int, int]] = {} # cid -> (read, errored)
191
+ self._outbound_stat_offsets: dict[
192
+ tuple[str, str], tuple[int, int]
193
+ ] = {} # key -> (written, dead)
183
194
  # The startup config dir is the default reload target and an implicit allowed root.
184
195
  self.config_dir: Path | None = Path(config_dir).resolve() if config_dir else None
185
196
  roots = [Path(r).resolve() for r in config_reload_roots]
@@ -712,6 +723,83 @@ class Engine:
712
723
  self._registry_runner.notify_work()
713
724
  return requeued
714
725
 
726
+ # --- connections-dashboard stats (in-memory reset baselines) -------------
727
+
728
+ async def connection_metrics_view(
729
+ self, *, now: float | None = None, rate_window: float = 60.0
730
+ ) -> ConnectionMetrics:
731
+ """Per-connection metrics for the dashboard with operator stats-resets applied. The cumulative
732
+ counters (inbound read/errored, outbound written/dead) have their reset baseline subtracted
733
+ (clamped at ``>= 0``); live gauges (queue depth, ages, last-seen) pass through untouched. With
734
+ no resets active this returns the store metrics verbatim, so the dashboard is byte-identical to
735
+ before this feature."""
736
+ metrics = await self.store.connection_metrics(
737
+ since=self.started_at, now=now, rate_window=rate_window
738
+ )
739
+ if not self._inbound_stat_offsets and not self._outbound_stat_offsets:
740
+ return metrics # fast path: nothing reset
741
+ inbound = {cid: self._apply_inbound_offset(cid, m) for cid, m in metrics.inbound.items()}
742
+ destinations = {
743
+ key: self._apply_outbound_offset(key, m) for key, m in metrics.destinations.items()
744
+ }
745
+ return ConnectionMetrics(inbound=inbound, destinations=destinations)
746
+
747
+ def _apply_inbound_offset(self, channel_id: str, m: InboundMetrics) -> InboundMetrics:
748
+ off = self._inbound_stat_offsets.get(channel_id)
749
+ if off is None:
750
+ return m
751
+ read0, errored0 = off
752
+ return replace(m, read=max(0, m.read - read0), errored=max(0, m.errored - errored0))
753
+
754
+ def _apply_outbound_offset(
755
+ self, key: tuple[str, str], m: DestinationMetrics
756
+ ) -> DestinationMetrics:
757
+ off = self._outbound_stat_offsets.get(key)
758
+ if off is None:
759
+ return m
760
+ written0, dead0 = off
761
+ return replace(m, written=max(0, m.written - written0), dead=max(0, m.dead - dead0))
762
+
763
+ async def reset_stats(
764
+ self,
765
+ *,
766
+ all_connections: bool = False,
767
+ inbound: Sequence[str] = (),
768
+ outbound: Sequence[tuple[str, str]] = (),
769
+ now: float | None = None,
770
+ ) -> int:
771
+ """Move the connections-dashboard "count from" mark to now for the targeted connections so the
772
+ visible cumulative counters (inbound read/errored, outbound written/dead) zero out. Implemented
773
+ as an in-memory snapshot of the current counts — message rows are never touched, and the
774
+ Prometheus ``/metrics`` counters (which must stay monotonic) are untouched too. ``all_connections``
775
+ resets every connection that has carried traffic. Returns the number of endpoints reset.
776
+
777
+ A connection with no traffic yet snapshots to ``(0, 0)``, which is correct: everything it sees
778
+ from here on arrives after the reset. Re-resetting overwrites the snapshot with the live counts,
779
+ so it re-zeroes."""
780
+ # Snapshot the RAW store counts (no offsets) so a re-reset captures the live cumulative value.
781
+ metrics = await self.store.connection_metrics(since=self.started_at, now=now)
782
+ count = 0
783
+ if all_connections:
784
+ for cid, m in metrics.inbound.items():
785
+ self._inbound_stat_offsets[cid] = (m.read, m.errored)
786
+ count += 1
787
+ for key, dm in metrics.destinations.items():
788
+ self._outbound_stat_offsets[key] = (dm.written, dm.dead)
789
+ count += 1
790
+ return count
791
+ for cid in inbound:
792
+ im = metrics.inbound.get(cid)
793
+ self._inbound_stat_offsets[cid] = (im.read, im.errored) if im is not None else (0, 0)
794
+ count += 1
795
+ for key in outbound:
796
+ dmet = metrics.destinations.get(key)
797
+ self._outbound_stat_offsets[key] = (
798
+ (dmet.written, dmet.dead) if dmet is not None else (0, 0)
799
+ )
800
+ count += 1
801
+ return count
802
+
715
803
  async def stop(self) -> None:
716
804
  """Stop the retention task + the wired graph, then close the store."""
717
805
  log.info("engine stopping")
@@ -196,7 +196,13 @@ def check_console_importable() -> CheckResult:
196
196
 
197
197
  def check_console_no_window() -> CheckResult:
198
198
  """The console's service-control path passes CREATE_NO_WINDOW (no console flash on Status poll)."""
199
- spec = importlib.util.find_spec("messagefoundry.console.service_control")
199
+ try:
200
+ # find_spec on a SUBMODULE imports the parent package; if console/__init__ ever drags a
201
+ # missing [console]-extra dep (e.g. httpx) this raises ModuleNotFoundError. Degrade to SKIP
202
+ # like every sibling check instead of crashing the whole `verify` run on a non-[console] box.
203
+ spec = importlib.util.find_spec("messagefoundry.console.service_control")
204
+ except (ImportError, ValueError):
205
+ spec = None
200
206
  if spec is None or not spec.origin:
201
207
  return CheckResult(
202
208
  "host.noflash",
@@ -5,6 +5,8 @@ fail-closed leak-check — engine side."""
5
5
 
6
6
  from __future__ import annotations
7
7
 
8
+ from pathlib import Path
9
+
8
10
  import pytest
9
11
 
10
12
  from messagefoundry.anon import (
@@ -22,6 +24,15 @@ from messagefoundry.anon import (
22
24
  )
23
25
  from messagefoundry.anon.surrogates import Seps, scrub_site_codes, surrogate_field
24
26
 
27
+ # The leak-check delegates to scripts/publish/scan_forbidden.py (the owner-managed publish guard — a
28
+ # dev/source-checkout tool, not in the wheel and deny-listed in the OSS mirror). Skip the two tests that
29
+ # exercise it where it's absent; the engine raises LeakCheckUnavailable there by design.
30
+ _LEAK_SCANNER = Path(__file__).resolve().parents[1] / "scripts" / "publish" / "scan_forbidden.py"
31
+ _NO_SCANNER = pytest.mark.skipif(
32
+ not _LEAK_SCANNER.exists(),
33
+ reason="leak-check needs scripts/publish/scan_forbidden.py (private-only; OSS-mirror deny-list)",
34
+ )
35
+
25
36
  _SALT = "unit-salt-0123456789abcdef"
26
37
  _SEPS = Seps()
27
38
 
@@ -184,6 +195,7 @@ def test_anonymize_reads_custom_separators_from_msh() -> None:
184
195
  # --- leak-check -----------------------------------------------------------------------------------
185
196
 
186
197
 
198
+ @_NO_SCANNER
187
199
  def test_leak_check_clean_and_dirty() -> None:
188
200
  assert leak_check(anonymize(_SAMPLE, salt=_SALT)) == []
189
201
  hits = leak_check("note mentioning OMNICELL and 540099")
@@ -191,6 +203,7 @@ def test_leak_check_clean_and_dirty() -> None:
191
203
  assert any("54" in h for h in hits)
192
204
 
193
205
 
206
+ @_NO_SCANNER
194
207
  def test_anonymize_checked_fails_closed_and_is_phi_safe() -> None:
195
208
  # estate token in a KEPT field (MSH-3) survives surrogation -> must raise
196
209
  dirty = _msg(
@@ -38,6 +38,11 @@ _REFUSED = ["", "PID|1||9^^^H^MR||DOE^JOHN", "MSH|^~|A|B", "not hl7 at all"]
38
38
 
39
39
  def _load_scan_forbidden() -> object:
40
40
  path = _ROOT / "scripts" / "publish" / "scan_forbidden.py"
41
+ if not path.exists():
42
+ # Private-only (scripts/publish/ is deny-listed in the OSS mirror); skip where it's absent.
43
+ pytest.skip(
44
+ "scan_forbidden.py is private-only (OSS-mirror deny-list)", allow_module_level=True
45
+ )
41
46
  spec = importlib.util.spec_from_file_location("scan_forbidden", path)
42
47
  assert spec is not None and spec.loader is not None
43
48
  mod = importlib.util.module_from_spec(spec)
@@ -40,6 +40,24 @@ def test_validate_clean_sample(capsys: pytest.CaptureFixture[str]) -> None:
40
40
  assert _out_json(capsys) == []
41
41
 
42
42
 
43
+ def test_top_level_help_encodes_on_legacy_windows_codepage(
44
+ capsys: pytest.CaptureFixture[str],
45
+ ) -> None:
46
+ # Regression: `messagefoundry --help` crashed with UnicodeEncodeError on a cp1252/charmap
47
+ # console because of a U+2192 arrow in the adr-analyze subparser help. Render the help string
48
+ # in-process and assert it survives a cp1252 encode -- reproduces the Windows-only crash on any
49
+ # runner without touching the real terminal (argparse --help raises SystemExit after printing).
50
+ with pytest.raises(SystemExit):
51
+ main(["--help"])
52
+ help_text = capsys.readouterr().out
53
+ assert "adr-analyze" in help_text, "top-level help did not render the subcommand list"
54
+ try:
55
+ help_text.encode("cp1252")
56
+ except UnicodeEncodeError as exc:
57
+ bad = help_text[exc.start]
58
+ pytest.fail(f"top-level --help is not cp1252-encodable: U+{ord(bad):04X} {bad!r}")
59
+
60
+
43
61
  def test_validate_reports_problems(tmp_path: Path, capsys: pytest.CaptureFixture[str]) -> None:
44
62
  (tmp_path / "bad.py").write_text("raise ValueError('boom')\n", encoding="utf-8")
45
63
  assert main(["validate", "--config", str(tmp_path), "--json"]) == 1