diff --git a/.ci/asciidoc-converter/build.gradle b/.ci/asciidoc-converter/build.gradle index cd0a1cc..ea10d78 100644 --- a/.ci/asciidoc-converter/build.gradle +++ b/.ci/asciidoc-converter/build.gradle @@ -36,3 +36,50 @@ asciidoctor { } } } + +tasks.register('pcimRequirementsJson', Exec) { + group = 'documentation' + description = 'Extract PCIM semantic requirement blocks to JSON.' + workingDir file('../..') + commandLine 'python3', + '.ci/asciidoc-converter/scripts/extract_pcim_requirements.py', + '--source', 'asciidoc/IHE_DEV_Suppl_PCIM.adoc', + '--output', 'output/referenced-artifacts/pcim-requirements.json', + '--trace-output', 'output/referenced-artifacts/pcim-requirement-trace.json' + + inputs.file file('../../asciidoc/IHE_DEV_Suppl_PCIM.adoc') + inputs.file file('scripts/extract_pcim_requirements.py') + outputs.file file('../../output/referenced-artifacts/pcim-requirements.json') + outputs.file file('../../output/referenced-artifacts/pcim-requirement-trace.json') +} + +tasks.register('pcimRequirementsCheck', Exec) { + group = 'verification' + description = 'Validate PCIM semantic requirement identifiers and required metadata.' + workingDir file('../..') + commandLine 'python3', + '.ci/asciidoc-converter/scripts/extract_pcim_requirements.py', + '--source', 'asciidoc/IHE_DEV_Suppl_PCIM.adoc', + '--check-only' + + inputs.file file('../../asciidoc/IHE_DEV_Suppl_PCIM.adoc') + inputs.file file('scripts/extract_pcim_requirements.py') +} + +tasks.register('pcimRequirementsFixture', Exec) { + group = 'documentation' + description = 'Generate a stable review fixture for PCIM requirements JSON.' + workingDir file('../..') + commandLine 'python3', + '.ci/asciidoc-converter/scripts/extract_pcim_requirements.py', + '--source', 'asciidoc/IHE_DEV_Suppl_PCIM.adoc', + '--output', '.ci/asciidoc-converter/fixtures/pcim-requirements.fixture.json', + '--omit-commit' + + inputs.file file('../../asciidoc/IHE_DEV_Suppl_PCIM.adoc') + inputs.file file('scripts/extract_pcim_requirements.py') + outputs.file file('fixtures/pcim-requirements.fixture.json') +} + +asciidoctor.finalizedBy tasks.named('pcimRequirementsJson') +check.dependsOn tasks.named('pcimRequirementsCheck') diff --git a/.ci/asciidoc-converter/fixtures/pcim-requirements.fixture.json b/.ci/asciidoc-converter/fixtures/pcim-requirements.fixture.json new file mode 100644 index 0000000..c08f88d --- /dev/null +++ b/.ci/asciidoc-converter/fixtures/pcim-requirements.fixture.json @@ -0,0 +1,1869 @@ +{ + "$schema": "https://profiles.ihe.net/DEV/PCIM/schemas/pcim-requirements.schema.json", + "artifactType": "pcim-requirements", + "profile": "PCIM", + "source": { + "repository": "IHE/DEV.PCIM", + "file": "asciidoc/IHE_DEV_Suppl_PCIM.adoc", + "commit": null, + "revision": "", + "publicationDate": "May 7, 2026" + }, + "count": 33, + "requirements": [ + { + "id": "PCIMR0001", + "anchor": "pcimr0001", + "level": "shall", + "type": "ihe_profile", + "status": "active", + "source": { + "repository": "IHE/DEV.PCIM", + "file": "asciidoc/IHE_DEV_Suppl_PCIM.adoc", + "line": 312, + "sectionPath": [ + "7 Point-of-Care Identity Management (PCIM) Profile", + "7.1 PCIM Actors, Transactions, and Content Modules" + ] + }, + "scope": { + "actors": [ + "dpar", + "dpam", + "dpac" + ], + "transactions": [], + "options": [], + "useCases": [], + "messages": [], + "segments": [] + }, + "metadata": { + "pcim_req_level": "shall", + "pcim_req_type": "ihe_profile", + "pcim_actor": "dpar,dpam,dpac", + "pcim_verification_method": "inspection", + "pcim_verification_level": "connectathon" + }, + "normativeText": "To claim compliance with the PCIM Profile, an actor shall support every\ntransaction listed as required for that actor in Table 7.1-1.", + "verification": { + "method": "inspection", + "level": "connectathon", + "text": "Verify by inspecting the implementation conformance claim for the PCIM actor and\nconfirming support for all required transactions in Table 7.1-1." + }, + "notes": [], + "rationale": [], + "related": [], + "examples": [] + }, + { + "id": "PCIMR0002", + "anchor": "pcimr0002", + "level": "shall", + "type": "ihe_profile", + "status": "active", + "source": { + "repository": "IHE/DEV.PCIM", + "file": "asciidoc/IHE_DEV_Suppl_PCIM.adoc", + "line": 376, + "sectionPath": [ + "7 Point-of-Care Identity Management (PCIM) Profile", + "7.1 PCIM Actors, Transactions, and Content Modules", + "7.1.1 Actor Descriptions and Actor Profile Requirements", + "7.1.1.1 Device-Patient Association Reporter" + ] + }, + "scope": { + "actors": [ + "dpar" + ], + "transactions": [ + "DEV-51" + ], + "options": [], + "useCases": [ + "uc1_associate_device_patient", + "uc2_disassociate_device_patient" + ], + "messages": [ + "ORU_R01" + ], + "segments": [ + "PID", + "PRT", + "OBR-7", + "OBR-8" + ] + }, + "metadata": { + "pcim_req_level": "shall", + "pcim_req_type": "ihe_profile", + "pcim_actor": "dpar", + "pcim_transaction": "DEV-51", + "pcim_message": "ORU_R01", + "pcim_segment": "PID,PRT,OBR-7,OBR-8", + "pcim_use_case": "uc1_associate_device_patient,uc2_disassociate_device_patient", + "pcim_verification_method": "test", + "pcim_verification_level": "connectathon" + }, + "normativeText": "The Device-Patient Association Reporter shall report the patient identifier,\ndevice identifier, and beginning or ending timestamp for each association or\ndisassociation event that it asserts.", + "verification": { + "method": "test", + "level": "connectathon", + "text": "Verify by inspecting DEV-51 messages originated by the Device-Patient Association\nReporter and confirming that the patient, device, and timestamp content is present." + }, + "notes": [], + "rationale": [], + "related": [], + "examples": [] + }, + { + "id": "PCIMR0003", + "anchor": "pcimr0003", + "level": "shall", + "type": "ihe_profile", + "status": "active", + "source": { + "repository": "IHE/DEV.PCIM", + "file": "asciidoc/IHE_DEV_Suppl_PCIM.adoc", + "line": 393, + "sectionPath": [ + "7 Point-of-Care Identity Management (PCIM) Profile", + "7.1 PCIM Actors, Transactions, and Content Modules", + "7.1.1 Actor Descriptions and Actor Profile Requirements", + "7.1.1.1 Device-Patient Association Reporter" + ] + }, + "scope": { + "actors": [ + "dpar" + ], + "transactions": [ + "DEV-51" + ], + "options": [], + "useCases": [ + "uc1_associate_device_patient", + "uc2_disassociate_device_patient" + ], + "messages": [ + "ORU_R01" + ], + "segments": [ + "OBX-11" + ] + }, + "metadata": { + "pcim_req_level": "shall", + "pcim_req_type": "ihe_profile", + "pcim_actor": "dpar", + "pcim_transaction": "DEV-51", + "pcim_message": "ORU_R01", + "pcim_segment": "OBX-11", + "pcim_use_case": "uc1_associate_device_patient,uc2_disassociate_device_patient", + "pcim_verification_method": "test", + "pcim_verification_level": "connectathon" + }, + "normativeText": "The Device-Patient Association Reporter shall mark validated reports as final\nand shall mark non-validated reports as requiring validation.", + "verification": { + "method": "test", + "level": "connectathon", + "text": "Verify by inspecting OBX-11 in DEV-51 messages originated by the Device-Patient\nAssociation Reporter." + }, + "notes": [], + "rationale": [], + "related": [], + "examples": [] + }, + { + "id": "PCIMR0004", + "anchor": "pcimr0004", + "level": "shall", + "type": "ihe_profile", + "status": "active", + "source": { + "repository": "IHE/DEV.PCIM", + "file": "asciidoc/IHE_DEV_Suppl_PCIM.adoc", + "line": 413, + "sectionPath": [ + "7 Point-of-Care Identity Management (PCIM) Profile", + "7.1 PCIM Actors, Transactions, and Content Modules", + "7.1.1 Actor Descriptions and Actor Profile Requirements", + "7.1.1.2 Device-Patient Association Manager" + ] + }, + "scope": { + "actors": [ + "dpam" + ], + "transactions": [ + "DEV-52" + ], + "options": [], + "useCases": [ + "uc1_associate_device_patient", + "uc2_disassociate_device_patient", + "uc4_correct_verified_association", + "uc5_wrong_association" + ], + "messages": [ + "ORU_R01" + ], + "segments": [] + }, + "metadata": { + "pcim_req_level": "shall", + "pcim_req_type": "ihe_profile", + "pcim_actor": "dpam", + "pcim_transaction": "DEV-52", + "pcim_message": "ORU_R01", + "pcim_use_case": "uc1_associate_device_patient,uc2_disassociate_device_patient,uc4_correct_verified_association,uc5_wrong_association", + "pcim_verification_method": "test", + "pcim_verification_level": "connectathon" + }, + "normativeText": "The Device-Patient Association Manager shall communicate validated\ndevice-patient associations as event notifications.", + "verification": { + "method": "test", + "level": "connectathon", + "text": "Verify by inspecting DEV-52 messages originated by the Device-Patient Association\nManager after association validation." + }, + "notes": [], + "rationale": [], + "related": [], + "examples": [] + }, + { + "id": "PCIMR0005", + "anchor": "pcimr0005", + "level": "shall", + "type": "ihe_profile", + "status": "active", + "source": { + "repository": "IHE/DEV.PCIM", + "file": "asciidoc/IHE_DEV_Suppl_PCIM.adoc", + "line": 429, + "sectionPath": [ + "7 Point-of-Care Identity Management (PCIM) Profile", + "7.1 PCIM Actors, Transactions, and Content Modules", + "7.1.1 Actor Descriptions and Actor Profile Requirements", + "7.1.1.2 Device-Patient Association Manager" + ] + }, + "scope": { + "actors": [ + "dpam" + ], + "transactions": [], + "options": [], + "useCases": [ + "uc1_associate_device_patient", + "uc2_disassociate_device_patient", + "uc4_correct_verified_association", + "uc5_wrong_association" + ], + "messages": [], + "segments": [] + }, + "metadata": { + "pcim_req_level": "shall", + "pcim_req_type": "ihe_profile", + "pcim_actor": "dpam", + "pcim_use_case": "uc1_associate_device_patient,uc2_disassociate_device_patient,uc4_correct_verified_association,uc5_wrong_association", + "pcim_verification_method": "demonstration", + "pcim_verification_level": "connectathon" + }, + "normativeText": "The Device-Patient Association Manager shall provide an HMI for validating\nassociation assertions that require validation and for resolving conflicts.", + "verification": { + "method": "demonstration", + "level": "connectathon", + "text": "Verify by inspection or demonstration of the Device-Patient Association Manager\nvalidation and conflict-resolution HMI." + }, + "notes": [], + "rationale": [], + "related": [], + "examples": [] + }, + { + "id": "PCIMR0006", + "anchor": "pcimr0006", + "level": "shall", + "type": "ihe_profile", + "status": "active", + "source": { + "repository": "IHE/DEV.PCIM", + "file": "asciidoc/IHE_DEV_Suppl_PCIM.adoc", + "line": 486, + "sectionPath": [ + "7 Point-of-Care Identity Management (PCIM) Profile", + "7.2 PCIM Actor Options", + "7.2.1 Subscription and Filtering Option" + ] + }, + "scope": { + "actors": [ + "dpac" + ], + "transactions": [ + "DEV-19" + ], + "options": [ + "subscription_filtering" + ], + "useCases": [ + "uc3_filter_devices_for_patient" + ], + "messages": [ + "QSB_Q16" + ], + "segments": [] + }, + "metadata": { + "pcim_req_level": "shall", + "pcim_req_type": "ihe_profile", + "pcim_actor": "dpac", + "pcim_transaction": "DEV-19", + "pcim_option": "subscription_filtering", + "pcim_message": "QSB_Q16", + "pcim_use_case": "uc3_filter_devices_for_patient", + "pcim_verification_method": "test", + "pcim_verification_level": "connectathon" + }, + "normativeText": "A Device-Patient Association Consumer that supports the Subscription and\nFiltering Option shall formulate its filtering request as specified in Section\n3.19.", + "verification": { + "method": "test", + "level": "connectathon", + "text": "Verify by inspecting DEV-19 messages originated by a Device-Patient Association\nConsumer that claims the Subscription and Filtering Option." + }, + "notes": [], + "rationale": [], + "related": [], + "examples": [] + }, + { + "id": "PCIMR0007", + "anchor": "pcimr0007", + "level": "may", + "type": "ihe_profile", + "status": "active", + "source": { + "repository": "IHE/DEV.PCIM", + "file": "asciidoc/IHE_DEV_Suppl_PCIM.adoc", + "line": 503, + "sectionPath": [ + "7 Point-of-Care Identity Management (PCIM) Profile", + "7.2 PCIM Actor Options", + "7.2.1 Subscription and Filtering Option" + ] + }, + "scope": { + "actors": [ + "dpam" + ], + "transactions": [ + "DEV-19" + ], + "options": [ + "subscription_filtering" + ], + "useCases": [ + "uc3_filter_devices_for_patient" + ], + "messages": [ + "QSB_Q16" + ], + "segments": [] + }, + "metadata": { + "pcim_req_level": "may", + "pcim_req_type": "ihe_profile", + "pcim_actor": "dpam", + "pcim_transaction": "DEV-19", + "pcim_option": "subscription_filtering", + "pcim_message": "QSB_Q16", + "pcim_use_case": "uc3_filter_devices_for_patient", + "pcim_verification_method": "test", + "pcim_verification_level": "connectathon" + }, + "normativeText": "The Device-Patient Association Manager may support the Subscription and\nFiltering Option.", + "verification": { + "method": "test", + "level": "connectathon", + "text": "Verify by inspecting the implementation conformance claim for the Device-Patient\nAssociation Manager and, when the option is claimed, by executing DEV-19 tests." + }, + "notes": [], + "rationale": [], + "related": [], + "examples": [] + }, + { + "id": "PCIMR0100", + "anchor": "pcimr0100", + "level": "shall", + "type": "tech_feature", + "status": "active", + "source": { + "repository": "IHE/DEV.PCIM", + "file": "asciidoc/IHE_DEV_Suppl_PCIM.adoc", + "line": 930, + "sectionPath": [ + "Volume 2 -- Transactions", + "3.51 Communicate Association State [DEV-51]", + "3.51.2 Actor Roles" + ] + }, + "scope": { + "actors": [ + "dpar" + ], + "transactions": [ + "DEV-51" + ], + "options": [], + "useCases": [ + "uc1_associate_device_patient", + "uc2_disassociate_device_patient" + ], + "messages": [ + "ORU_R01" + ], + "segments": [ + "PRT" + ] + }, + "metadata": { + "pcim_req_level": "shall", + "pcim_req_type": "tech_feature", + "pcim_actor": "dpar", + "pcim_transaction": "DEV-51", + "pcim_message": "ORU_R01", + "pcim_segment": "PRT", + "pcim_use_case": "uc1_associate_device_patient,uc2_disassociate_device_patient", + "pcim_verification_method": "test", + "pcim_verification_level": "connectathon" + }, + "normativeText": "When verification occurs at the Device-Patient Association Reporter, the\nReporter shall record the responsible observer.", + "verification": { + "method": "test", + "level": "connectathon", + "text": "Verify by inspecting a DEV-51 message for the responsible observer information\nwhen the assertion is sent as already verified." + }, + "notes": [], + "rationale": [], + "related": [], + "examples": [] + }, + { + "id": "PCIMR0101", + "anchor": "pcimr0101", + "level": "shall", + "type": "tech_feature", + "status": "active", + "source": { + "repository": "IHE/DEV.PCIM", + "file": "asciidoc/IHE_DEV_Suppl_PCIM.adoc", + "line": 946, + "sectionPath": [ + "Volume 2 -- Transactions", + "3.51 Communicate Association State [DEV-51]", + "3.51.2 Actor Roles" + ] + }, + "scope": { + "actors": [ + "dpar" + ], + "transactions": [ + "DEV-51" + ], + "options": [], + "useCases": [ + "uc1_associate_device_patient", + "uc2_disassociate_device_patient" + ], + "messages": [ + "ORU_R01" + ], + "segments": [ + "OBX-11" + ] + }, + "metadata": { + "pcim_req_level": "shall", + "pcim_req_type": "tech_feature", + "pcim_actor": "dpar", + "pcim_transaction": "DEV-51", + "pcim_message": "ORU_R01", + "pcim_segment": "OBX-11", + "pcim_use_case": "uc1_associate_device_patient,uc2_disassociate_device_patient", + "pcim_verification_method": "test", + "pcim_verification_level": "connectathon" + }, + "normativeText": "The Device-Patient Association Reporter shall include an observation status\nfield indicating whether the assertion requires validation or is final.", + "verification": { + "method": "test", + "level": "connectathon", + "text": "Verify by inspecting OBX-11 in DEV-51 messages originated by the Reporter." + }, + "notes": [], + "rationale": [], + "related": [], + "examples": [] + }, + { + "id": "PCIMR0102", + "anchor": "pcimr0102", + "level": "shall", + "type": "tech_feature", + "status": "active", + "source": { + "repository": "IHE/DEV.PCIM", + "file": "asciidoc/IHE_DEV_Suppl_PCIM.adoc", + "line": 961, + "sectionPath": [ + "Volume 2 -- Transactions", + "3.51 Communicate Association State [DEV-51]", + "3.51.2 Actor Roles" + ] + }, + "scope": { + "actors": [ + "dpam" + ], + "transactions": [ + "DEV-51" + ], + "options": [], + "useCases": [ + "uc1_associate_device_patient", + "uc2_disassociate_device_patient", + "uc4_correct_verified_association", + "uc5_wrong_association" + ], + "messages": [], + "segments": [] + }, + "metadata": { + "pcim_req_level": "shall", + "pcim_req_type": "tech_feature", + "pcim_actor": "dpam", + "pcim_transaction": "DEV-51", + "pcim_use_case": "uc1_associate_device_patient,uc2_disassociate_device_patient,uc4_correct_verified_association,uc5_wrong_association", + "pcim_verification_method": "demonstration", + "pcim_verification_level": "connectathon" + }, + "normativeText": "The Device-Patient Association Manager shall provide an HMI to verify\nassociation and disassociation assertions received through DEV-51.", + "verification": { + "method": "demonstration", + "level": "connectathon", + "text": "Verify by inspection or demonstration of the Manager HMI for DEV-51 validation\nworkflow." + }, + "notes": [], + "rationale": [], + "related": [], + "examples": [] + }, + { + "id": "PCIMR0103", + "anchor": "pcimr0103", + "level": "shall", + "type": "message_constraint", + "status": "active", + "source": { + "repository": "IHE/DEV.PCIM", + "file": "asciidoc/IHE_DEV_Suppl_PCIM.adoc", + "line": 1020, + "sectionPath": [ + "Volume 2 -- Transactions", + "3.51 Communicate Association State [DEV-51]", + "3.51.4 Messages", + "3.51.4.1 Communicate Association State", + "3.51.4.1.2 Message Semantics" + ] + }, + "scope": { + "actors": [ + "dpar" + ], + "transactions": [ + "DEV-51" + ], + "options": [], + "useCases": [ + "uc1_associate_device_patient", + "uc2_disassociate_device_patient" + ], + "messages": [ + "ORU_R01" + ], + "segments": [ + "PID-3" + ] + }, + "metadata": { + "pcim_req_level": "shall", + "pcim_req_type": "message_constraint", + "pcim_actor": "dpar", + "pcim_transaction": "DEV-51", + "pcim_message": "ORU_R01", + "pcim_segment": "PID-3", + "pcim_use_case": "uc1_associate_device_patient,uc2_disassociate_device_patient", + "pcim_verification_method": "test", + "pcim_verification_level": "connectathon" + }, + "normativeText": "The patient identifier used in a DEV-51 message shall include the identifier\ntype and issuing entity.", + "verification": { + "method": "test", + "level": "connectathon", + "text": "Verify by inspecting PID-3 in DEV-51 messages originated by the Reporter." + }, + "notes": [], + "rationale": [], + "related": [], + "examples": [] + }, + { + "id": "PCIMR0104", + "anchor": "pcimr0104", + "level": "shall", + "type": "message_constraint", + "status": "active", + "source": { + "repository": "IHE/DEV.PCIM", + "file": "asciidoc/IHE_DEV_Suppl_PCIM.adoc", + "line": 1112, + "sectionPath": [ + "Volume 2 -- Transactions", + "3.51 Communicate Association State [DEV-51]", + "3.51.4 Messages", + "3.51.4.1 Communicate Association State", + "3.51.4.1.3 Correction Semantics" + ] + }, + "scope": { + "actors": [ + "dpar" + ], + "transactions": [ + "DEV-51" + ], + "options": [], + "useCases": [ + "uc4_correct_verified_association" + ], + "messages": [ + "ORU_R01" + ], + "segments": [ + "OBR-29.2" + ] + }, + "metadata": { + "pcim_req_level": "shall", + "pcim_req_type": "message_constraint", + "pcim_actor": "dpar", + "pcim_transaction": "DEV-51", + "pcim_message": "ORU_R01", + "pcim_segment": "OBR-29.2", + "pcim_use_case": "uc4_correct_verified_association", + "pcim_verification_method": "test", + "pcim_verification_level": "connectathon" + }, + "normativeText": "DEV-51 correction messages shall reference the association unique instance\nidentifier from the original message in OBR-29.2.", + "verification": { + "method": "test", + "level": "connectathon", + "text": "Verify by inspecting OBR-29.2 in DEV-51 correction messages and confirming it\nmatches OBR-3 from the original association message." + }, + "notes": [], + "rationale": [], + "related": [], + "examples": [] + }, + { + "id": "PCIMR0105", + "anchor": "pcimr0105", + "level": "shall", + "type": "message_constraint", + "status": "active", + "source": { + "repository": "IHE/DEV.PCIM", + "file": "asciidoc/IHE_DEV_Suppl_PCIM.adoc", + "line": 1128, + "sectionPath": [ + "Volume 2 -- Transactions", + "3.51 Communicate Association State [DEV-51]", + "3.51.4 Messages", + "3.51.4.1 Communicate Association State", + "3.51.4.1.3 Correction Semantics" + ] + }, + "scope": { + "actors": [ + "dpar" + ], + "transactions": [ + "DEV-51" + ], + "options": [], + "useCases": [ + "uc4_correct_verified_association" + ], + "messages": [ + "ORU_R01" + ], + "segments": [ + "PRT-10", + "OBR-29.2" + ] + }, + "metadata": { + "pcim_req_level": "shall", + "pcim_req_type": "message_constraint", + "pcim_actor": "dpar", + "pcim_transaction": "DEV-51", + "pcim_message": "ORU_R01", + "pcim_segment": "PRT-10,OBR-29.2", + "pcim_use_case": "uc4_correct_verified_association", + "pcim_verification_method": "test", + "pcim_verification_level": "connectathon" + }, + "normativeText": "The device identifier and association unique instance identifier shall not be\nchanged in a DEV-51 correction message.", + "verification": { + "method": "test", + "level": "connectathon", + "text": "Verify by comparing the device identifier and association unique instance\nidentifier in a DEV-51 correction message with the original association message." + }, + "notes": [], + "rationale": [], + "related": [], + "examples": [] + }, + { + "id": "PCIMR0106", + "anchor": "pcimr0106", + "level": "shall", + "type": "message_constraint", + "status": "active", + "source": { + "repository": "IHE/DEV.PCIM", + "file": "asciidoc/IHE_DEV_Suppl_PCIM.adoc", + "line": 1148, + "sectionPath": [ + "Volume 2 -- Transactions", + "3.51 Communicate Association State [DEV-51]", + "3.51.4 Messages", + "3.51.4.1 Communicate Association State", + "3.51.4.1.4 Wrong Semantics" + ] + }, + "scope": { + "actors": [ + "dpar" + ], + "transactions": [ + "DEV-51" + ], + "options": [], + "useCases": [ + "uc5_wrong_association" + ], + "messages": [ + "ORU_R01" + ], + "segments": [ + "OBR-29.2" + ] + }, + "metadata": { + "pcim_req_level": "shall", + "pcim_req_type": "message_constraint", + "pcim_actor": "dpar", + "pcim_transaction": "DEV-51", + "pcim_message": "ORU_R01", + "pcim_segment": "OBR-29.2", + "pcim_use_case": "uc5_wrong_association", + "pcim_verification_method": "test", + "pcim_verification_level": "connectathon" + }, + "normativeText": "DEV-51 messages asserting an existing device-patient association as wrong shall\nreference in OBR-29.2 the association unique instance identifier from OBR-3 of\nthe original association message.", + "verification": { + "method": "test", + "level": "connectathon", + "text": "Verify by inspecting OBR-29.2 in DEV-51 wrong-association messages and confirming\nit matches OBR-3 from the original association message." + }, + "notes": [], + "rationale": [], + "related": [], + "examples": [] + }, + { + "id": "PCIMR0200", + "anchor": "pcimr0200", + "level": "shall", + "type": "tech_feature", + "status": "active", + "source": { + "repository": "IHE/DEV.PCIM", + "file": "asciidoc/IHE_DEV_Suppl_PCIM.adoc", + "line": 1197, + "sectionPath": [ + "Volume 2 -- Transactions", + "3.52 Report Association State [DEV-52]", + "3.52.2 Actor Roles" + ] + }, + "scope": { + "actors": [ + "dpam" + ], + "transactions": [ + "DEV-52" + ], + "options": [], + "useCases": [ + "uc1_associate_device_patient", + "uc2_disassociate_device_patient", + "uc3_filter_devices_for_patient" + ], + "messages": [ + "ORU_R01" + ], + "segments": [] + }, + "metadata": { + "pcim_req_level": "shall", + "pcim_req_type": "tech_feature", + "pcim_actor": "dpam", + "pcim_transaction": "DEV-52", + "pcim_message": "ORU_R01", + "pcim_use_case": "uc1_associate_device_patient,uc2_disassociate_device_patient,uc3_filter_devices_for_patient", + "pcim_verification_method": "test", + "pcim_verification_level": "connectathon" + }, + "normativeText": "The Device-Patient Association Manager shall send current associations for all\ndevices that the Consumer is configured to receive reports for immediately after\na connection is established.", + "verification": { + "method": "test", + "level": "connectathon", + "text": "Verify by establishing a Manager-to-Consumer connection and confirming that\ncurrent matching associations are sent as DEV-52 messages." + }, + "notes": [], + "rationale": [], + "related": [], + "examples": [] + }, + { + "id": "PCIMR0201", + "anchor": "pcimr0201", + "level": "shall", + "type": "tech_feature", + "status": "active", + "source": { + "repository": "IHE/DEV.PCIM", + "file": "asciidoc/IHE_DEV_Suppl_PCIM.adoc", + "line": 1214, + "sectionPath": [ + "Volume 2 -- Transactions", + "3.52 Report Association State [DEV-52]", + "3.52.2 Actor Roles" + ] + }, + "scope": { + "actors": [ + "dpac" + ], + "transactions": [ + "DEV-52" + ], + "options": [], + "useCases": [ + "uc1_associate_device_patient", + "uc2_disassociate_device_patient", + "uc4_correct_verified_association", + "uc5_wrong_association" + ], + "messages": [ + "ACK" + ], + "segments": [] + }, + "metadata": { + "pcim_req_level": "shall", + "pcim_req_type": "tech_feature", + "pcim_actor": "dpac", + "pcim_transaction": "DEV-52", + "pcim_message": "ACK", + "pcim_use_case": "uc1_associate_device_patient,uc2_disassociate_device_patient,uc4_correct_verified_association,uc5_wrong_association", + "pcim_verification_method": "test", + "pcim_verification_level": "connectathon" + }, + "normativeText": "When a DEV-52 association report is successfully received, the Device-Patient\nAssociation Consumer shall return a commit-level accept acknowledgement to the\nDevice-Patient Association Manager.", + "verification": { + "method": "test", + "level": "connectathon", + "text": "Verify by inspecting the acknowledgement returned by the Consumer after receipt\nof a valid DEV-52 message." + }, + "notes": [], + "rationale": [], + "related": [], + "examples": [] + }, + { + "id": "PCIMR0202", + "anchor": "pcimr0202", + "level": "shall", + "type": "tech_feature", + "status": "active", + "source": { + "repository": "IHE/DEV.PCIM", + "file": "asciidoc/IHE_DEV_Suppl_PCIM.adoc", + "line": 1255, + "sectionPath": [ + "Volume 2 -- Transactions", + "3.52 Report Association State [DEV-52]", + "3.52.4 Messages", + "3.52.4.1 Report Association State" + ] + }, + "scope": { + "actors": [ + "dpam" + ], + "transactions": [ + "DEV-52" + ], + "options": [], + "useCases": [ + "uc1_associate_device_patient", + "uc2_disassociate_device_patient", + "uc3_filter_devices_for_patient", + "uc4_correct_verified_association", + "uc5_wrong_association" + ], + "messages": [ + "ORU_R01" + ], + "segments": [] + }, + "metadata": { + "pcim_req_level": "shall", + "pcim_req_type": "tech_feature", + "pcim_actor": "dpam", + "pcim_transaction": "DEV-52", + "pcim_message": "ORU_R01", + "pcim_use_case": "uc1_associate_device_patient,uc2_disassociate_device_patient,uc3_filter_devices_for_patient,uc4_correct_verified_association,uc5_wrong_association", + "pcim_verification_method": "test", + "pcim_verification_level": "connectathon" + }, + "normativeText": "The Device-Patient Association Manager shall send DEV-52 messages to all\nconfigured Device-Patient Association Consumer instances with matching filter\ncriteria.", + "verification": { + "method": "test", + "level": "connectathon", + "text": "Verify by configuring one or more Consumers and confirming that each matching\nConsumer receives the applicable DEV-52 message." + }, + "notes": [], + "rationale": [], + "related": [], + "examples": [] + }, + { + "id": "PCIMR0203", + "anchor": "pcimr0203", + "level": "shall", + "type": "tech_feature", + "status": "active", + "source": { + "repository": "IHE/DEV.PCIM", + "file": "asciidoc/IHE_DEV_Suppl_PCIM.adoc", + "line": 1304, + "sectionPath": [ + "Volume 2 -- Transactions", + "3.52 Report Association State [DEV-52]", + "3.52.4 Messages", + "3.52.4.1 Report Association State", + "3.52.4.1.3 Correction Semantics" + ] + }, + "scope": { + "actors": [ + "dpam" + ], + "transactions": [ + "DEV-52" + ], + "options": [], + "useCases": [ + "uc4_correct_verified_association" + ], + "messages": [ + "ORU_R01" + ], + "segments": [] + }, + "metadata": { + "pcim_req_level": "shall", + "pcim_req_type": "tech_feature", + "pcim_actor": "dpam", + "pcim_transaction": "DEV-52", + "pcim_message": "ORU_R01", + "pcim_use_case": "uc4_correct_verified_association", + "pcim_verification_method": "test", + "pcim_verification_level": "connectathon" + }, + "normativeText": "The Device-Patient Association Manager shall send correction reports to\nDevice-Patient Association Consumers when the corrections are validated.", + "verification": { + "method": "test", + "level": "connectathon", + "text": "Verify by validating a correction at the Manager and confirming that the\ncorresponding DEV-52 correction report is sent to applicable Consumers." + }, + "notes": [], + "rationale": [], + "related": [], + "examples": [] + }, + { + "id": "PCIMR0204", + "anchor": "pcimr0204", + "level": "shall", + "type": "message_constraint", + "status": "active", + "source": { + "repository": "IHE/DEV.PCIM", + "file": "asciidoc/IHE_DEV_Suppl_PCIM.adoc", + "line": 1324, + "sectionPath": [ + "Volume 2 -- Transactions", + "3.52 Report Association State [DEV-52]", + "3.52.4 Messages", + "3.52.4.1 Report Association State", + "3.52.4.1.4 Wrong Semantics" + ] + }, + "scope": { + "actors": [ + "dpam" + ], + "transactions": [ + "DEV-52" + ], + "options": [], + "useCases": [ + "uc5_wrong_association" + ], + "messages": [ + "ORU_R01" + ], + "segments": [ + "OBR-29.2" + ] + }, + "metadata": { + "pcim_req_level": "shall", + "pcim_req_type": "message_constraint", + "pcim_actor": "dpam", + "pcim_transaction": "DEV-52", + "pcim_message": "ORU_R01", + "pcim_segment": "OBR-29.2", + "pcim_use_case": "uc5_wrong_association", + "pcim_verification_method": "test", + "pcim_verification_level": "connectathon" + }, + "normativeText": "DEV-52 messages reporting an existing device-patient association as wrong shall\nreference in OBR-29.2 the association unique instance identifier from OBR-3 of\nthe original association message.", + "verification": { + "method": "test", + "level": "connectathon", + "text": "Verify by inspecting OBR-29.2 in DEV-52 wrong-association messages and confirming\nit matches OBR-3 from the original association message." + }, + "notes": [], + "rationale": [], + "related": [], + "examples": [] + }, + { + "id": "PCIMR0205", + "anchor": "pcimr0205", + "level": "shall", + "type": "risk_mitigation", + "status": "active", + "source": { + "repository": "IHE/DEV.PCIM", + "file": "asciidoc/IHE_DEV_Suppl_PCIM.adoc", + "line": 1343, + "sectionPath": [ + "Volume 2 -- Transactions", + "3.52 Report Association State [DEV-52]", + "3.52.4 Messages", + "3.52.4.1 Report Association State", + "3.52.4.1.4 Wrong Semantics" + ] + }, + "scope": { + "actors": [ + "dpac" + ], + "transactions": [ + "DEV-52" + ], + "options": [], + "useCases": [ + "uc5_wrong_association" + ], + "messages": [], + "segments": [] + }, + "metadata": { + "pcim_req_level": "shall", + "pcim_req_type": "risk_mitigation", + "pcim_actor": "dpac", + "pcim_transaction": "DEV-52", + "pcim_use_case": "uc5_wrong_association", + "pcim_verification_method": "test", + "pcim_verification_level": "connectathon" + }, + "normativeText": "A Device-Patient Association Consumer that is also a device data reporter actor\nshall stop including the wrong patient identifier in outgoing messages as soon\nas it receives the wrong-association report.", + "verification": { + "method": "test", + "level": "connectathon", + "text": "Verify by sending a DEV-52 wrong-association report to the Consumer and\nconfirming subsequent outgoing device data messages no longer include the wrong\npatient identifier." + }, + "notes": [], + "rationale": [], + "related": [], + "examples": [] + }, + { + "id": "PCIMR0300", + "anchor": "pcimr0300", + "level": "shall", + "type": "message_constraint", + "status": "active", + "source": { + "repository": "IHE/DEV.PCIM", + "file": "asciidoc/IHE_DEV_Suppl_PCIM.adoc", + "line": 1373, + "sectionPath": [ + "Volume 2 -- Transactions", + "3.19 Filter Associations [DEV-19]", + "3.19.1 Scope" + ] + }, + "scope": { + "actors": [ + "dpam" + ], + "transactions": [ + "DEV-19" + ], + "options": [ + "subscription_filtering" + ], + "useCases": [ + "uc3_filter_devices_for_patient" + ], + "messages": [ + "ACK" + ], + "segments": [ + "MSA-1" + ] + }, + "metadata": { + "pcim_req_level": "shall", + "pcim_req_type": "message_constraint", + "pcim_actor": "dpam", + "pcim_transaction": "DEV-19", + "pcim_message": "ACK", + "pcim_segment": "MSA-1", + "pcim_option": "subscription_filtering", + "pcim_use_case": "uc3_filter_devices_for_patient", + "pcim_verification_method": "test", + "pcim_verification_level": "connectathon" + }, + "normativeText": "When a DEV-19 message is accepted by the Device-Patient Association Manager, the\naccept acknowledgement shall contain the value `CA` in MSA-1.", + "verification": { + "method": "test", + "level": "connectathon", + "text": "Verify by inspecting MSA-1 in the acknowledgement returned by the Manager for an\naccepted DEV-19 message." + }, + "notes": [], + "rationale": [], + "related": [], + "examples": [] + }, + { + "id": "PCIMR0301", + "anchor": "pcimr0301", + "level": "shall", + "type": "message_constraint", + "status": "active", + "source": { + "repository": "IHE/DEV.PCIM", + "file": "asciidoc/IHE_DEV_Suppl_PCIM.adoc", + "line": 1391, + "sectionPath": [ + "Volume 2 -- Transactions", + "3.19 Filter Associations [DEV-19]", + "3.19.1 Scope" + ] + }, + "scope": { + "actors": [ + "dpam" + ], + "transactions": [ + "DEV-19" + ], + "options": [ + "subscription_filtering" + ], + "useCases": [ + "uc3_filter_devices_for_patient" + ], + "messages": [ + "ACK" + ], + "segments": [ + "MSA-1", + "ERR-3", + "ERR-4" + ] + }, + "metadata": { + "pcim_req_level": "shall", + "pcim_req_type": "message_constraint", + "pcim_actor": "dpam", + "pcim_transaction": "DEV-19", + "pcim_message": "ACK", + "pcim_segment": "MSA-1,ERR-3,ERR-4", + "pcim_option": "subscription_filtering", + "pcim_use_case": "uc3_filter_devices_for_patient", + "pcim_verification_method": "test", + "pcim_verification_level": "connectathon" + }, + "normativeText": "When DEV-19 is not supported, the Device-Patient Association Manager shall return\nan acknowledgement with `CR` in MSA-1, `200` in ERR-3, and `E` in ERR-4.", + "verification": { + "method": "test", + "level": "connectathon", + "text": "Verify by sending a DEV-19 message to a Manager that does not support DEV-19 and\ninspecting the returned acknowledgement." + }, + "notes": [], + "rationale": [], + "related": [], + "examples": [] + }, + { + "id": "PCIMR0302", + "anchor": "pcimr0302", + "level": "shall", + "type": "tech_feature", + "status": "active", + "source": { + "repository": "IHE/DEV.PCIM", + "file": "asciidoc/IHE_DEV_Suppl_PCIM.adoc", + "line": 1407, + "sectionPath": [ + "Volume 2 -- Transactions", + "3.19 Filter Associations [DEV-19]", + "3.19.1 Scope" + ] + }, + "scope": { + "actors": [ + "dpam" + ], + "transactions": [ + "DEV-19", + "DEV-52" + ], + "options": [], + "useCases": [ + "uc3_filter_devices_for_patient" + ], + "messages": [ + "ORU_R01" + ], + "segments": [] + }, + "metadata": { + "pcim_req_level": "shall", + "pcim_req_type": "tech_feature", + "pcim_actor": "dpam", + "pcim_transaction": "DEV-19,DEV-52", + "pcim_message": "ORU_R01", + "pcim_use_case": "uc3_filter_devices_for_patient", + "pcim_verification_method": "test", + "pcim_verification_level": "connectathon" + }, + "normativeText": "If DEV-19 is not supported and network connectivity between the Device-Patient\nAssociation Manager and Device-Patient Association Consumer is restored after a\nloss of connection, the Manager shall send DEV-52 messages for all current\ndevice-patient associations to the Consumer.", + "verification": { + "method": "test", + "level": "connectathon", + "text": "Verify by restoring a lost Manager-to-Consumer connection when DEV-19 is not\nsupported and confirming that current associations are sent as DEV-52 messages." + }, + "notes": [], + "rationale": [], + "related": [], + "examples": [] + }, + { + "id": "PCIMR0303", + "anchor": "pcimr0303", + "level": "shall", + "type": "message_constraint", + "status": "active", + "source": { + "repository": "IHE/DEV.PCIM", + "file": "asciidoc/IHE_DEV_Suppl_PCIM.adoc", + "line": 2460, + "sectionPath": [ + "Appendix A -- Proposed Messages", + "A.2 Filter Associations Message", + "A.2.3 Details of Device-Patient Association Query Message [DEV-19]", + "A.2.3.2 QPD Segment" + ] + }, + "scope": { + "actors": [ + "dpac" + ], + "transactions": [ + "DEV-19" + ], + "options": [ + "subscription_filtering" + ], + "useCases": [ + "uc3_filter_devices_for_patient" + ], + "messages": [ + "QSB_Q16" + ], + "segments": [ + "QPD-2" + ] + }, + "metadata": { + "pcim_req_level": "shall", + "pcim_req_type": "message_constraint", + "pcim_actor": "dpac", + "pcim_transaction": "DEV-19", + "pcim_message": "QSB_Q16", + "pcim_segment": "QPD-2", + "pcim_option": "subscription_filtering", + "pcim_use_case": "uc3_filter_devices_for_patient", + "pcim_verification_method": "test", + "pcim_verification_level": "connectathon" + }, + "normativeText": "The QueryTag in QPD.2 shall be unique for each DEV-19 query.", + "verification": { + "method": "test", + "level": "connectathon", + "text": "Verify by inspecting QPD.2 values in DEV-19 queries originated by the Consumer." + }, + "notes": [], + "rationale": [], + "related": [], + "examples": [] + }, + { + "id": "PCIMR0304", + "anchor": "pcimr0304", + "level": "shall", + "type": "message_constraint", + "status": "active", + "source": { + "repository": "IHE/DEV.PCIM", + "file": "asciidoc/IHE_DEV_Suppl_PCIM.adoc", + "line": 2478, + "sectionPath": [ + "Appendix A -- Proposed Messages", + "A.2 Filter Associations Message", + "A.2.3 Details of Device-Patient Association Query Message [DEV-19]", + "A.2.3.2 QPD Segment" + ] + }, + "scope": { + "actors": [ + "dpac" + ], + "transactions": [ + "DEV-19" + ], + "options": [ + "subscription_filtering" + ], + "useCases": [ + "uc3_filter_devices_for_patient" + ], + "messages": [ + "QSB_Q16" + ], + "segments": [ + "QSC-4" + ] + }, + "metadata": { + "pcim_req_level": "shall", + "pcim_req_type": "message_constraint", + "pcim_actor": "dpac", + "pcim_transaction": "DEV-19", + "pcim_message": "QSB_Q16", + "pcim_segment": "QSC-4", + "pcim_option": "subscription_filtering", + "pcim_use_case": "uc3_filter_devices_for_patient", + "pcim_verification_method": "test", + "pcim_verification_level": "connectathon" + }, + "normativeText": "If multiple DEV-19 query parameter specifications are present, QSC.4 shall\nspecify the relational conjunction except for the last specification.", + "verification": { + "method": "test", + "level": "connectathon", + "text": "Verify by inspecting QSC.4 values in DEV-19 queries that contain multiple query\nparameter specifications." + }, + "notes": [], + "rationale": [], + "related": [], + "examples": [] + }, + { + "id": "PCIMR0305", + "anchor": "pcimr0305", + "level": "shall", + "type": "tech_feature", + "status": "active", + "source": { + "repository": "IHE/DEV.PCIM", + "file": "asciidoc/IHE_DEV_Suppl_PCIM.adoc", + "line": 2542, + "sectionPath": [ + "Appendix A -- Proposed Messages", + "A.2 Filter Associations Message", + "A.2.4 RCP Segment" + ] + }, + "scope": { + "actors": [ + "dpac" + ], + "transactions": [ + "DEV-19" + ], + "options": [ + "subscription_filtering" + ], + "useCases": [ + "uc3_filter_devices_for_patient" + ], + "messages": [], + "segments": [] + }, + "metadata": { + "pcim_req_level": "shall", + "pcim_req_type": "tech_feature", + "pcim_actor": "dpac", + "pcim_transaction": "DEV-19", + "pcim_option": "subscription_filtering", + "pcim_use_case": "uc3_filter_devices_for_patient", + "pcim_verification_method": "test", + "pcim_verification_level": "connectathon" + }, + "normativeText": "A Device-Patient Association Consumer that uses DEV-19 shall support receiving a\ncontinuous real-time feed of association events and shall receive existing\nassociations matching the filter specification when the connection is first\nestablished.", + "verification": { + "method": "test", + "level": "connectathon", + "text": "Verify by establishing a filtered subscription and confirming that the Consumer\nreceives both the initial matching association state and subsequent real-time\nupdates." + }, + "notes": [], + "rationale": [], + "related": [], + "examples": [] + }, + { + "id": "PCIMR0400", + "anchor": "pcimr0400", + "level": "shall", + "type": "message_constraint", + "status": "active", + "source": { + "repository": "IHE/DEV.PCIM", + "file": "asciidoc/IHE_DEV_Suppl_PCIM.adoc", + "line": 1632, + "sectionPath": [ + "Appendix A -- Proposed Messages", + "A.1 Communicate and Report Association State", + "A.1.1 Message Structure" + ] + }, + "scope": { + "actors": [ + "dpar", + "dpam" + ], + "transactions": [ + "DEV-51", + "DEV-52" + ], + "options": [], + "useCases": [], + "messages": [ + "ORU_R01" + ], + "segments": [ + "MSH-21" + ] + }, + "metadata": { + "pcim_req_level": "shall", + "pcim_req_type": "message_constraint", + "pcim_actor": "dpar,dpam", + "pcim_transaction": "DEV-51,DEV-52", + "pcim_message": "ORU_R01", + "pcim_segment": "MSH-21", + "pcim_verification_method": "test", + "pcim_verification_level": "connectathon" + }, + "normativeText": "DEV-51 and DEV-52 messages shall value MSH-21 with the appropriate PCIM message\nprofile identifier for the transaction.", + "verification": { + "method": "test", + "level": "connectathon", + "text": "Verify by inspecting MSH-21 in DEV-51 and DEV-52 ORU_R01 messages." + }, + "notes": [], + "rationale": [], + "related": [], + "examples": [] + }, + { + "id": "PCIMR0401", + "anchor": "pcimr0401", + "level": "shall", + "type": "message_constraint", + "status": "active", + "source": { + "repository": "IHE/DEV.PCIM", + "file": "asciidoc/IHE_DEV_Suppl_PCIM.adoc", + "line": 1647, + "sectionPath": [ + "Appendix A -- Proposed Messages", + "A.1 Communicate and Report Association State", + "A.1.1 Message Structure" + ] + }, + "scope": { + "actors": [ + "dpar", + "dpam" + ], + "transactions": [ + "DEV-51", + "DEV-52" + ], + "options": [], + "useCases": [], + "messages": [ + "ORU_R01" + ], + "segments": [] + }, + "metadata": { + "pcim_req_level": "shall", + "pcim_req_type": "message_constraint", + "pcim_actor": "dpar,dpam", + "pcim_transaction": "DEV-51,DEV-52", + "pcim_message": "ORU_R01", + "pcim_verification_method": "test", + "pcim_verification_level": "connectathon" + }, + "normativeText": "DEV-51 and DEV-52 messages shall be constrained to reporting associations for a\nsingle patient and device.", + "verification": { + "method": "test", + "level": "connectathon", + "text": "Verify by inspecting each DEV-51 or DEV-52 ORU_R01 message and confirming that it\nreports only one patient-device association." + }, + "notes": [], + "rationale": [], + "related": [], + "examples": [] + }, + { + "id": "PCIMR0402", + "anchor": "pcimr0402", + "level": "shall", + "type": "message_constraint", + "status": "active", + "source": { + "repository": "IHE/DEV.PCIM", + "file": "asciidoc/IHE_DEV_Suppl_PCIM.adoc", + "line": 1691, + "sectionPath": [ + "Appendix A -- Proposed Messages", + "A.1 Communicate and Report Association State", + "A.1.2 Segments", + "A.1.2.1 MSH -- Message Header" + ] + }, + "scope": { + "actors": [ + "dpar", + "dpam" + ], + "transactions": [ + "DEV-51", + "DEV-52" + ], + "options": [], + "useCases": [], + "messages": [ + "ORU_R01" + ], + "segments": [ + "MSH-15" + ] + }, + "metadata": { + "pcim_req_level": "shall", + "pcim_req_type": "message_constraint", + "pcim_actor": "dpar,dpam", + "pcim_transaction": "DEV-51,DEV-52", + "pcim_message": "ORU_R01", + "pcim_segment": "MSH-15", + "pcim_verification_method": "test", + "pcim_verification_level": "connectathon" + }, + "normativeText": "MSH-15 in DEV-51 and DEV-52 messages shall be set to `AL`.", + "verification": { + "method": "test", + "level": "connectathon", + "text": "Verify by inspecting MSH-15 in DEV-51 and DEV-52 ORU_R01 messages." + }, + "notes": [], + "rationale": [], + "related": [], + "examples": [] + }, + { + "id": "PCIMR0403", + "anchor": "pcimr0403", + "level": "shall", + "type": "message_constraint", + "status": "active", + "source": { + "repository": "IHE/DEV.PCIM", + "file": "asciidoc/IHE_DEV_Suppl_PCIM.adoc", + "line": 1713, + "sectionPath": [ + "Appendix A -- Proposed Messages", + "A.1 Communicate and Report Association State", + "A.1.2 Segments", + "A.1.2.2 PID -- Patient Identification" + ] + }, + "scope": { + "actors": [ + "dpar", + "dpam" + ], + "transactions": [ + "DEV-51", + "DEV-52" + ], + "options": [], + "useCases": [], + "messages": [ + "ORU_R01" + ], + "segments": [ + "PID" + ] + }, + "metadata": { + "pcim_req_level": "shall", + "pcim_req_type": "message_constraint", + "pcim_actor": "dpar,dpam", + "pcim_transaction": "DEV-51,DEV-52", + "pcim_message": "ORU_R01", + "pcim_segment": "PID", + "pcim_verification_method": "test", + "pcim_verification_level": "connectathon" + }, + "normativeText": "DEV-51 and DEV-52 messages shall include a PID segment to identify the patient\nassociated with the device.", + "verification": { + "method": "test", + "level": "connectathon", + "text": "Verify by inspecting DEV-51 and DEV-52 ORU_R01 messages and confirming the PID\nsegment is present." + }, + "notes": [], + "rationale": [], + "related": [], + "examples": [] + }, + { + "id": "PCIMR0404", + "anchor": "pcimr0404", + "level": "shall", + "type": "message_constraint", + "status": "active", + "source": { + "repository": "IHE/DEV.PCIM", + "file": "asciidoc/IHE_DEV_Suppl_PCIM.adoc", + "line": 1729, + "sectionPath": [ + "Appendix A -- Proposed Messages", + "A.1 Communicate and Report Association State", + "A.1.2 Segments", + "A.1.2.2 PID -- Patient Identification" + ] + }, + "scope": { + "actors": [ + "dpar", + "dpam" + ], + "transactions": [ + "DEV-51", + "DEV-52" + ], + "options": [], + "useCases": [], + "messages": [ + "ORU_R01" + ], + "segments": [ + "PID-3" + ] + }, + "metadata": { + "pcim_req_level": "shall", + "pcim_req_type": "message_constraint", + "pcim_actor": "dpar,dpam", + "pcim_transaction": "DEV-51,DEV-52", + "pcim_message": "ORU_R01", + "pcim_segment": "PID-3", + "pcim_verification_method": "test", + "pcim_verification_level": "connectathon" + }, + "normativeText": "The Patient Identifier List in PID-3 shall contain an identifier that is unique\nfor all patients within the scope of the system.", + "verification": { + "method": "test", + "level": "connectathon", + "text": "Verify by inspecting PID-3 in DEV-51 and DEV-52 ORU_R01 messages." + }, + "notes": [], + "rationale": [], + "related": [], + "examples": [] + }, + { + "id": "PCIMR0405", + "anchor": "pcimr0405", + "level": "shall", + "type": "message_constraint", + "status": "active", + "source": { + "repository": "IHE/DEV.PCIM", + "file": "asciidoc/IHE_DEV_Suppl_PCIM.adoc", + "line": 1792, + "sectionPath": [ + "Appendix A -- Proposed Messages", + "A.1 Communicate and Report Association State", + "A.1.2 Segments", + "A.1.2.4 OBR -- Observation Request" + ] + }, + "scope": { + "actors": [ + "dpar", + "dpam" + ], + "transactions": [ + "DEV-51", + "DEV-52" + ], + "options": [], + "useCases": [], + "messages": [ + "ORU_R01" + ], + "segments": [ + "OBR-3" + ] + }, + "metadata": { + "pcim_req_level": "shall", + "pcim_req_type": "message_constraint", + "pcim_actor": "dpar,dpam", + "pcim_transaction": "DEV-51,DEV-52", + "pcim_message": "ORU_R01", + "pcim_segment": "OBR-3", + "pcim_verification_method": "test", + "pcim_verification_level": "connectathon" + }, + "normativeText": "OBR-3 in DEV-51 and DEV-52 messages shall contain a unique association event\ninstance identifier generated so that duplicate identifiers between sources are\nnot possible.", + "verification": { + "method": "test", + "level": "connectathon", + "text": "Verify by inspecting OBR-3 values in DEV-51 and DEV-52 ORU_R01 messages and\nconfirming uniqueness across message sources." + }, + "notes": [], + "rationale": [], + "related": [], + "examples": [] + }, + { + "id": "PCIMR0406", + "anchor": "pcimr0406", + "level": "shall", + "type": "message_constraint", + "status": "active", + "source": { + "repository": "IHE/DEV.PCIM", + "file": "asciidoc/IHE_DEV_Suppl_PCIM.adoc", + "line": 1851, + "sectionPath": [ + "Appendix A -- Proposed Messages", + "A.1 Communicate and Report Association State", + "A.1.2 Segments", + "A.1.2.4 OBR -- Observation Request" + ] + }, + "scope": { + "actors": [ + "dpar", + "dpam" + ], + "transactions": [ + "DEV-51", + "DEV-52" + ], + "options": [], + "useCases": [], + "messages": [ + "ORU_R01" + ], + "segments": [ + "OBR-7", + "OBR-8" + ] + }, + "metadata": { + "pcim_req_level": "shall", + "pcim_req_type": "message_constraint", + "pcim_actor": "dpar,dpam", + "pcim_transaction": "DEV-51,DEV-52", + "pcim_message": "ORU_R01", + "pcim_segment": "OBR-7,OBR-8", + "pcim_verification_method": "test", + "pcim_verification_level": "connectathon" + }, + "normativeText": "DEV-51 and DEV-52 association or disassociation event reports shall include in\nOBR-7 the earliest participant involvement timestamp and in OBR-8 the latest\nparticipant involvement timestamp.", + "verification": { + "method": "test", + "level": "connectathon", + "text": "Verify by comparing OBR-7 and OBR-8 with PRT-11 and PRT-12 timestamps in the\nsame DEV-51 or DEV-52 message." + }, + "notes": [], + "rationale": [], + "related": [], + "examples": [] + } + ] +} diff --git a/.ci/asciidoc-converter/scripts/extract_pcim_requirements.py b/.ci/asciidoc-converter/scripts/extract_pcim_requirements.py new file mode 100644 index 0000000..0d6d396 --- /dev/null +++ b/.ci/asciidoc-converter/scripts/extract_pcim_requirements.py @@ -0,0 +1,342 @@ +#!/usr/bin/env python3 +"""Extract PCIM semantic requirement blocks from AsciiDoc into JSON.""" + +import argparse +import json +import re +import subprocess +import sys +from pathlib import Path + + +TITLE_RE = re.compile(r"^\.(PCIMR\d{4})\s*$") +ATTR_RE = re.compile(r"^\[pcim_requirement#(pcimr\d{4})(?P.*)\]\s*$") +SECTION_RE = re.compile(r"^(=+)\s+(.+?)\s*$") +CONTENT_TAG_RE = re.compile( + r"^\[(NORMATIVE|VERIFICATION|NOTE|RATIONALE|RELATED|EXAMPLE)\]\s*$" +) + +LIST_METADATA = { + "pcim_actor", + "pcim_transaction", + "pcim_option", + "pcim_use_case", + "pcim_message", + "pcim_segment", +} + + +def git_value(args, cwd): + try: + return subprocess.check_output( + ["git", *args], cwd=cwd, text=True, stderr=subprocess.DEVNULL + ).strip() + except Exception: + return None + + +def split_attrs(attr_text): + if attr_text.startswith(","): + attr_text = attr_text[1:] + + parts = [] + current = [] + quote = None + escape = False + + for char in attr_text: + if escape: + current.append(char) + escape = False + continue + if char == "\\": + current.append(char) + escape = True + continue + if quote: + current.append(char) + if char == quote: + quote = None + continue + if char in ("'", '"'): + current.append(char) + quote = char + continue + if char == ",": + part = "".join(current).strip() + if part: + parts.append(part) + current = [] + continue + current.append(char) + + part = "".join(current).strip() + if part: + parts.append(part) + + attrs = {} + for part in parts: + if "=" not in part: + attrs[part] = True + continue + key, value = part.split("=", 1) + value = value.strip() + if len(value) >= 2 and value[0] == value[-1] and value[0] in ("'", '"'): + value = value[1:-1] + attrs[key.strip()] = value + return attrs + + +def as_list(metadata, key): + value = metadata.get(key) + if value is None or value is True: + return [] + return [item.strip() for item in str(value).split(",") if item.strip()] + + +def normalize_text(lines): + return "\n".join(line.rstrip() for line in lines).strip() + + +def parse_content_blocks(lines, start, end, errors): + blocks = {} + i = start + while i < end: + tag_match = CONTENT_TAG_RE.match(lines[i]) + if not tag_match: + i += 1 + continue + + tag = tag_match.group(1).lower() + fence_line = i + 1 + if fence_line >= end or lines[fence_line].strip() != "====": + errors.append(f"line {i + 1}: [{tag.upper()}] must be followed by ====") + i += 1 + continue + + content_start = fence_line + 1 + content_end = content_start + while content_end < end and lines[content_end].strip() != "====": + content_end += 1 + + if content_end >= end: + errors.append(f"line {i + 1}: [{tag.upper()}] block is not closed") + break + + blocks.setdefault(tag, []).append(normalize_text(lines[content_start:content_end])) + i = content_end + 1 + return blocks + + +def parse_requirements(source_path, repo_root): + lines = source_path.read_text(encoding="utf-8").splitlines() + requirements = [] + errors = [] + section_stack = [] + seen = {} + i = 0 + + while i < len(lines): + section_match = SECTION_RE.match(lines[i]) + if section_match: + level = len(section_match.group(1)) + title = section_match.group(2).strip() + section_stack = section_stack[: level - 1] + section_stack.append({"level": level, "title": title, "line": i + 1}) + + title_match = TITLE_RE.match(lines[i]) + if not title_match: + i += 1 + continue + + req_id = title_match.group(1) + attr_line = i + 1 + if attr_line >= len(lines): + errors.append(f"line {i + 1}: requirement title has no attribute line") + i += 1 + continue + + attr_match = ATTR_RE.match(lines[attr_line]) + if not attr_match: + errors.append(f"line {i + 1}: requirement title is not followed by pcim_requirement block") + i += 1 + continue + + anchor = attr_match.group(1) + expected_anchor = req_id.lower() + if anchor != expected_anchor: + errors.append( + f"line {attr_line + 1}: anchor {anchor} does not match {expected_anchor}" + ) + + metadata = split_attrs(attr_match.group("attrs")) + level = metadata.get("pcim_req_level") + req_type = metadata.get("pcim_req_type") + if level not in {"shall", "should", "may"}: + errors.append(f"line {attr_line + 1}: pcim_req_level is required") + if not req_type: + errors.append(f"line {attr_line + 1}: pcim_req_type is required") + + block_start = attr_line + 1 + while block_start < len(lines) and not lines[block_start].strip(): + block_start += 1 + if block_start >= len(lines) or lines[block_start].strip() != "****": + errors.append(f"line {attr_line + 1}: pcim_requirement block must start with ****") + i += 1 + continue + + block_end = block_start + 1 + while block_end < len(lines) and lines[block_end].strip() != "****": + block_end += 1 + if block_end >= len(lines): + errors.append(f"line {block_start + 1}: pcim_requirement block is not closed") + i += 1 + continue + + content = parse_content_blocks(lines, block_start + 1, block_end, errors) + normative = content.get("normative", []) + if len(normative) != 1: + errors.append(f"line {i + 1}: requirement must contain exactly one [NORMATIVE] block") + + if req_id in seen: + errors.append(f"line {i + 1}: duplicate requirement id {req_id}") + seen[req_id] = i + 1 + + rel_source = str(source_path.relative_to(repo_root)) + requirement = { + "id": req_id, + "anchor": anchor, + "level": level, + "type": req_type, + "status": metadata.get("pcim_req_status", "active"), + "source": { + "repository": "IHE/DEV.PCIM", + "file": rel_source, + "line": i + 1, + "sectionPath": [section["title"] for section in section_stack], + }, + "scope": { + "actors": as_list(metadata, "pcim_actor"), + "transactions": as_list(metadata, "pcim_transaction"), + "options": as_list(metadata, "pcim_option"), + "useCases": as_list(metadata, "pcim_use_case"), + "messages": as_list(metadata, "pcim_message"), + "segments": as_list(metadata, "pcim_segment"), + }, + "metadata": metadata, + "normativeText": normative[0] if normative else "", + "verification": { + "method": metadata.get("pcim_verification_method"), + "level": metadata.get("pcim_verification_level"), + "text": "\n\n".join(content.get("verification", [])), + }, + "notes": content.get("note", []), + "rationale": content.get("rationale", []), + "related": content.get("related", []), + "examples": content.get("example", []), + } + requirements.append(requirement) + i = block_end + 1 + + return requirements, errors + + +def read_doc_attrs(source_path): + attrs = {} + for line in source_path.read_text(encoding="utf-8").splitlines(): + if line.startswith(":revnumber:"): + attrs["revnumber"] = line.split(":", 2)[2].strip() + elif line.startswith("Date:"): + attrs["date"] = line.split(":", 1)[1].strip() + return attrs + + +def write_json(path, data): + path.parent.mkdir(parents=True, exist_ok=True) + path.write_text(json.dumps(data, indent=2, sort_keys=False) + "\n", encoding="utf-8") + + +def main(): + parser = argparse.ArgumentParser() + parser.add_argument("--source", required=True) + parser.add_argument("--output") + parser.add_argument("--trace-output") + parser.add_argument( + "--check-only", + action="store_true", + help="Validate requirement blocks without writing JSON artifacts.", + ) + parser.add_argument( + "--omit-commit", + action="store_true", + help="Write null for the source commit to keep generated review fixtures stable.", + ) + args = parser.parse_args() + + if not args.check_only and not args.output: + parser.error("--output is required unless --check-only is used") + + repo_root = Path.cwd().resolve() + source_path = (repo_root / args.source).resolve() + output_path = (repo_root / args.output).resolve() if args.output else None + trace_path = (repo_root / args.trace_output).resolve() if args.trace_output else None + + requirements, errors = parse_requirements(source_path, repo_root) + if errors: + for error in errors: + print(error, file=sys.stderr) + return 1 + requirements.sort(key=lambda requirement: requirement["id"]) + + if args.check_only: + print(f"Validated {len(requirements)} PCIM requirement identifiers") + return 0 + + doc_attrs = read_doc_attrs(source_path) + commit = None if args.omit_commit else git_value(["rev-parse", "HEAD"], repo_root) + + artifact = { + "$schema": "https://profiles.ihe.net/DEV/PCIM/schemas/pcim-requirements.schema.json", + "artifactType": "pcim-requirements", + "profile": "PCIM", + "source": { + "repository": "IHE/DEV.PCIM", + "file": str(source_path.relative_to(repo_root)), + "commit": commit, + "revision": doc_attrs.get("revnumber"), + "publicationDate": doc_attrs.get("date"), + }, + "count": len(requirements), + "requirements": requirements, + } + write_json(output_path, artifact) + + if trace_path: + trace = { + "$schema": "https://profiles.ihe.net/DEV/PCIM/schemas/pcim-requirement-trace.schema.json", + "artifactType": "pcim-requirement-trace", + "profile": "PCIM", + "source": artifact["source"], + "count": len(requirements), + "requirements": [ + { + "id": requirement["id"], + "level": requirement["level"], + "type": requirement["type"], + "source": requirement["source"], + "scope": requirement["scope"], + "verification": requirement["verification"], + } + for requirement in requirements + ], + } + write_json(trace_path, trace) + + print(f"Extracted {len(requirements)} PCIM requirements to {output_path}") + if trace_path: + print(f"Wrote PCIM requirement trace to {trace_path}") + return 0 + + +if __name__ == "__main__": + sys.exit(main()) diff --git a/asciidoc/IHE_DEV_Suppl_PCIM.adoc b/asciidoc/IHE_DEV_Suppl_PCIM.adoc index 8250fc3..d894b71 100644 --- a/asciidoc/IHE_DEV_Suppl_PCIM.adoc +++ b/asciidoc/IHE_DEV_Suppl_PCIM.adoc @@ -309,6 +309,22 @@ Actors which have a required grouping are shown in conjoined boxes (see Section Table 7.1-1 lists the transactions for each actor directly involved in the PCIM Profile. To claim compliance with this profile, an actor shall support all required transactions (labeled "`R`") and may support the optional transactions (labeled "`O`"). +.PCIMR0001 +[pcim_requirement#pcimr0001,pcim_req_level=shall,pcim_req_type=ihe_profile,pcim_actor="dpar,dpam,dpac",pcim_verification_method=inspection,pcim_verification_level=connectathon] +**** +[NORMATIVE] +==== +To claim compliance with the PCIM Profile, an actor shall support every +transaction listed as required for that actor in Table 7.1-1. +==== + +[VERIFICATION] +==== +Verify by inspecting the implementation conformance claim for the PCIM actor and +confirming support for all required transactions in Table 7.1-1. +==== +**** + **Table 7.1-1: PCIM Profile - Actors and Transactions** |=== @@ -357,10 +373,75 @@ This section documents any additional requirements on profile's actors. The Device-Patient Association Reporter actor asserts that a given device is associated or disassociated with a specific patient. The reporter may update existing associations. For each such event, the unique Patient ID, Device ID, and timestamp of the beginning of association or end of association shall be reported. If a location is known, it should be included in the report. Each report represents a single device patient association assertion. If the report is validated, the report observation status field shall be marked final, otherwise it shall be marked as requiring validation. +.PCIMR0002 +[pcim_requirement#pcimr0002,pcim_req_level=shall,pcim_req_type=ihe_profile,pcim_actor=dpar,pcim_transaction=DEV-51,pcim_message=ORU_R01,pcim_segment="PID,PRT,OBR-7,OBR-8",pcim_use_case="uc1_associate_device_patient,uc2_disassociate_device_patient",pcim_verification_method=test,pcim_verification_level=connectathon] +**** +[NORMATIVE] +==== +The Device-Patient Association Reporter shall report the patient identifier, +device identifier, and beginning or ending timestamp for each association or +disassociation event that it asserts. +==== + +[VERIFICATION] +==== +Verify by inspecting DEV-51 messages originated by the Device-Patient Association +Reporter and confirming that the patient, device, and timestamp content is present. +==== +**** + +.PCIMR0003 +[pcim_requirement#pcimr0003,pcim_req_level=shall,pcim_req_type=ihe_profile,pcim_actor=dpar,pcim_transaction=DEV-51,pcim_message=ORU_R01,pcim_segment=OBX-11,pcim_use_case="uc1_associate_device_patient,uc2_disassociate_device_patient",pcim_verification_method=test,pcim_verification_level=connectathon] +**** +[NORMATIVE] +==== +The Device-Patient Association Reporter shall mark validated reports as final +and shall mark non-validated reports as requiring validation. +==== + +[VERIFICATION] +==== +Verify by inspecting OBX-11 in DEV-51 messages originated by the Device-Patient +Association Reporter. +==== +**** + ==== 7.1.1.2 Device-Patient Association Manager The Device-Patient Association Manager actor collects and persists information on devices currently associated with patients within a defined scope, such as a clinical unit and shall communicate validated associations as event notifications. The system is responsible for resolving conflicts and shall provide an HMI for validating association assertions that require validation and resolving conflicts. +.PCIMR0004 +[pcim_requirement#pcimr0004,pcim_req_level=shall,pcim_req_type=ihe_profile,pcim_actor=dpam,pcim_transaction=DEV-52,pcim_message=ORU_R01,pcim_use_case="uc1_associate_device_patient,uc2_disassociate_device_patient,uc4_correct_verified_association,uc5_wrong_association",pcim_verification_method=test,pcim_verification_level=connectathon] +**** +[NORMATIVE] +==== +The Device-Patient Association Manager shall communicate validated +device-patient associations as event notifications. +==== + +[VERIFICATION] +==== +Verify by inspecting DEV-52 messages originated by the Device-Patient Association +Manager after association validation. +==== +**** + +.PCIMR0005 +[pcim_requirement#pcimr0005,pcim_req_level=shall,pcim_req_type=ihe_profile,pcim_actor=dpam,pcim_use_case="uc1_associate_device_patient,uc2_disassociate_device_patient,uc4_correct_verified_association,uc5_wrong_association",pcim_verification_method=demonstration,pcim_verification_level=connectathon] +**** +[NORMATIVE] +==== +The Device-Patient Association Manager shall provide an HMI for validating +association assertions that require validation and for resolving conflicts. +==== + +[VERIFICATION] +==== +Verify by inspection or demonstration of the Device-Patient Association Manager +validation and conflict-resolution HMI. +==== +**** + ==== 7.1.1.3 Device-Patient Association Consumer The Device-Patient Association Consumer actor receives information on what devices are associated with which patients. The actor initially receives current association status followed by updates in real-time. Common examples are a medical device or critical care system that charts device observations for a patient. The actor receives association updates in real-time. @@ -402,6 +483,39 @@ The subscription and filtering option applies to interactions between Device-Pat [.text-left] A Device-Patient Association Consumer that supports this option shall formulate its request in the form described in Section 3.19. +.PCIMR0006 +[pcim_requirement#pcimr0006,pcim_req_level=shall,pcim_req_type=ihe_profile,pcim_actor=dpac,pcim_transaction=DEV-19,pcim_option=subscription_filtering,pcim_message=QSB_Q16,pcim_use_case=uc3_filter_devices_for_patient,pcim_verification_method=test,pcim_verification_level=connectathon] +**** +[NORMATIVE] +==== +A Device-Patient Association Consumer that supports the Subscription and +Filtering Option shall formulate its filtering request as specified in Section +3.19. +==== + +[VERIFICATION] +==== +Verify by inspecting DEV-19 messages originated by a Device-Patient Association +Consumer that claims the Subscription and Filtering Option. +==== +**** + +.PCIMR0007 +[pcim_requirement#pcimr0007,pcim_req_level=may,pcim_req_type=ihe_profile,pcim_actor=dpam,pcim_transaction=DEV-19,pcim_option=subscription_filtering,pcim_message=QSB_Q16,pcim_use_case=uc3_filter_devices_for_patient,pcim_verification_method=test,pcim_verification_level=connectathon] +**** +[NORMATIVE] +==== +The Device-Patient Association Manager may support the Subscription and +Filtering Option. +==== + +[VERIFICATION] +==== +Verify by inspecting the implementation conformance claim for the Device-Patient +Association Manager and, when the option is claimed, by executing DEV-19 tests. +==== +**** + == 7.3 PCIM Required Actor Groupings There are no required actor groupings specified in the Point-of-Care Identity Management (PCIM) Profile. @@ -583,7 +697,205 @@ An actor that supports retrospective queries was considered. For the use cases o = Appendices to Volume 1 -None +== Appendix A -- PCIM Requirements Modeling and Markup + +This appendix defines the semantic AsciiDoc conventions used to identify PCIM +requirements for traceability, extraction, and conformance assessment tooling. +The conventions are based on the IHE DEV SDPi semantic AsciiDoc approach, using +PCIM-specific element names and identifiers. + +The requirement markup is intended to make this supplement a stable source for: + +* PCIM requirement identifiers and requirement text; +* references from requirements to PCIM actors, transactions, options, use cases, + and message constraints; +* generated requirements artifacts that may be consumed by independent + conformance assessment tools. + +This repository is the source for PCIM specification requirements. It does not +contain implementation-specific verification software, deployment artifacts, or +product evidence. + +=== A.1 Requirement Identifiers + +Each PCIM requirement uses a stable identifier with the following form: + +---- +PCIMR0001 +---- + +The `PCIMR` prefix identifies the requirement as a PCIM requirement. The +four-digit number is assigned once and is not reused after publication. +Requirement anchors use the same identifier in lower case, for example +`pcimr0001`. + +Requirement identifiers are assigned in the following ranges: + +|=== +|Range |Use + +|PCIMR0001-PCIMR0099 +|Profile-level actor, transaction, option, and grouping requirements + +|PCIMR0100-PCIMR0199 +|Communicate Association State [DEV-51] requirements + +|PCIMR0200-PCIMR0299 +|Report Association State [DEV-52] requirements + +|PCIMR0300-PCIMR0399 +|Filter Associations [DEV-19] requirements + +|PCIMR0400-PCIMR0599 +|Shared HL7 message structure and segment constraints + +|PCIMR9000-PCIMR9999 +|Deprecated or reserved requirements +|=== + +=== A.2 Requirement Block + +A PCIM requirement is represented as a titled AsciiDoc block with the +`pcim_requirement` block style and PCIM-specific metadata attributes. + +Example: + +---- +.PCIMRnnnn +[pcim_requirement#pcimrnnnn,pcim_req_level=shall,pcim_req_type=tech_feature,pcim_actor=dpar,pcim_transaction=DEV-51,pcim_message=ORU_R01,pcim_segment="PID,PRT,OBR-7,OBR-8",pcim_use_case="uc1_associate_device_patient,uc2_disassociate_device_patient",pcim_verification_method=test,pcim_verification_level=connectathon] +**** +[NORMATIVE] +==== +The Device-Patient Association Reporter shall include the patient identifier, device +identifier, and association event timestamp in each association or +disassociation assertion. +==== + +[VERIFICATION] +==== +Verify by inspecting a DEV-51 ORU_R01 message and confirming PID, PRT, OBR-7, +and OBR-8 content according to the PCIM message constraints. +==== +**** +---- + +The block title contains the visible requirement identifier. The block anchor +provides a stable target for cross-references and generated artifacts. + +=== A.3 Requirement Metadata + +Requirement blocks use the following attributes: + +|=== +|Attribute |Required |Description + +|`pcim_req_level` +|Yes +|Requirement level. Values are `shall`, `should`, or `may`. + +|`pcim_req_type` +|Yes +|Requirement type. Initial values are `ihe_profile`, `use_case_feature`, +`tech_feature`, `message_constraint`, and `risk_mitigation`. + +|`pcim_actor` +|When applicable +|Actor scope. Initial values are `dpar`, `dpam`, and `dpac`. + +|`pcim_transaction` +|When applicable +|Transaction scope. Initial values are `DEV-51`, `DEV-52`, and `DEV-19`. + +|`pcim_option` +|When applicable +|Option scope, such as `subscription_filtering`. + +|`pcim_use_case` +|When applicable +|Use case scope from Section 7.4.2. + +|`pcim_message` +|When applicable +|Message structure or trigger, such as `ORU_R01`, `ACK`, `QSB_Q16`, or +`QSX_J01`. + +|`pcim_segment` +|When applicable +|HL7 segment or field scope, such as `MSH-21`, `OBR-3`, `OBR-29.2`, +`OBX-11`, `PRT-4`, `QPD-3`, or `RCP-3`. + +|`pcim_verification_method` +|When applicable +|Expected verification method. Values are `inspection`, `analysis`, `test`, or +`demonstration`. + +|`pcim_verification_level` +|When applicable +|Expected verification level. Values are `unit`, `integration`, `system`, or +`connectathon`. +|=== + +Additional metadata may be added when needed, but processors should preserve +unknown attributes in generated artifacts. + +=== A.4 Requirement Content Blocks + +The `[NORMATIVE]` block contains the requirement text that is rendered and +exported as the requirement statement. + +The `[VERIFICATION]` block contains non-normative guidance for independent +tools, monitors, or reviewers that evaluate whether an implementation satisfies +the requirement. + +The `[NOTE]` and `[RATIONALE]` blocks may be used for supporting context. These +blocks are exported with the requirement, but they are not the requirement +statement. + +=== A.5 Extracted Artifacts + +The PCIM requirement processor should generate at least the following artifacts: + +* `pcim-requirements.json`; +* `pcim-requirements-deprecated.json`; +* `pcim-use-cases.json`; +* `pcim-transactions.json`; +* `pcim-requirement-trace.json`. + +ReqIF export may be generated from the same source model when exchange with +requirements-management tools is needed. OSLC Requirements Management may be +used later when a live service interface is needed. + +Each exported requirement record should include: + +* identifier and anchor; +* requirement level and type; +* source file, source line, repository, commit, and PCIM version; +* actor, transaction, option, use case, message, segment, and field scope; +* normative text; +* verification guidance; +* status, including active, deprecated, or reserved. + +=== A.6 Conformance Result Mapping + +Conformance assessment tools should report results against PCIM requirement +identifiers. A requirement can be displayed as passed when all mandatory +assertions mapped to that requirement have passed for the declared actor, +transaction, and option scope. + +Recommended result fields include: + +* PCIM requirement identifier; +* PCIM version or source commit; +* test scenario identifier; +* test step or assertion identifier; +* implementation under test; +* verdict: `pass`, `fail`, `not-run`, or `not-applicable`; +* evidence references and hashes; +* timestamp. + +This result mapping supports traceability from PCIM requirement to conformance +assertion to test execution to evidence without placing implementation-specific +test software or product evidence in this repository. = Volume 2 -- Transactions @@ -615,6 +927,53 @@ The roles in this transaction are defined in the following table and may be play |Establishes or updates the persistent record of the association. The manager must provide a HMI to verify association and disassociation assertions. The manager is also responsible for conflict resolution with the HMI and sending corresponding HL7 ACK error codes at commit or application levels. Note that the HMI need not be constrained to running on the same device as the manager. For example, the HMI may be in the form of a mobile app. |=== +.PCIMR0100 +[pcim_requirement#pcimr0100,pcim_req_level=shall,pcim_req_type=tech_feature,pcim_actor=dpar,pcim_transaction=DEV-51,pcim_message=ORU_R01,pcim_segment=PRT,pcim_use_case="uc1_associate_device_patient,uc2_disassociate_device_patient",pcim_verification_method=test,pcim_verification_level=connectathon] +**** +[NORMATIVE] +==== +When verification occurs at the Device-Patient Association Reporter, the +Reporter shall record the responsible observer. +==== + +[VERIFICATION] +==== +Verify by inspecting a DEV-51 message for the responsible observer information +when the assertion is sent as already verified. +==== +**** + +.PCIMR0101 +[pcim_requirement#pcimr0101,pcim_req_level=shall,pcim_req_type=tech_feature,pcim_actor=dpar,pcim_transaction=DEV-51,pcim_message=ORU_R01,pcim_segment=OBX-11,pcim_use_case="uc1_associate_device_patient,uc2_disassociate_device_patient",pcim_verification_method=test,pcim_verification_level=connectathon] +**** +[NORMATIVE] +==== +The Device-Patient Association Reporter shall include an observation status +field indicating whether the assertion requires validation or is final. +==== + +[VERIFICATION] +==== +Verify by inspecting OBX-11 in DEV-51 messages originated by the Reporter. +==== +**** + +.PCIMR0102 +[pcim_requirement#pcimr0102,pcim_req_level=shall,pcim_req_type=tech_feature,pcim_actor=dpam,pcim_transaction=DEV-51,pcim_use_case="uc1_associate_device_patient,uc2_disassociate_device_patient,uc4_correct_verified_association,uc5_wrong_association",pcim_verification_method=demonstration,pcim_verification_level=connectathon] +**** +[NORMATIVE] +==== +The Device-Patient Association Manager shall provide an HMI to verify +association and disassociation assertions received through DEV-51. +==== + +[VERIFICATION] +==== +Verify by inspection or demonstration of the Manager HMI for DEV-51 validation +workflow. +==== +**** + === 3.51.3 Referenced Standards HL7 2.6 Chapters 2, 3, 5 and 7 @@ -657,6 +1016,22 @@ Code used to identify the patient must be chosen so as to be unique at least ove The type and issuing entity shall be recorded with the code. Additional identity codes may be provided at the discretion of the institution. Note that any code identifiable with an individual patient must by secured from misuse in accordance with applicable legal and policy procedures. Implementations should account for cases where the patient identity may change as a result of chart corrections. This should trigger the sending of a correction message of the patient identity to the Manager for active associations known to the reporter. This may also trigger the sending of a correction message to the Manager for completed associations. + +.PCIMR0103 +[pcim_requirement#pcimr0103,pcim_req_level=shall,pcim_req_type=message_constraint,pcim_actor=dpar,pcim_transaction=DEV-51,pcim_message=ORU_R01,pcim_segment=PID-3,pcim_use_case="uc1_associate_device_patient,uc2_disassociate_device_patient",pcim_verification_method=test,pcim_verification_level=connectathon] +**** +[NORMATIVE] +==== +The patient identifier used in a DEV-51 message shall include the identifier +type and issuing entity. +==== + +[VERIFICATION] +==== +Verify by inspecting PID-3 in DEV-51 messages originated by the Reporter. +==== +**** + - Unique identity of Device. This again is determined by site considerations. It is preferable to use a universally unique identification of the individual instance of the device, such as an IEEE EUI-64 or a Unique Device Identifier such as one produced in accordance with the US FDA (or other regulatory agency) UDI standards. @@ -734,9 +1109,59 @@ Corrections should be sent from the Device-Patient Association Reporter to the D The device identifier and the association unique instance identifier SHALL NOT be changed in a correction message. All correction messages shall reference the association unique instance identifier from the original message in OBR-29.2. +.PCIMR0104 +[pcim_requirement#pcimr0104,pcim_req_level=shall,pcim_req_type=message_constraint,pcim_actor=dpar,pcim_transaction=DEV-51,pcim_message=ORU_R01,pcim_segment=OBR-29.2,pcim_use_case=uc4_correct_verified_association,pcim_verification_method=test,pcim_verification_level=connectathon] +**** +[NORMATIVE] +==== +DEV-51 correction messages shall reference the association unique instance +identifier from the original message in OBR-29.2. +==== + +[VERIFICATION] +==== +Verify by inspecting OBR-29.2 in DEV-51 correction messages and confirming it +matches OBR-3 from the original association message. +==== +**** + +.PCIMR0105 +[pcim_requirement#pcimr0105,pcim_req_level=shall,pcim_req_type=message_constraint,pcim_actor=dpar,pcim_transaction=DEV-51,pcim_message=ORU_R01,pcim_segment="PRT-10,OBR-29.2",pcim_use_case=uc4_correct_verified_association,pcim_verification_method=test,pcim_verification_level=connectathon] +**** +[NORMATIVE] +==== +The device identifier and association unique instance identifier shall not be +changed in a DEV-51 correction message. +==== + +[VERIFICATION] +==== +Verify by comparing the device identifier and association unique instance +identifier in a DEV-51 correction message with the original association message. +==== +**** + ===== 3.51.4.1.4 Wrong Semantics An existing device-patient association should be asserted as "Wrong" from the Device-Patient Association Reporter to the Device-Patient Association Manager whenever either the device or the patient that was reported with the association was wrong. All messages asserting an existing device-patient association as wrong shall reference the association unique instance identifier in OBR-29.2 that was sent in OBR-3 of the original message that asserted the association. + +.PCIMR0106 +[pcim_requirement#pcimr0106,pcim_req_level=shall,pcim_req_type=message_constraint,pcim_actor=dpar,pcim_transaction=DEV-51,pcim_message=ORU_R01,pcim_segment=OBR-29.2,pcim_use_case=uc5_wrong_association,pcim_verification_method=test,pcim_verification_level=connectathon] +**** +[NORMATIVE] +==== +DEV-51 messages asserting an existing device-patient association as wrong shall +reference in OBR-29.2 the association unique instance identifier from OBR-3 of +the original association message. +==== + +[VERIFICATION] +==== +Verify by inspecting OBR-29.2 in DEV-51 wrong-association messages and confirming +it matches OBR-3 from the original association message. +==== +**** + A new association with the valid patient may be asserted after the Wrong has been reported. Note that there are chart correction use cases where the Device-Patient Association Reporter's understanding of the identity of the patient changes but the human who is associated to the device is semantically the same (such as with a patient merge). In these cases, the patient identity change may be handled either by correcting the patient identity for the existing association as described in section 3.51.4.1.3 above or by marking the existing association as wrong and re-asserting the association. The new assertion shall have a new association unique instance identifier in OBR-3 and includes the corrected patient identity. @@ -769,6 +1194,40 @@ The roles in this transaction are defined in the following table and may be play |=== +.PCIMR0200 +[pcim_requirement#pcimr0200,pcim_req_level=shall,pcim_req_type=tech_feature,pcim_actor=dpam,pcim_transaction=DEV-52,pcim_message=ORU_R01,pcim_use_case="uc1_associate_device_patient,uc2_disassociate_device_patient,uc3_filter_devices_for_patient",pcim_verification_method=test,pcim_verification_level=connectathon] +**** +[NORMATIVE] +==== +The Device-Patient Association Manager shall send current associations for all +devices that the Consumer is configured to receive reports for immediately after +a connection is established. +==== + +[VERIFICATION] +==== +Verify by establishing a Manager-to-Consumer connection and confirming that +current matching associations are sent as DEV-52 messages. +==== +**** + +.PCIMR0201 +[pcim_requirement#pcimr0201,pcim_req_level=shall,pcim_req_type=tech_feature,pcim_actor=dpac,pcim_transaction=DEV-52,pcim_message=ACK,pcim_use_case="uc1_associate_device_patient,uc2_disassociate_device_patient,uc4_correct_verified_association,uc5_wrong_association",pcim_verification_method=test,pcim_verification_level=connectathon] +**** +[NORMATIVE] +==== +When a DEV-52 association report is successfully received, the Device-Patient +Association Consumer shall return a commit-level accept acknowledgement to the +Device-Patient Association Manager. +==== + +[VERIFICATION] +==== +Verify by inspecting the acknowledgement returned by the Consumer after receipt +of a valid DEV-52 message. +==== +**** + === 3.52.3 Referenced Standards HL7 2.6 Chapters 2, 3, 5 and 7 @@ -793,6 +1252,23 @@ This is an HL7 Version 2 message giving details of the association being reporte The manager must send this message to all configured Consumer instances with matching filter criteria. +.PCIMR0202 +[pcim_requirement#pcimr0202,pcim_req_level=shall,pcim_req_type=tech_feature,pcim_actor=dpam,pcim_transaction=DEV-52,pcim_message=ORU_R01,pcim_use_case="uc1_associate_device_patient,uc2_disassociate_device_patient,uc3_filter_devices_for_patient,uc4_correct_verified_association,uc5_wrong_association",pcim_verification_method=test,pcim_verification_level=connectathon] +**** +[NORMATIVE] +==== +The Device-Patient Association Manager shall send DEV-52 messages to all +configured Device-Patient Association Consumer instances with matching filter +criteria. +==== + +[VERIFICATION] +==== +Verify by configuring one or more Consumers and confirming that each matching +Consumer receives the applicable DEV-52 message. +==== +**** + ===== 3.52.4.1.1 Trigger Events This message is triggered when a validated association or disassociation is received. @@ -825,12 +1301,63 @@ On receipt of the message, the Consumer parses and extracts the association deta Correction reports must be sent from the Device-Patient Association Manager to Device-Patient Association Consumers when they are validated. See table 3.51.4.1.3-1 and table 3.51.4.1.3-2 for correctable parameters that may be reported for active and completed associations. +.PCIMR0203 +[pcim_requirement#pcimr0203,pcim_req_level=shall,pcim_req_type=tech_feature,pcim_actor=dpam,pcim_transaction=DEV-52,pcim_message=ORU_R01,pcim_use_case=uc4_correct_verified_association,pcim_verification_method=test,pcim_verification_level=connectathon] +**** +[NORMATIVE] +==== +The Device-Patient Association Manager shall send correction reports to +Device-Patient Association Consumers when the corrections are validated. +==== + +[VERIFICATION] +==== +Verify by validating a correction at the Manager and confirming that the +corresponding DEV-52 correction report is sent to applicable Consumers. +==== +**** + ===== 3.52.4.1.4 Wrong Semantics An existing device-patient association should be reported as "Wrong" from the Device-Patient Association Manager to the Device-Patient Association Consumer whenever either the device or the patient that was reported with the association was wrong. All messages reporting an existing device-patient association as wrong shall reference the association unique instance identifier in OBR-29.2 that was sent in OBR-3 of the original message that reported the association. +.PCIMR0204 +[pcim_requirement#pcimr0204,pcim_req_level=shall,pcim_req_type=message_constraint,pcim_actor=dpam,pcim_transaction=DEV-52,pcim_message=ORU_R01,pcim_segment=OBR-29.2,pcim_use_case=uc5_wrong_association,pcim_verification_method=test,pcim_verification_level=connectathon] +**** +[NORMATIVE] +==== +DEV-52 messages reporting an existing device-patient association as wrong shall +reference in OBR-29.2 the association unique instance identifier from OBR-3 of +the original association message. +==== + +[VERIFICATION] +==== +Verify by inspecting OBR-29.2 in DEV-52 wrong-association messages and confirming +it matches OBR-3 from the original association message. +==== +**** + When a device-patient association is reported to be "Wrong", any device data that was reported for that device-patient association should also be deleted or flagged for review in any consumers that are using the device-patient association to file received device data to the patient. Device-Patient Association Consumers that are also device data reporter actors shall stop including the wrong patient identifier in outgoing messages as soon as it receives the Wrong association report. +.PCIMR0205 +[pcim_requirement#pcimr0205,pcim_req_level=shall,pcim_req_type=risk_mitigation,pcim_actor=dpac,pcim_transaction=DEV-52,pcim_use_case=uc5_wrong_association,pcim_verification_method=test,pcim_verification_level=connectathon] +**** +[NORMATIVE] +==== +A Device-Patient Association Consumer that is also a device data reporter actor +shall stop including the wrong patient identifier in outgoing messages as soon +as it receives the wrong-association report. +==== + +[VERIFICATION] +==== +Verify by sending a DEV-52 wrong-association report to the Consumer and +confirming subsequent outgoing device data messages no longer include the wrong +patient identifier. +==== +**** + |=== |Editor: Insert in Section 3 of DEV TF-2 as new Section 3.19 |=== @@ -843,8 +1370,58 @@ This transaction is used by a Device Patient Association Consumer to access filt As stated previously, the DEV-19 transaction is optional. If the message is accepted by the Device-Patient Association Manager, the accept acknowledgement shall contain the value CA in MSA-1. +.PCIMR0300 +[pcim_requirement#pcimr0300,pcim_req_level=shall,pcim_req_type=message_constraint,pcim_actor=dpam,pcim_transaction=DEV-19,pcim_message=ACK,pcim_segment=MSA-1,pcim_option=subscription_filtering,pcim_use_case=uc3_filter_devices_for_patient,pcim_verification_method=test,pcim_verification_level=connectathon] +**** +[NORMATIVE] +==== +When a DEV-19 message is accepted by the Device-Patient Association Manager, the +accept acknowledgement shall contain the value `CA` in MSA-1. +==== + +[VERIFICATION] +==== +Verify by inspecting MSA-1 in the acknowledgement returned by the Manager for an +accepted DEV-19 message. +==== +**** + If this message is not supported, MSA-1 shall contain the value CR, ERR-3 (HL7 Error Code) shall contain the value 200 (Unsupported Message Type), and ERR-4 (Severity) shall contain the value E. If the transaction is not supported, and the network connection between the Device-Patient Association Manager and Device-Patient Association Consumer is lost, the Device-Patient Association Manager shall send DEV-52 messages for all current Device-Patient associations to the Device-Patient Association Consumer when network connectivity is restored. This ensures the Device-Patient Association Consumer has the current association state. +.PCIMR0301 +[pcim_requirement#pcimr0301,pcim_req_level=shall,pcim_req_type=message_constraint,pcim_actor=dpam,pcim_transaction=DEV-19,pcim_message=ACK,pcim_segment="MSA-1,ERR-3,ERR-4",pcim_option=subscription_filtering,pcim_use_case=uc3_filter_devices_for_patient,pcim_verification_method=test,pcim_verification_level=connectathon] +**** +[NORMATIVE] +==== +When DEV-19 is not supported, the Device-Patient Association Manager shall return +an acknowledgement with `CR` in MSA-1, `200` in ERR-3, and `E` in ERR-4. +==== + +[VERIFICATION] +==== +Verify by sending a DEV-19 message to a Manager that does not support DEV-19 and +inspecting the returned acknowledgement. +==== +**** + +.PCIMR0302 +[pcim_requirement#pcimr0302,pcim_req_level=shall,pcim_req_type=tech_feature,pcim_actor=dpam,pcim_transaction="DEV-19,DEV-52",pcim_message=ORU_R01,pcim_use_case=uc3_filter_devices_for_patient,pcim_verification_method=test,pcim_verification_level=connectathon] +**** +[NORMATIVE] +==== +If DEV-19 is not supported and network connectivity between the Device-Patient +Association Manager and Device-Patient Association Consumer is restored after a +loss of connection, the Manager shall send DEV-52 messages for all current +device-patient associations to the Consumer. +==== + +[VERIFICATION] +==== +Verify by restoring a lost Manager-to-Consumer connection when DEV-19 is not +supported and confirming that current associations are sent as DEV-52 messages. +==== +**** + === 3.19.2 Actor Roles **Figure 3.19.2-1: Use Case Diagram** @@ -1052,6 +1629,37 @@ l|} MSH, SFT, and UAC Segments follow the specifications for [PCD-01] in DEV TF-2 Appendix B.1, except that in the MSH segment, MSH-21 is valued “IHE_DEV_051^IHE PCD\^1.3.6.1.4.1.19376.1.6.1.51.1^ISO” to identify it as a Communicate Device-Patient Association or “IHE_DEV_052^IHE PCD\^1.3.6.1.4.1.19376.1.6.1.52.1^ISO” to identify it as a Report Device-Patient Association. In the context of this specification, the message is constrained to reporting association(s) for a single patient and device. +.PCIMR0400 +[pcim_requirement#pcimr0400,pcim_req_level=shall,pcim_req_type=message_constraint,pcim_actor="dpar,dpam",pcim_transaction="DEV-51,DEV-52",pcim_message=ORU_R01,pcim_segment=MSH-21,pcim_verification_method=test,pcim_verification_level=connectathon] +**** +[NORMATIVE] +==== +DEV-51 and DEV-52 messages shall value MSH-21 with the appropriate PCIM message +profile identifier for the transaction. +==== + +[VERIFICATION] +==== +Verify by inspecting MSH-21 in DEV-51 and DEV-52 ORU_R01 messages. +==== +**** + +.PCIMR0401 +[pcim_requirement#pcimr0401,pcim_req_level=shall,pcim_req_type=message_constraint,pcim_actor="dpar,dpam",pcim_transaction="DEV-51,DEV-52",pcim_message=ORU_R01,pcim_verification_method=test,pcim_verification_level=connectathon] +**** +[NORMATIVE] +==== +DEV-51 and DEV-52 messages shall be constrained to reporting associations for a +single patient and device. +==== + +[VERIFICATION] +==== +Verify by inspecting each DEV-51 or DEV-52 ORU_R01 message and confirming that it +reports only one patient-device association. +==== +**** + === A.1.2 Segments ==== A.1.2.1 MSH -- Message Header @@ -1080,6 +1688,20 @@ Since this message is effectively an unsolicited observation report, the content |=== +.PCIMR0402 +[pcim_requirement#pcimr0402,pcim_req_level=shall,pcim_req_type=message_constraint,pcim_actor="dpar,dpam",pcim_transaction="DEV-51,DEV-52",pcim_message=ORU_R01,pcim_segment=MSH-15,pcim_verification_method=test,pcim_verification_level=connectathon] +**** +[NORMATIVE] +==== +MSH-15 in DEV-51 and DEV-52 messages shall be set to `AL`. +==== + +[VERIFICATION] +==== +Verify by inspecting MSH-15 in DEV-51 and DEV-52 ORU_R01 messages. +==== +**** + ==== A.1.2.2 PID -- Patient Identification In order to assert an association between a patient and a device, the PID segment is required. @@ -1088,6 +1710,37 @@ The Patient Identifier List must contain an identifier that is unique for all pa By default, if an identifier on the list is identified as a medical record number, it is used (PID-3.5 Identifier Type code valued as "`MR`"). There may be multiple identifiers in the list, and implementers may choose to allow a different identifier than the medical record number to be used as a configuration option. +.PCIMR0403 +[pcim_requirement#pcimr0403,pcim_req_level=shall,pcim_req_type=message_constraint,pcim_actor="dpar,dpam",pcim_transaction="DEV-51,DEV-52",pcim_message=ORU_R01,pcim_segment=PID,pcim_verification_method=test,pcim_verification_level=connectathon] +**** +[NORMATIVE] +==== +DEV-51 and DEV-52 messages shall include a PID segment to identify the patient +associated with the device. +==== + +[VERIFICATION] +==== +Verify by inspecting DEV-51 and DEV-52 ORU_R01 messages and confirming the PID +segment is present. +==== +**** + +.PCIMR0404 +[pcim_requirement#pcimr0404,pcim_req_level=shall,pcim_req_type=message_constraint,pcim_actor="dpar,dpam",pcim_transaction="DEV-51,DEV-52",pcim_message=ORU_R01,pcim_segment=PID-3,pcim_verification_method=test,pcim_verification_level=connectathon] +**** +[NORMATIVE] +==== +The Patient Identifier List in PID-3 shall contain an identifier that is unique +for all patients within the scope of the system. +==== + +[VERIFICATION] +==== +Verify by inspecting PID-3 in DEV-51 and DEV-52 ORU_R01 messages. +==== +**** + **Table A.1.2.2-1: PID Fields** |=== @@ -1136,6 +1789,23 @@ It gives the association message a unique identifier in the Filler Order Number This is a required field: it acts as an association object instance identifier for tracking is used for tracking messages from all sources in the overall configuration of systems, so it must be constrained by some method of generation that assures that duplicate identifiers between sources are not possible. It gives the timestamp of the earliest participant involvement (OBR-7) and the latest participant involvement (OBR-8). +.PCIMR0405 +[pcim_requirement#pcimr0405,pcim_req_level=shall,pcim_req_type=message_constraint,pcim_actor="dpar,dpam",pcim_transaction="DEV-51,DEV-52",pcim_message=ORU_R01,pcim_segment=OBR-3,pcim_verification_method=test,pcim_verification_level=connectathon] +**** +[NORMATIVE] +==== +OBR-3 in DEV-51 and DEV-52 messages shall contain a unique association event +instance identifier generated so that duplicate identifiers between sources are +not possible. +==== + +[VERIFICATION] +==== +Verify by inspecting OBR-3 values in DEV-51 and DEV-52 ORU_R01 messages and +confirming uniqueness across message sources. +==== +**** + **Table A.1.2.4-1: OBR Fields** |=== @@ -1178,6 +1848,23 @@ Each report consists of two or more Participation Information Segments (PRT) and OBR-7 and OBR-8 conveys the range of time of all participants. See Table A.1.2.6-3 and Table A.1.2.6-4 for definitions of the timestamp semantics in PRT-11 and PRT-12. The logic for filling in the timestamp values for OBR-7 and OBR-8 is to examine the PRT segments that will be sent out in the report and set OBR-7 to the earliest timestamp value and OBR-8 to the latest timestamp value. OBR-7 and 8 may contain the same timestamp. +.PCIMR0406 +[pcim_requirement#pcimr0406,pcim_req_level=shall,pcim_req_type=message_constraint,pcim_actor="dpar,dpam",pcim_transaction="DEV-51,DEV-52",pcim_message=ORU_R01,pcim_segment="OBR-7,OBR-8",pcim_verification_method=test,pcim_verification_level=connectathon] +**** +[NORMATIVE] +==== +DEV-51 and DEV-52 association or disassociation event reports shall include in +OBR-7 the earliest participant involvement timestamp and in OBR-8 the latest +participant involvement timestamp. +==== + +[VERIFICATION] +==== +Verify by comparing OBR-7 and OBR-8 with PRT-11 and PRT-12 timestamps in the +same DEV-51 or DEV-52 message. +==== +**** + ==== A.1.2.5 OBX -- Observation This segment conveys the "`observation`" that the patient has been associated or disassociated to a device. @@ -1769,9 +2456,41 @@ Same as for transaction [PCD-01] in DEV TF-2 Appendix B.1, except that MSH-9 is [.text-left] The QueryTag (QPD.2) is used to identify a query instance and therefore must be unique for each query. A query cannot be modified, it must be cancelled and a new query issued, see section A.2.5 for details on cancellation. + +.PCIMR0303 +[pcim_requirement#pcimr0303,pcim_req_level=shall,pcim_req_type=message_constraint,pcim_actor=dpac,pcim_transaction=DEV-19,pcim_message=QSB_Q16,pcim_segment=QPD-2,pcim_option=subscription_filtering,pcim_use_case=uc3_filter_devices_for_patient,pcim_verification_method=test,pcim_verification_level=connectathon] +**** +[NORMATIVE] +==== +The QueryTag in QPD.2 shall be unique for each DEV-19 query. +==== + +[VERIFICATION] +==== +Verify by inspecting QPD.2 values in DEV-19 queries originated by the Consumer. +==== +**** + [.text-left] The Query Parameters field (QPD.3) is used to specify "`filtering`" values, so that the query response can be limited to, for example, the records matching a particular Assigned Location (by including a PV1.3.1 specification), a particular device (by adding a Participation Device PRT specification) and so on. If multiple specifications are given, the relational conjunction in QSC.4 shall be specified, except for the last one. For example, a patient location and a device identifier query filter specification will result in the subscription including associations involving both that patient location and device. The relational conjunction is defined as follows: If more than one comparison is to be made to select qualifying rows, a conjunction relates this repetition of the field to the next. The last specification does not need to specify a conjunction, as it is the last one. + +.PCIMR0304 +[pcim_requirement#pcimr0304,pcim_req_level=shall,pcim_req_type=message_constraint,pcim_actor=dpac,pcim_transaction=DEV-19,pcim_message=QSB_Q16,pcim_segment=QSC-4,pcim_option=subscription_filtering,pcim_use_case=uc3_filter_devices_for_patient,pcim_verification_method=test,pcim_verification_level=connectathon] +**** +[NORMATIVE] +==== +If multiple DEV-19 query parameter specifications are present, QSC.4 shall +specify the relational conjunction except for the last specification. +==== + +[VERIFICATION] +==== +Verify by inspecting QSC.4 values in DEV-19 queries that contain multiple query +parameter specifications. +==== +**** + [.text-left] The form of the Query Parameters specifications in QPD.3 field is a QSC data type. Any additional fields can be added as QPD.4, QPD.5, etc, one for each query parameter to be specified, with each field using the QSC data type. An example would be: @@ -1820,6 +2539,25 @@ Quantity limited requests are not supported, so RCP-2 Quantity Limited Request v The supported values of RCP-3 Response Modality is R (Real Time). The Device-Patient Association Consumer must support receiving a continuous real-time feed of association events and will receive all existing associations when the connection is first established that meet the desired filter specification to get the starting state. After that initial state is received, association records are sent as they arrive at the Device-Patient Association Manager. The Device-Patient Association Consumer can optionally configure (or reconfigure) filter criteria and even cancel the continuing real-time query dynamically. +.PCIMR0305 +[pcim_requirement#pcimr0305,pcim_req_level=shall,pcim_req_type=tech_feature,pcim_actor=dpac,pcim_transaction=DEV-19,pcim_option=subscription_filtering,pcim_use_case=uc3_filter_devices_for_patient,pcim_verification_method=test,pcim_verification_level=connectathon] +**** +[NORMATIVE] +==== +A Device-Patient Association Consumer that uses DEV-19 shall support receiving a +continuous real-time feed of association events and shall receive existing +associations matching the filter specification when the connection is first +established. +==== + +[VERIFICATION] +==== +Verify by establishing a filtered subscription and confirming that the Consumer +receives both the initial matching association state and subsequent real-time +updates. +==== +**** + === A.2.5 Cancelling a Subscription A subscription may be explicitly cancelled by the Device-Patient Association Consumer by sending a QSX{caret}J66{caret}QSX_J01 message, which is simply an MSH segment containing that string as MSH-9, followed by a QID segment identifying the subscription being cancelled with QID Query Identification Segment containing in field QID-1 the Query Tag (from QPD-2 of the original query establishing the subscription) and in QID-2 the Message Query Name (from QPD-1 of the original query). @@ -2007,4 +2745,4 @@ No content modules [chapter] = Volume 4 -- National Extensions -No national extensions \ No newline at end of file +No national extensions diff --git a/asciidoc/pcim_named_requirements_plan.adoc b/asciidoc/pcim_named_requirements_plan.adoc new file mode 100644 index 0000000..4c2e653 --- /dev/null +++ b/asciidoc/pcim_named_requirements_plan.adoc @@ -0,0 +1,497 @@ += PCIM Named Requirements Plan + +== Purpose + +This plan describes how to add named, traceable requirements to the PCIM +AsciiDoc source without adding implementation, product, container, reference UI, +or regulatory evidence artifacts to this repository. + +The PCIM repository remains the source for: + +* requirement identifiers and requirement text; +* metadata needed to extract requirements from AsciiDoc; +* references from requirements to PCIM actors, transactions, options, use cases, + and message constraints; +* a generated requirements artifact that other tools can consume. + +Downstream verification, implementation, deployment, and regulatory evidence +repositories should consume the exported PCIM requirements artifact. They should +not write implementation-specific artifacts back to this repository. + +== Inputs Reviewed + +* `asciidoc/IHE_DEV_Suppl_PCIM.adoc` +* `PCIM Connectathon Tests 2026.xlsx` +* IHE DEV.SDPi semantic AsciiDoc approach: + https://github.com/IHE/DEV.SDPi/blob/master/articles/sdpi-article-ihe-tf-asciidoc-cookbook.adoc +* Published SDPi requirements model: + https://profiles.ihe.net/DEV/SDPi/index.html +* Requirements Interchange Format, ReqIF: + https://www.omg.org/reqif/ +* OSLC Requirements Management: + https://www.oasis-open.org/standard/oslc-requirements-management-version-2-1-project-specification-02/ + +The spreadsheet is treated as draft test-planning input. Its README states that +Gazelle is the authoritative source for current tests, so the workbook should +not be treated as the canonical source of PCIM requirements. + +== Initial Inventory + +At the start of this branch, the PCIM supplement had no semantic requirement +blocks. + +Initial keyword scan of `IHE_DEV_Suppl_PCIM.adoc`: + +|=== +|Keyword |Occurrences + +|shall +|41 + +|must +|30 + +|should +|37 + +|may +|65 + +|existing semantic requirement blocks +|0 +|=== + +The keyword counts are not the final requirement count. Some occurrences are +editorial, explanatory, duplicate, or part of table headings. The first pass +should convert implementation-facing normative statements into explicit +requirements and leave explanatory text as notes. + +== Requirement Count To Add + +Initial plan: add 78 named PCIM requirement blocks. + +Initial implementation batch: 33 named PCIM requirement blocks have been added +to `IHE_DEV_Suppl_PCIM.adoc` across the profile-level, DEV-51, DEV-52, DEV-19, +and shared HL7 message-constraint ranges. + +|=== +|Requirement area |Estimated named requirements + +|Profile, actor, transaction, and option conformance +|6 + +|DEV-51 Communicate Association State +|16 + +|DEV-52 Report Association State +|11 + +|DEV-19 Filter Associations +|14 + +|Shared HL7 message structure and segment constraints +|31 + +|Total +|78 +|=== + +This number should be verified during authoring by reviewing each candidate +requirement for atomicity. If one statement contains multiple independently +testable obligations, split it. If two statements express the same obligation in +different sections, keep one normative requirement and cross-reference it from +the other location. + +=== Reconciled Count For First Pull Request + +The first pull request should add the 33 named requirements already marked in +the PCIM supplement and should not attempt to add every item from the initial +78-requirement estimate. The 78-item estimate remains useful as a discovery +ceiling, but it includes repeated workbook checks, overlapping actor and +transaction descriptions, and explanatory `should` or `may` statements that are +not all independently testable PCIM requirements. + +Reconciled planning count: + +|=== +|Requirement area |Initial estimate |Named in first PR |Working target after duplicate review |Additional candidates after first PR + +|Profile, actor, transaction, and option conformance +|6 +|7 +|7 +|0 + +|DEV-51 Communicate Association State +|16 +|7 +|13 +|6 + +|DEV-52 Report Association State +|11 +|6 +|9 +|3 + +|DEV-19 Filter Associations +|14 +|6 +|12 +|6 + +|Shared HL7 message structure and segment constraints +|31 +|7 +|23 +|16 + +|Total +|78 +|33 +|64 +|31 +|=== + +The working target of 64 unique requirements should be treated as an authoring +backlog estimate, not as a complete normative inventory. The additional 31 +candidates should be added in later passes only after review by the PCIM working +group. + +=== Duplicate And Overlap Reconciliation + +The active connectathon workbook scenarios repeat the same protocol behaviors +across different participant combinations. Those repetitions should map to the +same PCIM requirement identifiers and separate test assertions, not to duplicate +specification requirements. + +Current overlap decisions: + +|=== +|Overlap family |Disposition + +|Actor narrative vs. transaction role table +|Keep actor-level requirements only for conformance claims or actor +responsibilities. Add transaction-level requirements only when the transaction +adds a distinct, independently testable behavior. + +|Reporter validation status +|Keep the actor-level obligation to distinguish validated and unvalidated +assertions and keep the DEV-51 message-level obligation for the concrete +observation status encoding. + +|Manager HMI +|Keep the profile-level HMI obligation for validation and conflict resolution. +Keep the DEV-51 HMI obligation only as the transaction-specific validation +workflow requirement. + +|DEV-52 publication behavior +|Keep separate requirements for validated event notification, initial current +state delivery, matching filter delivery, correction publication, and +wrong-association publication because each has a different trigger or +acceptance condition. + +|OBR-3 and OBR-29 rules repeated in transaction text and appendix text +|Use shared HL7 message-constraint requirements for common data rules. Add +transaction-specific requirements only when sender responsibility or update +semantics differ. + +|Workbook scenario repetitions +|Map repeated checks in `PCIM_03`, `PCIM_04`, `PCIM_06`, and `PCIM_07` to the +same requirement identifiers and distinguish them by test scenario and assertion +identifier in downstream result artifacts. + +|Obsolete or observational workbook tabs +|Do not create PCIM requirement identifiers from obsolete or observational tabs +unless the working group brings those scenarios back into scope. + +|Explanatory `should` and `may` statements +|Do not create named requirements for implementation guidance unless the +statement is independently testable or tied to a declared optional capability. +|=== + +Before the first pull request, the review fixture should be checked for duplicate +identifiers and for obviously equivalent normative text. After this review, the +first pull request scope is 33 named PCIM requirements. + +== Identifier Scheme + +Use a PCIM-specific requirement identifier that is unique, stable, readable, and +compatible with the SDPi-style requirement-number pattern: + +---- +PCIMR0001 +---- + +Proposed ranges: + +|=== +|Range |Use + +|PCIMR0001-PCIMR0099 +|Profile-level actor, transaction, option, and grouping requirements + +|PCIMR0100-PCIMR0199 +|DEV-51 requirements + +|PCIMR0200-PCIMR0299 +|DEV-52 requirements + +|PCIMR0300-PCIMR0399 +|DEV-19 requirements + +|PCIMR0400-PCIMR0599 +|Shared HL7 message structure and segment constraints + +|PCIMR9000-PCIMR9999 +|Deprecated or reserved identifiers +|=== + +Identifier rules: + +* never renumber a published requirement; +* never reuse a deprecated identifier; +* preserve old identifiers in a deprecated-requirements artifact; +* use lower-case anchors for AsciiDoc navigation, for example `#pcimr0100`; +* use semantic cross-references instead of plain-text requirement numbers. + +== AsciiDoc Markup Model + +Follow the SDPi pattern, generalized for PCIM. A requirement block should have: + +* a visible title containing the requirement identifier; +* a stable anchor; +* requirement level: `shall`, `should`, or `may`; +* requirement type; +* actor, transaction, option, use case, and message-field metadata when + applicable; +* one normative statement; +* optional notes, rationale, and verification guidance. + +Example: + +---- +.PCIMR0100 +[pcim_requirement#pcimr0100,pcim_req_level=shall,pcim_req_type=tech_feature,pcim_actor=dpar,pcim_transaction=DEV-51,pcim_message=ORU_R01,pcim_segment="PID,PRT,OBR-7,OBR-8",pcim_use_case="uc1_associate_device_patient,uc2_disassociate_device_patient",pcim_verification_method=test,pcim_verification_level=connectathon] +**** +[NORMATIVE] +==== +The Device-Patient Association Reporter shall include the patient identifier, +device identifier, and association event timestamp in each association or +disassociation assertion. +==== + +[VERIFICATION] +==== +Verify by inspecting a DEV-51 ORU_R01 message and confirming PID, PRT, OBR-7, +and OBR-8 content according to the PCIM message constraints. +==== +**** +---- + +If the existing SDPi converter is reused before it is generalized, a temporary +compatibility layer may map `pcim_requirement` and `pcim_req_*` attributes to +the SDPi internal model. The PCIM source should retain PCIM names. + +== Export Format + +The primary generated artifact should be JSON because it is easy for +connectathon tooling, dashboards, and CI systems to consume. + +Proposed generated files: + +* `pcim-requirements.json` +* `pcim-requirements-deprecated.json` +* `pcim-use-cases.json` +* `pcim-transactions.json` +* `pcim-requirement-trace.json` + +For requirements-management tool exchange, also support ReqIF XML export. +ReqIF is the best fit for open requirements interchange between independent +requirements-management tools. OSLC RM is a good fit later if a service API is +needed for live linked-data integration. + +Minimum JSON fields: + +---- +{ + "id": "PCIMR0100", + "anchor": "pcimr0100", + "level": "shall", + "type": "tech_feature", + "status": "active", + "source": { + "repository": "IHE/DEV.PCIM", + "file": "asciidoc/IHE_DEV_Suppl_PCIM.adoc", + "line": 358, + "commit": "", + "version": "" + }, + "scope": { + "profile": "PCIM", + "actors": ["dpar"], + "transactions": ["DEV-51"], + "options": [] + }, + "normativeText": "...", + "verification": { + "method": "test", + "type": "system", + "evidenceExpected": ["message-capture", "validator-result"] + } +} +---- + +== Connectathon Validation Contract + +The PCIM repository should publish requirements and trace metadata. A third-party +connectathon validation tool should consume that metadata and produce verdicts. + +Recommended result contract: + +---- +{ + "requirementId": "PCIMR0100", + "requirementVersion": "", + "testScenarioId": "PCIM_01", + "testStepId": "210", + "implementationUnderTest": "", + "verdict": "pass", + "evidence": [ + { + "type": "message-capture", + "uri": "", + "hash": "" + }, + { + "type": "validator-output", + "uri": "", + "hash": "" + } + ], + "timestamp": "" +} +---- + +A green checkmark can be displayed for a requirement when all mandatory +assertions mapped to that requirement have a `pass` verdict for the declared +actor, option, and transaction scope. A failed or missing mandatory assertion +should produce a red failure or gray not-run status. Recommended (`should`) and +permitted (`may`) requirements should be reported separately so optional +capability claims are visible but do not fail an implementation that does not +claim the option. + +The result format can also be emitted as JUnit XML or Cucumber Messages for CI +and dashboard compatibility, but the source trace should remain the PCIM +requirement identifier. + +== Spreadsheet Test Scenario Summary + +Active workbook scenarios: + +|=== +|Scenario |Title |Step rows |Main transactions + +|PCIM_01 +|PCIM_AssociateDisassociateDevice +|22 +|DEV-51 + +|PCIM_02 +|PCIM_ConsumeAssociations +|18 +|DEV-19, DEV-52 + +|PCIM_03 +|PCIM_DPAR_DPAC_Single +|22 +|DEV-19, DEV-51, DEV-52 + +|PCIM_04 +|PCIM_Multiple_DPAR_DPAC +|48 +|DEV-19, DEV-51, DEV-52 + +|PCIM_05 +|PCIM_DPAR_DPAM_Communication_Link_Fails +|9 +|DEV-51 + +|PCIM_06 +|PCIM_Association_Correction +|32 +|DEV-19, DEV-51, DEV-52 + +|PCIM_07 +|PCIM_Wrong_Association +|22 +|DEV-19, DEV-51, DEV-52 + +|Total +| +|173 +| +|=== + +The active tabs contain 45 validation/pass-review steps and approximately 235 +candidate assertion checks. Many checks are repeated across scenarios; they +should map to a smaller number of reusable PCIM requirements and test +assertions. + +Obsolete or observational workbook tabs should not drive initial PCIM +requirements unless the working group decides to bring those scenarios back into +scope. + +== IEC 62304-Oriented V&V Metadata + +The PCIM repository should not store product-specific IEC 62304 evidence, but it +can provide metadata that lets other repositories create IEC 62304-compatible +traceability. + +Recommended requirement metadata: + +* `verification.method`: `inspection`, `analysis`, `test`, or `demonstration`; +* `verification.level`: `unit`, `integration`, `system`, or `connectathon`; +* `evidenceExpected`: expected evidence classes, such as message captures, + validator outputs, logs, screenshots, risk-control review, or manual monitor + attestation; +* `riskRelevance`: `safety`, `effectiveness`, `security`, or `interoperability`; +* `optionScope`: empty for mandatory profile behavior, or the PCIM option name + when optional behavior is claimed. + +This gives downstream V&V tools stable hooks for IEC 62304-style traceability: +requirement -> design element -> test case -> test run -> evidence -> verdict. + +== Implementation Plan For This Branch + +1. Add semantic markup conventions to the PCIM AsciiDoc source or a companion + authoring note. +2. Add the first requirement blocks in stable numeric ranges. +3. Add a lightweight extraction script or adapt the SDPi converter pattern to + emit PCIM JSON. +4. Add a uniqueness check for requirement identifiers. +5. Add a generated JSON fixture for review, but do not commit generated build + output if the repository convention treats it as disposable. +6. Add traceability fields for actor, transaction, option, use case, message + segment, and verification method. +7. Review the 78-requirement estimate and reconcile duplicates before the + first pull request. + +Status: + +* Steps 1 and 2 are started in `IHE_DEV_Suppl_PCIM.adoc`. +* Step 3 is implemented in `.ci/asciidoc-converter` with a + `pcimRequirementsJson` Gradle task. +* The task emits `output/referenced-artifacts/pcim-requirements.json`. +* The task emits `output/referenced-artifacts/pcim-requirement-trace.json`. +* Step 4 is implemented with a `pcimRequirementsCheck` Gradle task. +* The standard Gradle `check` lifecycle depends on `pcimRequirementsCheck`. +* Step 5 is implemented with a `pcimRequirementsFixture` Gradle task. +* The fixture is `.ci/asciidoc-converter/fixtures/pcim-requirements.fixture.json`. +* Generated build output remains under ignored `output/referenced-artifacts`. +* Step 6 is implemented for the initial 33 requirements with actor, + transaction, option, use case, message, segment, verification method, and + verification level metadata in the AsciiDoc source and generated JSON. +* Step 7 is implemented by reconciling the initial 78-requirement estimate to a + first pull request scope of 33 named requirements and a working backlog target + of 64 unique requirements after duplicate review.