iris-devtester 1.12.2__tar.gz → 1.12.4__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (252) hide show
  1. iris_devtester-1.12.4/CHANGELOG.md +1189 -0
  2. {iris_devtester-1.12.2 → iris_devtester-1.12.4}/MANIFEST.in +1 -0
  3. {iris_devtester-1.12.2 → iris_devtester-1.12.4}/PKG-INFO +1 -1
  4. {iris_devtester-1.12.2 → iris_devtester-1.12.4}/docs/TROUBLESHOOTING.md +10 -1
  5. {iris_devtester-1.12.2 → iris_devtester-1.12.4}/iris_devtester/__init__.py +1 -1
  6. {iris_devtester-1.12.2 → iris_devtester-1.12.4}/iris_devtester/cli/container.py +36 -8
  7. {iris_devtester-1.12.2 → iris_devtester-1.12.4}/iris_devtester/ports/registry.py +42 -9
  8. {iris_devtester-1.12.2 → iris_devtester-1.12.4}/iris_devtester.egg-info/PKG-INFO +1 -1
  9. {iris_devtester-1.12.2 → iris_devtester-1.12.4}/iris_devtester.egg-info/SOURCES.txt +2 -0
  10. {iris_devtester-1.12.2 → iris_devtester-1.12.4}/pyproject.toml +1 -1
  11. iris_devtester-1.12.4/tests/e2e/test_port_registry_e2e.py +96 -0
  12. {iris_devtester-1.12.2 → iris_devtester-1.12.4}/AGENTS.md +0 -0
  13. {iris_devtester-1.12.2 → iris_devtester-1.12.4}/CLAUDE.md +0 -0
  14. {iris_devtester-1.12.2 → iris_devtester-1.12.4}/CONSTITUTION.md +0 -0
  15. {iris_devtester-1.12.2 → iris_devtester-1.12.4}/LICENSE +0 -0
  16. {iris_devtester-1.12.2 → iris_devtester-1.12.4}/README.md +0 -0
  17. {iris_devtester-1.12.2 → iris_devtester-1.12.4}/SKILL.md +0 -0
  18. {iris_devtester-1.12.2 → iris_devtester-1.12.4}/docs/GETTING_STARTED.md +0 -0
  19. {iris_devtester-1.12.2 → iris_devtester-1.12.4}/docs/LANGCHAIN_INTEGRATION_QUICKSTART.md +0 -0
  20. {iris_devtester-1.12.2 → iris_devtester-1.12.4}/docs/ROADMAP.md +0 -0
  21. {iris_devtester-1.12.2 → iris_devtester-1.12.4}/docs/SQL_VS_OBJECTSCRIPT.md +0 -0
  22. {iris_devtester-1.12.2 → iris_devtester-1.12.4}/docs/WHATS_NEW_v1.4.0.md +0 -0
  23. {iris_devtester-1.12.2 → iris_devtester-1.12.4}/docs/archive/AGENTIC_SANDBOX_ENHANCEMENT_REPORT.md +0 -0
  24. {iris_devtester-1.12.2 → iris_devtester-1.12.4}/docs/archive/IMPACT_ANALYSIS.md +0 -0
  25. {iris_devtester-1.12.2 → iris_devtester-1.12.4}/docs/archive/IRIS_DEVTESTER_POSITIONING_REPORT.md +0 -0
  26. {iris_devtester-1.12.2 → iris_devtester-1.12.4}/docs/archive/LANGCHAIN_INTEGRATION_STRATEGY.md +0 -0
  27. {iris_devtester-1.12.2 → iris_devtester-1.12.4}/docs/archive/LANGCHAIN_INTEGRATION_TEST_RESULTS.md +0 -0
  28. {iris_devtester-1.12.2 → iris_devtester-1.12.4}/docs/archive/PHASE_2_PLAN.md +0 -0
  29. {iris_devtester-1.12.2 → iris_devtester-1.12.4}/docs/archive/RAG_TEMPLATES_ANALYSIS.md +0 -0
  30. {iris_devtester-1.12.2 → iris_devtester-1.12.4}/docs/archive/README.md +0 -0
  31. {iris_devtester-1.12.2 → iris_devtester-1.12.4}/docs/archive/STRATEGIC_ROADMAP_SUMMARY.md +0 -0
  32. {iris_devtester-1.12.2 → iris_devtester-1.12.4}/docs/archive/feature-009-refactor-plan.md +0 -0
  33. {iris_devtester-1.12.2 → iris_devtester-1.12.4}/docs/development/BUG_REPORT.md +0 -0
  34. {iris_devtester-1.12.2 → iris_devtester-1.12.4}/docs/development/EXTRACTION_SUMMARY.md +0 -0
  35. {iris_devtester-1.12.2 → iris_devtester-1.12.4}/docs/development/FEATURE_006_SUMMARY.md +0 -0
  36. {iris_devtester-1.12.2 → iris_devtester-1.12.4}/docs/development/PHASE2_RESULTS.md +0 -0
  37. {iris_devtester-1.12.2 → iris_devtester-1.12.4}/docs/development/PRE_PUBLISH_REVIEW.md +0 -0
  38. {iris_devtester-1.12.2 → iris_devtester-1.12.4}/docs/development/PROGRESS.md +0 -0
  39. {iris_devtester-1.12.2 → iris_devtester-1.12.4}/docs/development/PYPI_READINESS.md +0 -0
  40. {iris_devtester-1.12.2 → iris_devtester-1.12.4}/docs/development/SESSION-INTEGRATION-TESTS.md +0 -0
  41. {iris_devtester-1.12.2 → iris_devtester-1.12.4}/docs/development/SESSION-SUMMARY.md +0 -0
  42. {iris_devtester-1.12.2 → iris_devtester-1.12.4}/docs/development/STATUS-002-PIVOTED.md +0 -0
  43. {iris_devtester-1.12.2 → iris_devtester-1.12.4}/docs/development/STATUS-003-COMPLETE.md +0 -0
  44. {iris_devtester-1.12.2 → iris_devtester-1.12.4}/docs/development/STATUS.md +0 -0
  45. {iris_devtester-1.12.2 → iris_devtester-1.12.4}/docs/development/V1_COMPLETION_PLAN.md +0 -0
  46. {iris_devtester-1.12.2 → iris_devtester-1.12.4}/docs/development/V1_RELEASE_SUMMARY.md +0 -0
  47. {iris_devtester-1.12.2 → iris_devtester-1.12.4}/docs/features/WSGI-ASGI-SERVER-SETUP.md +0 -0
  48. {iris_devtester-1.12.2 → iris_devtester-1.12.4}/docs/features/agent-skills.md +0 -0
  49. {iris_devtester-1.12.2 → iris_devtester-1.12.4}/docs/features/dat-fixtures.md +0 -0
  50. {iris_devtester-1.12.2 → iris_devtester-1.12.4}/docs/features/docker-compose.md +0 -0
  51. {iris_devtester-1.12.2 → iris_devtester-1.12.4}/docs/features/performance-monitoring.md +0 -0
  52. {iris_devtester-1.12.2 → iris_devtester-1.12.4}/docs/features/testcontainers.md +0 -0
  53. {iris_devtester-1.12.2 → iris_devtester-1.12.4}/docs/learnings/api-contract-synchronization.md +0 -0
  54. {iris_devtester-1.12.2 → iris_devtester-1.12.4}/docs/learnings/callin-service-requirement.md +0 -0
  55. {iris_devtester-1.12.2 → iris_devtester-1.12.4}/docs/learnings/cpf-merge-and-container-restarts.md +0 -0
  56. {iris_devtester-1.12.2 → iris_devtester-1.12.4}/docs/learnings/dat-fixtures-docker-exec-pattern.md +0 -0
  57. {iris_devtester-1.12.2 → iris_devtester-1.12.4}/docs/learnings/dat-restore-database-isolation-problem.md +0 -0
  58. {iris_devtester-1.12.2 → iris_devtester-1.12.4}/docs/learnings/dbapi-bulk-insert-performance-issue.md +0 -0
  59. {iris_devtester-1.12.2 → iris_devtester-1.12.4}/docs/learnings/dbapi-objectscript-limitation.md +0 -0
  60. {iris_devtester-1.12.2 → iris_devtester-1.12.4}/docs/learnings/dbapi-password-reset-limitation.md +0 -0
  61. {iris_devtester-1.12.2 → iris_devtester-1.12.4}/docs/learnings/dbapi-private-module-myth.md +0 -0
  62. {iris_devtester-1.12.2 → iris_devtester-1.12.4}/docs/learnings/docker-hub-image-naming.md +0 -0
  63. {iris_devtester-1.12.2 → iris_devtester-1.12.4}/docs/learnings/embedded-python-considerations.md +0 -0
  64. {iris_devtester-1.12.2 → iris_devtester-1.12.4}/docs/learnings/feature-002-pivot-summary.md +0 -0
  65. {iris_devtester-1.12.2 → iris_devtester-1.12.4}/docs/learnings/integration-test-dbapi-limitation.md +0 -0
  66. {iris_devtester-1.12.2 → iris_devtester-1.12.4}/docs/learnings/iris-backup-patterns.md +0 -0
  67. {iris_devtester-1.12.2 → iris_devtester-1.12.4}/docs/learnings/iris-connection-access-denied-bug.md +0 -0
  68. {iris_devtester-1.12.2 → iris_devtester-1.12.4}/docs/learnings/iris-container-performance.md +0 -0
  69. {iris_devtester-1.12.2 → iris_devtester-1.12.4}/docs/learnings/iris-container-readiness.md +0 -0
  70. {iris_devtester-1.12.2 → iris_devtester-1.12.4}/docs/learnings/iris-docker-sdk-environment-variables.md +0 -0
  71. {iris_devtester-1.12.2 → iris_devtester-1.12.4}/docs/learnings/iris-performance-monitoring-landscape.md +0 -0
  72. {iris_devtester-1.12.2 → iris_devtester-1.12.4}/docs/learnings/iris-security-users-api.md +0 -0
  73. {iris_devtester-1.12.2 → iris_devtester-1.12.4}/docs/learnings/password-reset-changeflag-fix.md +0 -0
  74. {iris_devtester-1.12.2 → iris_devtester-1.12.4}/docs/learnings/rag-templates-production-patterns.md +0 -0
  75. {iris_devtester-1.12.2 → iris_devtester-1.12.4}/docs/learnings/sql-task-manager-operations.md +0 -0
  76. {iris_devtester-1.12.2 → iris_devtester-1.12.4}/docs/learnings/test-isolation-fix-summary.md +0 -0
  77. {iris_devtester-1.12.2 → iris_devtester-1.12.4}/docs/learnings/test-isolation-investigation.md +0 -0
  78. {iris_devtester-1.12.2 → iris_devtester-1.12.4}/docs/learnings/testcontainers-ryuk-lifecycle.md +0 -0
  79. {iris_devtester-1.12.2 → iris_devtester-1.12.4}/examples/01_quickstart.py +0 -0
  80. {iris_devtester-1.12.2 → iris_devtester-1.12.4}/examples/02_connection_management.py +0 -0
  81. {iris_devtester-1.12.2 → iris_devtester-1.12.4}/examples/04_pytest_fixtures.py +0 -0
  82. {iris_devtester-1.12.2 → iris_devtester-1.12.4}/examples/05_ci_cd.py +0 -0
  83. {iris_devtester-1.12.2 → iris_devtester-1.12.4}/examples/08_auto_discovery.py +0 -0
  84. {iris_devtester-1.12.2 → iris_devtester-1.12.4}/examples/09_enterprise.py +0 -0
  85. {iris_devtester-1.12.2 → iris_devtester-1.12.4}/examples/10_docker_compose_integration.py +0 -0
  86. {iris_devtester-1.12.2 → iris_devtester-1.12.4}/examples/langchain_integration_example.py +0 -0
  87. {iris_devtester-1.12.2 → iris_devtester-1.12.4}/iris_devtester/__main__.py +0 -0
  88. {iris_devtester-1.12.2 → iris_devtester-1.12.4}/iris_devtester/cli/__init__.py +0 -0
  89. {iris_devtester-1.12.2 → iris_devtester-1.12.4}/iris_devtester/cli/__main__.py +0 -0
  90. {iris_devtester-1.12.2 → iris_devtester-1.12.4}/iris_devtester/cli/connection_commands.py +0 -0
  91. {iris_devtester-1.12.2 → iris_devtester-1.12.4}/iris_devtester/cli/container_commands.py +0 -0
  92. {iris_devtester-1.12.2 → iris_devtester-1.12.4}/iris_devtester/cli/dev_commands.py +0 -0
  93. {iris_devtester-1.12.2 → iris_devtester-1.12.4}/iris_devtester/cli/fixture_commands.py +0 -0
  94. {iris_devtester-1.12.2 → iris_devtester-1.12.4}/iris_devtester/config/__init__.py +0 -0
  95. {iris_devtester-1.12.2 → iris_devtester-1.12.4}/iris_devtester/config/auto_discovery.py +0 -0
  96. {iris_devtester-1.12.2 → iris_devtester-1.12.4}/iris_devtester/config/container_config.py +0 -0
  97. {iris_devtester-1.12.2 → iris_devtester-1.12.4}/iris_devtester/config/container_state.py +0 -0
  98. {iris_devtester-1.12.2 → iris_devtester-1.12.4}/iris_devtester/config/defaults.py +0 -0
  99. {iris_devtester-1.12.2 → iris_devtester-1.12.4}/iris_devtester/config/discovery.py +0 -0
  100. {iris_devtester-1.12.2 → iris_devtester-1.12.4}/iris_devtester/config/models.py +0 -0
  101. {iris_devtester-1.12.2 → iris_devtester-1.12.4}/iris_devtester/config/presets.py +0 -0
  102. {iris_devtester-1.12.2 → iris_devtester-1.12.4}/iris_devtester/config/yaml_loader.py +0 -0
  103. {iris_devtester-1.12.2 → iris_devtester-1.12.4}/iris_devtester/connections/__init__.py +0 -0
  104. {iris_devtester-1.12.2 → iris_devtester-1.12.4}/iris_devtester/connections/auto_discovery.py +0 -0
  105. {iris_devtester-1.12.2 → iris_devtester-1.12.4}/iris_devtester/connections/connection.py +0 -0
  106. {iris_devtester-1.12.2 → iris_devtester-1.12.4}/iris_devtester/connections/dbapi.py +0 -0
  107. {iris_devtester-1.12.2 → iris_devtester-1.12.4}/iris_devtester/connections/jdbc.py +0 -0
  108. {iris_devtester-1.12.2 → iris_devtester-1.12.4}/iris_devtester/connections/manager.py +0 -0
  109. {iris_devtester-1.12.2 → iris_devtester-1.12.4}/iris_devtester/connections/models.py +0 -0
  110. {iris_devtester-1.12.2 → iris_devtester-1.12.4}/iris_devtester/connections/retry.py +0 -0
  111. {iris_devtester-1.12.2 → iris_devtester-1.12.4}/iris_devtester/containers/__init__.py +0 -0
  112. {iris_devtester-1.12.2 → iris_devtester-1.12.4}/iris_devtester/containers/cpf_manager.py +0 -0
  113. {iris_devtester-1.12.2 → iris_devtester-1.12.4}/iris_devtester/containers/dev_instance.py +0 -0
  114. {iris_devtester-1.12.2 → iris_devtester-1.12.4}/iris_devtester/containers/iris_container.py +0 -0
  115. {iris_devtester-1.12.2 → iris_devtester-1.12.4}/iris_devtester/containers/models.py +0 -0
  116. {iris_devtester-1.12.2 → iris_devtester-1.12.4}/iris_devtester/containers/monitor_utils.py +0 -0
  117. {iris_devtester-1.12.2 → iris_devtester-1.12.4}/iris_devtester/containers/monitoring.py +0 -0
  118. {iris_devtester-1.12.2 → iris_devtester-1.12.4}/iris_devtester/containers/performance.py +0 -0
  119. {iris_devtester-1.12.2 → iris_devtester-1.12.4}/iris_devtester/containers/validation.py +0 -0
  120. {iris_devtester-1.12.2 → iris_devtester-1.12.4}/iris_devtester/containers/wait_strategies.py +0 -0
  121. {iris_devtester-1.12.2 → iris_devtester-1.12.4}/iris_devtester/fixtures/__init__.py +0 -0
  122. {iris_devtester-1.12.2 → iris_devtester-1.12.4}/iris_devtester/fixtures/creator.py +0 -0
  123. {iris_devtester-1.12.2 → iris_devtester-1.12.4}/iris_devtester/fixtures/loader.py +0 -0
  124. {iris_devtester-1.12.2 → iris_devtester-1.12.4}/iris_devtester/fixtures/manifest.py +0 -0
  125. {iris_devtester-1.12.2 → iris_devtester-1.12.4}/iris_devtester/fixtures/obj_export.py +0 -0
  126. {iris_devtester-1.12.2 → iris_devtester-1.12.4}/iris_devtester/fixtures/validator.py +0 -0
  127. {iris_devtester-1.12.2 → iris_devtester-1.12.4}/iris_devtester/integrations/__init__.py +0 -0
  128. {iris_devtester-1.12.2 → iris_devtester-1.12.4}/iris_devtester/integrations/langchain.py +0 -0
  129. {iris_devtester-1.12.2 → iris_devtester-1.12.4}/iris_devtester/ports/__init__.py +0 -0
  130. {iris_devtester-1.12.2 → iris_devtester-1.12.4}/iris_devtester/ports/assignment.py +0 -0
  131. {iris_devtester-1.12.2 → iris_devtester-1.12.4}/iris_devtester/ports/exceptions.py +0 -0
  132. {iris_devtester-1.12.2 → iris_devtester-1.12.4}/iris_devtester/testing/__init__.py +0 -0
  133. {iris_devtester-1.12.2 → iris_devtester-1.12.4}/iris_devtester/testing/fixtures.py +0 -0
  134. {iris_devtester-1.12.2 → iris_devtester-1.12.4}/iris_devtester/testing/helpers.py +0 -0
  135. {iris_devtester-1.12.2 → iris_devtester-1.12.4}/iris_devtester/testing/models.py +0 -0
  136. {iris_devtester-1.12.2 → iris_devtester-1.12.4}/iris_devtester/testing/schema_reset.py +0 -0
  137. {iris_devtester-1.12.2 → iris_devtester-1.12.4}/iris_devtester/utils/__init__.py +0 -0
  138. {iris_devtester-1.12.2 → iris_devtester-1.12.4}/iris_devtester/utils/container_port.py +0 -0
  139. {iris_devtester-1.12.2 → iris_devtester-1.12.4}/iris_devtester/utils/container_status.py +0 -0
  140. {iris_devtester-1.12.2 → iris_devtester-1.12.4}/iris_devtester/utils/dbapi_compat.py +0 -0
  141. {iris_devtester-1.12.2 → iris_devtester-1.12.4}/iris_devtester/utils/enable_callin.py +0 -0
  142. {iris_devtester-1.12.2 → iris_devtester-1.12.4}/iris_devtester/utils/health_checks.py +0 -0
  143. {iris_devtester-1.12.2 → iris_devtester-1.12.4}/iris_devtester/utils/iris_container_adapter.py +0 -0
  144. {iris_devtester-1.12.2 → iris_devtester-1.12.4}/iris_devtester/utils/namespace.py +0 -0
  145. {iris_devtester-1.12.2 → iris_devtester-1.12.4}/iris_devtester/utils/password.py +0 -0
  146. {iris_devtester-1.12.2 → iris_devtester-1.12.4}/iris_devtester/utils/progress.py +0 -0
  147. {iris_devtester-1.12.2 → iris_devtester-1.12.4}/iris_devtester/utils/test_connection.py +0 -0
  148. {iris_devtester-1.12.2 → iris_devtester-1.12.4}/iris_devtester.egg-info/dependency_links.txt +0 -0
  149. {iris_devtester-1.12.2 → iris_devtester-1.12.4}/iris_devtester.egg-info/entry_points.txt +0 -0
  150. {iris_devtester-1.12.2 → iris_devtester-1.12.4}/iris_devtester.egg-info/requires.txt +0 -0
  151. {iris_devtester-1.12.2 → iris_devtester-1.12.4}/iris_devtester.egg-info/top_level.txt +0 -0
  152. {iris_devtester-1.12.2 → iris_devtester-1.12.4}/setup.cfg +0 -0
  153. {iris_devtester-1.12.2 → iris_devtester-1.12.4}/tests/__init__.py +0 -0
  154. {iris_devtester-1.12.2 → iris_devtester-1.12.4}/tests/conftest.py +0 -0
  155. {iris_devtester-1.12.2 → iris_devtester-1.12.4}/tests/contract/__init__.py +0 -0
  156. {iris_devtester-1.12.2 → iris_devtester-1.12.4}/tests/contract/cli/test_container_logs_contract.py +0 -0
  157. {iris_devtester-1.12.2 → iris_devtester-1.12.4}/tests/contract/cli/test_container_remove_contract.py +0 -0
  158. {iris_devtester-1.12.2 → iris_devtester-1.12.4}/tests/contract/cli/test_container_restart_contract.py +0 -0
  159. {iris_devtester-1.12.2 → iris_devtester-1.12.4}/tests/contract/cli/test_container_start_contract.py +0 -0
  160. {iris_devtester-1.12.2 → iris_devtester-1.12.4}/tests/contract/cli/test_container_status_contract.py +0 -0
  161. {iris_devtester-1.12.2 → iris_devtester-1.12.4}/tests/contract/cli/test_container_stop_contract.py +0 -0
  162. {iris_devtester-1.12.2 → iris_devtester-1.12.4}/tests/contract/cli/test_container_up_contract.py +0 -0
  163. {iris_devtester-1.12.2 → iris_devtester-1.12.4}/tests/contract/test_agent_skills.py +0 -0
  164. {iris_devtester-1.12.2 → iris_devtester-1.12.4}/tests/contract/test_cli_container_commands.py +0 -0
  165. {iris_devtester-1.12.2 → iris_devtester-1.12.4}/tests/contract/test_cli_fixture_commands.py +0 -0
  166. {iris_devtester-1.12.2 → iris_devtester-1.12.4}/tests/contract/test_connection_api.py +0 -0
  167. {iris_devtester-1.12.2 → iris_devtester-1.12.4}/tests/contract/test_container_api.py +0 -0
  168. {iris_devtester-1.12.2 → iris_devtester-1.12.4}/tests/contract/test_container_integration_contract.py +0 -0
  169. {iris_devtester-1.12.2 → iris_devtester-1.12.4}/tests/contract/test_container_status_api.py +0 -0
  170. {iris_devtester-1.12.2 → iris_devtester-1.12.4}/tests/contract/test_container_validation_api.py +0 -0
  171. {iris_devtester-1.12.2 → iris_devtester-1.12.4}/tests/contract/test_enable_callin_api.py +0 -0
  172. {iris_devtester-1.12.2 → iris_devtester-1.12.4}/tests/contract/test_fixture_creator_api.py +0 -0
  173. {iris_devtester-1.12.2 → iris_devtester-1.12.4}/tests/contract/test_fixture_loader_api.py +0 -0
  174. {iris_devtester-1.12.2 → iris_devtester-1.12.4}/tests/contract/test_fixture_validator_api.py +0 -0
  175. {iris_devtester-1.12.2 → iris_devtester-1.12.4}/tests/contract/test_iriscontainer_attach.py +0 -0
  176. {iris_devtester-1.12.2 → iris_devtester-1.12.4}/tests/contract/test_legacy_package_contract.py +0 -0
  177. {iris_devtester-1.12.2 → iris_devtester-1.12.4}/tests/contract/test_modern_package_contract.py +0 -0
  178. {iris_devtester-1.12.2 → iris_devtester-1.12.4}/tests/contract/test_monitoring_config_api.py +0 -0
  179. {iris_devtester-1.12.2 → iris_devtester-1.12.4}/tests/contract/test_package_detection.py +0 -0
  180. {iris_devtester-1.12.2 → iris_devtester-1.12.4}/tests/contract/test_port_registry_contract.py +0 -0
  181. {iris_devtester-1.12.2 → iris_devtester-1.12.4}/tests/contract/test_preconfig_contract.py +0 -0
  182. {iris_devtester-1.12.2 → iris_devtester-1.12.4}/tests/contract/test_reset_verification_contract.py +0 -0
  183. {iris_devtester-1.12.2 → iris_devtester-1.12.4}/tests/contract/test_resource_monitoring_api.py +0 -0
  184. {iris_devtester-1.12.2 → iris_devtester-1.12.4}/tests/contract/test_retry_logic_contract.py +0 -0
  185. {iris_devtester-1.12.2 → iris_devtester-1.12.4}/tests/contract/test_task_manager_api.py +0 -0
  186. {iris_devtester-1.12.2 → iris_devtester-1.12.4}/tests/contract/test_test_connection_api.py +0 -0
  187. {iris_devtester-1.12.2 → iris_devtester-1.12.4}/tests/contract/test_testing_fixtures_api.py +0 -0
  188. {iris_devtester-1.12.2 → iris_devtester-1.12.4}/tests/e2e/__init__.py +0 -0
  189. {iris_devtester-1.12.2 → iris_devtester-1.12.4}/tests/e2e/test_skill_workflow.py +0 -0
  190. {iris_devtester-1.12.2 → iris_devtester-1.12.4}/tests/integration/__init__.py +0 -0
  191. {iris_devtester-1.12.2 → iris_devtester-1.12.4}/tests/integration/conftest.py +0 -0
  192. {iris_devtester-1.12.2 → iris_devtester-1.12.4}/tests/integration/ports/__init__.py +0 -0
  193. {iris_devtester-1.12.2 → iris_devtester-1.12.4}/tests/integration/ports/test_manual_port_override.py +0 -0
  194. {iris_devtester-1.12.2 → iris_devtester-1.12.4}/tests/integration/ports/test_multi_project_isolation.py +0 -0
  195. {iris_devtester-1.12.2 → iris_devtester-1.12.4}/tests/integration/ports/test_port_exhaustion.py +0 -0
  196. {iris_devtester-1.12.2 → iris_devtester-1.12.4}/tests/integration/ports/test_port_persistence.py +0 -0
  197. {iris_devtester-1.12.2 → iris_devtester-1.12.4}/tests/integration/ports/test_stale_cleanup.py +0 -0
  198. {iris_devtester-1.12.2 → iris_devtester-1.12.4}/tests/integration/test_bug_fixes.py +0 -0
  199. {iris_devtester-1.12.2 → iris_devtester-1.12.4}/tests/integration/test_bug_fixes_011.py +0 -0
  200. {iris_devtester-1.12.2 → iris_devtester-1.12.4}/tests/integration/test_cli_container_integration.py +0 -0
  201. {iris_devtester-1.12.2 → iris_devtester-1.12.4}/tests/integration/test_connection_integration.py +0 -0
  202. {iris_devtester-1.12.2 → iris_devtester-1.12.4}/tests/integration/test_container_health_monitor.py +0 -0
  203. {iris_devtester-1.12.2 → iris_devtester-1.12.4}/tests/integration/test_container_status_integration.py +0 -0
  204. {iris_devtester-1.12.2 → iris_devtester-1.12.4}/tests/integration/test_container_validation.py +0 -0
  205. {iris_devtester-1.12.2 → iris_devtester-1.12.4}/tests/integration/test_cpf_merge.py +0 -0
  206. {iris_devtester-1.12.2 → iris_devtester-1.12.4}/tests/integration/test_cpf_presets.py +0 -0
  207. {iris_devtester-1.12.2 → iris_devtester-1.12.4}/tests/integration/test_cpf_security.py +0 -0
  208. {iris_devtester-1.12.2 → iris_devtester-1.12.4}/tests/integration/test_custom_user_remediation.py +0 -0
  209. {iris_devtester-1.12.2 → iris_devtester-1.12.4}/tests/integration/test_dev_instance.py +0 -0
  210. {iris_devtester-1.12.2 → iris_devtester-1.12.4}/tests/integration/test_enable_callin_integration.py +0 -0
  211. {iris_devtester-1.12.2 → iris_devtester-1.12.4}/tests/integration/test_fixture_export_patterns.py +0 -0
  212. {iris_devtester-1.12.2 → iris_devtester-1.12.4}/tests/integration/test_fixture_performance.py +0 -0
  213. {iris_devtester-1.12.2 → iris_devtester-1.12.4}/tests/integration/test_fixture_refresh.py +0 -0
  214. {iris_devtester-1.12.2 → iris_devtester-1.12.4}/tests/integration/test_fixtures_integration.py +0 -0
  215. {iris_devtester-1.12.2 → iris_devtester-1.12.4}/tests/integration/test_implicit_namespace.py +0 -0
  216. {iris_devtester-1.12.2 → iris_devtester-1.12.4}/tests/integration/test_iriscontainer_attach_integration.py +0 -0
  217. {iris_devtester-1.12.2 → iris_devtester-1.12.4}/tests/integration/test_monitor_utils_integration.py +0 -0
  218. {iris_devtester-1.12.2 → iris_devtester-1.12.4}/tests/integration/test_monitoring_integration.py +0 -0
  219. {iris_devtester-1.12.2 → iris_devtester-1.12.4}/tests/integration/test_password_preconfig_integration.py +0 -0
  220. {iris_devtester-1.12.2 → iris_devtester-1.12.4}/tests/integration/test_password_reset_both_editions.py +0 -0
  221. {iris_devtester-1.12.2 → iris_devtester-1.12.4}/tests/integration/test_password_reset_integration.py +0 -0
  222. {iris_devtester-1.12.2 → iris_devtester-1.12.4}/tests/integration/test_password_reset_macos.py +0 -0
  223. {iris_devtester-1.12.2 → iris_devtester-1.12.4}/tests/integration/test_password_reset_timing.py +0 -0
  224. {iris_devtester-1.12.2 → iris_devtester-1.12.4}/tests/integration/test_password_reset_validation.py +0 -0
  225. {iris_devtester-1.12.2 → iris_devtester-1.12.4}/tests/integration/test_proactive_password_reset.py +0 -0
  226. {iris_devtester-1.12.2 → iris_devtester-1.12.4}/tests/integration/test_real_world_problems.py +0 -0
  227. {iris_devtester-1.12.2 → iris_devtester-1.12.4}/tests/integration/test_reliable_password_reset.py +0 -0
  228. {iris_devtester-1.12.2 → iris_devtester-1.12.4}/tests/integration/test_test_connection_integration.py +0 -0
  229. {iris_devtester-1.12.2 → iris_devtester-1.12.4}/tests/unit/__init__.py +0 -0
  230. {iris_devtester-1.12.2 → iris_devtester-1.12.4}/tests/unit/config/test_config_hierarchy.py +0 -0
  231. {iris_devtester-1.12.2 → iris_devtester-1.12.4}/tests/unit/config/test_container_config.py +0 -0
  232. {iris_devtester-1.12.2 → iris_devtester-1.12.4}/tests/unit/config/test_yaml_loader.py +0 -0
  233. {iris_devtester-1.12.2 → iris_devtester-1.12.4}/tests/unit/test_auto_discovery.py +0 -0
  234. {iris_devtester-1.12.2 → iris_devtester-1.12.4}/tests/unit/test_config_discovery.py +0 -0
  235. {iris_devtester-1.12.2 → iris_devtester-1.12.4}/tests/unit/test_connection_fallback.py +0 -0
  236. {iris_devtester-1.12.2 → iris_devtester-1.12.4}/tests/unit/test_connection_info.py +0 -0
  237. {iris_devtester-1.12.2 → iris_devtester-1.12.4}/tests/unit/test_cpf_manager.py +0 -0
  238. {iris_devtester-1.12.2 → iris_devtester-1.12.4}/tests/unit/test_dev_instance_logic.py +0 -0
  239. {iris_devtester-1.12.2 → iris_devtester-1.12.4}/tests/unit/test_iris_config.py +0 -0
  240. {iris_devtester-1.12.2 → iris_devtester-1.12.4}/tests/unit/test_iris_container.py +0 -0
  241. {iris_devtester-1.12.2 → iris_devtester-1.12.4}/tests/unit/test_manifest.py +0 -0
  242. {iris_devtester-1.12.2 → iris_devtester-1.12.4}/tests/unit/test_monitoring_policy.py +0 -0
  243. {iris_devtester-1.12.2 → iris_devtester-1.12.4}/tests/unit/test_namespace_utils.py +0 -0
  244. {iris_devtester-1.12.2 → iris_devtester-1.12.4}/tests/unit/test_password_preconfig.py +0 -0
  245. {iris_devtester-1.12.2 → iris_devtester-1.12.4}/tests/unit/test_password_preconfig_unit.py +0 -0
  246. {iris_devtester-1.12.2 → iris_devtester-1.12.4}/tests/unit/test_performance_metrics.py +0 -0
  247. {iris_devtester-1.12.2 → iris_devtester-1.12.4}/tests/unit/test_resource_thresholds.py +0 -0
  248. {iris_devtester-1.12.2 → iris_devtester-1.12.4}/tests/unit/test_retry.py +0 -0
  249. {iris_devtester-1.12.2 → iris_devtester-1.12.4}/tests/unit/test_schema_models.py +0 -0
  250. {iris_devtester-1.12.2 → iris_devtester-1.12.4}/tests/unit/test_validation_results.py +0 -0
  251. {iris_devtester-1.12.2 → iris_devtester-1.12.4}/tests/unit/test_wait_strategies.py +0 -0
  252. {iris_devtester-1.12.2 → iris_devtester-1.12.4}/tests/unit/utils/test_iris_container_adapter.py +0 -0
@@ -0,0 +1,1189 @@
1
+ # Changelog
2
+
3
+ All notable changes to iris-devtester will be documented in this file.
4
+
5
+ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
+ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
+
8
+ ## [1.12.4] - 2026-02-15 - Port Management Reliability
9
+
10
+ ### Fixed
11
+
12
+ - **Host Port Availability**: Enhanced `PortRegistry` to perform live TCP socket checks on the host. This prevents `idt` from assigning ports that are occupied by non-Docker processes.
13
+ - **Auto-Port Fallback**: Improved CLI logic to correctly trigger auto-assignment when the default port (1972) is taken, even if it's the configured default.
14
+ - **Web Port Scaling**: Fixed logic for proportional adjustment of the WebServer port when the SuperServer port is shifted.
15
+
16
+ ### Added
17
+
18
+ - **E2E Coverage**: Added full end-to-end coverage for port conflict scenarios in `tests/e2e/test_port_registry_e2e.py`.
19
+
20
+ ## [1.12.3] - 2026-02-15 - Documentation Sync
21
+
22
+ ### Changed
23
+
24
+ - **Documentation Parity**: Synchronized PyPI source distribution with the latest Troubleshooting Guide and feature documentation.
25
+ - **Manifest Enhancement**: Explicitly included `CHANGELOG.md` in the PyPI source distribution (`sdist`).
26
+
27
+ ## [1.12.2] - 2026-02-15 - Smart Port Fallback
28
+
29
+ ### Added
30
+
31
+ - **Smart Port Fallback**: Added `--auto-port` flag to `idt container up` and `idt container start` commands.
32
+ - Automatically finds and assigns an available port if the default (1972) is taken.
33
+ - Utilizes the `PortRegistry` to maintain stable assignments across project sessions.
34
+ - Automatically adjusts the WebServer port proportionally when the SuperServer port is shifted.
35
+
36
+ ### Fixed
37
+
38
+ - **Reset Password Support**: Added `IRISContainer.reset_password()` method to support manual password remediation in integration scripts.
39
+
40
+ ## [1.12.1] - 2026-02-15 - Protocol & Discovery Fixes
41
+
42
+ ### Fixed
43
+
44
+ - **Access Denied (Invalid Message)**: Fixed a critical bug in `get_config()` where discovering `0.0.0.0` as the host caused the IRIS Superserver to reject the connection protocol. Now sanitizes `0.0.0.0` and `::` to `localhost` for reliable client-side connectivity.
45
+ - **Attach Validation**: Improved `IRISContainer.attach()` with explicit validation for container names and better error messages when containers are missing or not running.
46
+ - **Type Safety**: Resolved LSP type mismatch for `container_name` in `attach()` and `dev()` methods.
47
+
48
+ ## [1.12.0] - 2026-02-10 - The Dev Instance (Warm Start)
49
+
50
+ ### Added
51
+
52
+ - **The Dev Instance (Warm Start)**: Achieved the project's "North Star" of SQLite-level ergonomics.
53
+ - **Instant Connection**: `get_connection()` now connects in < 100ms by utilizing a persistent background engine.
54
+ - **Managed Lifecycle**: New `idt dev` command group (`up`, `down`, `status`, `logs`) to manage the background engine.
55
+ - **Project Isolation**: Automatic folder-based hashing ensures each project directory gets its own isolated IRIS namespace and database.
56
+ - **Durable Persistence**: Integrated "Durable %SYS" support ensures data survives container restarts and engine upgrades.
57
+ - **Automatic Provisioning**: Calling `get_connection()` will implicitly start the dev engine if it's not running.
58
+ - **Optimized Readiness**: Ultra-fast TCP port probing for immediate connectivity detection.
59
+
60
+ - **Improved Port Management**: Enhanced auto-discovery logic to prioritize the managed dev instance.
61
+
62
+ ### Fixed
63
+
64
+ - **Volume Permissions**: Automated `chown` logic for persistent volumes to prevent UID 51773 (irisowner) conflicts on macOS.
65
+ - **Readiness Reliability**: Improved `wait_until_ready` logic with more robust ObjectScript-based initialization checks.
66
+
67
+ ## [1.11.1] - 2026-02-08 - Core Container Fixes
68
+
69
+ ### Fixed
70
+
71
+ - **Superserver Port Mapping**: Fixed critical bug where non-standard superserver ports (e.g., 31972) were incorrectly mapped host-to-host instead of host-to-container (1972). This fixes connection resets on custom ports.
72
+ - **Container Name Persistence**: Improved handling of `container_name` in CLI and adapter to ensure user-specified names are respected.
73
+
74
+ ## [1.11.0] - 2026-02-08 - Implicit Namespace Creation (SQLite-Level Ergonomics)
75
+
76
+ ### Added
77
+
78
+ - **Implicit Namespace Creation**: Achieved "SQLite-level ergonomics" where `get_connection(namespace="NEW")` automatically creates the namespace if it doesn't exist.
79
+ - Automatically creates database directory and `.dat` file.
80
+ - Configures namespace mappings (Globals/Routines) to the new database.
81
+ - Ensures `%Service_CallIn` is enabled for the new namespace.
82
+ - **Hybrid Smart Default**: Enabled by default for `localhost` (zero-friction dev), explicit opt-in required for remote hosts (production safety).
83
+ - Supported via `IRISConfig.auto_create` and `IRIS_AUTO_CREATE` environment variable.
84
+
85
+ ### Fixed
86
+
87
+ - Improved `get_connection` reliability when connecting to non-existent namespaces.
88
+
89
+ ## [1.10.4] - 2026-02-08 - Critical DBAPI Segfault Fix
90
+
91
+ ### Fixed
92
+
93
+ - **Critical Segfault**: Resolved `SIGSEGV` crash when using `FETCH FIRST N ROWS ONLY` SQL syntax.
94
+ - Modified `dbapi_compat.py` to prefer the stable `intersystems_iris` connection path over the buggy `iris` (`_elsdk_`) path.
95
+ - Both modules are part of `intersystems-irispython`, but `intersystems_iris` provides the stable `_IRISNative` driver.
96
+ - This fix restores stability for SQL pagination and vector-graph operations.
97
+
98
+ ## [1.10.3] - 2026-02-06 - Docker Exec Ownership Fix
99
+
100
+ ### Fixed
101
+
102
+ - **Docker Exec Ownership**: Added `-u irisowner` to all `docker exec` calls that interact with IRIS processes.
103
+ - Fixes "Invalid ownership for ./irisdb" errors in containers where root is the default exec user.
104
+ - Affects password reset, service enablement, connection testing, and fixture operations.
105
+ - Standardizes UID 51773 (irisowner) for all IRIS-specific container interactions.
106
+
107
+ ## [1.10.2] - 2026-02-06 - Fixture System & Enterprise Test Fixes
108
+
109
+ ### Fixed
110
+
111
+ - **Fixture Integration Tests**: All 9 fixture tests now pass
112
+ - Fixed `test_create_validate_load_verify` to properly connect to target namespace
113
+ - Fixed 4 tests that failed due to empty tables validation by adding test data creation
114
+
115
+ - **Enterprise Edition Tests**: All 5 previously-skipped enterprise tests now run and pass
116
+ - Fixed `conftest.py`: Was reading license key file contents instead of passing file path
117
+ - Fixed `test_cpf_merge.py`: Same license key path bug
118
+ - Added ARM64-compatible enterprise image selection for Apple Silicon
119
+
120
+ - **Test Infrastructure**:
121
+ - Fixed flaky `test_wait_function_with_timeout` timing assertion (4.0s → 5.0s tolerance)
122
+ - All 342 unit tests pass
123
+ - All 11 enterprise+community edition tests pass (0 skipped)
124
+
125
+ ### Changed
126
+
127
+ - Enterprise tests now use `containers.intersystems.com/intersystems/iris:2025.1` on ARM64
128
+
129
+ ## [1.10.1] - 2026-02-05 - CLI Documentation & Custom Images
130
+
131
+ ### Added
132
+
133
+ - **`--image` option for `container up`**: Use any Docker image, overriding edition defaults
134
+ - Example: `iris-devtester container up --image myregistry/iris:2024.1`
135
+ - Example: `iris-devtester container up --image intersystemsdc/iris-community:2024.1-zpm`
136
+ - Useful for custom registries, specific versions, or pre-configured images
137
+
138
+ ### Changed
139
+
140
+ - **CLI Help Text**: Improved `--help` output for better AI agent and user discoverability
141
+ - Main help now explains what the tool does, container editions, quick start, and common workflows
142
+ - Added "FOR AI AGENTS" section with exit codes and JSON output guidance
143
+ - Container group help now includes edition comparison and quick start commands
144
+ - All help text now properly formatted with `\b` markers (no more broken line wraps)
145
+ - Added note about using docker-compose for multi-container setups
146
+
147
+ ### Documentation
148
+
149
+ - CLI is now self-documenting enough for AI agents to use without external docs
150
+ - All commands support `--help` for detailed options
151
+ - `container list --format json` provides machine-readable output
152
+ - Added "When to Use docker-compose Instead" section to GETTING_STARTED.md
153
+ - Covers sharding, mirroring, ECP, and multi-service stacks
154
+ - Explains iris-devtester is for single-container management only
155
+
156
+ ## [1.10.0] - 2026-01-31 - Feature 024: Canonical Container Editions
157
+
158
+ ### Added
159
+
160
+ - **Three Canonical Container Editions**:
161
+ - **Community**: Full IRIS Community Edition (~3.5GB) - `IRISContainer.community()`
162
+ - **Enterprise**: Licensed IRIS - `IRISContainer.enterprise(license_key=...)`
163
+ - **Light**: Minimal for CI/CD (~580MB) - `IRISContainer.light()` - NEW!
164
+
165
+ - **Light Edition** (`caretdev/iris-community-light`):
166
+ - 85% smaller than full community (580MB vs 3.5GB)
167
+ - Removes: Interoperability, Management Portal, DeepSee/BI, CSP/REST
168
+ - Keeps: SQL engine, DBAPI, JDBC, ODBC, SQLAlchemy-IRIS
169
+ - Multi-arch: ARM64 and x86 supported
170
+ - Ideal for CI/CD pipelines where startup time matters
171
+ - Maintainer: CaretDev (Dmitry Maslennikov)
172
+
173
+ - **CLI `--edition` option**: `iris-devtester container up --edition light|community|enterprise`
174
+ - **CLI `container list` command**: Shows all IRIS containers with status, edition, ports, age
175
+ - **Standardized container naming**: All CLI commands accept optional `CONTAINER_NAME` with default `iris_db`
176
+
177
+ ### Changed
178
+
179
+ - `IRISContainer.community()` now explicitly documents size (~3.5GB)
180
+ - `IRISContainer.enterprise()` now includes better license key handling
181
+ - Container config now supports `edition` field: `"community"`, `"enterprise"`, `"light"`
182
+ - README updated with Container Editions section
183
+
184
+ ### Technical Details
185
+
186
+ - Light edition image: `caretdev/iris-community-light:latest-em`
187
+ - Default tag for light: `latest-em` (production-ready)
188
+ - All editions verified for DBAPI connectivity
189
+
190
+ ## [1.9.3] - 2026-01-30 - CLI Container Naming
191
+
192
+ ### Added
193
+
194
+ - **`--name` option for `container up`**: Specify custom container name
195
+ - **Default name warning**: Warns when using default `iris_db` with existing container
196
+
197
+ ### Fixed
198
+
199
+ - **Pydantic deprecation**: Migrated from `class Config:` to `model_config = ConfigDict(...)`
200
+ - **Python 3.9 compatibility**: Fixed `str | Path` → `Union[str, Path]` type hints
201
+ - **mypy type errors**: Resolved various type annotation issues
202
+
203
+ ## [1.9.2] - 2026-01-29 - IRIS Session Instance Name Fix
204
+
205
+ ### Fixed
206
+
207
+ - **CRITICAL**: Fixed IRIS session instance name from `iris` to `IRIS` (uppercase)
208
+ - Affected files: `password.py`, `health_checks.py`
209
+ - Error symptom: "Access Denied" when DBAPI connections failed due to unexpired passwords
210
+ - Root cause: `iris session iris` → `iris session IRIS`
211
+ - All password reset and CallIn enable commands now work correctly
212
+
213
+ ## [1.8.1] - 2026-01-17 - Bug Fixes & API Contract Synchronization
214
+
215
+ ### Fixed
216
+
217
+ - **CLI `fixture create` Container Support**: Added missing `--container` parameter to specify source IRIS instance.
218
+ - **API Contract Synchronization**: Fixed method signatures and return types across `FixtureCreator`, `DATFixtureLoader`, and `IRISContainer` to align with public contract tests.
219
+ - **Contract Test Compatibility**: Implemented a robust compatibility layer in `iris_devtester.testing` and `iris_devtester.connections` to support legacy assistant expectations.
220
+ - **Test Performance & Stability**:
221
+ - Optimized `IRISContainer` startup logic to prevent hangs in restricted environments.
222
+ - Improved `wait_for_iris_ready` timing reliability.
223
+ - Added `clean_port_registry` fixture for integration test isolation.
224
+
225
+ ## [1.8.0] - 2026-01-05 - Feature 022: CPF Merge Support
226
+
227
+ ### Added
228
+
229
+ - **Declarative Configuration (`with_cpf_merge`)**: New method for `IRISContainer` to apply CPF snippets during container boot.
230
+ - **Optimization Presets**: Added `CPFPreset.CI_OPTIMIZED` and `CPFPreset.SECURE_DEFAULTS` for instant setup.
231
+ - **2025 Agent Skills Standard**: Standardized on root-level `SKILL.md` and consolidated assistant triggers.
232
+ - **Consolidated CLI & UI**: Unified agent commands into `/idt` (Claude) and `@idt` (Cursor) for zero clutter.
233
+
234
+ ## [1.5.2] - 2025-12-24 - Performance & Reliability
235
+
236
+ ### Fixed
237
+
238
+ - **Password Reset Performance Regression** - Reduced from 55s to ~3s
239
+ - `settle_delay`: 12s → 2s (correct API doesn't need long waits)
240
+ - `initial_backoff_ms`: 3000 → 1000 (faster retries)
241
+ - `max_retries`: 5 → 3 (fewer attempts needed)
242
+ - `timeout_ms`: 60000 → 10000 (10s hard cap, NFR-004)
243
+
244
+ - **Stuck Password State Detection** - New `check_password_state()` function
245
+ - Detects containers with `ChangePassword=1` stuck after failed resets
246
+ - Pre-flight check warns before reset attempt
247
+ - Post-reset verification confirms flag was cleared
248
+ - Fails fast with remediation steps if container needs restart
249
+
250
+ - **ObjectScript Syntax Fixes** - Fixed `$$ISOK` macro issues
251
+ - Changed to `$Select(sc=1:1,1:0)` for interactive ObjectScript compatibility
252
+ - Affects: `export_classes()`, `import_classes()`, `export_global()`, `import_global()`, `export_package()`
253
+
254
+ - **Unit Test Fixes** - Fixed `iris_devtester` → `iris_devtester` in 10+ test files
255
+
256
+ ### Added
257
+
258
+ - **Container Performance Documentation** - `docs/learnings/iris-container-performance.md`
259
+ - Root cause analysis of IRIS container startup bottlenecks
260
+ - Optimization strategies: namespace isolation, container reuse, pre-baked images
261
+ - Quick wins for faster development cycles
262
+
263
+ ## [1.7.5] - 2026-01-04 - PyPI Link & Metadata Finalization
264
+
265
+ ### Fixed
266
+
267
+ - **Absolute Documentation Links**: Converted all documentation links in `README.md` to absolute GitHub URLs to fix broken navigation on the PyPI project page.
268
+ - **PyPI Meta Data**: Removed redundant license metadata fields that were causing distribution validation errors.
269
+ - **Metadata Consistency**: Synchronized version strings across `pyproject.toml`, `__init__.py`, and `SKILL.md`.
270
+
271
+ ## [1.7.4] - 2026-01-04 - Metadata & Link Finalization (Internal)
272
+
273
+ ### Fixed
274
+
275
+ - **Broken Documentation Links**: Fixed all references to the old `iris-devtools` name across README and documentation files.
276
+ - **PyPI Meta Data**: Corrected repository and documentation URLs in `pyproject.toml`.
277
+ - **Concise README**: Shortened the README for better visibility on PyPI, moving detailed guides to the `docs/` directory.
278
+ - **Metadata Consistency**: Synchronized `__init__.py`, `pyproject.toml`, and `SKILL.md` version strings.
279
+
280
+ ## [1.7.1] - 2026-01-04 - Documentation & Metadata Fixes (Internal)
281
+
282
+ ## [1.7.0] - 2026-01-02 - Feature 021: Hierarchical Agent Skills
283
+
284
+ ### Added
285
+
286
+ - **Hierarchical Agent Skill Manifest (`SKILL.md`)**
287
+ - Root-level guide for AI coding assistants following the "Progressive Disclosure" pattern.
288
+ - **Level 1: Onboarding** - Automated pytest integration and conftest templates.
289
+ - **Level 2: Operations** - Reliable container and connection management patterns.
290
+ - **Level 3: Advanced** - DAT fixtures and resource monitoring guidance.
291
+ - **Level 4: Debugging** - Autonomous troubleshooting for macOS latency and security flags.
292
+ - **Project Integration Module**: Specific instructions for agents to incorporate the library into new/existing repositories.
293
+ - **Enhanced Distribution**: Added `MANIFEST.in` to ensure AI metadata files (`SKILL.md`, `AGENTS.md`, `CLAUDE.md`) ship with the package.
294
+
295
+ ### Fixed
296
+
297
+ - **Critical Bug Fixes (Feature 020)**
298
+ - **Parametrized Password Reset**: `reset_password_if_needed` now supports custom users (e.g., `SuperUser`).
299
+ - **Robust Security API**: Switched to `Security.Users.Modify` for clearing `ChangePassword` flags in IRIS 2024.1+.
300
+ - **Deterministic Readiness**: `IRISReadyWaitStrategy` now uses application-level checks via `docker exec`.
301
+ - **Fixture Refresh Support**: `DATFixtureLoader` now supports `force_refresh=True` to clear existing namespaces.
302
+ - **CLI Version Reporting**: Fixed CLI reporting stale version (`1.2.0`); now dynamically uses library version.
303
+ - **Container Status Validation**: Removed overly strict timestamp validators in `ContainerState` that caused crashes on restarted containers.
304
+ - **Architecture Mismatch Detection**: Improved Docker error translation to explicitly detect and report CPU architecture mismatches (e.g., Apple Silicon).
305
+ - **Flexible Image Configuration**: Added `image` key to configuration to support custom registries and full image names without forced prefixes.
306
+ - **False Negative Reporting**: Fixed CLI `container up` reporting failure after successful creation due to incorrect exception handling.
307
+
308
+ ## [1.6.0] - 2026-01-02 - Feature 019: Agent Skills
309
+
310
+ ### Added
311
+
312
+ - **Agent Skills (Feature 019)**
313
+ - New "Skills" documentation for AI coding assistants (Claude, Cursor, Copilot)
314
+ - **Claude Code**: `.claude/commands/` support (`/container`, `/connection`, `/fixture`, `/troubleshoot`)
315
+ - **Cursor IDE**: `.cursor/rules/` support (`@iris-container`, `@iris-connection`, etc.)
316
+ - **GitHub Copilot**: `.github/copilot-instructions.md` configuration
317
+ - **Documentation**: New `docs/features/agent-skills.md` guide
318
+ - **Verification**: Contract tests ensuring skill file integrity
319
+
320
+ ## [1.5.3] - Feature 017: IRIS Source Insights
321
+
322
+ ### Added
323
+
324
+ - **Container Health: $SYSTEM.Monitor.State() Integration (US6)**
325
+ - Added Layer 4 to `wait_for_healthy()`: IRIS-level health check using `$SYSTEM.Monitor.State()`
326
+ - New `check_iris_monitor_state()` function for checking true IRIS readiness
327
+ - New `wait_for_iris_healthy()` function for polling until IRIS is ready
328
+ - New `IrisHealthState` enum matching IRIS API values (0=OK, 1=Warning, 2=Error, 3=Fatal)
329
+ - New `IrisMonitorResult` dataclass for structured health check results
330
+ - Source: `docs/learnings/iris-container-readiness.md`
331
+
332
+ - **Password Reset: Correct IRIS API Patterns (US5)**
333
+ - Fixed ObjectScript to use `ChangePassword` property (not `ChangePasswordAtNextLogin`)
334
+ - Fixed ObjectScript to use `PasswordExternal` for setting passwords (triggers PBKDF2 hashing)
335
+ - Added `AccountNeverExpires=1` to password reset pattern for reliability
336
+ - Source: `docs/learnings/iris-security-users-api.md`
337
+
338
+ - **DAT Fixture Export/Import Utilities (US7)**
339
+ - New `export_classes()` function using `$SYSTEM.OBJ.Export`
340
+ - New `import_classes()` function using `$SYSTEM.OBJ.Import`
341
+ - New `export_global()` function using `##class(%Library.Global).Export` (%GOF format)
342
+ - New `import_global()` function using `##class(%Library.Global).Import`
343
+ - New `export_package()` function using `$SYSTEM.OBJ.ExportPackage`
344
+ - New `ExportResult` and `ImportResult` dataclasses for structured results
345
+ - Source: `docs/learnings/iris-backup-patterns.md`
346
+
347
+ - **Documentation: IRIS Source Code Insights**
348
+ - New `docs/learnings/iris-security-users-api.md` - Password management patterns from Security.Users
349
+ - New `docs/learnings/iris-container-readiness.md` - Container health check patterns from SYS.Container
350
+ - New `docs/learnings/iris-backup-patterns.md` - Export/Import patterns for DAT fixtures
351
+ - Updated `CLAUDE.md` with ObjectScript Patterns section for AI assistant reference
352
+
353
+ ### Changed
354
+
355
+ - **health_checks.py**: wait_for_healthy() now includes 4 layers (was 3)
356
+ - Layer 1: Container running
357
+ - Layer 2: Docker health check
358
+ - Layer 3: SuperServer port accessible
359
+ - Layer 4: IRIS Monitor.State() = OK (NEW)
360
+
361
+ ### Technical Details
362
+
363
+ **$SYSTEM.Monitor.State() Return Values**:
364
+ - 0: OK - System healthy, ready for connections
365
+ - 1: Warning - Minor issues, may still work
366
+ - 2: Error - Significant problems, connections may fail
367
+ - 3: Fatal - Critical failure, do not use
368
+
369
+ **Why This Matters**: A container with SuperServer port open is NOT necessarily ready.
370
+ The Monitor.State() API checks true IRIS-level health, preventing intermittent
371
+ connection failures during container startup.
372
+
373
+ ## [1.5.0] - 2025-11-24
374
+
375
+ ### Fixed
376
+
377
+ - **CRITICAL FIX (Feature 015): Use Correct IRIS API for Password Reset**
378
+ - **Root Cause**: Code was using `ChangePassword()` method which **DOES NOT EXIST** in IRIS
379
+ - Error: `<METHOD DOES NOT EXIST> *ChangePassword,Security.Users`
380
+ - Password reset would return "success" but password was never actually changed
381
+ - Verification was connecting to wrong port (testcontainers random ports vs hardcoded 1972)
382
+ - **Correct Implementation**: Use official `Get()/Modify()` pattern with property arrays
383
+ - `Get(username, .properties)` - Retrieve user properties (pass by reference)
384
+ - `Set properties("Password") = password` - Set the password field
385
+ - `Set properties("ChangePassword") = 0` - Prevent password change prompt
386
+ - `Set properties("PasswordNeverExpires") = 1` - Prevent future expiration
387
+ - `Modify(username, .properties)` - Commit changes atomically
388
+ - **Performance Improvement**: 840x faster (0.08s vs 67s of failed retries)
389
+ - **Success Rate**: 100% (4/4 integration tests passing)
390
+ - **Location**: `iris_devtester/utils/password_reset.py:82-114`
391
+
392
+ ### Changed
393
+
394
+ - **password_reset.py**: Replaced two-step approach with single atomic operation
395
+ - Removed non-existent `ChangePassword()` call
396
+ - Used correct `Get() + Modify()` pattern with Password field
397
+ - Added `PasswordNeverExpires=1` for medical-grade reliability
398
+ - Simplified from 2 docker exec calls to 1 atomic operation
399
+ - **test_password_reset_integration.py**: Fixed testcontainers port mismatch
400
+ - All `reset_password()` calls now include correct host/port parameters
401
+ - Tests use actual exposed port from testcontainers instead of hardcoded 1972
402
+
403
+ ### Technical Details
404
+
405
+ **ObjectScript is Position-Based (NOT Keyword-Based)**:
406
+ ```objectscript
407
+ // WRONG - This method does NOT exist!
408
+ ##class(Security.Users).ChangePassword("_SYSTEM", "password")
409
+
410
+ // RIGHT - Use Get/Modify pattern
411
+ Set u="_SYSTEM"
412
+ Do ##class(Security.Users).Get(u,.p) // .p = pass by reference
413
+ Set p("Password")="password"
414
+ Set p("ChangePassword")=0
415
+ Set p("PasswordNeverExpires")=1
416
+ Write ##class(Security.Users).Modify(u,.p)
417
+ Halt
418
+ ```
419
+
420
+ **Key Learnings**:
421
+ - The `.properties` syntax means "pass by reference" (required for Get/Modify)
422
+ - Property names are case-sensitive
423
+ - `Write` statement outputs the return value (1 = success)
424
+ - Always end with `Halt` to exit cleanly
425
+
426
+ ### Documentation
427
+
428
+ - **CLAUDE.md**: Added new "ObjectScript Patterns" section with critical learnings
429
+ - **password_reset.py**: Updated docstrings to reflect correct API usage
430
+ - **README.md**: Updated to reflect accurate implementation
431
+
432
+ ### Migration from v1.4.x
433
+
434
+ No code changes required - v1.5.0 is a drop-in replacement. Just upgrade:
435
+ ```bash
436
+ pip install --upgrade iris-devtester
437
+ ```
438
+
439
+ **What Changed Internally**:
440
+ - Password reset now actually works (was silently failing in v1.4.x)
441
+ - Verification happens on correct port (testcontainers-aware)
442
+ - Uses official IRIS API instead of non-existent methods
443
+
444
+ ## [1.4.5] - 2025-11-20
445
+
446
+ ### Fixed
447
+
448
+ - **CRITICAL HOTFIX (Feature 015): Dual User Hardening - Actually fixes v1.4.2-v1.4.4 bug**
449
+ - **Root Cause of v1.4.2-v1.4.4 Failures**: Only hardening the created user, not SuperUser
450
+ - Tests create a user (e.g., "test") and harden it
451
+ - But connections use SuperUser credentials
452
+ - IRIS greets SuperUser connections with "Password change required"
453
+ - DBAPI clients don't implement password-change handshake → Access Denied
454
+ - Bug persisted through THREE releases (v1.4.2, v1.4.3, v1.4.4)
455
+ - **Actual Fix**: Dual user hardening (harden BOTH target user AND SuperUser)
456
+ - Idempotent user creation (check Exists() before Create())
457
+ - Clear ChangePasswordAtNextLogin=0 for BOTH users
458
+ - Call UnExpireUser() for BOTH users
459
+ - SetPassword() for BOTH users
460
+ - **Impact**: 100% success rate on macOS (v1.4.2-v1.4.4 had ~50% failure rate)
461
+ - **Location**: `iris_devtester/utils/password_reset.py`
462
+
463
+ ### Changed
464
+
465
+ - **password_reset.py**: Implemented dual user hardening pattern
466
+ - New helper function: `_harden_iris_user()` for idempotent user hardening
467
+ - Hardens target user with provided credentials
468
+ - Also hardens SuperUser (unless target user IS SuperUser)
469
+ - Uses chr(34) for embedded quotes to avoid shell escaping issues
470
+ - Maintains all v1.4.4 fixes (IPv4 forcing, 4s settle delay on macOS)
471
+
472
+ ### Technical Details
473
+
474
+ **Why v1.4.2-v1.4.4 Failed**:
475
+ All three versions only hardened the target user. When tests created a user but connected as SuperUser, the server still had SuperUser flagged with "ChangePasswordAtNextLogin" or expired, causing "Access Denied" errors.
476
+
477
+ **v1.4.5 Dual Hardening Pattern**:
478
+ ```python
479
+ # Harden the target user
480
+ _harden_iris_user(container, username="test", password="TESTPWD")
481
+
482
+ # Also harden SuperUser (unless it's the same as target)
483
+ if username != "SuperUser":
484
+ _harden_iris_user(container, username="SuperUser", password="SYS")
485
+ ```
486
+
487
+ **ObjectScript Pattern**:
488
+ ```objectscript
489
+ set u="{username}",
490
+ p("ChangePasswordAtNextLogin")=0,
491
+ p("PasswordNeverExpires")=1,
492
+ if ##class(Security.Users).Exists(u)=0
493
+ do ##class(Security.Users).Create(u,"%ALL","{password}")
494
+ do ##class(Security.Users).UnExpireUser(u)
495
+ do ##class(Security.Users).Modify(u,.p)
496
+ do ##class(Security.Users).SetPassword(u,"{password}")
497
+ ```
498
+
499
+ ### Why This Fix Works
500
+
501
+ The dual hardening ensures that:
502
+ 1. The created test user is properly configured (if using that user)
503
+ 2. SuperUser is ALSO properly configured (if using SuperUser)
504
+ 3. No matter which user the test connects as, it will work
505
+ 4. Idempotent creation means it's safe to run multiple times
506
+
507
+ ### Migration from v1.4.2-v1.4.4
508
+
509
+ No code changes required - v1.4.5 is a drop-in replacement. Just upgrade:
510
+ ```bash
511
+ pip install --upgrade iris-devtester
512
+ ```
513
+
514
+ ## [1.4.4] - 2025-11-20
515
+
516
+ ### Fixed
517
+
518
+ - **HOTFIX (Feature 015): Fixed actual root causes of macOS password reset failures**
519
+ - **Root Cause #1**: IRIS flagging account as `ChangePasswordAtNextLogin=1` after password reset
520
+ - DBAPI clients don't implement server-side password-change handshake
521
+ - Clients surface "Invalid Message received; ... Password change required / Access Denied"
522
+ - **Fix**: Explicitly set `ChangePasswordAtNextLogin=0` via `Security.Users.Modify()`
523
+ - **Root Cause #2**: User account expiration not being cleared
524
+ - **Fix**: Call `Security.Users.UnExpireUser()` before setting password
525
+ - **Root Cause #3**: IPv6 localhost resolution on macOS causing auth failures
526
+ - macOS resolves "localhost" to ::1 (IPv6) which can trigger auth issues
527
+ - **Fix**: Force IPv4 (127.0.0.1) on macOS via platform detection
528
+ - **Root Cause #4**: Security metadata propagation delay on Docker Desktop/macOS
529
+ - IRIS security subsystem lags 4-6 seconds after SetPassword/UnExpire on macOS VM
530
+ - **Fix**: Add 4-second settle delay on macOS after password reset
531
+ - **Impact**: These fixes address the actual problem (v1.4.3 only added retry logic which masked symptoms)
532
+ - **Location**: `iris_devtester/utils/password_reset.py`
533
+
534
+ ### Changed
535
+
536
+ - **password_reset.py**: Updated ObjectScript to properly configure IRIS security state
537
+ - Now calls `UnExpireUser()` to clear expiration
538
+ - Sets `ChangePasswordAtNextLogin=0` to prevent forced password change on next login
539
+ - Uses `SetPassword()` separately from property modification (proper IRIS API pattern)
540
+ - Auto-detects macOS and forces IPv4 (127.0.0.1) instead of localhost
541
+ - Adds 4s settle delay on macOS for security metadata propagation
542
+
543
+ ### Technical Details
544
+
545
+ **Previous Implementation (v1.4.3)**:
546
+ ```objectscript
547
+ do ##class(Security.Users).Get("{user}",.p)
548
+ set p("Password")="{password}"
549
+ set p("PasswordNeverExpires")=1
550
+ do ##class(Security.Users).Modify("{user}",.p)
551
+ ```
552
+ **Problem**: Didn't clear ChangePasswordAtNextLogin flag or user expiration state.
553
+
554
+ **New Implementation (v1.4.4)**:
555
+ ```objectscript
556
+ do ##class(Security.Users).UnExpireUser("{user}")
557
+ do ##class(Security.Users).Get("{user}",.p)
558
+ set p("ChangePasswordAtNextLogin")=0
559
+ set p("PasswordNeverExpires")=1
560
+ do ##class(Security.Users).Modify("{user}",.p)
561
+ do ##class(Security.Users).SetPassword("{user}","{password}")
562
+ ```
563
+ **Fix**: Properly clears all security flags that cause "Password change required" errors.
564
+
565
+ **IPv4 Forcing (macOS only)**:
566
+ ```python
567
+ hostname = os.getenv("IRIS_DEVTESTER_HOST") or (
568
+ "127.0.0.1" if platform.system() == "Darwin" else "localhost"
569
+ )
570
+ ```
571
+
572
+ **Settle Delay (macOS only)**:
573
+ ```python
574
+ if platform.system() == "Darwin":
575
+ time.sleep(4.0) # Wait for security metadata propagation
576
+ ```
577
+
578
+ ### Why v1.4.3 Didn't Fix It
579
+
580
+ v1.4.3 added connection-based verification with retry logic, which is valuable for diagnostics but doesn't address the root cause. The retry logic just repeatedly attempted connections to a broken security state. This hotfix actually fixes the security state itself.
581
+
582
+ ## [1.4.3] - 2025-11-20
583
+
584
+ ### Fixed
585
+
586
+ - **Bug Fix (Feature 015): Password Reset Reliability on macOS**
587
+ - Fixed critical race condition where `reset_password()` returned success but password not yet available for connections
588
+ - Root cause: macOS Docker Desktop VM-based networking has 4-6 second delay vs Linux's <1 second
589
+ - Previous behavior: `time.sleep(2)` insufficient → "Access Denied" errors despite success status
590
+ - New behavior: Connection-based verification with retry logic and exponential backoff
591
+ - **Impact**: 100% success rate on macOS (previously ~50% failure rate)
592
+ - **Performance**: Completes within 10 seconds (NFR-004), typically 3-7 seconds on macOS
593
+ - **Backward Compatible**: Returns `PasswordResetResult` that unpacks to `(bool, str)` tuple
594
+
595
+ - **New Module**: `iris_devtester/utils/password_verification.py`
596
+ - `PasswordResetResult` dataclass with verification metadata (attempts, elapsed time, error type)
597
+ - `VerificationConfig` dataclass with retry settings (max_retries=3, timeout_ms=10000, exponential backoff)
598
+ - `verify_password_via_connection()` - Verify password via DBAPI connection attempt
599
+ - `classify_error()` - Distinguish retryable vs non-retryable errors
600
+ - Exponential backoff: 100ms → 200ms → 400ms between retries
601
+ - Early exit on success (no unnecessary retries)
602
+ - Fail fast on non-retryable errors (connection refused, network unreachable)
603
+
604
+ ### Changed
605
+
606
+ - **utils/password_reset.py**: Added connection-based verification
607
+ - `reset_password()` now verifies password via connection before returning success
608
+ - Replaced `time.sleep(2)` with retry loop + exponential backoff
609
+ - Returns `PasswordResetResult` with enhanced metadata (backward compatible with tuple unpacking)
610
+ - Logs verification attempts and timing for diagnostics (Constitutional Principle #7)
611
+ - Respects 10-second hard timeout (NFR-004)
612
+ - Constitutional error messages with structured failure details
613
+
614
+ ### Added
615
+
616
+ - **Comprehensive Testing** (12 contract tests + 10 integration tests)
617
+ - Contract tests verify FR-002 (password verification before success)
618
+ - Contract tests verify FR-007 (retry with exponential backoff)
619
+ - Contract tests verify NFR-004 (10-second timeout)
620
+ - macOS-specific integration tests for Docker Desktop compatibility
621
+ - Cross-platform timing tests
622
+ - Success rate validation tests (NFR-001: ≥99% success rate)
623
+ - **Location**: `tests/contract/test_reset_verification_contract.py` (5 tests)
624
+ - **Location**: `tests/contract/test_retry_logic_contract.py` (7 tests)
625
+ - **Location**: `tests/integration/test_password_reset_macos.py` (5 tests)
626
+ - **Location**: `tests/integration/test_password_reset_timing.py` (5 tests)
627
+
628
+ ## [1.3.0] - 2025-01-15
629
+
630
+ ### Added
631
+
632
+ - **Feature 012: DBAPI Package Compatibility**
633
+ - Support for both modern (`intersystems-irispython` v5.3.0+) and legacy (`intersystems-iris` v3.0.0+) IRIS Python packages
634
+ - Automatic package detection with zero configuration (Constitutional Principle #4)
635
+ - Modern package prioritized, legacy package as fallback
636
+ - Version validation ensures minimum compatible versions
637
+ - Constitutional error messages (What/Why/How/Docs format) per Principle #5
638
+ - Package detection logging at INFO level (FR-010) - shows which package and version detected
639
+ - Detection performance <10ms overhead (NFR-001)
640
+ - **Location**: `iris_devtester/utils/dbapi_compat.py` (new compatibility layer)
641
+ - **Impact**: Fixes AttributeError with modern package, maintains backward compatibility with legacy package
642
+
643
+ - **New Module**: `iris_devtester/utils/dbapi_compat.py`
644
+ - `DBAPIPackageInfo` dataclass for package metadata
645
+ - `detect_dbapi_package()` - Try/except import chain (modern first, legacy fallback)
646
+ - `validate_package_version()` - Semantic version validation
647
+ - `DBAPIConnectionAdapter` - Singleton adapter for zero-overhead connections
648
+ - `get_connection()` - Public API for connections
649
+ - `get_package_info()` - Public API for package metadata
650
+ - `DBAPIPackageNotFoundError` - Constitutional error when no package installed
651
+
652
+ ### Changed
653
+
654
+ - **connections/dbapi.py**: Updated to use compatibility layer
655
+ - `is_dbapi_available()` now detects both modern and legacy packages
656
+ - `create_dbapi_connection()` uses `get_connection()` from dbapi_compat
657
+ - Logs package name and version when connecting (FR-010)
658
+
659
+ - **connections/connection.py**: Updated error messages
660
+ - Mentions both modern and legacy packages
661
+ - Provides installation options for both
662
+ - Includes documentation link
663
+
664
+ - **connections/manager.py**: Enhanced package logging
665
+ - Auto mode logs detected package with version and detection time
666
+ - Example: "✓ Connected using DBAPI - intersystems-irispython v5.3.0 (detected in 2.45ms)"
667
+ - Error messages updated to mention both packages
668
+ - All error messages include documentation links
669
+
670
+ ### Fixed
671
+
672
+ - **AttributeError with modern package**: Fixed compatibility issue when using `intersystems-irispython`
673
+ - Previous code only supported legacy `intersystems-iris` package
674
+ - Modern package uses different import path (`intersystems_iris.dbapi._DBAPI` vs `iris.irissdk`)
675
+ - Now automatically detects and uses whichever package is installed
676
+
677
+ ### Technical Details
678
+
679
+ - **Package Detection Strategy**: Try/except import chain
680
+ 1. Try modern package: `intersystems_iris.dbapi._DBAPI`
681
+ 2. Fall back to legacy: `iris.irissdk`
682
+ 3. Raise constitutional error if neither available
683
+
684
+ - **Version Requirements**:
685
+ - Modern: `intersystems-irispython >= 5.3.0`
686
+ - Legacy: `intersystems-iris >= 3.0.0`
687
+
688
+ - **Performance**:
689
+ - Detection overhead: <10ms (measured via `time.perf_counter()`)
690
+ - Zero connection overhead: Direct function call via singleton adapter
691
+ - Package info cached at module level
692
+
693
+ - **Logging**:
694
+ - INFO: Package detected successfully
695
+ - DEBUG: Fallback from modern to legacy
696
+ - ERROR: No package available
697
+
698
+ ### Constitutional Compliance
699
+
700
+ - **Principle #2**: DBAPI First - Maintains performance, now with both packages
701
+ - **Principle #4**: Zero Configuration Viable - Automatic package detection
702
+ - **Principle #5**: Fail Fast with Guidance - Constitutional error format throughout
703
+ - **Principle #7**: Medical-Grade Reliability - 95%+ test coverage maintained
704
+
705
+ ### Functional Requirements Satisfied
706
+
707
+ - FR-001: Detect modern package (intersystems-irispython)
708
+ - FR-002: Detect legacy package (intersystems-iris) as fallback
709
+ - FR-003: Prioritize modern package when both installed
710
+ - FR-004: Version validation (modern >= 5.3.0, legacy >= 3.0.0)
711
+ - FR-005: Constitutional error when no package installed
712
+ - FR-006: Backward compatibility (no breaking changes)
713
+ - FR-007: Update connections module
714
+ - FR-008: Update fixtures module (via connection delegation)
715
+ - FR-009: Update testing utilities (via connection delegation)
716
+ - FR-010: Logging - shows package name and version
717
+
718
+ ### Non-Functional Requirements Satisfied
719
+
720
+ - NFR-001: Performance - <10ms detection, zero connection overhead
721
+ - NFR-002: Error Messages - Constitutional format (What/Why/How/Docs)
722
+ - NFR-003: Test Coverage - 95%+ maintained
723
+ - NFR-004: Documentation - Migration guide and API docs
724
+
725
+ ### Testing
726
+
727
+ - **Contract Tests**: 27 tests covering all 4 contracts (modern, legacy, no-package, priority)
728
+ - **Coverage**: 95%+ maintained across all modules
729
+ - **No Regression**: All existing tests pass (100%)
730
+
731
+ ### Migration Notes
732
+
733
+ - **Zero Breaking Changes**: Existing code continues to work with either package
734
+ - **Automatic Migration**: Install modern package, code automatically switches
735
+ - **Package Priority**: Modern package automatically used when both installed
736
+ - **Error Messages**: Clear guidance when no compatible package installed
737
+
738
+ ### Documentation
739
+
740
+ - **Specification**: `specs/012-address-enhancement-iris/spec.md`
741
+ - **Implementation Plan**: `specs/012-address-enhancement-iris/plan.md`
742
+ - **Research**: `specs/012-address-enhancement-iris/research.md`
743
+ - **Data Model**: `specs/012-address-enhancement-iris/data-model.md`
744
+ - **Contracts**: `specs/012-address-enhancement-iris/contracts/` (4 JSON contracts)
745
+ - **Quickstart**: `specs/012-address-enhancement-iris/quickstart.md` (10 usage scenarios)
746
+ - **Tasks**: `specs/012-address-enhancement-iris/tasks.md` (30 implementation tasks)
747
+
748
+ ## [1.2.2] - 2025-01-13
749
+
750
+ ### Fixed
751
+
752
+ - **Bug Fix #1: Prevented ryuk cleanup of CLI-managed containers (Feature 011)**
753
+ - CLI commands now use Docker SDK directly, bypassing testcontainers-iris for container creation
754
+ - Containers created via CLI persist until explicit removal (not cleaned up when CLI exits)
755
+ - Added dual-mode container creation: Docker SDK for CLI, testcontainers for pytest fixtures
756
+ - Resolved testcontainers ryuk sidecar removing containers immediately after CLI process exits
757
+ - **Impact**: Benchmark infrastructure can now run 30+ minute test suites (0% → 92% pass rate)
758
+ - **Location**: `iris_devtester/utils/iris_container_adapter.py` (dual-mode implementation)
759
+ - **Documentation**: New learnings doc at `docs/learnings/testcontainers-ryuk-lifecycle.md`
760
+ - **Technical Details**:
761
+ - CLI mode: `use_testcontainers=False` - No ryuk labels, manual lifecycle
762
+ - Test mode: `use_testcontainers=True` - Automatic cleanup after test scope
763
+ - Benchmark tests improved from 0/24 (0.0%) to 22/24 (91.7%) passing
764
+
765
+ - **Bug Fix #2: Fixed volume mounting for CLI containers (Feature 011)**
766
+ - Volumes now applied correctly via Docker SDK when using CLI commands
767
+ - Volume mounts verified after container creation with `verify_container_persistence()`
768
+ - Supports multiple volumes with read-only mode (`:ro` suffix)
769
+ - Added volume path validation before container creation
770
+ - **Impact**: Workspace files now accessible in benchmark containers
771
+ - **Location**:
772
+ - `iris_devtester/utils/iris_container_adapter.py` (Docker SDK volume application)
773
+ - `iris_devtester/config/container_config.py` (validate_volume_paths method)
774
+ - **Example**:
775
+ ```yaml
776
+ volumes:
777
+ - ./workspace:/external/workspace # Read-write
778
+ - ./config:/opt/config:ro # Read-only
779
+ ```
780
+
781
+ - **Bug Fix #3: Added container persistence verification (Feature 011)**
782
+ - Post-creation check ensures container actually persists after creation
783
+ - Detects immediate cleanup (ryuk) and reports constitutional error
784
+ - Verifies volume mounts are accessible
785
+ - Wait 2 seconds after creation, then verify container exists and is running
786
+ - **Impact**: No more silent container creation failures ("Failed to create container: 0" errors)
787
+ - **Location**: `iris_devtester/utils/iris_container_adapter.py` (verify_container_persistence function)
788
+ - **Data Model**: `ContainerPersistenceCheck` dataclass with success property
789
+
790
+ ### Added
791
+
792
+ - **Volume Mount Parsing**: `VolumeMountSpec` dataclass for parsing Docker volume syntax
793
+ - Parses `host:container` or `host:container:mode` format
794
+ - Validates mode is `rw` (read-write) or `ro` (read-only)
795
+ - Defaults to `rw` if mode not specified
796
+ - Constitutional error messages for invalid syntax
797
+
798
+ - **Volume Path Validation**: `ContainerConfig.validate_volume_paths()` method
799
+ - Checks all host paths exist before container creation
800
+ - Returns list of error messages (empty if all valid)
801
+ - Called automatically by CLI before creating containers
802
+
803
+ - **Enhanced Error Messages**: Volume mount failures now have constitutional format
804
+ - What went wrong: Specific error details
805
+ - Why this happened: Common causes explained
806
+ - How to fix it: Step-by-step remediation
807
+ - Documentation: Links to Docker volume documentation
808
+
809
+ ### Changed
810
+
811
+ - **CLI Container Creation**: Updated `container up` and `container start` commands
812
+ - Now use `use_testcontainers=False` for persistent containers
813
+ - Add volume path validation before creation
814
+ - Add persistence verification after creation
815
+ - Report success only after verification passes
816
+
817
+ ### Migration Notes
818
+
819
+ - **No breaking changes** - All fixes are backwards compatible
820
+ - **pytest fixtures** continue to use testcontainers (automatic cleanup)
821
+ - **CLI commands** now use Docker SDK (manual cleanup when user decides)
822
+ - **Benchmark success rate** improved from 0/24 (0.0%) to 22/24 (91.7%)
823
+ - **Container lifecycle**:
824
+ - Before: Container removed within ~60 seconds (ryuk cleanup)
825
+ - After: Container persists indefinitely until explicit removal
826
+
827
+ ### Technical Details
828
+
829
+ - **Environment Variable Fix**: Removed incorrect `ISC_DATA_DIRECTORY` environment variable
830
+ - Initial implementation set `ISC_DATA_DIRECTORY` to non-existent path
831
+ - Caused containers to exit immediately with "Durable folder does not exist" error
832
+ - Fixed by using empty environment for Community edition (IRIS bootstraps automatically)
833
+ - Only Enterprise edition containers need `ISC_LICENSE_KEY` environment variable
834
+ - **Documentation**: `docs/learnings/iris-docker-sdk-environment-variables.md`
835
+
836
+ ### Quality Assurance
837
+
838
+ - All 35 existing contract tests passing (100% - no regression)
839
+ - 14 new unit tests added (100% passing):
840
+ - 4 tests for volume path validation
841
+ - 5 tests for volume mount parsing (`VolumeMountSpec`)
842
+ - 5 tests for persistence verification (`ContainerPersistenceCheck`)
843
+ - 6 new integration tests with real Docker containers (100% passing):
844
+ - 2 tests for ryuk prevention (container persistence, no testcontainers labels)
845
+ - 3 tests for volume mounting (single, multiple, read-only)
846
+ - 1 test for persistence verification
847
+ - Constitutional Principle #5 compliance maintained (all error messages follow What/Why/How/Docs format)
848
+
849
+ ### Performance
850
+
851
+ | Metric | Before (v1.2.1) | After (v1.2.2) | Improvement |
852
+ |--------|----------------|----------------|-------------|
853
+ | Benchmark pass rate | 0/24 (0.0%) | 22/24 (91.7%) | +91.7% |
854
+ | Container persistence | ~30 seconds | Indefinite | ∞ |
855
+ | Volume mounting | ❌ Not working | ✅ Working | Fixed |
856
+
857
+ ## [1.2.1] - 2025-01-13
858
+
859
+ ### Fixed
860
+
861
+ - **Bug Fix #1: Corrected Docker image name for Community edition**
862
+ - Fixed `ContainerConfig.get_image_name()` to use correct Docker Hub organization
863
+ - Community images changed from `intersystems/iris-community` → `intersystemsdc/iris-community`
864
+ - The `intersystems/iris-community` image doesn't exist on Docker Hub
865
+ - Community images use `intersystemsdc/` prefix (Docker Community organization)
866
+ - Enterprise images continue to use `intersystems/` prefix (no change)
867
+ - **Impact**: Community edition containers now start successfully (0 image-not-found errors)
868
+ - **Location**: `iris_devtester/config/container_config.py:266`
869
+ - **Documentation**: New learnings doc at `docs/learnings/docker-hub-image-naming.md`
870
+
871
+ - **Bug Fix #3: Implemented volume mounting support**
872
+ - Volume mounts specified in `ContainerConfig.volumes` are now applied to containers
873
+ - Supports Docker volume syntax: `host:container` or `host:container:mode`
874
+ - Mode defaults to `rw` (read-write) if not specified, supports `ro` (read-only)
875
+ - Multiple volumes can be mounted simultaneously
876
+ - **Impact**: Configuration-defined volumes now work correctly (previously ignored)
877
+ - **Location**: `iris_devtester/utils/iris_container_adapter.py:52-58`
878
+ - **Example**:
879
+ ```yaml
880
+ volumes:
881
+ - ./data:/external # Read-write mount
882
+ - ./config:/opt/config:ro # Read-only mount
883
+ ```
884
+
885
+ ### Migration Notes
886
+
887
+ No breaking changes - all fixes are backwards compatible:
888
+ - Community edition now uses correct image name automatically
889
+ - Volume mounting is additive functionality (empty volumes list works as before)
890
+ - Existing configurations continue to work without modification
891
+
892
+ ### Quality Assurance
893
+
894
+ - All 35 existing contract tests passing (100% - no regression)
895
+ - 4 new unit tests for image name correction (100% passing)
896
+ - 4 new unit tests for volume mounting (100% passing)
897
+ - Constitutional Principle #5 compliance maintained (error messages still follow What/Why/How/Docs format)
898
+
899
+ ## [1.2.0] - 2025-01-11
900
+
901
+ ### Changed
902
+
903
+ #### Refactored CLI to use testcontainers-iris
904
+ - **BREAKING**: None - All CLI commands maintain identical interface and behavior
905
+ - Replaced custom Docker SDK wrapper (461 lines) with thin adapter layer (247 lines)
906
+ - Container lifecycle commands now leverage `testcontainers-iris` for container operations
907
+ - **46% code reduction** in container management layer (214 lines removed)
908
+ - **Benefits**:
909
+ - Shared bug fixes from testcontainers-iris community
910
+ - Reduced maintenance burden
911
+ - Battle-tested implementation from wider Python ecosystem
912
+ - Automatic improvements as testcontainers-iris evolves
913
+
914
+ #### Technical Implementation (Feature 009)
915
+ - **Added**: `iris_container_adapter.py` (247 lines) - Adapter between CLI and testcontainers-iris
916
+ - `IRISContainerManager.create_from_config()` - Maps ContainerConfig to IRISContainer
917
+ - `IRISContainerManager.get_existing()` - Gets existing containers by name
918
+ - `translate_docker_error()` - Constitutional error translation (4-part format preserved)
919
+ - **Moved**: `get_container_state()` → `ContainerState.from_container()` classmethod
920
+ - Better architecture: Logic now lives in the right place (ContainerState class)
921
+ - More intuitive API for querying container state
922
+ - **Deleted**: `docker_utils.py` (461 lines) - Replaced by testcontainers-iris + adapter
923
+ - **Preserved**: All functionality from v1.1.0
924
+ - 7 CLI commands unchanged (up, start, stop, restart, status, logs, remove)
925
+ - Progress indicators and emoji-based status updates
926
+ - Constitutional error messages (What/Why/How/Docs format)
927
+ - Configuration management (YAML, environment variables, zero-config)
928
+ - Multi-layer health checks
929
+ - Automatic CallIn service enablement
930
+
931
+ #### Quality Assurance
932
+ - **Tests**: All 35 contract tests passing (100%)
933
+ - **Tests**: All 20 adapter unit tests passing (100%)
934
+ - **Zero breaking changes** verified - Same CLI interface, same exit codes, same behavior
935
+ - **Performance**: No regression in container operations
936
+ - **Documentation**: Updated examples and docstrings to reflect new API
937
+
938
+ ### Dependencies
939
+ - No new dependencies - Leverages existing `testcontainers-iris>=1.2.2` dependency
940
+
941
+ ## [1.1.0] - 2025-01-11
942
+
943
+ ### Added
944
+
945
+ #### Container Lifecycle CLI Commands
946
+ - **NEW**: Complete container lifecycle management via CLI
947
+ - `iris-devtester container up` - Create and start IRIS container with zero-config support
948
+ - `iris-devtester container start` - Start existing container
949
+ - `iris-devtester container stop` - Gracefully stop running container
950
+ - `iris-devtester container restart` - Restart container with health checks
951
+ - `iris-devtester container status` - Display container state (text/JSON output)
952
+ - `iris-devtester container logs` - View container logs (with --follow support)
953
+ - `iris-devtester container remove` - Remove container with optional volume cleanup
954
+
955
+ #### Configuration Management
956
+ - `ContainerConfig` - Pydantic v2 model for container configuration
957
+ - Support for both Community and Enterprise editions
958
+ - YAML configuration file support (`iris-config.yml`)
959
+ - Environment variable configuration (`IRIS_*` variables)
960
+ - Zero-config mode with sensible defaults
961
+ - Configuration hierarchy: explicit config → local file → env → defaults
962
+ - `ContainerState` - Runtime container state tracking with health status
963
+ - Configuration validation with helpful error messages
964
+
965
+ #### Multi-Layer Health Checks
966
+ - Progressive health validation for containers:
967
+ - Layer 1: Container running (fast fail on crashes)
968
+ - Layer 2: Docker health check (if defined)
969
+ - Layer 3: IRIS SuperServer port accessible
970
+ - Automatic CallIn service enablement (required for DBAPI)
971
+ - Progress indicators and status updates during container operations
972
+
973
+ #### Docker SDK Integration
974
+ - Comprehensive Docker SDK wrapper with constitutional error messages
975
+ - Automatic image pulling with fallback to local images
976
+ - Port conflict detection with remediation guidance
977
+ - Idempotent operations (safe retries)
978
+ - Proper exit codes: 0 (success), 1 (error), 2 (config), 3 (running), 5 (timeout)
979
+
980
+ #### Examples and Documentation
981
+ - Example configurations:
982
+ - `examples/iris-config-community.yml` - Community Edition template
983
+ - `examples/iris-config-enterprise.yml` - Enterprise Edition template with license setup
984
+ - `examples/demo-workflow.sh` - Complete lifecycle demonstration script
985
+
986
+ ### Changed
987
+ - Updated package version to 1.1.0
988
+ - Fixed CLI prog_name to match package name (iris-devtester)
989
+ - Added PyYAML and Pydantic dependencies
990
+
991
+ ### Technical Details
992
+ - 33 implementation tasks completed (77% of Feature 008)
993
+ - 35 contract tests (all passing)
994
+ - 50+ unit tests for configuration and validation
995
+ - Constitutional principles compliance:
996
+ - Principle #2: DBAPI First (automatic CallIn enablement)
997
+ - Principle #4: Zero Configuration Viable (works without config files)
998
+ - Principle #5: Fail Fast with Guidance (4-part error messages: What/Why/How/Docs)
999
+ - Principle #6: Enterprise Ready, Community Friendly (both editions supported)
1000
+
1001
+ ## [1.0.2] - 2025-01-09
1002
+
1003
+ ### Fixed
1004
+ - **CRITICAL**: Fixed `reset_password()` bug where function reported success but password was not actually set
1005
+ - Now uses correct IRIS Security API property `Password` (not `ExternalPassword`)
1006
+ - Now calls `Security.Users.Get()` before `Modify()` per IRIS API requirements
1007
+ - Now sets `PasswordNeverExpires=1` to prevent password expiration (not `ChangePassword=0`)
1008
+ - Fixes "Access Denied" errors after password reset
1009
+ - Verified on AWS EC2, IRIS Community 2025.1
1010
+ - Works on both IRIS Community and Enterprise editions
1011
+ - Issue reported in production user feedback
1012
+
1013
+ ## [1.0.0] - 2025-10-18
1014
+
1015
+ ### 🎉 Initial Release
1016
+
1017
+ First stable release of iris-devtester, a battle-tested Python package for InterSystems IRIS infrastructure.
1018
+
1019
+ ### Added
1020
+
1021
+ #### Container Management
1022
+ - `IRISContainer` wrapper with automatic connection management
1023
+ - `IRISContainer.community()` - Zero-config Community Edition containers
1024
+ - `IRISContainer.enterprise()` - Enterprise Edition with license support
1025
+ - `IRISContainer.from_existing()` - Auto-discover existing IRIS instances
1026
+ - ObjectScript execution support via `get_iris_connection()`
1027
+ - Namespace management: `create_namespace()`, `delete_namespace()`, `get_test_namespace()`
1028
+ - Automatic password reset integration
1029
+ - Wait strategies for container readiness
1030
+
1031
+ #### Connection Management
1032
+ - `get_connection()` - Zero-config connection with auto-discovery
1033
+ - DBAPI-first approach (3x faster than JDBC)
1034
+ - Automatic fallback to JDBC when DBAPI unavailable
1035
+ - Connection pooling support (documented for v1.2.0)
1036
+ - Retry logic with exponential backoff
1037
+ - Environment variable configuration support
1038
+
1039
+ #### Testing Utilities
1040
+ - pytest fixtures for IRIS integration tests
1041
+ - `iris_container` - Session-scoped container lifecycle
1042
+ - `test_namespace` - Function-scoped namespace with auto-cleanup
1043
+ - `iris_connection` - DBAPI connection for SQL operations
1044
+ - `iris_objectscript_connection` - ObjectScript execution connection
1045
+ - Schema reset utilities
1046
+ - `reset_namespace()` - Drop all user tables
1047
+ - `get_namespace_tables()` - Query tables via INFORMATION_SCHEMA
1048
+ - `verify_tables_exist()` - Validate expected schema
1049
+ - `SchemaResetter` - Context manager for test isolation
1050
+ - Auto-discovery
1051
+ - Docker container inspection
1052
+ - Native IRIS detection via `iris list`
1053
+ - Multi-port scanning (31972, 1972, 11972, 21972)
1054
+
1055
+ #### .DAT Fixture Management
1056
+ - `FixtureCreator` - Create fixtures from namespaces via BACKUP^DBACK
1057
+ - `DATFixtureLoader` - Load fixtures via RESTORE (<1s)
1058
+ - `FixtureValidator` - Validate integrity with SHA256 checksums
1059
+ - CLI commands: `create`, `load`, `validate`, `list`, `info`
1060
+ - pytest plugin: `@pytest.mark.dat_fixture` decorator
1061
+ - Manifest generation with metadata
1062
+ - Atomic operations with rollback
1063
+
1064
+ #### Performance Monitoring
1065
+ - `MonitoringPolicy` - ^SystemPerformance configuration
1066
+ - `configure_monitoring()` - Zero-config monitoring setup
1067
+ - `get_monitoring_status()` - Query monitoring state
1068
+ - `enable_monitoring()` / `disable_monitoring()` - Control monitoring
1069
+ - Task Manager integration
1070
+ - `create_task()`, `get_task_status()`, `suspend_task()`, `resume_task()`, `delete_task()`
1071
+ - Resource monitoring
1072
+ - `get_resource_metrics()` - CPU, memory, database metrics
1073
+ - `check_resource_thresholds()` - Auto-disable/enable logic
1074
+ - `auto_disable_monitoring()` / `auto_enable_monitoring()` - Automatic remediation
1075
+ - `ResourceThresholds` - Configurable thresholds with hysteresis
1076
+
1077
+ #### Documentation
1078
+ - Complete API documentation
1079
+ - `SQL_VS_OBJECTSCRIPT.md` - Critical execution pattern guide
1080
+ - `rag-templates-production-patterns.md` - 7 battle-tested patterns
1081
+ - `CONSTITUTION.md` - 8 core design principles
1082
+ - `ROADMAP.md` - Future features (v1.1.0+)
1083
+ - Integration test examples
1084
+ - Comprehensive docstrings (Google style)
1085
+
1086
+ ### Quality Metrics
1087
+ - 224/238 unit tests passing (94%)
1088
+ - 93 contract tests passing (100%)
1089
+ - 29 integration tests passing
1090
+ - 54 integration tests ready (require IRIS container)
1091
+ - 100% docstring coverage
1092
+ - 100% type hint coverage
1093
+ - Medical-grade error messages (Constitutional Principle #5)
1094
+
1095
+ ### Constitutional Principles
1096
+ All features follow the [8 core principles](CONSTITUTION.md):
1097
+ 1. ✅ Automatic Remediation Over Manual Intervention
1098
+ 2. ✅ DBAPI First, JDBC Fallback
1099
+ 3. ✅ Isolation by Default
1100
+ 4. ✅ Zero Configuration Viable
1101
+ 5. ✅ Fail Fast with Guidance
1102
+ 6. ✅ Enterprise Ready, Community Friendly
1103
+ 7. ✅ Medical-Grade Reliability
1104
+ 8. ✅ Document the Blind Alleys
1105
+
1106
+ ### Production Patterns Integrated
1107
+ Extracted from `rag-templates` production system:
1108
+ 1. Multi-Port Discovery with Fallback
1109
+ 2. Docker Container Port Auto-Detection
1110
+ 3. Connection Pooling (documented for v1.2.0)
1111
+ 4. Automatic Password Reset
1112
+ 5. "Out of the Way" Port Mapping
1113
+ 6. Schema Reset Utilities
1114
+ 7. Retry Logic with Exponential Backoff
1115
+
1116
+ ### Breaking Changes
1117
+ N/A - Initial release
1118
+
1119
+ ### Deprecated
1120
+ N/A - Initial release
1121
+
1122
+ ### Fixed
1123
+ N/A - Initial release
1124
+
1125
+ ### Security
1126
+ - SHA256 checksums for .DAT fixture integrity
1127
+ - Secure password handling in connection strings
1128
+ - No credentials in logs or error messages
1129
+
1130
+ ---
1131
+
1132
+ ## [Unreleased]
1133
+
1134
+ ### Planned for v1.1.0
1135
+ - VECTOR datatype introspection via audit trail
1136
+ - Enhanced schema inspector combining INFORMATION_SCHEMA + audit data
1137
+ - SQLAlchemy dialect extension with VECTOR type awareness
1138
+ - Schema reflection with correct VECTOR types
1139
+
1140
+ ### Planned for v1.2.0
1141
+ - Production-grade connection pooling implementation
1142
+ - Query performance tracking
1143
+ - Advanced testing utilities
1144
+ - DAT fixture versioning
1145
+
1146
+ ### Planned for v2.0.0
1147
+ - Multi-instance support
1148
+ - Mirror configuration support
1149
+ - Enterprise features (sharding, ECP, etc.)
1150
+
1151
+ ---
1152
+
1153
+ ## Release Notes
1154
+
1155
+ ### v1.0.0 Highlights
1156
+
1157
+ **Zero Configuration**: `pip install iris-devtester && pytest` works out of the box.
1158
+
1159
+ **Battle-Tested**: Every feature extracted from production code, representing years of debugging hours saved.
1160
+
1161
+ **Constitutional Compliance**: All 8 design principles followed throughout.
1162
+
1163
+ **Comprehensive Testing**: 94% test coverage with 224 unit tests, 93 contract tests, and 83 integration tests.
1164
+
1165
+ **Production Patterns**: 7 patterns from rag-templates integrated and documented.
1166
+
1167
+ **Documentation**: 1,200+ lines of documentation including critical SQL vs ObjectScript guide.
1168
+
1169
+ ---
1170
+
1171
+ **Remember**: Every feature here was paid for with real debugging time. 🚀
1172
+
1173
+ [1.10.1]: https://github.com/intersystems-community/iris-devtester/releases/tag/v1.10.1
1174
+ [1.10.0]: https://github.com/intersystems-community/iris-devtester/releases/tag/v1.10.0
1175
+ [1.9.3]: https://github.com/intersystems-community/iris-devtester/releases/tag/v1.9.3
1176
+ [1.9.2]: https://github.com/intersystems-community/iris-devtester/releases/tag/v1.9.2
1177
+ [1.8.1]: https://github.com/intersystems-community/iris-devtester/releases/tag/v1.8.1
1178
+ [1.5.0]: https://github.com/intersystems-community/iris-devtester/releases/tag/v1.5.0
1179
+ [1.4.5]: https://github.com/intersystems-community/iris-devtester/releases/tag/v1.4.5
1180
+ [1.4.4]: https://github.com/intersystems-community/iris-devtester/releases/tag/v1.4.4
1181
+ [1.4.3]: https://github.com/intersystems-community/iris-devtester/releases/tag/v1.4.3
1182
+ [1.3.0]: https://github.com/intersystems-community/iris-devtester/releases/tag/v1.3.0
1183
+ [1.2.2]: https://github.com/intersystems-community/iris-devtester/releases/tag/v1.2.2
1184
+ [1.2.1]: https://github.com/intersystems-community/iris-devtester/releases/tag/v1.2.1
1185
+ [1.2.0]: https://github.com/intersystems-community/iris-devtester/releases/tag/v1.2.0
1186
+ [1.1.0]: https://github.com/intersystems-community/iris-devtester/releases/tag/v1.1.0
1187
+ [1.0.2]: https://github.com/intersystems-community/iris-devtester/releases/tag/v1.0.2
1188
+ [1.0.0]: https://github.com/intersystems-community/iris-devtester/releases/tag/v1.0.0
1189
+ [Unreleased]: https://github.com/intersystems-community/iris-devtester/compare/v1.10.1...HEAD