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