messagefoundry 0.2.13__tar.gz → 0.2.14__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.
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/CHANGELOG.md +40 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/PKG-INFO +1 -1
- messagefoundry-0.2.14/docs/releases/DELTA-SECURITY-FIXES-MULTISESSION-PLAN.md +197 -0
- messagefoundry-0.2.14/docs/reviews/DELTA-REVIEW-2026-07-01.md +262 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/harness/__main__.py +130 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/harness/config/connscale/_shape.py +30 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/harness/config/connscale/graph.py +7 -4
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/harness/load/connscale/report.py +7 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/harness/load/connscale/runner.py +90 -55
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/harness/load/enginepoll.py +44 -0
- messagefoundry-0.2.14/harness/load/multishard.py +753 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/harness/load/report.py +64 -7
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/harness/load/runner.py +24 -4
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/messagefoundry/__init__.py +1 -1
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/messagefoundry/parsing/_builtin_hl7.py +21 -1
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/messagefoundry/parsing/peek.py +5 -1
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/messagefoundry/parsing/xml/signature.py +16 -4
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/messagefoundry/pipeline/wiring_runner.py +29 -15
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/messagefoundry/support/bundle.py +17 -2
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/messagefoundry/support/redact.py +34 -17
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/messagefoundry/transports/http_listener.py +16 -1
- messagefoundry-0.2.14/tests/test_builtin_hl7_hardening.py +87 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/tests/test_connscale_report.py +31 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/tests/test_connscale_smoke.py +10 -3
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/tests/test_fhir_lookup.py +15 -0
- messagefoundry-0.2.14/tests/test_harness_reconcile.py +230 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/tests/test_inbound_http_source.py +40 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/tests/test_load_runner.py +34 -10
- messagefoundry-0.2.14/tests/test_multishard_smoke.py +139 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/tests/test_support_bundle.py +67 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/tests/test_xml_schema_signature.py +4 -1
- messagefoundry-0.2.14/tests/test_xml_signature_anchor.py +44 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/.claude/settings.json +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/.dockerignore +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/.gitattributes +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/.github/CODEOWNERS +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/.github/ISSUE_TEMPLATE/config.yml +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/.github/ISSUE_TEMPLATE/feature_request.md +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/.github/PULL_REQUEST_TEMPLATE.md +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/.github/SECURITY.md +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/.github/dependabot.yml +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/.github/workflows/benchmark.yml +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/.github/workflows/ci.yml +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/.github/workflows/cla.yml +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/.github/workflows/codeql.yml +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/.github/workflows/dependabot-auto-merge.yml +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/.github/workflows/dependabot-lock-resync.yml +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/.github/workflows/freethread-smoke.yml +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/.github/workflows/manifest-lint.yml +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/.github/workflows/release-sync-check.yml +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/.github/workflows/release.yml +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/.github/workflows/scorecard.yml +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/.github/workflows/security.yml +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/.github/workflows/selfhosted-win2025-sql.yml +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/.github/workflows/vuln-metrics.yml +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/.github/zizmor.yml +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/.gitignore +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/.gitleaks.toml +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/.mefor-hooks/pre-commit +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/.pre-commit-config.yaml +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/.semgrep/messagefoundry.yml +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/CLA.md +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/CLAUDE.md +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/CODE_OF_CONDUCT.md +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/COMMERCIAL-LICENSE.md +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/CONTRIBUTING.md +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/GOVERNANCE.md +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/LICENSE +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/MAINTAINERS.md +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/NOTICE +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/README.md +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/docker/Dockerfile +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/docker/README.md +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/docker/compose.yaml +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/docker/k8s/ha-postgres.yaml +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/docker/k8s/secret.example.yaml +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/docker/k8s/statefulset.yaml +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/docker/locks/requirements-core.lock +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/docker/locks/requirements-sqlserver.lock +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/docker/secrets.env.example +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/docker/smoke/Dockerfile +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/docker/smoke/config/IB_Test_ADT.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/docker/smoke/send_adt.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/docs/ADOPTER-CI.md +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/docs/AI.md +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/docs/ANTIVIRUS-FIREWALL.md +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/docs/ARCHITECTURE.md +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/docs/BACKLOG.md +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/docs/BRAND.md +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/docs/CI-QUALITY.md +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/docs/CLOUD-DEPLOYMENT.md +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/docs/CLOUD-PHI-HIPAA.md +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/docs/CLUSTERING.md +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/docs/CODESETS.md +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/docs/CONFIGURATION.md +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/docs/CONNECTIONS.md +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/docs/CONTAINER-EXPOSURE-EVALUATION.md +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/docs/CONTRIBUTOR-FIRST-ISSUES.md +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/docs/CONTRIBUTOR-PROGRAM-PLAN.md +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/docs/COUNSEL-ENGAGEMENT-BRIEF.md +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/docs/DEPLOY-SERVER-DB.md +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/docs/DEPLOYMENT.md +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/docs/DICOM.md +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/docs/DUAL_LICENSING_PLAN.md +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/docs/EARLY-ADOPTER-GUIDE.md +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/docs/FEATURE-MAP.md +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/docs/HL7-VALIDATION.md +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/docs/INSTALL-GUIDE.md +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/docs/LOAD-TESTING.md +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/docs/MENTAL-MODEL.md +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/docs/MessageFoundry-Mental-Model.docx +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/docs/PHI.md +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/docs/POSITIONING.md +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/docs/REMOTE-CONSOLE-CUSTOMER-GUIDE.md +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/docs/REMOTE-CONSOLE.md +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/docs/SECURITY-REMEDIATION-LEDGER.md +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/docs/SECURITY.md +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/docs/SERVICE.md +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/docs/SUPPORT-POLICY.md +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/docs/SYSTEM-REQUIREMENTS.md +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/docs/Secure_AI_Development_Standards.md +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/docs/Secure_Development_Standards.md +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/docs/TEE-RELAY.md +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/docs/THROUGHPUT-IMPROVEMENTS.md +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/docs/THROUGHPUT.md +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/docs/USER-GUIDE.md +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/docs/WORKTREES.md +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/docs/adr/0001-staged-pipeline-architecture.md +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/docs/adr/0002-phase2-transport-security-and-strong-auth.md +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/docs/adr/0003-non-hl7-transports-database-rest-soap.md +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/docs/adr/0004-payload-agnostic-ingress.md +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/docs/adr/0005-transform-accessible-state.md +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/docs/adr/0006-external-data-lookups.md +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/docs/adr/0007-gui-manageable-connections-toml.md +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/docs/adr/0008-cluster-observability-api.md +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/docs/adr/0009-run-scoped-context-providers.md +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/docs/adr/0010-handler-callable-db-lookup.md +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/docs/adr/0011-timer-scheduled-source.md +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/docs/adr/0012-x12-edi-codec.md +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/docs/adr/0013-increment-2-reingress-design.md +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/docs/adr/0013-query-response-orchestration.md +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/docs/adr/0014-alerting-rules-engine.md +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/docs/adr/0015-ws-soap-outbound-mtls-wssecurity.md +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/docs/adr/0016-synchronous-x12-request-response.md +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/docs/adr/0017-consumer-deployment-model.md +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/docs/adr/0018-per-message-signatures-accepted-risk.md +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/docs/adr/0019-pluggable-keyprovider-hsm-kms-vault.md +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/docs/adr/0020-protocol-diagnostic-capture.md +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/docs/adr/0021-inbound-ack-nak-capture-response-sent.md +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/docs/adr/0022-fhir-resource-codec-rest-client.md +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/docs/adr/0023-inbound-http-listener.md +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/docs/adr/0024-smart-backend-services-token-provider.md +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/docs/adr/0025-dicom-codec-store-connectors.md +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/docs/adr/0026-off-box-egress-update-check.md +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/docs/adr/0027-per-connection-retention.md +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/docs/adr/0028-base64-binary-carriage-codec.md +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/docs/adr/0029-email-smtp-destination.md +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/docs/adr/0030-anonymization-test-harness-tee.md +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/docs/adr/0031-startup-connection-fault-isolation.md +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/docs/adr/0032-console-desktop-launch.md +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/docs/adr/0033-gui-manageable-code-sets.md +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/docs/adr/0034-static-analysis-triage-policy-accepted-risk-register.md +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/docs/adr/0035-ide-extension-workspace-trust-and-scope.md +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/docs/adr/0036-windows-config-source-trust.md +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/docs/adr/0037-multi-process-sharding-l3.md +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/docs/adr/0038-internal-pass-through-connector.md +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/docs/adr/0039-database-tier-sharding-l5.md +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/docs/adr/0040-free-threaded-engine-support.md +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/docs/adr/0041-load-path-attestation-and-change-attribution.md +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/docs/adr/0042-embedded-document-pruning.md +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/docs/adr/0043-fhir-read-lookup.md +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/docs/adr/0044-operator-alert-state.md +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/docs/adr/0045-custom-rbac-roles.md +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/docs/adr/0046-message-content-search.md +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/docs/adr/0047-cloud-kubernetes-ha-deployment-packaging.md +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/docs/adr/0048-third-tier-disaster-recovery-standby.md +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/docs/adr/0049-turnkey-dr-backup-restore-verify.md +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/docs/adr/0050-single-project-root-config-anchoring.md +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/docs/adr/0051-corepoint-throughput-parity-strategy.md +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/docs/adr/0052-enterprise-scale-target.md +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/docs/adr/0053-free-threaded-multicore-engine.md +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/docs/adr/0054-low-allocation-builtins-hl7-parser.md +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/docs/adr/0055-group-commit-durable-write.md +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/docs/adr/0056-engine-managed-vip-failover.md +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/docs/adr/0057-inline-step-a-fast-path.md +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/docs/adr/0058-batch-claim-fifo-prefix.md +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/docs/adr/0059-seq-only-fifo-ordering.md +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/docs/adr/0060-rename-based-fifo-index-migration.md +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/docs/adr/0061-per-lane-wake-events.md +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/docs/adr/0062-default-store-pool-size.md +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/docs/adr/0063-no-split-store-unified-store-for-sharding.md +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/docs/adr/README.md +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/docs/adr/TEMPLATE.md +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/docs/architecture-components.png +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/docs/architecture-components.svg +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/docs/architecture-config-graph.png +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/docs/architecture-config-graph.svg +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/docs/architecture-diagram.md +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/docs/architecture-message-flow.png +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/docs/architecture-message-flow.svg +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/docs/architecture-topology.png +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/docs/architecture-topology.svg +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/docs/benchmarks/TUNING-BASELINE.md +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/docs/benchmarks/results/2026-06-16-ci-linux/environment.txt +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/docs/benchmarks/results/2026-06-16-ci-linux/failover-postgres.json +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/docs/benchmarks/results/2026-06-16-ci-linux/failover-sqlserver.json +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/docs/benchmarks/results/2026-06-16-ci-linux/reference-postgres.json +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/docs/benchmarks/results/2026-06-16-ci-linux/reference-sqlite.json +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/docs/benchmarks/results/2026-06-16-ci-linux/reference-sqlserver.json +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/docs/benchmarks/step-b-write-amplification.md +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/docs/design/dbshard.md +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/docs/design/freethread-spike.md +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/docs/design/freethread.md +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/docs/design/multiproc.md +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/docs/hl7-message-ordering-reference.md +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/docs/message-ordering-design.md +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/docs/releases/ASVS-OPTION-A-MULTISESSION-PLAN.md +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/docs/releases/ASVS-PARTIALS-SWEEP-MULTISESSION-PLAN.md +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/docs/releases/DOGFOOD-BACKLOG-MULTISESSION-PLAN.md +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/docs/releases/MULTISESSION-PLAN-3.md +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/docs/releases/MULTISESSION-PLAN-4.md +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/docs/releases/MULTISESSION-PLAN-5.md +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/docs/releases/MULTISESSION-PLAN-6.md +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/docs/releases/MULTISESSION-PLAN-v0.2.md +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/docs/releases/MULTISESSION-PLAN.md +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/docs/releases/PLAN-3-LANE-HANDOFFS.md +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/docs/releases/V0.2-LANE-HANDOFFS.md +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/docs/releases/v0.1-EXECUTION-PLAN.md +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/docs/releases/v0.1-PLAN.md +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/docs/releases/v0.1.0-PRETAG-CHECKLIST.md +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/docs/research/cloud-deployment-research-2026-06.md +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/docs/research/config-ux-review.md +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/docs/research/non-hl7-transform-components.md +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/docs/reviews/DEPENDENCY-INFOSEC-POSTURE-2026-06-23.md +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/docs/reviews/FULL-REVIEW-2026-06-10.md +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/docs/security/ADVISORY-PROCESS.md +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/docs/security/ASVS-FAILS-REMEDIATION-PLAN.md +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/docs/security/ASVS-L2-PHASE0-CHANGES.md +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/docs/security/ASVS-L2-REMEDIATION-PLAN.md +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/docs/security/ASVS-L3-ASSESSMENT.md +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/docs/security/ASVS-L3-REMEDIATION-PLAN.md +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/docs/security/ASVS-L3-STATUS.md +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/docs/security/BEYOND-ASVS-L3-ONEPAGE.md +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/docs/security/BEYOND-ASVS-L3-REMEDIATION-PLAN-ONEPAGE.md +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/docs/security/BEYOND-ASVS-L3-REMEDIATION-PLAN.md +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/docs/security/BEYOND-ASVS-L3.md +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/docs/security/DEP-CVE-RUNBOOK.md +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/docs/security/DEPENDENCY-METRICS.md +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/docs/security/MEFOR-Code-Review-Checklist.xlsx +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/docs/security/PHASE-8C-RBAC.md +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/docs/security/PUBLISHING.md +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/docs/security/RCA-TEMPLATE.md +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/docs/security/RELEASE-GATE.md +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/docs/security/REMEDIATION-PLAN.md +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/docs/security/REVIEW-2026-06-07.md +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/docs/security/SDS-CONFORMANCE-REVIEW-2026-06-12.md +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/docs/security/SDS-REMEDIATION-PLAN.md +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/docs/security/SECURITY-POSTURE.md +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/docs/security/SOUP-DEPENDENCY-HANDLING.md +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/docs/security/SOUP-REVIEW-2026-06-18.md +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/docs/security/SOUP-REVIEW-PROCEDURE.md +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/docs/security/THREAT-MODEL.md +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/docs/testing/VERIFY.md +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/docs/testing/WIN2025-ACCEPTANCE.md +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/docs/testing/WIN2025-TEST-MATRIX.md +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/docs/testing/WIN2025-TEST-PLAN.md +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/docs/throughput-build-plan.md +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/docs/throughput-roadmap.md +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/environments/dev.toml +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/environments/prod.toml +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/harness/README.md +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/harness/acceptance/__init__.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/harness/acceptance/__main__.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/harness/acceptance/matrix.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/harness/acceptance/probes.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/harness/acceptance/report.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/harness/acceptance/runner.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/harness/compose.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/harness/config/connscale/__init__.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/harness/config/connscale/gen_toml.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/harness/config/coverage.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/harness/config/load/_shape.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/harness/config/load/graph.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/harness/config/passthrough/graph.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/harness/config/store_once/graph.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/harness/file_panel.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/harness/file_transport.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/harness/load/__init__.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/harness/load/connscale/__init__.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/harness/load/connscale/driver.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/harness/load/connscale/probe.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/harness/load/connscale/profile.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/harness/load/corpus.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/harness/load/correlator.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/harness/load/failover.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/harness/load/failover_track.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/harness/load/governor.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/harness/load/ids.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/harness/load/metrics.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/harness/load/profile.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/harness/load/profiles/README.md +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/harness/load/profiles/adt-fanout-stress.toml +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/harness/load/profiles/closed-loop.toml +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/harness/load/profiles/connscale-smoke.toml +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/harness/load/profiles/connscale.toml +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/harness/load/profiles/failover.toml +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/harness/load/profiles/fanout-baseline.toml +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/harness/load/profiles/malformed-load.toml +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/harness/load/profiles/reference.toml +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/harness/load/profiles/smoke-sqlserver.toml +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/harness/load/profiles/smoke.toml +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/harness/load/profiles/soak.toml +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/harness/load/profiles/spike-burst.toml +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/harness/load/profiles/sustained-overload.toml +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/harness/load/profiles/writeamp.toml +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/harness/load/sender.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/harness/load/sink.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/harness/mllp.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/harness/monitor.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/harness/receive.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/harness/reconcile/__init__.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/harness/reconcile/__main__.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/harness/reconcile/capture.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/harness/reconcile/compare.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/harness/reconcile/normalize.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/harness/reconcile/report.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/harness/scenarios.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/harness/send.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/harness/window.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/ide/.gitignore +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/ide/.vscodeignore +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/ide/README.md +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/ide/esbuild.js +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/ide/media/hl7schema.json +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/ide/media/icon-amber.svg +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/ide/media/icon.png +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/ide/media/icon.svg +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/ide/package-lock.json +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/ide/package.json +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/ide/snippets/messagefoundry.code-snippets +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/ide/src/aiPolicy.ts +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/ide/src/alertEditor.ts +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/ide/src/auth.ts +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/ide/src/chat.ts +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/ide/src/cli.ts +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/ide/src/codeSetEditor.ts +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/ide/src/codesetsTree.ts +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/ide/src/completion.ts +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/ide/src/connectionEditor.ts +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/ide/src/editorToolbar.ts +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/ide/src/engineClient.ts +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/ide/src/engineTarget.ts +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/ide/src/extension.ts +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/ide/src/generate.ts +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/ide/src/git.ts +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/ide/src/graphTree.ts +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/ide/src/home.ts +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/ide/src/insertElement.ts +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/ide/src/newRoute.ts +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/ide/src/promote.ts +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/ide/src/promoteTarget.ts +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/ide/src/sourceControl.ts +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/ide/src/test/runTest.ts +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/ide/src/test/suite/ai-policy.test.ts +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/ide/src/test/suite/chat.test.ts +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/ide/src/test/suite/editor-toolbar.test.ts +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/ide/src/test/suite/engine-target.test.ts +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/ide/src/test/suite/extension.test.ts +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/ide/src/test/suite/index.ts +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/ide/src/test/suite/insert-element.test.ts +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/ide/src/test/suite/promote-target.test.ts +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/ide/src/test/suite/pythonpath.test.ts +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/ide/src/test/suite/settings-scope.test.ts +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/ide/src/testBench.ts +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/ide/src/validate.ts +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/ide/tsconfig.json +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/ide/tsconfig.test.json +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/mefor.code-workspace +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/messagefoundry/__main__.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/messagefoundry/adr_analyze.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/messagefoundry/anon/__init__.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/messagefoundry/anon/_pools.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/messagefoundry/anon/hl7.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/messagefoundry/anon/keying.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/messagefoundry/anon/leak.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/messagefoundry/anon/rules.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/messagefoundry/anon/surrogates.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/messagefoundry/api/__init__.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/messagefoundry/api/app.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/messagefoundry/api/approvals.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/messagefoundry/api/auth_models.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/messagefoundry/api/auth_routes.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/messagefoundry/api/field_authz.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/messagefoundry/api/metrics.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/messagefoundry/api/models.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/messagefoundry/api/security.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/messagefoundry/api/tls.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/messagefoundry/auth/__init__.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/messagefoundry/auth/data/common_passwords.NOTICE +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/messagefoundry/auth/data/common_passwords.txt +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/messagefoundry/auth/identity.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/messagefoundry/auth/ldap.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/messagefoundry/auth/notifications.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/messagefoundry/auth/passwords.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/messagefoundry/auth/permissions.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/messagefoundry/auth/policy.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/messagefoundry/auth/ratelimit.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/messagefoundry/auth/service.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/messagefoundry/auth/tokens.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/messagefoundry/auth/totp.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/messagefoundry/checks.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/messagefoundry/config/__init__.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/messagefoundry/config/active_environment.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/messagefoundry/config/ai_policy.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/messagefoundry/config/alerts_edit.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/messagefoundry/config/anchor.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/messagefoundry/config/code_sets.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/messagefoundry/config/codeset_edit.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/messagefoundry/config/connections_edit.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/messagefoundry/config/connections_file.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/messagefoundry/config/db_lookup.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/messagefoundry/config/environments.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/messagefoundry/config/fhir_lookup.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/messagefoundry/config/fingerprint.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/messagefoundry/config/ingest_time.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/messagefoundry/config/models.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/messagefoundry/config/reference.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/messagefoundry/config/response.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/messagefoundry/config/run_context.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/messagefoundry/config/settings.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/messagefoundry/config/state.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/messagefoundry/config/tls_policy.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/messagefoundry/config/wiring.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/messagefoundry/console/__init__.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/messagefoundry/console/__main__.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/messagefoundry/console/_async.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/messagefoundry/console/alerts_page.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/messagefoundry/console/change_password.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/messagefoundry/console/client.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/messagefoundry/console/connections.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/messagefoundry/console/dead_letters_page.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/messagefoundry/console/delegates.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/messagefoundry/console/event_log_page.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/messagefoundry/console/icons/alerts.svg +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/messagefoundry/console/icons/connections.svg +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/messagefoundry/console/icons/dead-letters.svg +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/messagefoundry/console/icons/engine-status.svg +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/messagefoundry/console/icons/log-search.svg +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/messagefoundry/console/icons/logo-lockup.svg +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/messagefoundry/console/icons/users.svg +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/messagefoundry/console/login.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/messagefoundry/console/mfa.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/messagefoundry/console/reauth.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/messagefoundry/console/resources/README.md +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/messagefoundry/console/resources/app.ico +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/messagefoundry/console/resources/app.svg +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/messagefoundry/console/search.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/messagefoundry/console/service_control.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/messagefoundry/console/sessions.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/messagefoundry/console/shards.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/messagefoundry/console/shell.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/messagefoundry/console/status.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/messagefoundry/console/theme.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/messagefoundry/console/users_page.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/messagefoundry/console/widgets.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/messagefoundry/generators/README.md +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/messagefoundry/generators/__init__.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/messagefoundry/generators/_core.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/messagefoundry/generators/_hl7data.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/messagefoundry/generators/adt.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/messagefoundry/generators/all_types.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/messagefoundry/generators/bar.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/messagefoundry/generators/dft.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/messagefoundry/generators/documents.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/messagefoundry/generators/mdm.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/messagefoundry/generators/mfn.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/messagefoundry/generators/oml.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/messagefoundry/generators/orl.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/messagefoundry/generators/orm.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/messagefoundry/generators/oru.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/messagefoundry/generators/ras.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/messagefoundry/generators/rde.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/messagefoundry/generators/siu.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/messagefoundry/generators/vxu.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/messagefoundry/hl7schema.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/messagefoundry/integrity.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/messagefoundry/last_resort.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/messagefoundry/logging_setup.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/messagefoundry/parsing/__init__.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/messagefoundry/parsing/_backend.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/messagefoundry/parsing/binary.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/messagefoundry/parsing/consistency.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/messagefoundry/parsing/dicom/__init__.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/messagefoundry/parsing/dicom/_deps.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/messagefoundry/parsing/dicom/_util.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/messagefoundry/parsing/dicom/dataset.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/messagefoundry/parsing/dicom/errors.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/messagefoundry/parsing/dicom/hl7_map.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/messagefoundry/parsing/dicom/peek.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/messagefoundry/parsing/fhir/__init__.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/messagefoundry/parsing/fhir/_deps.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/messagefoundry/parsing/fhir/errors.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/messagefoundry/parsing/fhir/peek.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/messagefoundry/parsing/fhir/resource.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/messagefoundry/parsing/groups.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/messagefoundry/parsing/message.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/messagefoundry/parsing/split.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/messagefoundry/parsing/summary.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/messagefoundry/parsing/tree.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/messagefoundry/parsing/validate.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/messagefoundry/parsing/x12/__init__.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/messagefoundry/parsing/x12/_deps.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/messagefoundry/parsing/x12/delimiters.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/messagefoundry/parsing/x12/errors.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/messagefoundry/parsing/x12/interchange.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/messagefoundry/parsing/x12/message.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/messagefoundry/parsing/x12/peek.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/messagefoundry/parsing/x12/validate.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/messagefoundry/parsing/xml/__init__.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/messagefoundry/parsing/xml/_deps.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/messagefoundry/parsing/xml/errors.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/messagefoundry/parsing/xml/harden.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/messagefoundry/parsing/xml/message.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/messagefoundry/parsing/xml/schema.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/messagefoundry/pipeline/__init__.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/messagefoundry/pipeline/alert_sinks.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/messagefoundry/pipeline/alerts.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/messagefoundry/pipeline/cert_expiry.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/messagefoundry/pipeline/cluster.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/messagefoundry/pipeline/cluster_sqlserver.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/messagefoundry/pipeline/config_convergence.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/messagefoundry/pipeline/connscale_shim.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/messagefoundry/pipeline/dr.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/messagefoundry/pipeline/dr_backup.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/messagefoundry/pipeline/dryrun.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/messagefoundry/pipeline/engine.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/messagefoundry/pipeline/leader_tasks.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/messagefoundry/pipeline/reference_sync.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/messagefoundry/pipeline/retention.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/messagefoundry/pipeline/security_notify.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/messagefoundry/pipeline/sharding.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/messagefoundry/pipeline/state_convergence.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/messagefoundry/pipeline/supervisor.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/messagefoundry/pipeline/update_check.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/messagefoundry/py.typed +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/messagefoundry/redaction.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/messagefoundry/scaffold.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/messagefoundry/secrets_dpapi.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/messagefoundry/store/__init__.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/messagefoundry/store/audit_tee.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/messagefoundry/store/backup_codec.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/messagefoundry/store/base.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/messagefoundry/store/content_search.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/messagefoundry/store/crypto.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/messagefoundry/store/document_strip.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/messagefoundry/store/keyprovider.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/messagefoundry/store/pool_metrics.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/messagefoundry/store/postgres.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/messagefoundry/store/sqlserver.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/messagefoundry/store/store.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/messagefoundry/support/__init__.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/messagefoundry/timezone.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/messagefoundry/transports/__init__.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/messagefoundry/transports/base.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/messagefoundry/transports/database.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/messagefoundry/transports/dicom.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/messagefoundry/transports/dicomweb.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/messagefoundry/transports/email.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/messagefoundry/transports/fhir.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/messagefoundry/transports/file.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/messagefoundry/transports/framing.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/messagefoundry/transports/loopback.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/messagefoundry/transports/mllp.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/messagefoundry/transports/passthrough.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/messagefoundry/transports/remotefile.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/messagefoundry/transports/rest.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/messagefoundry/transports/signing.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/messagefoundry/transports/smart.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/messagefoundry/transports/soap.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/messagefoundry/transports/tcp.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/messagefoundry/transports/timer.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/messagefoundry/transports/x12.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/messagefoundry/verify/__init__.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/messagefoundry/verify/checks.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/messagefoundry/verify/model.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/messagefoundry/verify/report.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/messagefoundry/verify/runner.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/messagefoundry/verify/smoke.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/packaging/console-installer/README.md +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/packaging/console-installer/THIRD-PARTY-NOTICES.md +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/packaging/console-installer/THIRD-PARTY-NOTICES.txt +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/packaging/console-installer/console_launcher.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/packaging/console-installer/licenses/GPL-3.0.txt +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/packaging/console-installer/licenses/LGPL-3.0.txt +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/packaging/console-installer/messagefoundry-console.iss +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/packaging/console-installer/messagefoundry-console.spec +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/packaging/messagefoundry-harness/README.md +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/packaging/messagefoundry-harness/pyproject.toml +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/pyproject.toml +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/requirements.lock +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/samples/config/IB_ACME_ADT.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/samples/config/IB_FHIR_INTAKE.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/samples/config/IB_IMMUNIZATION_VXU.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/samples/config/IB_PARTNER_X12.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/samples/config/IB_RADIOLOGY_SR.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/samples/config/IB_RTE_ELIGIBILITY.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/samples/config/adt.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/samples/config/codesets/event_labels.csv +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/samples/config/codesets/facility_mnemonics.toml +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/samples/config/connections.toml +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/samples/consistency/validated_adt.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/samples/dicom/generate_sr_sample.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/samples/messages/adt_a01.hl7 +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/samples/messages/adt_batch.hl7 +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/samples/messages/hapi-hl7v2/.gitattributes +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/samples/messages/hapi-hl7v2/README.md +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/samples/messages/hapi-hl7v2/adt_a01.txt +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/samples/messages/hapi-hl7v2/adt_a03.txt +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/samples/messages/hapi-hl7v2/batch_18_messages.txt +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/samples/messages/hapi-hl7v2/erp_z99_v231.hl7 +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/samples/messages/hapi-hl7v2/omd_o03.txt +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/samples/messages/hapi-hl7v2/omd_o03_rep.txt +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/samples/messages/hapi-hl7v2/oml_o21.hl7 +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/samples/messages/x12_270_eligibility.edi +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/samples/results_relay/README.md +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/samples/results_relay/codesets/test_codes.csv +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/samples/results_relay/messages/oru_all_cancelled.hl7 +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/samples/results_relay/messages/oru_results.hl7 +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/samples/results_relay/results_relay.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/samples/send_mllp.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/scripts/console/install-console-shortcut.ps1 +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/scripts/console/pack_ico.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/scripts/console/uninstall-console-shortcut.ps1 +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/scripts/dev/postgres.ps1 +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/scripts/dev/sqlserver-docker.ps1 +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/scripts/dev/sqlserver.ps1 +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/scripts/hooks/block-blanket-git-stage.ps1 +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/scripts/publish/check_release_sync.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/scripts/publish/publish-denylist.txt +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/scripts/publish/publish.ps1 +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/scripts/publish/scan_forbidden.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/scripts/security/crypto_inventory_check.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/scripts/security/vuln_metrics.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/scripts/service/import-db-ca.ps1 +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/scripts/service/install-service.ps1 +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/scripts/service/uninstall-service.ps1 +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/scripts/trace_icon.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/scripts/worktree/new.ps1 +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/scripts/worktree/remove.ps1 +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/scripts/worktree/session-context.ps1 +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/scripts/worktree/spawn.ps1 +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/tee/__init__.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/tee/__main__.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/tee/anon/__init__.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/tee/anon/_hl7data.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/tee/anon/_pools.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/tee/anon/hl7.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/tee/anon/keying.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/tee/anon/leak.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/tee/anon/rules.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/tee/anon/surrogates.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/tee/compare.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/tee/correlate.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/tee/hl7_fields.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/tee/mefor_api.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/tee/mllp.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/tee/relay.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/tee/report.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/tee/store.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/tests/_dicom_sample.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/tests/_failover_load_support.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/tests/_fhir_fixtures.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/tests/conftest.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/tests/test_acceptance_framework.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/tests/test_ack_capture_runner.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/tests/test_ack_sent_store.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/tests/test_active_environment.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/tests/test_ad_group_scope.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/tests/test_admin_new_ip.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/tests/test_adr_analyze.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/tests/test_ai_policy.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/tests/test_alert_rules.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/tests/test_alert_sinks.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/tests/test_alert_state.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/tests/test_alerts_edit.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/tests/test_alerts_rules_api.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/tests/test_anon_core.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/tests/test_anon_integration.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/tests/test_anon_parity.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/tests/test_api.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/tests/test_api_alerts.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/tests/test_api_auth.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/tests/test_api_reload.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/tests/test_api_tls.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/tests/test_approvals.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/tests/test_asvs_phase0.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/tests/test_audit_integrity.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/tests/test_audit_offbox_tee.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/tests/test_auth_core.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/tests/test_auth_entry_hardening.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/tests/test_auth_hardening.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/tests/test_auth_service.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/tests/test_auth_session_lifecycle.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/tests/test_auth_store.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/tests/test_backup_crypto.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/tests/test_backup_restore_atleastonce.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/tests/test_backup_runner.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/tests/test_batch_claim_fifo.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/tests/test_batch_claim_locking.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/tests/test_batch_claim_worker.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/tests/test_binary_carriage.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/tests/test_bootstrap_admin_perms.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/tests/test_builtin_hl7_parity.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/tests/test_cert_expiry.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/tests/test_channel_rbac.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/tests/test_checks.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/tests/test_checks_lint.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/tests/test_cli.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/tests/test_cli_offline_resolution.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/tests/test_cluster.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/tests/test_cluster_failover_postgres.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/tests/test_cluster_failover_sqlserver.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/tests/test_cluster_graph_gating.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/tests/test_cluster_lease.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/tests/test_code_sets.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/tests/test_codeset_edit.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/tests/test_config_anchoring.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/tests/test_config_fingerprint.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/tests/test_config_source_trust.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/tests/test_connection_api.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/tests/test_connection_event_api.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/tests/test_connection_event_emit.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/tests/test_connection_event_outbound.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/tests/test_connection_event_scope.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/tests/test_connection_event_store.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/tests/test_connection_resilience.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/tests/test_connections_cli.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/tests/test_connections_file.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/tests/test_connscale_config.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/tests/test_connscale_driver.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/tests/test_connscale_postgres.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/tests/test_connscale_profile.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/tests/test_consistency.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/tests/test_console_alerts.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/tests/test_console_auth.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/tests/test_console_client.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/tests/test_console_dead_letters.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/tests/test_console_event_log.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/tests/test_console_hardening.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/tests/test_console_icon.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/tests/test_console_password.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/tests/test_console_sessions.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/tests/test_console_shards.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/tests/test_console_status.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/tests/test_console_step_up.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/tests/test_console_theme.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/tests/test_console_users.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/tests/test_console_widgets.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/tests/test_content_search.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/tests/test_custom_roles.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/tests/test_database_connector_integration.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/tests/test_database_transport.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/tests/test_db_lookup.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/tests/test_db_lookup_live_runner.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/tests/test_delivery_settings.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/tests/test_dependabot_automerge_guardrails.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/tests/test_dependency_boundaries.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/tests/test_dicom_codec.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/tests/test_dicom_scp.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/tests/test_dicom_scp_security.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/tests/test_dicom_scu.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/tests/test_dicom_wiring.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/tests/test_dicomweb.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/tests/test_docs_runbooks.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/tests/test_dr_activation.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/tests/test_dr_api_status.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/tests/test_dr_failback.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/tests/test_dr_rbac.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/tests/test_dr_run_profile.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/tests/test_dr_seeding.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/tests/test_dryrun.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/tests/test_dual_control_reload.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/tests/test_ed_documents.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/tests/test_ed_documents_e2e.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/tests/test_egress_allowlist.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/tests/test_email_destination.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/tests/test_embedded_document_pruning.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/tests/test_enginepoll_aggregate.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/tests/test_environments.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/tests/test_fhir_parsing.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/tests/test_fhir_resource.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/tests/test_fhir_transport.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/tests/test_field_authz.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/tests/test_field_authz_metadata.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/tests/test_fifo_index_migration.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/tests/test_fifo_ordering.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/tests/test_frozen_launch_smoke.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/tests/test_generate_cli.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/tests/test_generated_adt.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/tests/test_generators_core.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/tests/test_generators_types.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/tests/test_group_commit.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/tests/test_groups.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/tests/test_harness.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/tests/test_harness_compose.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/tests/test_harness_config.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/tests/test_harness_faults.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/tests/test_harness_file.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/tests/test_harness_monitor.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/tests/test_harness_scenarios.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/tests/test_hl7_core_features.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/tests/test_hl7schema.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/tests/test_inbound_bind.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/tests/test_ingest_time.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/tests/test_inline_fast_path.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/tests/test_keyprovider.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/tests/test_last_admin_guard.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/tests/test_last_resort.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/tests/test_leader_tasks.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/tests/test_license_notice.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/tests/test_listener_tls_exposure.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/tests/test_load_config.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/tests/test_load_corpus.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/tests/test_load_failover_postgres.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/tests/test_load_failover_sqlserver.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/tests/test_load_failover_unit.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/tests/test_load_metrics.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/tests/test_load_profile.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/tests/test_load_report.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/tests/test_load_sender.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/tests/test_load_sink.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/tests/test_logging.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/tests/test_message.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/tests/test_message_split.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/tests/test_message_timestamps.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/tests/test_metrics_exporter.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/tests/test_mfa.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/tests/test_mllp_encoding_override.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/tests/test_mllp_tls.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/tests/test_nonhl7_ingress_size_cap.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/tests/test_operability_config.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/tests/test_outbound_signing.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/tests/test_outbound_simulate.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/tests/test_packaging.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/tests/test_parse_tree.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/tests/test_parsing.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/tests/test_passthrough.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/tests/test_passthrough_graph.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/tests/test_payload_agnostic_ingress.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/tests/test_per_connection_retention.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/tests/test_per_lane_wake.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/tests/test_pool_warm.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/tests/test_postgres_store.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/tests/test_priority_resolution.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/tests/test_reconcile_capture.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/tests/test_reconcile_compare.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/tests/test_reconcile_harness.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/tests/test_redaction.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/tests/test_reference_sets.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/tests/test_reingress.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/tests/test_release_console_installer.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/tests/test_remotefile_transport.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/tests/test_response_capture.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/tests/test_rest_transport.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/tests/test_restore_verify.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/tests/test_retention.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/tests/test_run_context.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/tests/test_scaffold.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/tests/test_scaffold_requirements.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/tests/test_scan_forbidden.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/tests/test_secrets_dpapi.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/tests/test_security_notify.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/tests/test_security_static.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/tests/test_seq_only_fifo.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/tests/test_service_control.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/tests/test_settings.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/tests/test_sharding.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/tests/test_sibling_helper_finder.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/tests/test_smart_backend.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/tests/test_soap_transport.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/tests/test_soap_wssecurity.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/tests/test_sqlserver_coordinator.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/tests/test_sqlserver_cursor_close.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/tests/test_sqlserver_schema_init.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/tests/test_sqlserver_store.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/tests/test_staged_pipeline.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/tests/test_startup_attestation.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/tests/test_startup_fault_isolation.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/tests/test_stats_reset.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/tests/test_step_up.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/tests/test_store.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/tests/test_store_backend.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/tests/test_store_encryption.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/tests/test_store_file_hardening.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/tests/test_store_once_deliver_many.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/tests/test_store_once_graph.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/tests/test_store_read_pool.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/tests/test_store_ssl.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/tests/test_summary.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/tests/test_supervisor.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/tests/test_synchronous_baseline.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/tests/test_task_resilience.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/tests/test_tcp_transport.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/tests/test_tee_cli.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/tests/test_tee_compare.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/tests/test_tee_correlate.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/tests/test_tee_hl7_fields.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/tests/test_tee_mefor_api.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/tests/test_tee_mllp.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/tests/test_tee_relay.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/tests/test_tee_report.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/tests/test_tee_store.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/tests/test_timer_source.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/tests/test_timezone.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/tests/test_tls_policy.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/tests/test_totp.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/tests/test_totp_window.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/tests/test_transform_offloop.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/tests/test_transform_state.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/tests/test_transports.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/tests/test_update_check.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/tests/test_verify.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/tests/test_version.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/tests/test_win2025_acceptance.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/tests/test_wiring.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/tests/test_wiring_engine.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/tests/test_wiring_reload.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/tests/test_wiring_serve.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/tests/test_ws_stats_revalidation.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/tests/test_x12_parsing.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/tests/test_x12_rte.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/tests/test_x12_source_ip_allowlist.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/tests/test_x12_transport.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/tests/test_x12_validate.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/tests/test_xml_message.py +0 -0
- {messagefoundry-0.2.13 → messagefoundry-0.2.14}/uv.lock +0 -0
|
@@ -6,6 +6,46 @@ All notable changes to MessageFoundry are documented here. The format follows
|
|
|
6
6
|
|
|
7
7
|
## [Unreleased]
|
|
8
8
|
|
|
9
|
+
## [0.2.14] — 2026-07-01 — Early Access
|
|
10
|
+
|
|
11
|
+
**Delta security-audit remediation.** A focused security audit of the surface added since the
|
|
12
|
+
2026-06-10 full review (v0.2.0 → v0.2.13) surfaced seven verified findings; this release fixes all of
|
|
13
|
+
them. No new critical, no SQL injection, no auth bypass, no RCE — the most serious was an
|
|
14
|
+
unauthenticated memory-exhaustion DoS in the new default HL7 parser. Each fix ships with a regression
|
|
15
|
+
test. See [`docs/reviews/DELTA-REVIEW-2026-07-01.md`](docs/reviews/DELTA-REVIEW-2026-07-01.md).
|
|
16
|
+
|
|
17
|
+
### Security
|
|
18
|
+
- **Bounded the built-in HL7 rich-text repetition escape** (DELTA-01/02;
|
|
19
|
+
[`_builtin_hl7.py`](messagefoundry/parsing/_builtin_hl7.py)). The tolerant built-in parser (now the
|
|
20
|
+
default hot-path backend, ADR 0054) expanded `\.inN\`-style repetition escapes with no cap, so a
|
|
21
|
+
~15-byte inbound field (`\.in2000000000\`) allocated gigabytes synchronously on the event loop
|
|
22
|
+
**before the ACK** — an unauthenticated OOM/denial-of-service. The count is now clamped
|
|
23
|
+
(`MAX_ESCAPE_REPEAT = 512`), and a malformed count no longer raises out of a field read — that had
|
|
24
|
+
severed the connection and dropped a parseable message with **no disposition**, breaking the
|
|
25
|
+
count-and-log invariant.
|
|
26
|
+
- **XML-DSig `verify()` now requires an explicit trust anchor** (DELTA-03;
|
|
27
|
+
[`parsing/xml/signature.py`](messagefoundry/parsing/xml/signature.py)). Called with neither `x509_cert`
|
|
28
|
+
nor `ca_pem_file`, it previously fell back to signxml's default of trusting **any** certificate that
|
|
29
|
+
chains to the host's system CA store (origin-blind verification); it now raises `ValueError`.
|
|
30
|
+
**Behavior change** for the opt-in `[xml]` codec — a caller must pin the expected signer or a partner
|
|
31
|
+
CA. No in-repo caller relied on the old default.
|
|
32
|
+
- **FhirLookup SMART token endpoint is now egress-gated** (DELTA-04;
|
|
33
|
+
[`[egress].allowed_http`](docs/CONFIGURATION.md)). A `fhir_lookup` connection composed with
|
|
34
|
+
`with_smart_backend()` POSTs a signed `client_assertion` to its `smart_token_url`; that host was not
|
|
35
|
+
checked against the egress allowlist (only the FHIR base host was), so a crafted `smart_token_url`
|
|
36
|
+
could exfiltrate the assertion to an un-allowlisted host. The lookup and outbound arms now share one
|
|
37
|
+
gate ([ADR 0043](docs/adr/0043-fhir-read-lookup.md) §D3).
|
|
38
|
+
- **Support bundle no longer discloses the store host/database; its log redaction was widened**
|
|
39
|
+
(DELTA-05/07; [`support/`](messagefoundry/support/)). The offline support bundle's `status.json`
|
|
40
|
+
carried the SQL Server `host/database` verbatim — it is now reduced to the backend kind (file basename
|
|
41
|
+
only for SQLite). The bundled-log redactor previously used a fixed HL7-segment allowlist with no
|
|
42
|
+
free-text name/DOB heuristics; it now delegates to the engine redactor
|
|
43
|
+
([`messagefoundry.redaction`](messagefoundry/redaction.py)) for parity with stored-error redaction.
|
|
44
|
+
- **Inbound HTTP listener rejects ambiguous framing** (DELTA-06;
|
|
45
|
+
[`transports/http_listener.py`](messagefoundry/transports/http_listener.py)). A duplicate
|
|
46
|
+
`Content-Length`, a duplicate `Transfer-Encoding`, or the two present together are now refused with
|
|
47
|
+
`400` per RFC 7230 §3.3.3 — closing an HTTP request-smuggling / desync surface behind a fronting proxy.
|
|
48
|
+
|
|
9
49
|
## [0.2.13] — 2026-07-01 — Early Access
|
|
10
50
|
|
|
11
51
|
The **store connection-scale sizing** wave — right-size the server-DB connection pool to the measured
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: messagefoundry
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.14
|
|
4
4
|
Summary: Open-source healthcare integration engine — route, transform, and validate messages across many formats and connection types
|
|
5
5
|
Project-URL: Homepage, https://messagefoundry.org/
|
|
6
6
|
Project-URL: Documentation, https://messagefoundry.org/
|
|
@@ -0,0 +1,197 @@
|
|
|
1
|
+
# MessageFoundry — Delta Security-Fixes Multisession Plan (2026-07-01)
|
|
2
|
+
|
|
3
|
+
**Scope.** Remediate the **seven verified findings** from the delta security audit
|
|
4
|
+
([`docs/reviews/DELTA-REVIEW-2026-07-01.md`](../reviews/DELTA-REVIEW-2026-07-01.md)) — the code surface
|
|
5
|
+
that landed since the 2026-06-10 full review (v0.2.0 → v0.2.13). No new features, **no ADRs** (these are
|
|
6
|
+
bug fixes, not decision records). The six candidates the audit *refuted* are out of scope.
|
|
7
|
+
|
|
8
|
+
**This is a plan, not a build.** Per the project convention, nothing is built until the owner gives an
|
|
9
|
+
explicit "go".
|
|
10
|
+
|
|
11
|
+
**Why it parallelizes cleanly.** The seven findings touch **five disjoint source-file sets** — there is no
|
|
12
|
+
source-file overlap between lanes. The only shared files are `CHANGELOG.md` and the review doc's status
|
|
13
|
+
column (handled in §D). So all five lanes can run **fully in parallel** with near-zero contention; Lane A
|
|
14
|
+
just takes **merge priority** because it is the only High.
|
|
15
|
+
|
|
16
|
+
**Autonomy: L1** — workers build + verify (full quartet) + commit **local**; the **owner** opens/merges PRs.
|
|
17
|
+
Single-writer coordination ledger in AI memory. Worktree-per-lane off `origin/main` @ `0febba9`.
|
|
18
|
+
|
|
19
|
+
---
|
|
20
|
+
|
|
21
|
+
## A. Findings → lanes
|
|
22
|
+
|
|
23
|
+
| Lane | Finding(s) | Severity | Fix in one line | Primary file(s) |
|
|
24
|
+
|---|---|---|---|---|
|
|
25
|
+
| **L-A hl7-parser-hardening** | DELTA-01, DELTA-02 | **High** + Medium | Clamp + guard the repetition-escape count in built-in unescape | `parsing/_builtin_hl7.py`, `parsing/peek.py` |
|
|
26
|
+
| **L-B xml-dsig-anchor** | DELTA-03 | Medium | Require an explicit trust anchor in `verify()` (no OS-CA default-trust) | `parsing/xml/signature.py` |
|
|
27
|
+
| **L-C fhir-lookup-egress** | DELTA-04 | Medium | Gate `smart_token_url` against `[egress].allowed_http` on the lookup arm | `pipeline/wiring_runner.py` |
|
|
28
|
+
| **L-D support-bundle-disclosure** | DELTA-05, DELTA-07 | Low + Low | Strip store host/db-name from the bundle; align its redactor with the engine's | `support/bundle.py`, `support/redact.py` |
|
|
29
|
+
| **L-E http-listener-framing** | DELTA-06 | Low | Reject ambiguous CL/TE framing in the request parser | `transports/http_listener.py` |
|
|
30
|
+
|
|
31
|
+
Each lane = **one coherent PR**. L-A and L-D each fix two findings that share a file/theme, so they stay
|
|
32
|
+
one PR apiece; the rest are one finding = one PR.
|
|
33
|
+
|
|
34
|
+
---
|
|
35
|
+
|
|
36
|
+
## B. Lane detail (worktree per lane off `origin/main` @ `0febba9`)
|
|
37
|
+
|
|
38
|
+
> `scripts/worktree/new.ps1 -Name <lane>` (isolated checkout + branch + `.venv`); cleanup `remove.ps1`.
|
|
39
|
+
> See [`docs/WORKTREES.md`](../WORKTREES.md). Every lane: **new behavior gets a test**, then the full quartet
|
|
40
|
+
> green before the owner PRs it.
|
|
41
|
+
|
|
42
|
+
### L-A — HL7 parser hardening (DELTA-01 High, DELTA-02 Medium) — **P0, merge first**
|
|
43
|
+
- **Root cause (one line, one block):** `parsing/_builtin_hl7.py:527-528` —
|
|
44
|
+
`out.append(default_map[value[:3]] * int(value[3:]))` — the repetition count is **unbounded** (DELTA-01
|
|
45
|
+
DoS) **and** `int(value[3:])` is **unguarded** (DELTA-02 `ValueError`). Contrast the hex branch just below
|
|
46
|
+
(lines 534-539), which already wraps its `int(...)` in `try/except ValueError: continue`.
|
|
47
|
+
- **Fix:**
|
|
48
|
+
1. Introduce a small module constant (e.g. `MAX_ESCAPE_REPEAT`, a few hundred) and, in the `.`-prefix
|
|
49
|
+
repetition branch, wrap the conversion + multiply in `try/except ValueError` and reject counts above the
|
|
50
|
+
cap. Treat an over-limit or non-numeric count as an **unmappable** sequence → `continue` (drop it),
|
|
51
|
+
matching the existing "log-and-discard" behavior for other unmappable escapes.
|
|
52
|
+
2. Defense-in-depth: broaden `parsing/peek.py` `_resolve_builtin` (~lines 189-192) to map `ValueError` to
|
|
53
|
+
`None` like it already does `IndexError`, so a stray conversion error can never escape a `Peek.field`
|
|
54
|
+
read.
|
|
55
|
+
- **Tests:** unit — `\.in2000000000\` expands to a **bounded / dropped** result (no multi-GB allocation);
|
|
56
|
+
`\.inX\`, `\.in \`, `\.br9z\` do **not** raise and the field reads cleanly. Pipeline/integration — a
|
|
57
|
+
message whose `PID-3.1` carries a malformed count is still **persisted with a disposition** (`RECEIVED`),
|
|
58
|
+
proving the **count-and-log invariant** holds (DELTA-02's real bite). Use synthetic HL7 only.
|
|
59
|
+
- **Verify:** this is the **default hot-path parser** — run the **full** suite (not a subset), and confirm
|
|
60
|
+
the parse-fallback guard + count-and-log paths behave. No new deps.
|
|
61
|
+
|
|
62
|
+
### L-B — XML-DSig anchor enforcement (DELTA-03 Medium)
|
|
63
|
+
- **Fix:** in `parsing/xml/signature.py` `verify()` (~lines 44-60), **raise** `XmlError`/`ValueError` when
|
|
64
|
+
**both** `x509_cert` and `ca_pem_file` are `None`, instead of forwarding to signxml's "trust any
|
|
65
|
+
system-CA cert" default. Update the docstring to state an anchor is **mandatory**. Mirror the explicit-key
|
|
66
|
+
posture already in `transports/signing.py`.
|
|
67
|
+
- **Tests:** a document signed by an arbitrary system-trusted cert **fails** `verify()` when no anchor is
|
|
68
|
+
passed (now raises); a document verified **with** a pinned `x509_cert` / partner `ca_pem_file` still passes.
|
|
69
|
+
- **Callout (owner sign-off):** this is an intentional **secure-by-default behavior change** — `verify()`
|
|
70
|
+
now requires an anchor. The audit's caller grep found **no in-repo consumer** relying on the old default
|
|
71
|
+
(only package `__init__` re-exports import it), so blast radius is a hypothetical external Handler. Flag it
|
|
72
|
+
in the PR / CHANGELOG as a breaking change for that opt-in codec.
|
|
73
|
+
|
|
74
|
+
### L-C — FhirLookup egress gate (DELTA-04 Medium)
|
|
75
|
+
- **Fix:** in `pipeline/wiring_runner.py` `check_fhir_lookup_allowed` (~lines 2831-2842), after validating the
|
|
76
|
+
FHIR base `url`, read `settings.get("smart_token_url")`; if set, require
|
|
77
|
+
`_http_egress_allowed(token_url, egress.allowed_http)` and honor `deny_by_default` — the exact check the
|
|
78
|
+
**outbound** arm already performs (~lines 3086-3097). **Factor a shared helper** so the read-side lookup and
|
|
79
|
+
write-side outbound gates stay in lockstep (they diverged, which is how this gap opened). This realizes
|
|
80
|
+
ADR 0043 §D3 ("`smart_token_url` must be checked against `[egress].allowed_http`").
|
|
81
|
+
- **Tests:** a FhirLookup with an **un-allow-listed** `smart_token_url` is **rejected** at load (mirror the
|
|
82
|
+
existing outbound test); an allow-listed one loads.
|
|
83
|
+
- **Note:** sole toucher of the large `wiring_runner.py` among these lanes; if a sibling wave lands there,
|
|
84
|
+
rebase and re-run the start / reload / dry-run guard tests.
|
|
85
|
+
|
|
86
|
+
### L-D — Support-bundle disclosure (DELTA-05 Low, DELTA-07 Low)
|
|
87
|
+
- **Fix DELTA-05:** in `support/bundle.py` (~line 137), **omit/redact** the SQL Server store **host** and
|
|
88
|
+
**database name** from `status.json` — the bundle's stated no-host/no-path contract. Keep the useful
|
|
89
|
+
non-identifying status (backend kind, health) but drop the DSN-derived host/db.
|
|
90
|
+
- **Fix DELTA-07:** in `support/redact.py` (~line 27), replace the fixed segment allowlist with alignment to
|
|
91
|
+
the **engine redactor** (`messagefoundry/redaction.py`) — ideally **reuse** it rather than maintain a
|
|
92
|
+
weaker second redactor — so free-text name/DOB heuristics are applied to bundled logs.
|
|
93
|
+
- **Tests:** bundle `status.json` contains **no** store host/db-name; the bundle log redactor scrubs the
|
|
94
|
+
free-text PHI patterns the engine redactor catches (parametrize against a synthetic sample).
|
|
95
|
+
- **Note:** two `support/` files, one theme (off-box bundle info-disclosure) → one PR. PHI rule: build the
|
|
96
|
+
fixtures from **synthetic** data only.
|
|
97
|
+
|
|
98
|
+
### L-E — HTTP listener framing (DELTA-06 Low)
|
|
99
|
+
- **Fix:** in `transports/http_listener.py` (~line 180) reject **ambiguous framing** per RFC 7230 — a request
|
|
100
|
+
bearing both `Content-Length` and `Transfer-Encoding`, or **multiple/duplicate** `Content-Length` values →
|
|
101
|
+
respond `400` and close, rather than parsing one interpretation. (Self-desync is currently blunted by
|
|
102
|
+
`Connection: close`, so this is hardening the surface, not closing a live smuggle.)
|
|
103
|
+
- **Tests:** a request with duplicate `Content-Length` or `CL`+`TE` is **rejected** (400), not parsed; a
|
|
104
|
+
well-formed request is unaffected.
|
|
105
|
+
|
|
106
|
+
---
|
|
107
|
+
|
|
108
|
+
## C. Land-order
|
|
109
|
+
|
|
110
|
+
1. **L-A first** — the only High, and it is on the unauthenticated pre-ACK hot path. Merge before a release.
|
|
111
|
+
2. **L-B / L-C / L-D / L-E** — parallel, any order; all lower severity and fully independent. No lane blocks
|
|
112
|
+
another (disjoint files).
|
|
113
|
+
3. Each lane: **full quartet** green — `ruff format --check` + `ruff check` + `mypy` (strict) +
|
|
114
|
+
`pytest` (with `QT_QPA_PLATFORM=offscreen`) — **before** the owner opens the PR. Run the **whole** pytest
|
|
115
|
+
suite, never a subset (the leak-gate / forbidden-content jobs only fire on a full run).
|
|
116
|
+
|
|
117
|
+
**Suggested session mapping** (they collapse to fit however many sessions you want to run):
|
|
118
|
+
- *Max parallelism:* five worktrees, one per lane.
|
|
119
|
+
- *Recommended (2–3 sessions):* one session owns **L-A** (priority, verify-heavy); a second session sweeps
|
|
120
|
+
**L-B → L-C** (both small logic + test); a third (or the second, sequentially) sweeps **L-D → L-E**.
|
|
121
|
+
- *Minimum:* a single session does all five sequentially in one worktree, one PR at a time (still five PRs).
|
|
122
|
+
|
|
123
|
+
---
|
|
124
|
+
|
|
125
|
+
## D. Contention matrix
|
|
126
|
+
|
|
127
|
+
| File(s) | Lanes | Resolution |
|
|
128
|
+
|---|---|---|
|
|
129
|
+
| **Source files** (`_builtin_hl7.py`+`peek.py`; `xml/signature.py`; `wiring_runner.py`; `support/*`; `http_listener.py`) | disjoint per lane | **No overlap.** No cross-lane rebasing of product code. |
|
|
130
|
+
| **`CHANGELOG.md`** | all five | Each PR adds its own line (additive). Last-writer rebases, or the **owner consolidates** the five lines at merge. |
|
|
131
|
+
| **`docs/reviews/DELTA-REVIEW-2026-07-01.md`** (status column) | all five | **Do not** have each lane edit the review doc (write contention). The **coordinator/owner** flips each finding's status to *fixed (PR #…)* **once**, after merge. |
|
|
132
|
+
| **Test files** | per lane | Each lane adds tests in its subsystem's existing test module or a new one — disjoint. |
|
|
133
|
+
|
|
134
|
+
---
|
|
135
|
+
|
|
136
|
+
## E. Coordination rules
|
|
137
|
+
|
|
138
|
+
1. **Worktree per lane**, branched off `origin/main` @ `0febba9`. **Never edit a sibling worktree.** Use the
|
|
139
|
+
lane's own `.venv` (`.\.venv\Scripts\Activate.ps1`) — the six other active worktrees share this repo's
|
|
140
|
+
history but **not** the checkout.
|
|
141
|
+
2. **Single-writer coord ledger** in AI memory (one session writes live status; others read). One logical
|
|
142
|
+
lane per session. **This session does not own memory writes unless the owner confirms it** (parallel
|
|
143
|
+
sessions; last write wins).
|
|
144
|
+
3. **Autonomy L1:** build + verify + commit **local**; the **owner** opens/merges PRs. Do **not** push, open a
|
|
145
|
+
PR, or merge without an explicit owner "go".
|
|
146
|
+
4. **`git add` explicit paths** — the repo pre-tool hook blocks `git add -A` / `git add .`. Stage the exact
|
|
147
|
+
files.
|
|
148
|
+
5. **Commit trailer:** **omit** the `Co-Authored-By: Claude` trailer — the CLA bot fails on it (project
|
|
149
|
+
convention; supersedes the older note in `MULTISESSION-PLAN-6.md`). One coherent layer per commit.
|
|
150
|
+
6. **Auto-merge + CI gate:** branches off `0febba9` post-date the CI-gate roll-up, so no `git merge main`
|
|
151
|
+
catch-up is needed; still, rebase if `origin/main` advances before your PR merges.
|
|
152
|
+
|
|
153
|
+
---
|
|
154
|
+
|
|
155
|
+
## F. Build gotchas (checklist — apply per lane)
|
|
156
|
+
|
|
157
|
+
1. **SPDX header** on every **new** `.py` (e.g. a new test module) — the header sweep only covered
|
|
158
|
+
pre-existing files. Editing an existing file needs none.
|
|
159
|
+
2. **No new runtime deps expected** — all five are logic/validation changes. If a lane somehow needs one,
|
|
160
|
+
follow **DEP-1**: add to `pyproject.toml`, then re-lock from the **repo root** (`uv lock` / `uv export`),
|
|
161
|
+
never `uv export --directory`. Verify the package is real before adding (§7 of `CLAUDE.md`).
|
|
162
|
+
3. **Crypto-inventory gate does NOT trip here:** L-B (`signature.py`/signxml) and L-C (SMART JWT signing)
|
|
163
|
+
touch **existing** modules already in `scripts/security/crypto_inventory_check.py`. The gate only fires on
|
|
164
|
+
a **new** `.py` importing `hashlib`/`hmac`/`secrets`/`ssl`/`cryptography`/`argon2` — none is introduced.
|
|
165
|
+
4. **L-A is the default hot-path parser:** run the **full** suite and add a **pipeline-level** test that a
|
|
166
|
+
malformed-count message still records a disposition — the DELTA-02 fix must preserve **count-and-log** and
|
|
167
|
+
**at-least-once**, not just stop the crash.
|
|
168
|
+
5. **PHI rule:** all fixtures are **synthetic** HL7/XML. Never real PHI; never customer host/IP/port/site
|
|
169
|
+
names in code, tests, or the CHANGELOG. L-D specifically asserts the *absence* of host/db-name — build its
|
|
170
|
+
fixtures with fake DSNs.
|
|
171
|
+
6. **L-B behavior change** (`verify()` now raises without an anchor) — call it out in the PR and CHANGELOG as
|
|
172
|
+
an intentional secure-by-default break for the opt-in XML codec.
|
|
173
|
+
|
|
174
|
+
---
|
|
175
|
+
|
|
176
|
+
## G. Owner-gated / decision callouts
|
|
177
|
+
|
|
178
|
+
- **Merge order & PRs (all lanes):** L1 autonomy — the owner opens and merges every PR. Recommended: merge
|
|
179
|
+
**L-A before the next release**; the rest can trail.
|
|
180
|
+
- **L-B secure-by-default break:** owner sign-off that requiring an explicit anchor is acceptable (it is the
|
|
181
|
+
correct posture; the audit found no in-repo caller depending on the old default).
|
|
182
|
+
- **L-D redactor unification:** owner call on whether L-D should **reuse** the engine redactor outright
|
|
183
|
+
(preferred) vs. only strengthen the bundle's local one — the former is cleaner but touches the shared
|
|
184
|
+
redaction seam.
|
|
185
|
+
|
|
186
|
+
---
|
|
187
|
+
|
|
188
|
+
## H. Definition of done (per lane)
|
|
189
|
+
|
|
190
|
+
- The finding's fix is in place with a **regression test** that fails before / passes after.
|
|
191
|
+
- Full quartet green on the lane's own `.venv`: `ruff format --check` · `ruff check` · `mypy` (strict) ·
|
|
192
|
+
`pytest` (offscreen, **full** suite).
|
|
193
|
+
- One coherent local commit (no co-author trailer), explicit-path staged, ready for the owner to PR.
|
|
194
|
+
- CHANGELOG line drafted; the review-doc status flip is left to the coordinator/owner (§D).
|
|
195
|
+
|
|
196
|
+
**Aggregate done:** all five PRs merged; `docs/reviews/DELTA-REVIEW-2026-07-01.md` status column updated to
|
|
197
|
+
*fixed (PR #…)* for DELTA-01 … DELTA-07 by the coordinator.
|
|
@@ -0,0 +1,262 @@
|
|
|
1
|
+
# MessageFoundry — DELTA Security-Audit Report
|
|
2
|
+
|
|
3
|
+
*Date: 2026-07-01*
|
|
4
|
+
|
|
5
|
+
*Scope: the **delta** since the last full review (2026-06-10) — code ADDED or MODIFIED between roughly v0.2.0 and v0.2.13. Earlier code was already reviewed in [`docs/reviews/FULL-REVIEW-2026-06-10.md`](../reviews/FULL-REVIEW-2026-06-10.md) and is out of scope except where a pre-existing issue sits in a changed file and is materially exploitable. This is an authorized defensive audit: read-only, no runtime execution, synthetic data only, no customer-identifying data.*
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## 1. Scope & Methodology
|
|
10
|
+
|
|
11
|
+
This report covers only the code surface that changed in the review window. Delta scoping was established with `git log --since=2026-06-10` and `git show/diff` per file. The major feature landings audited (all in-window) are:
|
|
12
|
+
|
|
13
|
+
- **Built-in tolerant HL7 parser** (ADR 0054, #655 / commit `2868571`) — now the **default** `Peek`/`Message` backend (`_backend.USE_BUILTIN=True`), running on the pre-ACK hot path.
|
|
14
|
+
- **Inbound HTTP listener + custom RBAC + content search** (Plan-5 Wave 2, #624 / `de53154`).
|
|
15
|
+
- **X12 strict (pyx12) + `[xml]` structured-codec layer** including XML-DSig (#619 / `417974e`).
|
|
16
|
+
- **`fhir_lookup`, SMTP email, ops support-bundle / update-check** (Plan-5 Wave 1, #618 / `c729573`).
|
|
17
|
+
|
|
18
|
+
**Methodology.** Nine parallel per-surface *finder* agents (HL7 core + binary carriage; structured-format codecs XML/X12/FHIR; egress/SSRF/outbound lookups; network listeners & transports; crypto/secrets/PHI redaction/de-identification; auth/RBAC/API; store/SQL; pipeline/config; supply-chain/infra) each enumerated candidate defects. Every candidate was then handed to an **independent adversarial verifier** operating default-to-refute: it re-traced reachability from attacker-influenceable input (inbound HL7/X12/DICOM/FHIR/XML/binary over MLLP/TCP/HTTP/DICOM listeners; file contents; connection config; outbound-lookup responses) to the sink, checked every intervening guard, and either CONFIRMED, marked PLAUSIBLE, or REFUTED with corrected severity. Only findings that survived verification appear below; notable refuted/deprioritized candidates are summarized in §5 for transparency. This synthesis merges duplicates and ranks by corrected severity then reachability.
|
|
19
|
+
|
|
20
|
+
**Severity taxonomy** matches the house report: Critical / High / Medium / Low, assigned by realistic impact × reachability. Two of the seven findings carry a `PLAUSIBLE` verdict (real code defect, conditional reachability); the rest are `CONFIRMED`.
|
|
21
|
+
|
|
22
|
+
---
|
|
23
|
+
|
|
24
|
+
## 2. Executive Summary
|
|
25
|
+
|
|
26
|
+
The delta introduces no new critical finding, no auth bypass, no SQL injection, and no remote-content RCE. The core ACK-after-commit and count-and-log invariants remain intact on the happy path. The **one materially serious new issue** is a resource-exhaustion DoS in the new default HL7 parser: because the built-in tolerant backend replicates python-hl7's unbounded repetition-escape expansion (`ch * count` with no cap) and is now invoked on the pre-ACK hot path via `summarize()`, a tiny attacker-controlled field value expands to multiple gigabytes synchronously on the asyncio event loop, freezing or OOM-killing the engine without authentication. A sibling malformed-count `ValueError` in the same branch is a lower-severity but real count-and-log break (a parseable message is dropped with no disposition).
|
|
27
|
+
|
|
28
|
+
The remaining findings are on lower-reachability surfaces — an opt-in XML signature-verification footgun, a config-plane egress allowlist gap, an HTTP framing-ambiguity smuggling surface that requires a fronting proxy, and two operator-facing support-bundle disclosure/redaction gaps. None is reachable from raw inbound message data except the two HL7-core findings.
|
|
29
|
+
|
|
30
|
+
### Severity counts
|
|
31
|
+
|
|
32
|
+
| Severity | Count |
|
|
33
|
+
|---|---|
|
|
34
|
+
| Critical | 0 |
|
|
35
|
+
| High | 2 |
|
|
36
|
+
| Medium | 3 |
|
|
37
|
+
| Low | 2 |
|
|
38
|
+
| **Total** | **7** |
|
|
39
|
+
|
|
40
|
+
### Health by surface (delta)
|
|
41
|
+
|
|
42
|
+
| Surface | Health | Note |
|
|
43
|
+
|---|---|---|
|
|
44
|
+
| HL7 core parser + binary carriage | **needs attention** | New default built-in parser ports python-hl7's unbounded repetition expansion (DoS) and a malformed-count crash onto the pre-ACK hot path. |
|
|
45
|
+
| Structured-format codecs (XML/X12/FHIR) | adequate | XML-DSig `verify()` is a secure-by-default footgun but opt-in; no wired sink. |
|
|
46
|
+
| Egress / SSRF / outbound lookups | adequate | FhirLookup token-endpoint gate is fail-open on one arm; config-plane only. |
|
|
47
|
+
| Network listeners & transports | adequate | New HTTP listener parser accepts ambiguous CL/TE framing; self-desync blocked by `Connection: close`. |
|
|
48
|
+
| Crypto / secrets / PHI redaction | adequate | Support bundle leaks DB host/db-name and under-redacts free-text PHI vs. the engine redactor. |
|
|
49
|
+
| Auth / RBAC / API | adequate | No new confirmed defect in-delta (see §5 refuted). |
|
|
50
|
+
| Store / SQL | adequate | No new confirmed defect in-delta (see §5 refuted TOCTOU). |
|
|
51
|
+
|
|
52
|
+
---
|
|
53
|
+
|
|
54
|
+
## 3. Findings Summary Table
|
|
55
|
+
|
|
56
|
+
| ID | Severity | Surface | Title | Location | Verdict |
|
|
57
|
+
|---|---|---|---|---|---|
|
|
58
|
+
| DELTA-01 | High | HL7 core | Unbounded HL7 escape-repetition expansion → pre-ACK memory-exhaustion DoS | `messagefoundry/parsing/_builtin_hl7.py:528` | CONFIRMED |
|
|
59
|
+
| DELTA-02 | Medium | HL7 core | Malformed rich-text escape count raises uncaught `ValueError`, silently dropping a parseable message (count-and-log break) | `messagefoundry/parsing/_builtin_hl7.py:528` | CONFIRMED |
|
|
60
|
+
| DELTA-03 | Medium | Structured codecs | XML-DSig `verify()` trusts any system-CA cert when no anchor is supplied | `messagefoundry/parsing/xml/signature.py:60` | PLAUSIBLE |
|
|
61
|
+
| DELTA-04 | Medium | Egress/SSRF | FhirLookup SMART token endpoint bypasses `[egress].allowed_http` allowlist | `messagefoundry/pipeline/wiring_runner.py:2831` | CONFIRMED |
|
|
62
|
+
| DELTA-05 | Low | Crypto/PHI | Support bundle `status.json` discloses SQL Server store host + database name | `messagefoundry/support/bundle.py:137` | CONFIRMED |
|
|
63
|
+
| DELTA-06 | Low | Listeners | HTTP listener accepts ambiguous CL/TE framing (request-smuggling surface behind a proxy) | `messagefoundry/transports/http_listener.py:180` | PLAUSIBLE |
|
|
64
|
+
| DELTA-07 | Low | Crypto/PHI | Support-bundle log redactor under-redacts vs. the engine redactor (fixed segment allowlist, no name/DOB heuristics) | `messagefoundry/support/redact.py:27` | PLAUSIBLE |
|
|
65
|
+
|
|
66
|
+
*Note: DELTA-01 and DELTA-02 share the same file:line (`_builtin_hl7.py:528`, the repetition-escape branch) and root cause (the count/`int()` conversion). They are reported separately because they have distinct failure modes (memory-exhaustion DoS vs. uncaught-exception message loss) and severities, but both are fixed by the same one-block change; see the shared recommendation.*
|
|
67
|
+
|
|
68
|
+
---
|
|
69
|
+
|
|
70
|
+
## 4. Detailed Findings
|
|
71
|
+
|
|
72
|
+
### DELTA-01 — Unbounded HL7 escape-repetition expansion in built-in unescape enables a pre-ACK memory-exhaustion DoS on the hot path
|
|
73
|
+
|
|
74
|
+
- **Severity:** High (CONFIRMED, reachable from unauthenticated network input)
|
|
75
|
+
- **CWE:** CWE-1284 / CWE-770 (improper validation of specified quantity / uncontrolled resource allocation)
|
|
76
|
+
- **Location:** `messagefoundry/parsing/_builtin_hl7.py:528`
|
|
77
|
+
|
|
78
|
+
**Description.** The new built-in HL7 unescape (ADR 0054, #655 — now the **default** tolerant backend, `_backend.USE_BUILTIN=True`) expands HL7 rich-text repetition escapes (`\.in<N>\`, `\.ti<N>\`, `\.sk<N>\`, `\.br<N>\`, …) with `default_map[value[:3]] * int(value[3:])` and applies **no cap** on the repetition count. A ~15-byte attacker-controlled field value such as `\.in2000000000\` allocates `' ' * 2000000000` (~8 GB); a larger count pushes toward guaranteed OOM. This runs during a component/subcomponent leaf read (`extract_field` → `unescape`), which is **not** wrapped by the parse fallback guard (that guard wraps only `_builtin_hl7.parse` in `Peek.parse`). The engine's 16 MiB ingress size cap (`peek.enforce_size_limits`) measures the *raw* message length and cannot bound post-unescape expansion, so the tiny sequence sails through.
|
|
79
|
+
|
|
80
|
+
**Attack scenario.** An attacker who can deliver an inbound HL7 message (MLLP/file/HTTP listener — partner-facing and unauthenticated) sends a well-formed message whose `PID-3.1` (or `PID-5.1` / `MSH-9.1`) contains `\.in2000000000\`. In `wiring_runner._handle_inbound`, after a successful `Peek.parse` and **before** the ACK, the ingress path evaluates `summary = summarize(peek)` (`summary.py:31/38/39` calls `peek.field("PID-3.1")` etc.), each a `comp=1` leaf read that invokes built-in `extract_field` → `unescape`. The multi-GB string is allocated synchronously on the event-loop thread, stalling every listener/worker/API call and driving the process toward OOM. Repeated messages amplify to a reliable engine-wide denial of service; a single large-count value can OOM-kill it outright.
|
|
81
|
+
|
|
82
|
+
**Evidence.**
|
|
83
|
+
```
|
|
84
|
+
_builtin_hl7.py:527-528
|
|
85
|
+
elif value.startswith(".") and value[:3] in default_map:
|
|
86
|
+
out.append(default_map[value[:3]] * int(value[3:])) # no upper bound on int(value[3:])
|
|
87
|
+
```
|
|
88
|
+
Reachable pre-ACK via `summary.py:31` `mrn = peek.field("PID-3.1")` and `wiring_runner.py:1729` `summary=summarize(peek)`. The fallback guard in `peek.py:141-151` wraps only `_builtin_hl7.parse`, not the field reads; `_resolve_builtin` (`peek.py:189-192`) catches only `IndexError`, so a resulting `MemoryError` propagates and crashes the task. The `summarize` call is a plain synchronous call (no `to_thread`/`run_in_executor`).
|
|
89
|
+
|
|
90
|
+
**Verdict & confidence.** CONFIRMED; high confidence. The verifier independently traced the full path (unauthenticated listener → `_handle_inbound` on the event loop → default built-in backend → `enforce_size_limits` passes a ~15-byte input → pre-ACK `summarize` → leaf `unescape` → synchronous multi-GB allocation) and checked every guard. Impact is DoS only (no PHI disclosure/RCE), which is why this is high, not critical. Note the built-in faithfully replicates python-hl7's own unbounded `ch * count` (`hl7/util.py`), so the legacy fallback shares the flaw — but the delta made the built-in the default, always-on hot-path parser.
|
|
91
|
+
|
|
92
|
+
**Recommendation.** Clamp the repetition count to a small sane maximum (e.g. reject/cap counts above a few hundred) **before** the `ch * count` multiplication, and/or bound total unescaped output length. The cap must live in built-in `unescape` itself (the upstream 16 MiB raw cap cannot mitigate a ~15-byte→gigabytes expansion). Treat an over-limit count as an unmappable sequence and drop it, matching the existing "log and discard" behavior for other unmappable escapes. This single fix also resolves DELTA-02.
|
|
93
|
+
|
|
94
|
+
---
|
|
95
|
+
|
|
96
|
+
### DELTA-02 — Malformed rich-text escape count raises an uncaught `ValueError` from built-in unescape, silently dropping a parseable message
|
|
97
|
+
|
|
98
|
+
- **Severity:** Medium (CONFIRMED; corrected up from the finder's Low because it breaks the count-and-log invariant)
|
|
99
|
+
- **CWE:** CWE-248 (uncaught exception) — with a downstream count-and-log invariant break
|
|
100
|
+
- **Location:** `messagefoundry/parsing/_builtin_hl7.py:528`
|
|
101
|
+
|
|
102
|
+
**Description.** In the same repetition-escape branch, `int(value[3:])` is unguarded. When `value[:3]` matches a valid 3-char rich-text prefix but the full value is not an exact key and the suffix is non-numeric — e.g. `\.inX\`, `\.in \`, `\.br9z\` — `int("X")` raises `ValueError`. Unlike the hex branch (`lines 534-539`, which wraps `int(...,16)` in `try/except ValueError: continue`), this `ValueError` is not caught inside `unescape`. It propagates out of `extract_field`; `Peek._resolve_builtin` (`peek.py:189-192`) catches only `IndexError`, so the `ValueError` escapes `Peek.field`. On the inbound path it fires inside `summarize(peek)` at `wiring_runner.py:1729`, reached **after** the `HL7PeekError`/`UnicodeDecodeError` guards and **before** `enqueue_ingress`, and is not wrapped by the parser fallback guard.
|
|
103
|
+
|
|
104
|
+
**Attack scenario.** An attacker sends structurally valid inbound HL7 over MLLP with `PID-3.1` (or `PID-5.x`/`MSH-9`) = `\.inX\`. `Peek.parse` succeeds; `summarize`'s `PID-3.1` read raises `ValueError` before the message is persisted. The exception is caught only by the MLLP per-connection last-resort handler (`mllp.py:676-687`), which logs redacted and drops the TCP connection. Because the raise happens **before** `enqueue_ingress`, the message is neither persisted (no `RECEIVED`/`ERROR` row) nor ACK'd/NAK'd — the connection is simply severed and a parseable healthcare message is lost with no disposition, directly violating the project's count-and-log invariant ("every received message is persisted before the ACK; nothing is accepted-and-dropped").
|
|
105
|
+
|
|
106
|
+
**Evidence.**
|
|
107
|
+
```
|
|
108
|
+
_builtin_hl7.py:528 ... * int(value[3:]) # no try/except (contrast hex branch 534-539)
|
|
109
|
+
peek.py:191 except IndexError: # ValueError not mapped to None
|
|
110
|
+
summary.py:31 mrn = peek.field("PID-3.1") # unconditional pre-ACK read
|
|
111
|
+
wiring_runner.py:1729 summary=summarize(peek) # evaluated before enqueue_ingress
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
**Verdict & confidence.** CONFIRMED; high confidence. Correction to the finding: the finder's `\.in\` (empty-count) example does **not** trigger the bug — `value=".in"` is caught by the earlier exact-key match. Real triggers are a valid 3-char prefix followed by a non-numeric/space suffix (`\.inX\`, `\.in \`, `\.br9z\`). Severity raised from Low to Medium because the failure is not a benign crash: it drops the connection **and** loses the message with no disposition (a "do-not-break" invariant), driven by trivially attacker-controlled inbound HL7 on the default parser. Not higher because engine/listener/other-connection stability is unaffected and the sender can reconnect.
|
|
115
|
+
|
|
116
|
+
**Recommendation.** Wrap the `int(value[3:])` conversion and the subsequent multiplication in `try/except ValueError`, dropping the sequence on failure (matching python-hl7's log-and-discard intent and the built-in's own hex-branch handling). Additionally broaden `peek._resolve_builtin` to map `ValueError` to `None` like `IndexError`. The DELTA-01 count-clamp fix should be applied in the same block.
|
|
117
|
+
|
|
118
|
+
---
|
|
119
|
+
|
|
120
|
+
### DELTA-03 — XML-DSig `verify()` trusts any system-CA cert when no anchor is supplied (signxml default-trust)
|
|
121
|
+
|
|
122
|
+
- **Severity:** Medium (PLAUSIBLE; corrected down from High — opt-in codec, not a wired sink)
|
|
123
|
+
- **CWE:** CWE-347 (improper verification of cryptographic signature)
|
|
124
|
+
- **Location:** `messagefoundry/parsing/xml/signature.py:60`
|
|
125
|
+
|
|
126
|
+
**Description.** `verify()` forwards `x509_cert` and `ca_pem_file` straight to signxml's `XMLVerifier.verify()`, and both parameters default to `None` (`lines 47-48`). When a caller invokes `verify(document)` with neither anchor, signxml applies its documented default: it trusts **any** valid XML-DSig signature whose embedded `X509Certificate` chains to the host's system CA trust store. signxml's own docs warn: "the default behavior is to trust any valid XML signature generated using a valid X.509 certificate trusted by your system's CA store. This means anyone can get an SSL certificate and generate a signature that you will trust." The docstring frames the anchors as optional ("Pass `x509_cert` … or `ca_pem_file`"), and there is no guard rejecting the both-`None` case, so a Handler author following the API silently gets origin-blind verification returning `verified=True` for an attacker-forged signature.
|
|
127
|
+
|
|
128
|
+
**Attack scenario.** An attacker forges a signed inbound XML/SOAP clinical message: they tamper with the body (alter a patient identifier or order), strip the legitimate enveloped signature, obtain any free domain-validated certificate for a domain they control, re-sign the modified document, and embed the cert in `ds:KeyInfo/X509Certificate`. A Handler that calls `verify(document)` without pinning `x509_cert` or a partner CA receives `XmlSignatureResult(verified=True)`, so the engine treats the forged message as authentic and routes/transforms it.
|
|
129
|
+
|
|
130
|
+
**Evidence.**
|
|
131
|
+
```
|
|
132
|
+
signature.py:44-48 def verify(document, *, x509_cert=None, ca_pem_file=None)
|
|
133
|
+
signature.py:60 verifier.verify(root, x509_cert=x509_cert, ca_pem_file=ca_pem_file)
|
|
134
|
+
```
|
|
135
|
+
No guard rejects the both-`None` call; signxml (pinned 5.0.1) then falls back to trusting any system-CA-trusted embedded cert.
|
|
136
|
+
|
|
137
|
+
**Verdict & confidence.** PLAUSIBLE; high confidence in the defect, low in active reachability. The code defect and signxml behavior are real and accurately described — a genuine secure-by-default failure, invited by the docstring. However, an exhaustive caller grep shows the only importers of `parsing.xml.verify` are package `__init__` re-exports; nothing in `pipeline/`, `transports/`, or any automatic message path invokes it. Per ADR 0004 the XML codec is payload-agnostic and called on demand by a code-first Handler, never pushed through the pipeline. So attacker-influenceable input reaches this sink only if an adopter writes a custom Handler that calls `verify(document)` without pinning an anchor **and** treats `verified=True` as an authenticity gate. That misuse is plausible (and invited) but is not present in-repo and not automatically reachable — hence PLAUSIBLE and a downgrade from High to Medium.
|
|
138
|
+
|
|
139
|
+
**Recommendation.** Require an explicit trust anchor: raise (`XmlError`/`ValueError`) when both `x509_cert` and `ca_pem_file` are `None`, so a caller must pin the expected signer or a partner CA. Do not rely on signxml's implicit "trust anything the OS trusts" default. Update the docstring to state an anchor is mandatory, and add a test asserting a document signed by an arbitrary system-trusted cert does **not** verify without an explicit anchor. This mirrors the explicit-key enforcement already present in `transports/signing.py`.
|
|
140
|
+
|
|
141
|
+
---
|
|
142
|
+
|
|
143
|
+
### DELTA-04 — FhirLookup SMART token endpoint bypasses the `[egress].allowed_http` allowlist (client_assertion exfil / SSRF)
|
|
144
|
+
|
|
145
|
+
- **Severity:** Medium (CONFIRMED; config-plane reachability, not network input)
|
|
146
|
+
- **CWE:** CWE-918 (server-side request forgery) / egress-control fail-open
|
|
147
|
+
- **Location:** `messagefoundry/pipeline/wiring_runner.py:2831`
|
|
148
|
+
|
|
149
|
+
**Description.** `check_fhir_lookup_allowed()` gates only `settings['url']` (the FHIR base host) against `[egress].allowed_http`. A FhirLookup spec can compose `with_smart_backend()` (`transports/smart.py:262-263,304`, which explicitly accepts a `FhirLookupSpec`), which sets `smart_token_url`. `FhirLookupExecutor.__init__` (`transports/fhir.py:561`) then builds a `SmartBackendTokenProvider` from that `smart_token_url` and POSTs a signed `client_assertion` JWT (a credential-minting request) to it at read time. Unlike the outbound egress path, which explicitly gates `smart_token_url` (`wiring_runner.py:3086-3097`, with the comment: "Left ungated, a crafted smart_token_url would exfiltrate the assertion to an unlisted host (a fail-open hole)"), the FhirLookup path never checks the token endpoint host. The exact fail-open the outbound arm closes is left open on the read-side lookup arm. ADR 0043 §D3 explicitly states the FhirLookup's `smart_token_url` "must be checked against `[egress].allowed_http`" — so this is a documented, intended control the implementation fails to apply.
|
|
150
|
+
|
|
151
|
+
**Attack scenario.** An operator (or a config/GUI-edit path, or a compromised `env()` value) declares a FhirLookup whose FHIR base `url` is allow-listed but whose `smart_token_url` points at an attacker/unlisted host. `deny_by_default` + `allowed_http` provides no protection: the executor mints and POSTs the signed `client_assertion` to the un-allowlisted token endpoint, exfiltrating the assertion and defeating the egress control the outbound path enforces. The connection loads without error because only the FHIR base host is validated.
|
|
152
|
+
|
|
153
|
+
**Evidence.**
|
|
154
|
+
```
|
|
155
|
+
wiring_runner.py:2831-2842 check_fhir_lookup_allowed validates only url = str(settings.get("url","")); never reads smart_token_url
|
|
156
|
+
wiring_runner.py:3086-3097 outbound branch: token_url = dest.settings.get("smart_token_url"); if token_url and not _http_egress_allowed(...): raise WiringError(...)
|
|
157
|
+
transports/fhir.py:561 FhirLookupExecutor consumes smart_token_url via token_provider_from_settings(s)
|
|
158
|
+
transports/smart.py:181-191 SmartBackendTokenProvider._fetch_token POSTs the client_assertion to self.token_url
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
**Verdict & confidence.** CONFIRMED; high confidence. The sole egress gate for FhirLookups omits the token-endpoint check that the sibling outbound arm enforces against exactly this threat, and `SmartBackendTokenProvider` performs no allowlisting of its own — so the only place the check could live is `check_fhir_lookup_allowed`, which omits it. Reachability is config-plane (a FhirLookup spec / `connections.toml` / poisoned `env()`), not raw network input — so not High. But containing misconfigured/compromised egress destinations is the entire purpose of the `deny_by_default` allowlist, and the gap lets a signed `client_assertion` credential be POSTed to an un-allowlisted host (credential exfil + SSRF POST primitive). Replay value of the leaked assertion is limited because `aud` defaults to the (attacker) token URL, but the control bypass and exfil are real — Medium is correct.
|
|
162
|
+
|
|
163
|
+
**Recommendation.** In `check_fhir_lookup_allowed()`, after validating the FHIR base `url`, apply the same `smart_token_url` host check the outbound branch uses (read `settings.get("smart_token_url")`; if set, require `_http_egress_allowed(token_url, egress.allowed_http)`) and honor `deny_by_default`. Factor the outbound token-endpoint gate into a shared helper so read-side and write-side stay in lockstep. Add a test asserting an un-allowlisted `smart_token_url` on a FhirLookup is rejected (mirroring the outbound test).
|
|
164
|
+
|
|
165
|
+
---
|
|
166
|
+
|
|
167
|
+
### DELTA-05 — Support bundle `status.json` discloses the SQL Server store host and database name
|
|
168
|
+
|
|
169
|
+
- **Severity:** Low (CONFIRMED; corrected down from Medium — operator-shared vector, no secrets/PHI)
|
|
170
|
+
- **CWE:** CWE-200 (exposure of sensitive information)
|
|
171
|
+
- **Location:** `messagefoundry/support/bundle.py:137`
|
|
172
|
+
|
|
173
|
+
**Description.** `build_bundle()` writes `status.json` straight from `SystemStatus.model_dump()` with no redaction (`bundle.py:202-203`). `status_snapshot` → `_db_info` populates `DbInfo.path` from `store.db_status().path` (`bundle.py:137-146`). For the SQL Server backend, `MsSqlStore.path` is `f"{settings.server}/{settings.database}"` (`sqlserver.py:392`) — the raw ODBC server host (`hostname\instance` or IP) and database name. So the operator-emailed support zip carries the customer's DB server host and database name. This directly contradicts the module's own PHI contract, which promises the bundle carries "never a settings value, host, path" (`bundle.py:11-12`) and "no secrets" (`bundle.py:19`) — enforced for `config_summary` (which deliberately omits hosts) but not for `status_snapshot`. It is also contrary to the project rule that customer-identifying host/IP data must not leave the box. (For the SQLite backend the same field carries the local DB file path, which can embed an org/site name.)
|
|
174
|
+
|
|
175
|
+
**Attack scenario.** An operator runs `messagefoundry support-bundle` against a SQL Server deployment and emails/uploads the zip to third-party support or attaches it to a ticket, relying on the bundle's explicit "no host/path" promise. `status.json` exposes the internal DB server hostname/instance (or IP) and database name — customer-identifying infrastructure detail the bundle claims it never includes — to anyone who receives the bundle.
|
|
176
|
+
|
|
177
|
+
**Evidence.**
|
|
178
|
+
```
|
|
179
|
+
bundle.py:137-146 return DbInfo(path=db.path, ...)
|
|
180
|
+
sqlserver.py:392 self.path = f"{settings.server}/{settings.database}"
|
|
181
|
+
bundle.py:202-203 members["status.json"] = json.dumps(status, ...) # no redaction pass
|
|
182
|
+
bundle.py:11-12 contract: bundle omits "never a settings value, host, path"
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
**Verdict & confidence.** CONFIRMED; high confidence. The self-contradicting-contract leak is fully traced and real. The disclosed value is operator configuration (not attacker-supplied message input), so it is not reachable from untrusted message data; the vector is a trusted operator voluntarily sharing the zip. No secrets, credentials, or PHI are leaked — the connection-string password is not part of `settings.server`/`settings.database`; only reconnaissance-value host/instance/IP + DB name. This clears "info" (it leaks the customer-identifying host class the project forbids leaving the box) but is Low, not Medium, given no secrets/PHI and the voluntary-sharing dependency.
|
|
186
|
+
|
|
187
|
+
**Recommendation.** Before serializing status into the bundle, drop or redact `DbInfo.path` (replace with the backend type only, or a coarse `<redacted>` descriptor). Alternatively have `db_status()` expose a backend label for bundle use. Add a regression test asserting `status.json` contains no host/path token.
|
|
188
|
+
|
|
189
|
+
---
|
|
190
|
+
|
|
191
|
+
### DELTA-06 — HTTP listener accepts ambiguous framing headers (duplicate Content-Length, CL + obfuscated Transfer-Encoding) — request-smuggling surface behind a fronting proxy
|
|
192
|
+
|
|
193
|
+
- **Severity:** Low (PLAUSIBLE; conditional on a fronting proxy, this server cannot self-desync)
|
|
194
|
+
- **CWE:** CWE-444 (inconsistent interpretation of HTTP requests / request smuggling)
|
|
195
|
+
- **Location:** `messagefoundry/transports/http_listener.py:180`
|
|
196
|
+
|
|
197
|
+
**Description.** The hand-rolled header parser in `_read_request()` stores headers last-wins (`headers[name.strip().lower()] = value.strip()`, `line 183`) and never rejects duplicate `Content-Length` headers nor the simultaneous presence of `Content-Length` and `Transfer-Encoding`. It refuses `Transfer-Encoding` only when the (last-wins, lowercased) value equals exactly `"chunked"` (`line 192`); an obfuscated TE value (e.g. `Transfer-Encoding: chunked, identity`, `Transfer-Encoding:\tchunked`, or a duplicated TE header whose last value is not exactly `"chunked"`) is silently ignored and the request is framed by `Content-Length` (`lines 197-207`). RFC 7230 §3.3.3 requires rejecting a message with both CL and TE and rejecting/ignoring conflicting/duplicate `Content-Length`.
|
|
198
|
+
|
|
199
|
+
**Attack scenario.** An operator fronts partner traffic with a reverse proxy (TLS termination / load balancing) — a topology ADR 0023 §3 and ADR 0002 (WP-15) explicitly support. An attacker crafts a request with two `Content-Length` headers, or a `Content-Length` plus an obfuscated `Transfer-Encoding` the proxy honors as chunked but this backend ignores. The proxy and backend disagree on message boundaries, enabling classic HTTP request smuggling / queue poisoning against the pipeline in the fronted deployment.
|
|
200
|
+
|
|
201
|
+
**Evidence.**
|
|
202
|
+
```
|
|
203
|
+
http_listener.py:183 headers[name.strip().lower()] = value.strip() # last-wins, no dup detection
|
|
204
|
+
http_listener.py:192 if headers.get("transfer-encoding","").lower() == "chunked": # only exact-match rejected
|
|
205
|
+
http_listener.py:197 if cl_raw is not None: ... # CL used even if a TE header is also present
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
**Verdict & confidence.** PLAUSIBLE; medium confidence. All four technical claims verified against the new code (`de53154`). The attacker-influenceable raw HTTP request reaches this parser directly. Crucially, this server **cannot desync itself**: `_serve_one` reads exactly one request per socket, responds `Connection: close` (`build_response`), and closes — there is no keep-alive/pipelining, so any leftover smuggled bytes are discarded on close, and the most damaging queue-poisoning variant is blunted. The residual risk is a proxy↔backend framing disagreement in the supported fronted topology, whose impact depends on specific upstream proxy behavior. Real spec-compliance defect, deployment-conditional impact, no direct self-exploitation — Low.
|
|
209
|
+
|
|
210
|
+
**Recommendation.** Reject any request carrying both `Content-Length` and `Transfer-Encoding` (400); detect and reject a duplicate `Content-Length` (track seen names in the parse loop rather than overwriting at line 183); and reject any `Transfer-Encoding` whose token list contains `chunked` in **any** position (not only exact-string match at line 192). Low-cost hardening even though this server cannot self-desync, because the fronting-proxy topology is explicitly blessed.
|
|
211
|
+
|
|
212
|
+
---
|
|
213
|
+
|
|
214
|
+
### DELTA-07 — Support-bundle log redactor under-redacts vs. the engine's own redactor (fixed segment allowlist, no name/DOB heuristics)
|
|
215
|
+
|
|
216
|
+
- **Severity:** Low (PLAUSIBLE; primary redaction happens upstream, residual is a narrow non-logging-stdout edge)
|
|
217
|
+
- **CWE:** CWE-359 (exposure of private personal information)
|
|
218
|
+
- **Location:** `messagefoundry/support/redact.py:27`
|
|
219
|
+
|
|
220
|
+
**Description.** `support/redact.py` is the redactor applied to the app-log tail carried in the support bundle (`bundle.py:171`). Its HL7 catch (`_HL7_SEGMENT`, `lines 27-29`) matches only a hard-coded enumeration of segment ids (`MSH|PID|PV1|OBX|OBR|EVN|NK1|ORC|IN1|AL1|DG1|GT1|SPM|MSA|ERR|ED`). It omits free-text-bearing segments such as `NTE`, `TXA`, `RXA`/`RXR`, `PR1`, `IN2`, and any custom Z-segment, and it has no free-text name/DOB heuristic. By contrast the engine's exception-path redactor (`redaction.py:35`) matches **any** segment id via `[A-Z][A-Z0-9]{2}` and additionally scrubs delimiter-free date runs and multi-token name runs (`redaction.py:47-58`). A log line carrying e.g. `NTE|1||patient JANE DOE dob 1980-05-05` is fully redacted by `redaction.py` but passes through `support/redact.py` untouched.
|
|
221
|
+
|
|
222
|
+
**Attack scenario.** A dependency or a non-`safe_exc` log site emits content to stdout/stderr **outside** the logging framework (direct `print`, an interpreter traceback on a hard crash, subprocess stderr) that echoes an HL7 `NTE`/Z-segment or a free-text `LAST FIRST dob YYYY-MM-DD` fragment. NSSM captures that un-redacted line into the file the bundle reads. An operator generates a support bundle; `support/redact.py` does not match that segment/pattern, so the PHI fragment ships in `app-log.txt` inside the off-box zip.
|
|
223
|
+
|
|
224
|
+
**Evidence.**
|
|
225
|
+
```
|
|
226
|
+
support/redact.py:27-29 fixed list (MSH|PID|PV1|OBX|OBR|EVN|NK1|ORC|IN1|AL1|DG1|GT1|SPM|MSA|ERR|ED); no _NAME_RUN/_DATE_RUN
|
|
227
|
+
redaction.py:35 _HL7_SEGMENT = re.compile(r"\b([A-Z][A-Z0-9]{2})\|[^\r\n]*")
|
|
228
|
+
redaction.py:47-58 date/name heuristics
|
|
229
|
+
bundle.py:171 return redact_log_text(...)
|
|
230
|
+
```
|
|
231
|
+
|
|
232
|
+
**Verdict & confidence.** PLAUSIBLE; medium confidence. The code gap and regex behavior were reproduced (NTE/Z-segment/name/DOB runs redacted by `redaction.py`, untouched by `support/redact.py`). But the finder's headline WARNING-echo scenario is already mitigated: the engine adds no file handlers (`logging_setup.py:8`); NSSM captures the already-redacted stdout stream (strong `RedactionFilter` on the root handler, `logging_setup.py:213/271-276`), and child/third-party loggers propagate to root — so anything emitted via the logging framework is scrubbed by the strong redactor **before** reaching the file, and `support/redact.py` merely re-processes already-clean text. The only genuine bypass is content written to stdout/stderr outside the logging framework, and no engine path was found emitting message content that way. A real defense-in-depth reduction over a narrow residual, not a traced attacker→unredacted-sink path — Low.
|
|
233
|
+
|
|
234
|
+
**Recommendation.** Reuse `messagefoundry.redaction.redact` (or broaden `_HL7_SEGMENT` to `[A-Z][A-Z0-9]{2}` and add the `_DATE_RUN`/`_NAME_RUN` passes) so the bundle's log redactor is at least as strong as the engine's exception-path redactor — the off-box bundle is the higher-consequence surface.
|
|
235
|
+
|
|
236
|
+
---
|
|
237
|
+
|
|
238
|
+
## 5. Refuted / Deprioritized Candidates
|
|
239
|
+
|
|
240
|
+
These candidates were investigated and did **not** survive adversarial verification, or were real code observations without a materially exploitable security consequence in the delta. Summarized for transparency; they are not open findings.
|
|
241
|
+
|
|
242
|
+
- **FHIR JSON parse leaks uncaught `RecursionError` on deeply nested payloads** (structured-codecs). Technically real: `json.loads` on ~50k+ nested arrays raises `RecursionError`, which is neither `ValueError` nor `JSONDecodeError`, so it escapes the codec's typed `except` (`peek.py:69`, `resource.py:78`). **Refuted as security:** `FhirPeek.parse` is not on the automatic ingress hot path (only HL7 `Peek.parse` is), and every reachable caller sits inside a worker with a broad `except Exception` that dead-letters — and `RecursionError` **is** an `Exception`, so it is caught and cleanly dead-lettered. No crash, no DoS, no info leak. Remaining defect is a contract/robustness issue (typed error promised, untyped leaked), not a vulnerability.
|
|
243
|
+
|
|
244
|
+
- **Inbound HTTP listener success/health responses drain unbounded — slow-read DoS** (listeners). Code observation correct: `_respond()` does a bare `await writer.drain()` with no timeout, unlike `_write_safely()`. **Refuted:** every response through `_respond()` is a few hundred bytes at most (`{"status":"ok"}`, a short 202 receipt), far below the 64 KiB high-water mark, so `drain()` returns immediately regardless of the peer's read behavior; `Connection: close` + one-request-per-socket prevents buffer growth; `message_id` is an internal id, not attacker-inflatable. The request-side slow-read is already bounded by `receive_timeout`. Missing write timeout is a robustness parity nit, not a demonstrable DoS.
|
|
245
|
+
|
|
246
|
+
- **Retention document-strip TOCTOU on the in-flight guard** (store/SQL). Real structural TOCTOU: the in-flight guard is applied at candidate `SELECT` time but not re-checked before the write-back `UPDATE`. **Refuted:** the premise that stripping `messages.raw` can corrupt an in-flight replay is false — the staged pipeline re-derives from each queue row's **own** encrypted payload (`queue.payload`, per-handler `raw_payload`), never from `messages.raw`; `replay()` re-queues existing rows and never reads `messages.raw`. The strip mutates only the canonical display/audit copy. No delivery-integrity or security consequence. (The code even documents this invariant at `store.py:5125-5127`.)
|
|
247
|
+
|
|
248
|
+
- **Directory-disabled AD account keeps live engine sessions until timeout** (auth/RBAC). Real CWE-613 condition in the abstract. **Deprioritized/out-of-delta:** the exact sink lines (`service.py:691-694`) were introduced 2026-06-07, **before** the review window, and the in-window commits touching `service.py` did not modify the AD liveness/disabled-resync logic. Not reachable from message input (session-lifecycle policy gap). Already documented, accepted, and compensated: `SECURITY.md` residual (2) and `CISO-REVIEW.md #9`, with an existing admin bulk session-revoke. Duplicate of a known-accepted residual; window capped by idle/absolute timeouts.
|
|
249
|
+
|
|
250
|
+
- **`ai:assist` authorization is advisory only (client-side enforcement)** (auth/RBAC). `GET /ai/policy` is intentionally not behind `require()` and returns an advisory bit. **Refuted:** there is no server-side AI *action* endpoint to fail open against — the MVP IDE assistant talks to an external LLM directly, the engine is clamped to `code_only` and never in the AI data path. Intentional, documented design (docstring + CISO register), and the `/ai/policy` logic predates the review window. Architectural observation, at most info.
|
|
251
|
+
|
|
252
|
+
- **Custom roles may grant `CONFIG_DEPLOY`, not in the escalation-forbidden set** (auth/RBAC). Facts accurate (`CUSTOM_ROLE_FORBIDDEN_PERMISSIONS` omits `CONFIG_DEPLOY`), delta code. **Refuted:** ADR 0045 explicitly resolved this — `CONFIG_DEPLOY`/`SERVICE_CONFIGURE` are classified "privileged-but-not-escalating" and deliberately "stay assignable." The forbidden set is escalation primitives only; `CONFIG_DEPLOY` cannot grant more privilege than held (config reload does not touch the roles table). No new capability (an admin can already assign the built-in `DEPLOYMENT` role), and `/config/reload` is step-up-gated, path-confined, optionally dual-control, and audited. A design-intent disagreement, not a reachable vulnerability.
|
|
253
|
+
|
|
254
|
+
---
|
|
255
|
+
|
|
256
|
+
## 6. Coverage & Limitations
|
|
257
|
+
|
|
258
|
+
**Surfaces covered (delta since 2026-06-10).** Nine parallel finder passes covered: HL7 core parser + binary carriage; structured-format codecs (XML / X12 / FHIR); egress / SSRF / outbound lookups (`db_lookup`, `fhir_lookup`, SMART token provider); network listeners & transports (new HTTP listener, MLLP, file); crypto / secrets / PHI redaction / de-identification (support bundle, redactors); auth / RBAC / API (custom RBAC, `ai:assist`, AD sessions); store / SQL (retention strip, SQL Server); pipeline / config; and supply-chain / infra. Reachability was traced from attacker-influenceable inputs — inbound HL7/X12/DICOM/FHIR/XML/binary over MLLP/TCP/HTTP/DICOM listeners, file contents, connection config (`connections.toml` / `env()`), and outbound-lookup responses — to each candidate sink, reading callers and callees.
|
|
259
|
+
|
|
260
|
+
**Out of scope.** Code unchanged since 2026-06-10 (already covered by the prior full review) was not re-audited except where a pre-existing issue sits in a changed file and is materially exploitable. Pre-existing issues confirmed to predate the window (e.g. the AD-session liveness gap in §5) were deprioritized as out-of-delta. No re-litigation of the prior report's 78 findings.
|
|
261
|
+
|
|
262
|
+
**Read-only / no-runtime caveat.** This audit was strictly read-only: no repo files were edited, the engine was never run, and no exploit was executed against any live system. Proof-of-concept payloads (e.g. `\.in2000000000\`) are inert text in the findings. No real PHI, credentials, or key/secret files were read; no customer-identifying data (real IPs, ports, partner/hospital names, site codes) appears anywhere in this report. Findings are grounded in concrete `file:line` evidence; DoS/expansion magnitudes were reasoned from the code and interpreter behavior, not measured against a running instance. `PLAUSIBLE` verdicts denote a verified code defect whose exploitability is conditional (opt-in Handler use for DELTA-03; a fronting proxy with divergent framing for DELTA-06); they warrant fixing but were not demonstrated end-to-end in a live deployment.
|