codd-dev 2.12.0__tar.gz → 2.14.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (471) hide show
  1. {codd_dev-2.12.0 → codd_dev-2.14.0}/PKG-INFO +5 -4
  2. {codd_dev-2.12.0 → codd_dev-2.14.0}/README.md +4 -3
  3. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd/cli.py +56 -3
  4. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd/coverage_metrics.py +11 -1
  5. codd_dev-2.14.0/codd/dag/auto_repair.py +164 -0
  6. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd/dag/builder.py +90 -5
  7. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd/dag/checks/__init__.py +41 -1
  8. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd/dag/checks/ci_health.py +68 -8
  9. codd_dev-2.14.0/codd/dag/checks/opt_out.py +265 -0
  10. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd/dag/checks/user_journey_coherence.py +36 -5
  11. codd_dev-2.14.0/codd/dag/runner.py +146 -0
  12. codd_dev-2.14.0/codd/defaults.py +32 -0
  13. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd/deployer.py +25 -4
  14. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd/deployment/__init__.py +9 -0
  15. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd/deployment/extractor.py +56 -0
  16. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd/deployment/providers/ai_command.py +5 -4
  17. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd/elicit/engine.py +15 -0
  18. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd/lexicon.py +21 -9
  19. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd/required_artifacts_deriver.py +3 -1
  20. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd/requirement_completeness_auditor.py +3 -1
  21. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd/validator.py +30 -0
  22. {codd_dev-2.12.0 → codd_dev-2.14.0}/pyproject.toml +1 -1
  23. codd_dev-2.12.0/codd/dag/runner.py +0 -79
  24. {codd_dev-2.12.0 → codd_dev-2.14.0}/.gitignore +0 -0
  25. {codd_dev-2.12.0 → codd_dev-2.14.0}/LICENSE +0 -0
  26. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd/__init__.py +0 -0
  27. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd/__main__.py +0 -0
  28. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd/_git_helper.py +0 -0
  29. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd/ask_user_question_adapter.py +0 -0
  30. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd/assembler.py +0 -0
  31. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd/bridge.py +0 -0
  32. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd/brownfield/__init__.py +0 -0
  33. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd/brownfield/pipeline.py +0 -0
  34. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd/clustering.py +0 -0
  35. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd/coherence_adapters.py +0 -0
  36. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd/coherence_engine.py +0 -0
  37. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd/config.py +0 -0
  38. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd/contracts.py +0 -0
  39. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd/coverage_auditor.py +0 -0
  40. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd/dag/__init__.py +0 -0
  41. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd/dag/checks/depends_on_consistency.py +0 -0
  42. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd/dag/checks/deployment_completeness.py +0 -0
  43. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd/dag/checks/edge_validity.py +0 -0
  44. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd/dag/checks/environment_coverage.py +0 -0
  45. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd/dag/checks/implementation_coverage.py +0 -0
  46. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd/dag/checks/node_completeness.py +0 -0
  47. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd/dag/checks/task_completion.py +0 -0
  48. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd/dag/checks/transitive_closure.py +0 -0
  49. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd/dag/coverage_axes.py +0 -0
  50. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd/dag/defaults/cli.yaml +0 -0
  51. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd/dag/defaults/cpp_embedded.yaml +0 -0
  52. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd/dag/defaults/csharp.yaml +0 -0
  53. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd/dag/defaults/elixir.yaml +0 -0
  54. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd/dag/defaults/generic.yaml +0 -0
  55. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd/dag/defaults/iot.yaml +0 -0
  56. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd/dag/defaults/java.yaml +0 -0
  57. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd/dag/defaults/kotlin.yaml +0 -0
  58. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd/dag/defaults/mobile.yaml +0 -0
  59. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd/dag/defaults/ruby.yaml +0 -0
  60. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd/dag/defaults/rust.yaml +0 -0
  61. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd/dag/defaults/scala.yaml +0 -0
  62. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd/dag/defaults/swift.yaml +0 -0
  63. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd/dag/defaults/test_frameworks.yaml +0 -0
  64. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd/dag/defaults/web.yaml +0 -0
  65. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd/dag/extractor.py +0 -0
  66. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd/defaults.yaml +0 -0
  67. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd/deploy_targets/__init__.py +0 -0
  68. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd/deploy_targets/app_service.py +0 -0
  69. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd/deploy_targets/base.py +0 -0
  70. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd/deploy_targets/docker_compose.py +0 -0
  71. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd/deployment/checks/__init__.py +0 -0
  72. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd/deployment/defaults/deploy_targets.yaml +0 -0
  73. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd/deployment/defaults/runtime_capability_inference.yaml +0 -0
  74. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd/deployment/defaults/schema_providers.yaml +0 -0
  75. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd/deployment/defaults/verification_templates.yaml +0 -0
  76. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd/deployment/providers/__init__.py +0 -0
  77. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd/deployment/providers/llm_consideration.py +0 -0
  78. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd/deployment/providers/schema/__init__.py +0 -0
  79. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd/deployment/providers/schema/prisma.py +0 -0
  80. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd/deployment/providers/target/__init__.py +0 -0
  81. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd/deployment/providers/target/docker_compose.py +0 -0
  82. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd/deployment/providers/verification/__init__.py +0 -0
  83. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd/deployment/providers/verification/assertion_handlers.py +0 -0
  84. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd/deployment/providers/verification/cdp_browser.py +0 -0
  85. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd/deployment/providers/verification/cdp_engines.py +0 -0
  86. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd/deployment/providers/verification/cdp_launchers.py +0 -0
  87. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd/deployment/providers/verification/cdp_wire.py +0 -0
  88. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd/deployment/providers/verification/curl.py +0 -0
  89. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd/deployment/providers/verification/form_strategies.py +0 -0
  90. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd/deployment/providers/verification/means_catalog.py +0 -0
  91. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd/deployment/providers/verification/playwright.py +0 -0
  92. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd/design_md.py +0 -0
  93. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd/diff/__init__.py +0 -0
  94. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd/diff/apply.py +0 -0
  95. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd/diff/engine.py +0 -0
  96. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd/diff/persistence.py +0 -0
  97. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd/diff/templates/diff_prompt.md +0 -0
  98. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd/drift.py +0 -0
  99. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd/e2e_extractor.py +0 -0
  100. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd/e2e_generator.py +0 -0
  101. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd/e2e_runner.py +0 -0
  102. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd/elicit/__init__.py +0 -0
  103. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd/elicit/apply.py +0 -0
  104. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd/elicit/finding.py +0 -0
  105. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd/elicit/formatters/__init__.py +0 -0
  106. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd/elicit/formatters/base.py +0 -0
  107. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd/elicit/formatters/interactive.py +0 -0
  108. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd/elicit/formatters/json_fmt.py +0 -0
  109. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd/elicit/formatters/md.py +0 -0
  110. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd/elicit/lexicon_loader.py +0 -0
  111. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd/elicit/persistence.py +0 -0
  112. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd/elicit/templates/elicit_prompt_L0.md +0 -0
  113. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd/env_refs.py +0 -0
  114. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd/extract_ai.py +0 -0
  115. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd/extractor.py +0 -0
  116. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd/fixer.py +0 -0
  117. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd/fixup_drift.py +0 -0
  118. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd/fixup_drift_strategies/__init__.py +0 -0
  119. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd/fixup_drift_strategies/design_token_drift.py +0 -0
  120. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd/fixup_drift_strategies/lexicon_violation.py +0 -0
  121. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd/fixup_drift_strategies/url_drift.py +0 -0
  122. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd/generator.py +0 -0
  123. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd/graph.py +0 -0
  124. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd/hitl_session.py +0 -0
  125. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd/hooks/__init__.py +0 -0
  126. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd/hooks/pre-commit +0 -0
  127. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd/hooks/recipes/claude_settings_example.json +0 -0
  128. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd/hooks/recipes/codex_hook.sh +0 -0
  129. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd/hooks/recipes/git_post_commit.sh +0 -0
  130. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd/hooks/recipes/git_pre_commit.sh +0 -0
  131. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd/implementer/__init__.py +0 -0
  132. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd/implementer/chunked_runner.py +0 -0
  133. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd/implementer/typecheck_loop.py +0 -0
  134. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd/implementer.py +0 -0
  135. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd/inheritance.py +0 -0
  136. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd/init/__init__.py +0 -0
  137. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd/init/lexicon_suggest.py +0 -0
  138. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd/init/llm_lexicon_suggester.py +0 -0
  139. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd/init/stack_detector.py +0 -0
  140. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd/knowledge_fetcher.py +0 -0
  141. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd/lexicon_cli/__init__.py +0 -0
  142. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd/lexicon_cli/formatters/__init__.py +0 -0
  143. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd/lexicon_cli/formatters/html.py +0 -0
  144. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd/lexicon_cli/formatters/json_fmt.py +0 -0
  145. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd/lexicon_cli/formatters/md.py +0 -0
  146. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd/lexicon_cli/inspector.py +0 -0
  147. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd/lexicon_cli/manager.py +0 -0
  148. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd/lexicon_cli/reporter.py +0 -0
  149. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd/lexicon_cli/threshold.py +0 -0
  150. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd/llm/__init__.py +0 -0
  151. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd/llm/approval.py +0 -0
  152. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd/llm/best_practice_augmenter.py +0 -0
  153. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd/llm/criteria_expander.py +0 -0
  154. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd/llm/design_doc_extractor.py +0 -0
  155. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd/llm/impl_step_deriver.py +0 -0
  156. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd/llm/means_catalog_loader.py +0 -0
  157. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd/llm/parser.py +0 -0
  158. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd/llm/plan_deriver.py +0 -0
  159. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd/llm/prompt_builder.py +0 -0
  160. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd/llm/strategy_validator.py +0 -0
  161. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd/llm/templates/best_practice_augment_meta.md +0 -0
  162. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd/llm/templates/criteria_expand_meta.md +0 -0
  163. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd/llm/templates/design_doc_extract_meta.md +0 -0
  164. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd/llm/templates/impl_step_derive_meta.md +0 -0
  165. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd/llm/templates/implementation_step_catalog.yaml +0 -0
  166. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd/llm/templates/meta_instruction.md +0 -0
  167. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd/llm/templates/plan_derive_meta.md +0 -0
  168. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd/llm/templates/verification_means_catalog.yaml +0 -0
  169. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd/mcp_server.py +0 -0
  170. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd/measure.py +0 -0
  171. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd/parsing.py +0 -0
  172. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd/planner.py +0 -0
  173. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd/policy.py +0 -0
  174. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd/preflight/__init__.py +0 -0
  175. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd/preflight/defaults/cli.yaml +0 -0
  176. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd/preflight/defaults/iot.yaml +0 -0
  177. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd/preflight/defaults/mobile.yaml +0 -0
  178. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd/preflight/defaults/web.yaml +0 -0
  179. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd/propagate.py +0 -0
  180. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd/propagator.py +0 -0
  181. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd/registry.py +0 -0
  182. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd/repair/__init__.py +0 -0
  183. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd/repair/approval_repair.py +0 -0
  184. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd/repair/engine.py +0 -0
  185. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd/repair/git_patcher.py +0 -0
  186. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd/repair/history.py +0 -0
  187. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd/repair/llm_repair_engine.py +0 -0
  188. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd/repair/loop.py +0 -0
  189. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd/repair/primary_picker.py +0 -0
  190. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd/repair/proof_breaks.py +0 -0
  191. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd/repair/repair_result.py +0 -0
  192. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd/repair/repairability_classifier.py +0 -0
  193. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd/repair/schema.py +0 -0
  194. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd/repair/templates/analyze_meta.md +0 -0
  195. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd/repair/templates/propose_meta.md +0 -0
  196. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd/repair/templates/repair_strategy_meta.md +0 -0
  197. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd/repair/templates/repairability_meta.md +0 -0
  198. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd/repair/verify_runner.py +0 -0
  199. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd/repair_slice.py +0 -0
  200. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd/require.py +0 -0
  201. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd/require_plugins.py +0 -0
  202. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd/require_propagate.py +0 -0
  203. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd/required_artifacts/defaults/cli.yaml +0 -0
  204. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd/required_artifacts/defaults/iot.yaml +0 -0
  205. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd/required_artifacts/defaults/mobile.yaml +0 -0
  206. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd/required_artifacts/defaults/web.yaml +0 -0
  207. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd/requirement_completeness/defaults/cli.yaml +0 -0
  208. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd/requirement_completeness/defaults/iot.yaml +0 -0
  209. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd/requirement_completeness/defaults/mobile.yaml +0 -0
  210. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd/requirement_completeness/defaults/web.yaml +0 -0
  211. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd/restore.py +0 -0
  212. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd/routes_extractor.py +0 -0
  213. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd/scanner.py +0 -0
  214. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd/schema_refs.py +0 -0
  215. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd/screen_flow_validator.py +0 -0
  216. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd/screen_transition_extractor.py +0 -0
  217. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd/screen_transitions/defaults.yaml +0 -0
  218. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd/synth.py +0 -0
  219. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd/templates/codd.yaml.tmpl +0 -0
  220. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd/templates/conventions.yaml.tmpl +0 -0
  221. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd/templates/data_dependencies.yaml.tmpl +0 -0
  222. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd/templates/doc_links.yaml.tmpl +0 -0
  223. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd/templates/extract_ai_prompt_baseline.md +0 -0
  224. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd/templates/extracted/api-contract.md.j2 +0 -0
  225. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd/templates/extracted/architecture-overview.md.j2 +0 -0
  226. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd/templates/extracted/module-detail.md.j2 +0 -0
  227. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd/templates/extracted/schema-design.md.j2 +0 -0
  228. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd/templates/extracted/system-context.md.j2 +0 -0
  229. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd/templates/gitignore.tmpl +0 -0
  230. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd/templates/lexicon_questions.md +0 -0
  231. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd/templates/lexicon_schema.yaml +0 -0
  232. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd/templates/overrides.yaml.tmpl +0 -0
  233. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd/traceability.py +0 -0
  234. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd/watch/__init__.py +0 -0
  235. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd/watch/events.py +0 -0
  236. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd/watch/propagation_log.py +0 -0
  237. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd/watch/propagation_pipeline.py +0 -0
  238. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd/watch/test_runner.py +0 -0
  239. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd/watch/watcher.py +0 -0
  240. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd/wiring.py +0 -0
  241. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd_plugins/lexicons/ai_governance_eu_act/coverage_matrix.md +0 -0
  242. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd_plugins/lexicons/ai_governance_eu_act/elicit_extend.md +0 -0
  243. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd_plugins/lexicons/ai_governance_eu_act/lexicon.yaml +0 -0
  244. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd_plugins/lexicons/ai_governance_eu_act/manifest.yaml +0 -0
  245. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd_plugins/lexicons/ai_governance_eu_act/recommended_kinds.yaml +0 -0
  246. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd_plugins/lexicons/ai_governance_eu_act/severity_rules.yaml +0 -0
  247. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd_plugins/lexicons/api_rate_limiting_caching/coverage_matrix.md +0 -0
  248. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd_plugins/lexicons/api_rate_limiting_caching/elicit_extend.md +0 -0
  249. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd_plugins/lexicons/api_rate_limiting_caching/lexicon.yaml +0 -0
  250. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd_plugins/lexicons/api_rate_limiting_caching/manifest.yaml +0 -0
  251. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd_plugins/lexicons/api_rate_limiting_caching/recommended_kinds.yaml +0 -0
  252. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd_plugins/lexicons/api_rate_limiting_caching/severity_rules.yaml +0 -0
  253. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd_plugins/lexicons/api_rest_openapi/coverage_matrix.md +0 -0
  254. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd_plugins/lexicons/api_rest_openapi/elicit_extend.md +0 -0
  255. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd_plugins/lexicons/api_rest_openapi/lexicon.yaml +0 -0
  256. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd_plugins/lexicons/api_rest_openapi/manifest.yaml +0 -0
  257. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd_plugins/lexicons/api_rest_openapi/recommended_kinds.yaml +0 -0
  258. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd_plugins/lexicons/api_rest_openapi/severity_rules.yaml +0 -0
  259. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd_plugins/lexicons/babok/elicit_extend.md +0 -0
  260. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd_plugins/lexicons/babok/lexicon.yaml +0 -0
  261. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd_plugins/lexicons/babok/manifest.yaml +0 -0
  262. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd_plugins/lexicons/babok/recommended_kinds.yaml +0 -0
  263. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd_plugins/lexicons/babok/severity_rules.yaml +0 -0
  264. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd_plugins/lexicons/backend_event_cloudevents/coverage_matrix.md +0 -0
  265. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd_plugins/lexicons/backend_event_cloudevents/elicit_extend.md +0 -0
  266. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd_plugins/lexicons/backend_event_cloudevents/lexicon.yaml +0 -0
  267. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd_plugins/lexicons/backend_event_cloudevents/manifest.yaml +0 -0
  268. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd_plugins/lexicons/backend_event_cloudevents/recommended_kinds.yaml +0 -0
  269. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd_plugins/lexicons/backend_event_cloudevents/severity_rules.yaml +0 -0
  270. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd_plugins/lexicons/backend_graphql/coverage_matrix.md +0 -0
  271. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd_plugins/lexicons/backend_graphql/elicit_extend.md +0 -0
  272. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd_plugins/lexicons/backend_graphql/lexicon.yaml +0 -0
  273. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd_plugins/lexicons/backend_graphql/manifest.yaml +0 -0
  274. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd_plugins/lexicons/backend_graphql/recommended_kinds.yaml +0 -0
  275. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd_plugins/lexicons/backend_graphql/severity_rules.yaml +0 -0
  276. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd_plugins/lexicons/backend_grpc_proto/coverage_matrix.md +0 -0
  277. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd_plugins/lexicons/backend_grpc_proto/elicit_extend.md +0 -0
  278. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd_plugins/lexicons/backend_grpc_proto/lexicon.yaml +0 -0
  279. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd_plugins/lexicons/backend_grpc_proto/manifest.yaml +0 -0
  280. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd_plugins/lexicons/backend_grpc_proto/recommended_kinds.yaml +0 -0
  281. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd_plugins/lexicons/backend_grpc_proto/severity_rules.yaml +0 -0
  282. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd_plugins/lexicons/compliance_hipaa/coverage_matrix.md +0 -0
  283. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd_plugins/lexicons/compliance_hipaa/elicit_extend.md +0 -0
  284. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd_plugins/lexicons/compliance_hipaa/lexicon.yaml +0 -0
  285. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd_plugins/lexicons/compliance_hipaa/manifest.yaml +0 -0
  286. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd_plugins/lexicons/compliance_hipaa/recommended_kinds.yaml +0 -0
  287. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd_plugins/lexicons/compliance_hipaa/severity_rules.yaml +0 -0
  288. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd_plugins/lexicons/compliance_iso27001/coverage_matrix.md +0 -0
  289. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd_plugins/lexicons/compliance_iso27001/elicit_extend.md +0 -0
  290. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd_plugins/lexicons/compliance_iso27001/lexicon.yaml +0 -0
  291. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd_plugins/lexicons/compliance_iso27001/manifest.yaml +0 -0
  292. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd_plugins/lexicons/compliance_iso27001/recommended_kinds.yaml +0 -0
  293. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd_plugins/lexicons/compliance_iso27001/severity_rules.yaml +0 -0
  294. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd_plugins/lexicons/compliance_pci_dss_4/coverage_matrix.md +0 -0
  295. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd_plugins/lexicons/compliance_pci_dss_4/elicit_extend.md +0 -0
  296. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd_plugins/lexicons/compliance_pci_dss_4/lexicon.yaml +0 -0
  297. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd_plugins/lexicons/compliance_pci_dss_4/manifest.yaml +0 -0
  298. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd_plugins/lexicons/compliance_pci_dss_4/recommended_kinds.yaml +0 -0
  299. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd_plugins/lexicons/compliance_pci_dss_4/severity_rules.yaml +0 -0
  300. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd_plugins/lexicons/data_eventsourcing_es_cqrs/coverage_matrix.md +0 -0
  301. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd_plugins/lexicons/data_eventsourcing_es_cqrs/elicit_extend.md +0 -0
  302. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd_plugins/lexicons/data_eventsourcing_es_cqrs/lexicon.yaml +0 -0
  303. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd_plugins/lexicons/data_eventsourcing_es_cqrs/manifest.yaml +0 -0
  304. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd_plugins/lexicons/data_eventsourcing_es_cqrs/recommended_kinds.yaml +0 -0
  305. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd_plugins/lexicons/data_eventsourcing_es_cqrs/severity_rules.yaml +0 -0
  306. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd_plugins/lexicons/data_governance_appi_gdpr/coverage_matrix.md +0 -0
  307. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd_plugins/lexicons/data_governance_appi_gdpr/elicit_extend.md +0 -0
  308. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd_plugins/lexicons/data_governance_appi_gdpr/lexicon.yaml +0 -0
  309. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd_plugins/lexicons/data_governance_appi_gdpr/manifest.yaml +0 -0
  310. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd_plugins/lexicons/data_governance_appi_gdpr/recommended_kinds.yaml +0 -0
  311. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd_plugins/lexicons/data_governance_appi_gdpr/severity_rules.yaml +0 -0
  312. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd_plugins/lexicons/data_nosql_jsonschema/coverage_matrix.md +0 -0
  313. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd_plugins/lexicons/data_nosql_jsonschema/elicit_extend.md +0 -0
  314. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd_plugins/lexicons/data_nosql_jsonschema/lexicon.yaml +0 -0
  315. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd_plugins/lexicons/data_nosql_jsonschema/manifest.yaml +0 -0
  316. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd_plugins/lexicons/data_nosql_jsonschema/recommended_kinds.yaml +0 -0
  317. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd_plugins/lexicons/data_nosql_jsonschema/severity_rules.yaml +0 -0
  318. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd_plugins/lexicons/data_relational_iso_sql/coverage_matrix.md +0 -0
  319. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd_plugins/lexicons/data_relational_iso_sql/elicit_extend.md +0 -0
  320. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd_plugins/lexicons/data_relational_iso_sql/lexicon.yaml +0 -0
  321. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd_plugins/lexicons/data_relational_iso_sql/manifest.yaml +0 -0
  322. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd_plugins/lexicons/data_relational_iso_sql/recommended_kinds.yaml +0 -0
  323. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd_plugins/lexicons/data_relational_iso_sql/severity_rules.yaml +0 -0
  324. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd_plugins/lexicons/ddd_domain_driven_design/coverage_matrix.md +0 -0
  325. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd_plugins/lexicons/ddd_domain_driven_design/elicit_extend.md +0 -0
  326. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd_plugins/lexicons/ddd_domain_driven_design/lexicon.yaml +0 -0
  327. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd_plugins/lexicons/ddd_domain_driven_design/manifest.yaml +0 -0
  328. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd_plugins/lexicons/ddd_domain_driven_design/recommended_kinds.yaml +0 -0
  329. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd_plugins/lexicons/ddd_domain_driven_design/severity_rules.yaml +0 -0
  330. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd_plugins/lexicons/dora_sre_metrics/coverage_matrix.md +0 -0
  331. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd_plugins/lexicons/dora_sre_metrics/elicit_extend.md +0 -0
  332. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd_plugins/lexicons/dora_sre_metrics/lexicon.yaml +0 -0
  333. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd_plugins/lexicons/dora_sre_metrics/manifest.yaml +0 -0
  334. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd_plugins/lexicons/dora_sre_metrics/recommended_kinds.yaml +0 -0
  335. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd_plugins/lexicons/dora_sre_metrics/severity_rules.yaml +0 -0
  336. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd_plugins/lexicons/i18n_unicode_cldr/coverage_matrix.md +0 -0
  337. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd_plugins/lexicons/i18n_unicode_cldr/elicit_extend.md +0 -0
  338. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd_plugins/lexicons/i18n_unicode_cldr/lexicon.yaml +0 -0
  339. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd_plugins/lexicons/i18n_unicode_cldr/manifest.yaml +0 -0
  340. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd_plugins/lexicons/i18n_unicode_cldr/recommended_kinds.yaml +0 -0
  341. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd_plugins/lexicons/i18n_unicode_cldr/severity_rules.yaml +0 -0
  342. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd_plugins/lexicons/ml_model_cards/coverage_matrix.md +0 -0
  343. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd_plugins/lexicons/ml_model_cards/elicit_extend.md +0 -0
  344. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd_plugins/lexicons/ml_model_cards/lexicon.yaml +0 -0
  345. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd_plugins/lexicons/ml_model_cards/manifest.yaml +0 -0
  346. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd_plugins/lexicons/ml_model_cards/recommended_kinds.yaml +0 -0
  347. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd_plugins/lexicons/ml_model_cards/severity_rules.yaml +0 -0
  348. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd_plugins/lexicons/mobile_a11y_native/coverage_matrix.md +0 -0
  349. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd_plugins/lexicons/mobile_a11y_native/elicit_extend.md +0 -0
  350. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd_plugins/lexicons/mobile_a11y_native/lexicon.yaml +0 -0
  351. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd_plugins/lexicons/mobile_a11y_native/manifest.yaml +0 -0
  352. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd_plugins/lexicons/mobile_a11y_native/recommended_kinds.yaml +0 -0
  353. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd_plugins/lexicons/mobile_a11y_native/severity_rules.yaml +0 -0
  354. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd_plugins/lexicons/mobile_android_material3/coverage_matrix.md +0 -0
  355. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd_plugins/lexicons/mobile_android_material3/elicit_extend.md +0 -0
  356. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd_plugins/lexicons/mobile_android_material3/lexicon.yaml +0 -0
  357. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd_plugins/lexicons/mobile_android_material3/manifest.yaml +0 -0
  358. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd_plugins/lexicons/mobile_android_material3/recommended_kinds.yaml +0 -0
  359. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd_plugins/lexicons/mobile_android_material3/severity_rules.yaml +0 -0
  360. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd_plugins/lexicons/mobile_ios_hig/coverage_matrix.md +0 -0
  361. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd_plugins/lexicons/mobile_ios_hig/elicit_extend.md +0 -0
  362. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd_plugins/lexicons/mobile_ios_hig/lexicon.yaml +0 -0
  363. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd_plugins/lexicons/mobile_ios_hig/manifest.yaml +0 -0
  364. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd_plugins/lexicons/mobile_ios_hig/recommended_kinds.yaml +0 -0
  365. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd_plugins/lexicons/mobile_ios_hig/severity_rules.yaml +0 -0
  366. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd_plugins/lexicons/mobile_security_masvs/coverage_matrix.md +0 -0
  367. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd_plugins/lexicons/mobile_security_masvs/elicit_extend.md +0 -0
  368. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd_plugins/lexicons/mobile_security_masvs/lexicon.yaml +0 -0
  369. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd_plugins/lexicons/mobile_security_masvs/manifest.yaml +0 -0
  370. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd_plugins/lexicons/mobile_security_masvs/recommended_kinds.yaml +0 -0
  371. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd_plugins/lexicons/mobile_security_masvs/severity_rules.yaml +0 -0
  372. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd_plugins/lexicons/ops_cicd_pipeline/coverage_matrix.md +0 -0
  373. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd_plugins/lexicons/ops_cicd_pipeline/elicit_extend.md +0 -0
  374. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd_plugins/lexicons/ops_cicd_pipeline/lexicon.yaml +0 -0
  375. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd_plugins/lexicons/ops_cicd_pipeline/manifest.yaml +0 -0
  376. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd_plugins/lexicons/ops_cicd_pipeline/recommended_kinds.yaml +0 -0
  377. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd_plugins/lexicons/ops_cicd_pipeline/severity_rules.yaml +0 -0
  378. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd_plugins/lexicons/ops_iac_terraform/coverage_matrix.md +0 -0
  379. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd_plugins/lexicons/ops_iac_terraform/elicit_extend.md +0 -0
  380. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd_plugins/lexicons/ops_iac_terraform/lexicon.yaml +0 -0
  381. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd_plugins/lexicons/ops_iac_terraform/manifest.yaml +0 -0
  382. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd_plugins/lexicons/ops_iac_terraform/recommended_kinds.yaml +0 -0
  383. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd_plugins/lexicons/ops_iac_terraform/severity_rules.yaml +0 -0
  384. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd_plugins/lexicons/ops_kubernetes/coverage_matrix.md +0 -0
  385. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd_plugins/lexicons/ops_kubernetes/elicit_extend.md +0 -0
  386. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd_plugins/lexicons/ops_kubernetes/lexicon.yaml +0 -0
  387. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd_plugins/lexicons/ops_kubernetes/manifest.yaml +0 -0
  388. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd_plugins/lexicons/ops_kubernetes/recommended_kinds.yaml +0 -0
  389. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd_plugins/lexicons/ops_kubernetes/severity_rules.yaml +0 -0
  390. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd_plugins/lexicons/ops_observability_otel/coverage_matrix.md +0 -0
  391. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd_plugins/lexicons/ops_observability_otel/elicit_extend.md +0 -0
  392. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd_plugins/lexicons/ops_observability_otel/lexicon.yaml +0 -0
  393. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd_plugins/lexicons/ops_observability_otel/manifest.yaml +0 -0
  394. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd_plugins/lexicons/ops_observability_otel/recommended_kinds.yaml +0 -0
  395. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd_plugins/lexicons/ops_observability_otel/severity_rules.yaml +0 -0
  396. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd_plugins/lexicons/process_iso25010/coverage_matrix.md +0 -0
  397. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd_plugins/lexicons/process_iso25010/elicit_extend.md +0 -0
  398. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd_plugins/lexicons/process_iso25010/lexicon.yaml +0 -0
  399. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd_plugins/lexicons/process_iso25010/manifest.yaml +0 -0
  400. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd_plugins/lexicons/process_iso25010/recommended_kinds.yaml +0 -0
  401. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd_plugins/lexicons/process_iso25010/severity_rules.yaml +0 -0
  402. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd_plugins/lexicons/process_test_iso29119/coverage_matrix.md +0 -0
  403. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd_plugins/lexicons/process_test_iso29119/elicit_extend.md +0 -0
  404. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd_plugins/lexicons/process_test_iso29119/lexicon.yaml +0 -0
  405. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd_plugins/lexicons/process_test_iso29119/manifest.yaml +0 -0
  406. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd_plugins/lexicons/process_test_iso29119/recommended_kinds.yaml +0 -0
  407. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd_plugins/lexicons/process_test_iso29119/severity_rules.yaml +0 -0
  408. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd_plugins/lexicons/twelve_factor_app/coverage_matrix.md +0 -0
  409. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd_plugins/lexicons/twelve_factor_app/elicit_extend.md +0 -0
  410. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd_plugins/lexicons/twelve_factor_app/lexicon.yaml +0 -0
  411. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd_plugins/lexicons/twelve_factor_app/manifest.yaml +0 -0
  412. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd_plugins/lexicons/twelve_factor_app/recommended_kinds.yaml +0 -0
  413. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd_plugins/lexicons/twelve_factor_app/severity_rules.yaml +0 -0
  414. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd_plugins/lexicons/web_a11y_wcag22_aa/coverage_matrix.md +0 -0
  415. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd_plugins/lexicons/web_a11y_wcag22_aa/elicit_extend.md +0 -0
  416. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd_plugins/lexicons/web_a11y_wcag22_aa/lexicon.yaml +0 -0
  417. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd_plugins/lexicons/web_a11y_wcag22_aa/manifest.yaml +0 -0
  418. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd_plugins/lexicons/web_a11y_wcag22_aa/recommended_kinds.yaml +0 -0
  419. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd_plugins/lexicons/web_a11y_wcag22_aa/severity_rules.yaml +0 -0
  420. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd_plugins/lexicons/web_authn_webauthn/coverage_matrix.md +0 -0
  421. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd_plugins/lexicons/web_authn_webauthn/elicit_extend.md +0 -0
  422. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd_plugins/lexicons/web_authn_webauthn/lexicon.yaml +0 -0
  423. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd_plugins/lexicons/web_authn_webauthn/manifest.yaml +0 -0
  424. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd_plugins/lexicons/web_authn_webauthn/recommended_kinds.yaml +0 -0
  425. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd_plugins/lexicons/web_authn_webauthn/severity_rules.yaml +0 -0
  426. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd_plugins/lexicons/web_browser_compat/coverage_matrix.md +0 -0
  427. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd_plugins/lexicons/web_browser_compat/elicit_extend.md +0 -0
  428. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd_plugins/lexicons/web_browser_compat/lexicon.yaml +0 -0
  429. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd_plugins/lexicons/web_browser_compat/manifest.yaml +0 -0
  430. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd_plugins/lexicons/web_browser_compat/recommended_kinds.yaml +0 -0
  431. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd_plugins/lexicons/web_browser_compat/severity_rules.yaml +0 -0
  432. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd_plugins/lexicons/web_forms_html5/coverage_matrix.md +0 -0
  433. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd_plugins/lexicons/web_forms_html5/elicit_extend.md +0 -0
  434. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd_plugins/lexicons/web_forms_html5/lexicon.yaml +0 -0
  435. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd_plugins/lexicons/web_forms_html5/manifest.yaml +0 -0
  436. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd_plugins/lexicons/web_forms_html5/recommended_kinds.yaml +0 -0
  437. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd_plugins/lexicons/web_forms_html5/severity_rules.yaml +0 -0
  438. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd_plugins/lexicons/web_performance_core_web_vitals/coverage_matrix.md +0 -0
  439. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd_plugins/lexicons/web_performance_core_web_vitals/elicit_extend.md +0 -0
  440. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd_plugins/lexicons/web_performance_core_web_vitals/lexicon.yaml +0 -0
  441. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd_plugins/lexicons/web_performance_core_web_vitals/manifest.yaml +0 -0
  442. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd_plugins/lexicons/web_performance_core_web_vitals/recommended_kinds.yaml +0 -0
  443. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd_plugins/lexicons/web_performance_core_web_vitals/severity_rules.yaml +0 -0
  444. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd_plugins/lexicons/web_pwa_manifest/coverage_matrix.md +0 -0
  445. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd_plugins/lexicons/web_pwa_manifest/elicit_extend.md +0 -0
  446. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd_plugins/lexicons/web_pwa_manifest/lexicon.yaml +0 -0
  447. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd_plugins/lexicons/web_pwa_manifest/manifest.yaml +0 -0
  448. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd_plugins/lexicons/web_pwa_manifest/recommended_kinds.yaml +0 -0
  449. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd_plugins/lexicons/web_pwa_manifest/severity_rules.yaml +0 -0
  450. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd_plugins/lexicons/web_responsive/coverage_matrix.md +0 -0
  451. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd_plugins/lexicons/web_responsive/elicit_extend.md +0 -0
  452. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd_plugins/lexicons/web_responsive/lexicon.yaml +0 -0
  453. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd_plugins/lexicons/web_responsive/manifest.yaml +0 -0
  454. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd_plugins/lexicons/web_responsive/recommended_kinds.yaml +0 -0
  455. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd_plugins/lexicons/web_responsive/severity_rules.yaml +0 -0
  456. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd_plugins/lexicons/web_security_owasp/coverage_matrix.md +0 -0
  457. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd_plugins/lexicons/web_security_owasp/elicit_extend.md +0 -0
  458. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd_plugins/lexicons/web_security_owasp/lexicon.yaml +0 -0
  459. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd_plugins/lexicons/web_security_owasp/manifest.yaml +0 -0
  460. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd_plugins/lexicons/web_security_owasp/recommended_kinds.yaml +0 -0
  461. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd_plugins/lexicons/web_security_owasp/severity_rules.yaml +0 -0
  462. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd_plugins/lexicons/web_seo_schemaorg/coverage_matrix.md +0 -0
  463. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd_plugins/lexicons/web_seo_schemaorg/elicit_extend.md +0 -0
  464. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd_plugins/lexicons/web_seo_schemaorg/lexicon.yaml +0 -0
  465. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd_plugins/lexicons/web_seo_schemaorg/manifest.yaml +0 -0
  466. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd_plugins/lexicons/web_seo_schemaorg/recommended_kinds.yaml +0 -0
  467. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd_plugins/lexicons/web_seo_schemaorg/severity_rules.yaml +0 -0
  468. {codd_dev-2.12.0 → codd_dev-2.14.0}/codd_plugins/stack_map.yaml +0 -0
  469. {codd_dev-2.12.0 → codd_dev-2.14.0}/docs/cookbook/cdp_browser/README.md +0 -0
  470. {codd_dev-2.12.0 → codd_dev-2.14.0}/docs/requirements/README.md +0 -0
  471. {codd_dev-2.12.0 → codd_dev-2.14.0}/tests/integration/standalone_repair_skeleton/README.md +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: codd-dev
3
- Version: 2.12.0
3
+ Version: 2.14.0
4
4
  Summary: CoDD: Coherence-Driven Development — cross-artifact change impact analysis
5
5
  Project-URL: Homepage, https://github.com/yohey-w/codd-dev
6
6
  Project-URL: Repository, https://github.com/yohey-w/codd-dev
@@ -153,10 +153,11 @@ This is what lets CoDD ship one core that works for Next.js, Django, FastAPI, Ra
153
153
 
154
154
  ## 🧭 Roadmap
155
155
 
156
- - **v2.12.0 (current)** — Test-completeness gates: C7 `actors_without_journeys` amber promotion + new C8 `ci_health` static check (workflow presence, trigger coverage, verification-in-workflow). Defaults to opt-in for legacy projects; new `codd init` projects get `ci:` defaults from the template. See [post-mortem](docs/post-mortems/test_completeness_gap.md).
156
+ - **v2.14.0 (current)** — 8 structural gaps closed (cmd_466 dogfood). Sidecar `<test>.codd.yaml` with `verified_by:` (C6) and `axis_matrix:` (C9); lexicon schema SSoT; completeness_audit batch; `scan.exclude` bug fix (−52% amber noise); `codd dag verify --auto-repair`; elicit mock-AI sentinel; AI timeout 3600 s SSoT. Dogfood re-run: red 22 → 0. See [CHANGELOG](CHANGELOG.md).
157
+ - **v2.13.0** — Opt-out protection: `OptOutPolicy` requires a `justification` + `expires_at` for every config-level opt-out (`ci.provider=none`, etc.). Silent SKIP abolished; severity preserved. `codd validate` reports policy violations. See [post-mortem](docs/post-mortems/optout_loophole.md).
158
+ - **v2.12.0** — Test-completeness gates: C7 `actors_without_journeys` amber promotion + new C8 `ci_health` static check (workflow presence, trigger coverage, verification-in-workflow). See [post-mortem](docs/post-mortems/test_completeness_gap.md).
157
159
  - **v2.11.0** — Sprint-less `codd implement` (`--design <path> --output <dir>` directly; `implementation_plan.md` parser removed). See [migration guide](docs/migrations/v2.11.0-sprintless.md).
158
- - **v2.10.0** — Lexicon-driven completeness, 38 plug-ins, LLM-enhanced init, scope/phase filter, auto-repair across the full DAG.
159
- - **v2.13.0 (next)** — C8 `ci_health` runtime mode (opt-in `ci.runtime_check: true`) polling the CI provider for latest-run-on-default-branch success.
160
+ - **v2.15.0 (next)** — C8 `ci_health` runtime mode (opt-in `ci.runtime_check: true`) polling the CI provider for latest-run-on-default-branch success.
160
161
 
161
162
  ---
162
163
 
@@ -113,10 +113,11 @@ This is what lets CoDD ship one core that works for Next.js, Django, FastAPI, Ra
113
113
 
114
114
  ## 🧭 Roadmap
115
115
 
116
- - **v2.12.0 (current)** — Test-completeness gates: C7 `actors_without_journeys` amber promotion + new C8 `ci_health` static check (workflow presence, trigger coverage, verification-in-workflow). Defaults to opt-in for legacy projects; new `codd init` projects get `ci:` defaults from the template. See [post-mortem](docs/post-mortems/test_completeness_gap.md).
116
+ - **v2.14.0 (current)** — 8 structural gaps closed (cmd_466 dogfood). Sidecar `<test>.codd.yaml` with `verified_by:` (C6) and `axis_matrix:` (C9); lexicon schema SSoT; completeness_audit batch; `scan.exclude` bug fix (−52% amber noise); `codd dag verify --auto-repair`; elicit mock-AI sentinel; AI timeout 3600 s SSoT. Dogfood re-run: red 22 → 0. See [CHANGELOG](CHANGELOG.md).
117
+ - **v2.13.0** — Opt-out protection: `OptOutPolicy` requires a `justification` + `expires_at` for every config-level opt-out (`ci.provider=none`, etc.). Silent SKIP abolished; severity preserved. `codd validate` reports policy violations. See [post-mortem](docs/post-mortems/optout_loophole.md).
118
+ - **v2.12.0** — Test-completeness gates: C7 `actors_without_journeys` amber promotion + new C8 `ci_health` static check (workflow presence, trigger coverage, verification-in-workflow). See [post-mortem](docs/post-mortems/test_completeness_gap.md).
117
119
  - **v2.11.0** — Sprint-less `codd implement` (`--design <path> --output <dir>` directly; `implementation_plan.md` parser removed). See [migration guide](docs/migrations/v2.11.0-sprintless.md).
118
- - **v2.10.0** — Lexicon-driven completeness, 38 plug-ins, LLM-enhanced init, scope/phase filter, auto-repair across the full DAG.
119
- - **v2.13.0 (next)** — C8 `ci_health` runtime mode (opt-in `ci.runtime_check: true`) polling the CI provider for latest-run-on-default-branch success.
120
+ - **v2.15.0 (next)** — C8 `ci_health` runtime mode (opt-in `ci.runtime_check: true`) polling the CI provider for latest-run-on-default-branch success.
120
121
 
121
122
  ---
122
123
 
@@ -4890,7 +4890,28 @@ def dag_build(project_path: str, output_format: str, cache: bool, output: str |
4890
4890
  type=click.Choice(["text", "json"]),
4891
4891
  help="Output format",
4892
4892
  )
4893
- def dag_verify(project_path: str, check_names: tuple[str, ...], output_format: str):
4893
+ @click.option(
4894
+ "--auto-repair",
4895
+ is_flag=True,
4896
+ default=False,
4897
+ help="Apply violation-output suggestions mechanically (e.g. append "
4898
+ "suggested_lexicon_entry to project_lexicon.yaml). Implies a dry-run "
4899
+ "preview unless --apply is also supplied.",
4900
+ )
4901
+ @click.option(
4902
+ "--apply",
4903
+ "apply_changes",
4904
+ is_flag=True,
4905
+ default=False,
4906
+ help="Write changes to disk when --auto-repair is set. Default: dry run.",
4907
+ )
4908
+ def dag_verify(
4909
+ project_path: str,
4910
+ check_names: tuple[str, ...],
4911
+ output_format: str,
4912
+ auto_repair: bool,
4913
+ apply_changes: bool,
4914
+ ):
4894
4915
  """Run DAG completeness checks."""
4895
4916
  from codd.dag.runner import run_all_checks
4896
4917
 
@@ -4901,10 +4922,13 @@ def dag_verify(project_path: str, check_names: tuple[str, ...], output_format: s
4901
4922
  click.echo(f"Error: {exc}")
4902
4923
  raise SystemExit(1)
4903
4924
 
4925
+ opt_out_results = [result for result in results if _dag_result_status(result) == "opt_out"]
4904
4926
  failed_red = [
4905
4927
  result
4906
4928
  for result in results
4907
- if not _dag_result_passed(result) and _dag_result_severity(result) == "red"
4929
+ if not _dag_result_passed(result)
4930
+ and _dag_result_severity(result) == "red"
4931
+ and _dag_result_status(result) != "opt_out"
4908
4932
  ]
4909
4933
  amber_findings = [
4910
4934
  result
@@ -4917,7 +4941,10 @@ def dag_verify(project_path: str, check_names: tuple[str, ...], output_format: s
4917
4941
  else:
4918
4942
  for result in results:
4919
4943
  severity = _dag_result_severity(result)
4920
- if _dag_result_passed(result):
4944
+ status_value = _dag_result_status(result)
4945
+ if status_value == "opt_out":
4946
+ status = "OPT_OUT"
4947
+ elif _dag_result_passed(result):
4921
4948
  status = "PASS"
4922
4949
  else:
4923
4950
  status = "WARN" if severity == "amber" else "FAIL"
@@ -4929,6 +4956,24 @@ def dag_verify(project_path: str, check_names: tuple[str, ...], output_format: s
4929
4956
  click.echo(f"\n{len(failed_red)} check(s) FAILED (severity=red)")
4930
4957
  elif amber_findings:
4931
4958
  click.echo(f"\n{len(amber_findings)} check(s) WARN (severity=amber, deploy allowed)")
4959
+ if opt_out_results:
4960
+ click.echo(f"\n{len(opt_out_results)} active opt-out(s) (deploy allowed):")
4961
+ for result in opt_out_results:
4962
+ click.echo(f" - {_dag_result_name(result)}: {_dag_result_message(result)}")
4963
+
4964
+ if auto_repair:
4965
+ from codd.dag.auto_repair import apply_auto_repair
4966
+
4967
+ outcome = apply_auto_repair(project_root, results, dry_run=not apply_changes)
4968
+ click.echo("")
4969
+ verb = "Would apply" if not apply_changes else "Applied"
4970
+ click.echo(f"{verb} {len(outcome.applied)} repair(s):")
4971
+ for action in outcome.applied:
4972
+ click.echo(f" - {action.description}")
4973
+ if outcome.skipped:
4974
+ click.echo(f"\nSkipped {len(outcome.skipped)} non-repairable violation(s):")
4975
+ for action in outcome.skipped:
4976
+ click.echo(f" - {action.description}")
4932
4977
 
4933
4978
  raise SystemExit(1 if failed_red else 0)
4934
4979
 
@@ -5185,6 +5230,14 @@ def _dag_result_passed(result: Any) -> bool:
5185
5230
  return _dag_result_value(result, "passed") is not False
5186
5231
 
5187
5232
 
5233
+ def _dag_result_status(result: Any) -> str:
5234
+ return str(_dag_result_value(result, "status") or "")
5235
+
5236
+
5237
+ def _dag_result_message(result: Any) -> str:
5238
+ return str(_dag_result_value(result, "message") or "")
5239
+
5240
+
5188
5241
  def _dag_result_has_findings(result: Any) -> bool:
5189
5242
  for key in (
5190
5243
  "violations",
@@ -183,12 +183,17 @@ def compute_dag_completeness(
183
183
  return _exception_result("dag_completeness", threshold, exc)
184
184
 
185
185
  red_results = [result for result in results if _dag_result_severity(result) == "red"]
186
- failed_red = [result for result in red_results if _dag_result_passed(result) is False]
186
+ failed_red = [
187
+ result
188
+ for result in red_results
189
+ if _dag_result_passed(result) is False and _dag_result_status(result) != "opt_out"
190
+ ]
187
191
  amber_findings = [
188
192
  result
189
193
  for result in results
190
194
  if _dag_result_severity(result) == "amber" and _dag_result_has_findings(result)
191
195
  ]
196
+ opt_outs = [result for result in results if _dag_result_status(result) == "opt_out"]
192
197
 
193
198
  total = len(red_results)
194
199
  uncovered = len(failed_red)
@@ -197,6 +202,7 @@ def compute_dag_completeness(
197
202
  details = [f"checks: {len(results)}", f"red_failures: {uncovered}"]
198
203
  details.extend(_format_dag_result(result) for result in failed_red[:5])
199
204
  details.extend(f"warning: {_format_dag_result(result)}" for result in amber_findings[:5])
205
+ details.extend(f"opt_out: {_format_dag_result(result)}" for result in opt_outs[:5])
200
206
 
201
207
  return CoverageResult(
202
208
  metric="dag_completeness",
@@ -361,6 +367,10 @@ def _dag_result_passed(result: Any) -> bool:
361
367
  return _dag_result_value(result, "passed") is not False
362
368
 
363
369
 
370
+ def _dag_result_status(result: Any) -> str:
371
+ return str(_dag_result_value(result, "status") or "")
372
+
373
+
364
374
  def _dag_result_name(result: Any) -> str:
365
375
  return str(_dag_result_value(result, "check_name") or result.__class__.__name__)
366
376
 
@@ -0,0 +1,164 @@
1
+ """Mechanical auto-repair for DAG-verify violations.
2
+
3
+ Reads the violation output produced by ``codd dag verify`` and applies the
4
+ ``suggested_*`` payloads to the project's filesystem without invoking AI.
5
+
6
+ Currently supported repair types:
7
+
8
+ * ``missing_journey_lexicon`` — append the ``suggested_lexicon_entry`` to
9
+ ``project_lexicon.yaml`` under ``required_artifacts``.
10
+
11
+ Repair types that need a project-specific anchor (e.g. ``no_plan_task_for_journey``
12
+ which requires the user to choose which plan section gets the new outputs)
13
+ are listed in ``RepairOutcome.skipped`` with a human-readable reason so the
14
+ operator knows what still has to be done by hand.
15
+ """
16
+
17
+ from __future__ import annotations
18
+
19
+ from dataclasses import dataclass, field
20
+ from pathlib import Path
21
+ from typing import Any, Iterable
22
+
23
+ import yaml
24
+
25
+
26
+ @dataclass(frozen=True)
27
+ class RepairAction:
28
+ description: str
29
+
30
+
31
+ @dataclass
32
+ class RepairOutcome:
33
+ applied: list[RepairAction] = field(default_factory=list)
34
+ skipped: list[RepairAction] = field(default_factory=list)
35
+
36
+
37
+ def apply_auto_repair(
38
+ project_root: Path,
39
+ results: Iterable[Any],
40
+ *,
41
+ dry_run: bool = True,
42
+ ) -> RepairOutcome:
43
+ """Apply mechanical repairs derived from DAG verify violation output.
44
+
45
+ Parameters
46
+ ----------
47
+ project_root
48
+ Project root used to resolve relative file paths.
49
+ results
50
+ Iterable of DAG check result objects (or dicts) as returned by
51
+ ``codd.dag.runner.run_all_checks``.
52
+ dry_run
53
+ When True, the function reports what *would* be applied without
54
+ modifying the filesystem.
55
+ """
56
+
57
+ outcome = RepairOutcome()
58
+ suggested_entries: list[dict[str, Any]] = []
59
+
60
+ for result in results:
61
+ violations = _result_value(result, "violations") or []
62
+ if not isinstance(violations, list):
63
+ continue
64
+ for violation in violations:
65
+ if not isinstance(violation, dict):
66
+ continue
67
+ v_type = violation.get("type")
68
+ if v_type == "missing_journey_lexicon":
69
+ entry = violation.get("suggested_lexicon_entry")
70
+ if isinstance(entry, dict) and entry.get("id"):
71
+ suggested_entries.append(entry)
72
+ else:
73
+ outcome.skipped.append(
74
+ RepairAction(
75
+ description=(
76
+ "missing_journey_lexicon without suggested_lexicon_entry; "
77
+ "violation cannot be auto-repaired"
78
+ )
79
+ )
80
+ )
81
+ continue
82
+ outcome.skipped.append(
83
+ RepairAction(
84
+ description=f"{v_type or '<unknown>'} — no mechanical repair available",
85
+ )
86
+ )
87
+
88
+ if suggested_entries:
89
+ repaired_ids = _apply_lexicon_entries(
90
+ project_root, suggested_entries, dry_run=dry_run
91
+ )
92
+ for entry_id in repaired_ids:
93
+ verb = "would append" if dry_run else "appended"
94
+ outcome.applied.append(
95
+ RepairAction(
96
+ description=(
97
+ f"project_lexicon.yaml: {verb} required_artifacts entry "
98
+ f"'{entry_id}'"
99
+ )
100
+ )
101
+ )
102
+ skipped_existing = {entry["id"] for entry in suggested_entries} - set(repaired_ids)
103
+ for entry_id in sorted(skipped_existing):
104
+ outcome.skipped.append(
105
+ RepairAction(
106
+ description=(
107
+ f"project_lexicon.yaml: required_artifacts entry "
108
+ f"'{entry_id}' already declared"
109
+ )
110
+ )
111
+ )
112
+
113
+ return outcome
114
+
115
+
116
+ def _apply_lexicon_entries(
117
+ project_root: Path,
118
+ entries: list[dict[str, Any]],
119
+ *,
120
+ dry_run: bool,
121
+ ) -> list[str]:
122
+ lexicon_path = project_root / "project_lexicon.yaml"
123
+ if not lexicon_path.is_file():
124
+ return []
125
+
126
+ payload = yaml.safe_load(lexicon_path.read_text(encoding="utf-8")) or {}
127
+ if not isinstance(payload, dict):
128
+ return []
129
+
130
+ required_artifacts = payload.get("required_artifacts")
131
+ if not isinstance(required_artifacts, list):
132
+ required_artifacts = []
133
+
134
+ existing_ids = {
135
+ entry.get("id")
136
+ for entry in required_artifacts
137
+ if isinstance(entry, dict) and entry.get("id")
138
+ }
139
+
140
+ added_ids: list[str] = []
141
+ for entry in entries:
142
+ entry_id = entry.get("id")
143
+ if not entry_id or entry_id in existing_ids:
144
+ continue
145
+ required_artifacts.append(dict(entry))
146
+ existing_ids.add(entry_id)
147
+ added_ids.append(entry_id)
148
+
149
+ if not added_ids:
150
+ return added_ids
151
+
152
+ payload["required_artifacts"] = required_artifacts
153
+ if not dry_run:
154
+ lexicon_path.write_text(
155
+ yaml.safe_dump(payload, sort_keys=False, allow_unicode=True),
156
+ encoding="utf-8",
157
+ )
158
+ return added_ids
159
+
160
+
161
+ def _result_value(result: Any, key: str) -> Any:
162
+ if isinstance(result, dict):
163
+ return result.get(key)
164
+ return getattr(result, key, None)
@@ -222,7 +222,11 @@ def _add_design_docs(dag: DAG, project_root: Path, settings: dict[str, Any]) ->
222
222
  design_docs: dict[str, dict[str, Any]] = {}
223
223
  aliases: dict[str, str] = {}
224
224
  frontmatter_alias = _frontmatter_alias_settings(settings)
225
- for md_path in _glob_project_paths(project_root, settings.get("design_doc_patterns", [])):
225
+ for md_path in _glob_project_paths(
226
+ project_root,
227
+ settings.get("design_doc_patterns", []),
228
+ exclude_patterns=settings.get("scan_exclude_patterns"),
229
+ ):
226
230
  if not md_path.is_file():
227
231
  continue
228
232
  node_id = _relative_id(md_path, project_root)
@@ -256,7 +260,11 @@ def _add_impl_files(dag: DAG, project_root: Path, settings: dict[str, Any]) -> d
256
260
  impl_nodes: dict[str, Path] = {}
257
261
  capability_patterns = _capability_patterns(settings)
258
262
  implementation_suffixes = _suffix_tuple(settings.get("implementation_suffixes")) or LEGACY_IMPLEMENTATION_SUFFIXES
259
- for file_path in _glob_project_paths(project_root, settings.get("impl_file_patterns", [])):
263
+ for file_path in _glob_project_paths(
264
+ project_root,
265
+ settings.get("impl_file_patterns", []),
266
+ exclude_patterns=settings.get("scan_exclude_patterns"),
267
+ ):
260
268
  if (
261
269
  not file_path.is_file()
262
270
  or file_path.suffix not in implementation_suffixes
@@ -284,7 +292,11 @@ def _add_impl_files(dag: DAG, project_root: Path, settings: dict[str, Any]) -> d
284
292
  def _add_test_files(dag: DAG, project_root: Path, settings: dict[str, Any]) -> dict[str, Path]:
285
293
  test_nodes: dict[str, Path] = {}
286
294
  test_suffixes = _suffix_tuple(settings.get("test_suffixes")) or LEGACY_TEST_SUFFIXES
287
- for file_path in _glob_project_paths(project_root, settings.get("test_file_patterns", [])):
295
+ for file_path in _glob_project_paths(
296
+ project_root,
297
+ settings.get("test_file_patterns", []),
298
+ exclude_patterns=settings.get("scan_exclude_patterns"),
299
+ ):
288
300
  if not file_path.is_file() or file_path.suffix not in test_suffixes or not _is_test_file(file_path, project_root):
289
301
  continue
290
302
  node_id = _relative_id(file_path, project_root)
@@ -1067,7 +1079,11 @@ def _alias_candidates(import_ref: str, project_root: Path, aliases: dict[str, li
1067
1079
  return candidates
1068
1080
 
1069
1081
 
1070
- def _glob_project_paths(project_root: Path, patterns: Any) -> list[Path]:
1082
+ def _glob_project_paths(
1083
+ project_root: Path,
1084
+ patterns: Any,
1085
+ exclude_patterns: Any = None,
1086
+ ) -> list[Path]:
1071
1087
  paths: dict[str, Path] = {}
1072
1088
  for pattern in _as_list(patterns):
1073
1089
  if not isinstance(pattern, str) or not pattern:
@@ -1075,7 +1091,69 @@ def _glob_project_paths(project_root: Path, patterns: Any) -> list[Path]:
1075
1091
  for expanded in _expand_braces(pattern):
1076
1092
  for path in project_root.glob(expanded):
1077
1093
  paths[str(path.resolve())] = path.resolve()
1078
- return [paths[key] for key in sorted(paths)]
1094
+ excludes = [
1095
+ str(pattern)
1096
+ for pattern in _as_list(exclude_patterns)
1097
+ if isinstance(pattern, str) and pattern.strip()
1098
+ ]
1099
+ if not excludes:
1100
+ return [paths[key] for key in sorted(paths)]
1101
+ project_root_resolved = project_root.resolve()
1102
+ filtered: list[Path] = []
1103
+ for key in sorted(paths):
1104
+ path = paths[key]
1105
+ if _path_matches_any_pattern(path, project_root_resolved, excludes):
1106
+ continue
1107
+ filtered.append(path)
1108
+ return filtered
1109
+
1110
+
1111
+ def _path_matches_any_pattern(
1112
+ path: Path,
1113
+ project_root: Path,
1114
+ patterns: list[str],
1115
+ ) -> bool:
1116
+ try:
1117
+ relative = path.resolve().relative_to(project_root)
1118
+ except ValueError:
1119
+ return False
1120
+ rel_text = relative.as_posix()
1121
+ parts = relative.parts
1122
+
1123
+ for pattern in patterns:
1124
+ if fnmatch.fnmatch(rel_text, pattern):
1125
+ return True
1126
+ # Honour shell-style "any depth" wildcards by stripping the outer
1127
+ # ``**/`` and ``/**`` decorations and looking for the inner pattern
1128
+ # against any path slice. Examples:
1129
+ # **/node_modules/** -> "node_modules" must appear as a path component
1130
+ # **/dist/** -> "dist" must appear as a path component
1131
+ # src/**/*.py -> not stripped here; falls back to fnmatch above
1132
+ inner = pattern
1133
+ stripped = True
1134
+ while stripped:
1135
+ stripped = False
1136
+ if inner.startswith("**/"):
1137
+ inner = inner[3:]
1138
+ stripped = True
1139
+ if inner.endswith("/**"):
1140
+ inner = inner[:-3]
1141
+ stripped = True
1142
+ if not inner or inner == pattern:
1143
+ continue
1144
+ if "/" not in inner and "*" not in inner:
1145
+ if inner in parts:
1146
+ return True
1147
+ continue
1148
+ # Inner still contains glob syntax: check every contiguous slice of
1149
+ # the relative path against ``inner`` so e.g. ``a/b/c/d`` matches
1150
+ # ``a/b`` or ``c/d`` etc.
1151
+ for start in range(len(parts)):
1152
+ for end in range(start + 1, len(parts) + 1):
1153
+ candidate = "/".join(parts[start:end])
1154
+ if fnmatch.fnmatch(candidate, inner):
1155
+ return True
1156
+ return False
1079
1157
 
1080
1158
 
1081
1159
  def _expand_braces(pattern: str) -> list[str]:
@@ -1306,6 +1384,11 @@ def _apply_scan_patterns(settings: dict[str, Any], config: dict[str, Any]) -> No
1306
1384
  source_dirs = _as_list(scan.get("source_dirs"))
1307
1385
  test_dirs = _as_list(scan.get("test_dirs"))
1308
1386
  doc_dirs = _as_list(scan.get("doc_dirs"))
1387
+ exclude_patterns = [
1388
+ str(pattern)
1389
+ for pattern in _as_list(scan.get("exclude"))
1390
+ if isinstance(pattern, str) and pattern.strip()
1391
+ ]
1309
1392
 
1310
1393
  if source_dirs:
1311
1394
  _extend_unique(
@@ -1324,6 +1407,8 @@ def _apply_scan_patterns(settings: dict[str, Any], config: dict[str, Any]) -> No
1324
1407
  )
1325
1408
  if doc_dirs:
1326
1409
  _extend_unique(settings, "design_doc_patterns", _file_patterns_for_dirs(doc_dirs, (".md",)))
1410
+ if exclude_patterns:
1411
+ _extend_unique(settings, "scan_exclude_patterns", exclude_patterns)
1327
1412
 
1328
1413
 
1329
1414
  def _normalize_dag_section(section: dict[str, Any]) -> dict[str, Any]:
@@ -3,8 +3,12 @@
3
3
  from __future__ import annotations
4
4
 
5
5
  from dataclasses import dataclass
6
+ from datetime import date
6
7
  from pathlib import Path
7
- from typing import Any
8
+ from typing import Any, TYPE_CHECKING
9
+
10
+ if TYPE_CHECKING:
11
+ from codd.dag.checks.opt_out import OptOutDeclaration, OptOutPolicy, OptOutSignal
8
12
 
9
13
 
10
14
  _REGISTRY: dict[str, type[Any]] = {}
@@ -34,14 +38,50 @@ class DagCheck:
34
38
  dag: Any | None = None,
35
39
  project_root: str | Path | None = None,
36
40
  settings: dict[str, Any] | None = None,
41
+ opt_out_policy: "OptOutPolicy | None" = None,
42
+ today: date | None = None,
37
43
  ) -> None:
38
44
  self.dag = dag
39
45
  self.project_root = Path(project_root) if project_root is not None else None
40
46
  self.settings = settings or {}
47
+ self.opt_out_policy = opt_out_policy
48
+ self.today = today or date.today()
41
49
 
42
50
  def run(self, dag: Any | None = None) -> CheckResult:
43
51
  raise NotImplementedError
44
52
 
53
+ def detect_opt_out(self, codd_config: dict[str, Any]) -> "OptOutSignal | None":
54
+ """Return an OptOutSignal when this check's config requests an opt-out.
55
+
56
+ Default: no opt-out detection. Subclasses that own a config-level
57
+ opt-out flag (e.g. ``ci.provider: none``) override this and route the
58
+ request through :class:`OptOutPolicy` rather than handling it inline.
59
+ """
60
+
61
+ del codd_config
62
+ return None
63
+
64
+ def resolve_opt_out(
65
+ self,
66
+ codd_config: dict[str, Any] | None = None,
67
+ ) -> "tuple[OptOutSignal, OptOutDeclaration | None] | None":
68
+ """Convenience helper: run detect_opt_out and look up a declaration.
69
+
70
+ Returns ``None`` when no opt-out signal is detected. Returns
71
+ ``(signal, declaration_or_None)`` otherwise so the caller can decide
72
+ whether the missing-or-expired declaration should fail red or pass
73
+ through.
74
+ """
75
+
76
+ config = codd_config if codd_config is not None else self.settings
77
+ signal = self.detect_opt_out(config)
78
+ if signal is None:
79
+ return None
80
+ declaration = (
81
+ self.opt_out_policy.lookup(signal.check_name) if self.opt_out_policy else None
82
+ )
83
+ return signal, declaration
84
+
45
85
 
46
86
  def register_dag_check(name: str):
47
87
  """Register a DAG check class under ``name``."""
@@ -12,9 +12,15 @@ from typing import Any, Mapping
12
12
  import yaml
13
13
 
14
14
  from codd.dag.checks import DagCheck, register_dag_check
15
+ from codd.dag.checks.opt_out import (
16
+ OPT_OUT_STATUS,
17
+ OptOutDeclaration,
18
+ OptOutSignal,
19
+ )
15
20
 
16
21
 
17
22
  _DEFAULT_PROVIDER = "github" + "_actions"
23
+ _OPT_OUT_PROVIDER = "none"
18
24
 
19
25
 
20
26
  @dataclass
@@ -30,7 +36,11 @@ class CiConfig:
30
36
  @classmethod
31
37
  def from_mapping(cls, value: Mapping[str, Any] | None) -> "CiConfig":
32
38
  if not isinstance(value, Mapping):
33
- return cls(provider="none")
39
+ # Missing ``ci:`` section is no longer treated as a silent opt-out.
40
+ # The default provider applies; if no workflow files exist this
41
+ # surfaces as a normal red ``ci_workflow_missing`` finding rather
42
+ # than a free PASS.
43
+ return cls()
34
44
 
35
45
  config = cls()
36
46
  return cls(
@@ -87,17 +97,67 @@ class CiHealthCheck(DagCheck):
87
97
  del dag
88
98
  root = Path(project_root or self.project_root or ".").resolve()
89
99
  active_settings = codd_config or settings or self.settings
90
- return self.check(root, CiConfig.from_mapping(_mapping_value(active_settings, "ci")))
100
+ config = CiConfig.from_mapping(_mapping_value(active_settings, "ci"))
101
+ return self.check(root, config)
102
+
103
+ def detect_opt_out(self, codd_config: dict[str, Any]) -> OptOutSignal | None:
104
+ config = CiConfig.from_mapping(_mapping_value(codd_config, "ci"))
105
+ if self._is_opt_out_provider(config):
106
+ return OptOutSignal(
107
+ check_name=self.check_name,
108
+ source="ci.provider=none",
109
+ )
110
+ return None
91
111
 
92
- def check(self, project_root: Path, config: CiConfig) -> CiHealthResult:
93
- project_root = Path(project_root).resolve()
94
- if config.provider.strip().lower() == "none":
112
+ @staticmethod
113
+ def _is_opt_out_provider(config: CiConfig) -> bool:
114
+ return config.provider.strip().lower() == _OPT_OUT_PROVIDER
115
+
116
+ def _make_opt_out_result(self, declaration: OptOutDeclaration | None) -> CiHealthResult:
117
+ today = self.today
118
+ if declaration is None:
119
+ return CiHealthResult(
120
+ status="fail",
121
+ severity="red",
122
+ block_deploy=True,
123
+ message=(
124
+ "C8 ci_health: ci.provider=none requires an opt_outs declaration "
125
+ "in codd.yaml (check: ci_health, reason: ..., expires_at: "
126
+ "YYYY-MM-DD)."
127
+ ),
128
+ passed=False,
129
+ )
130
+ if declaration.is_expired(today):
95
131
  return CiHealthResult(
96
- status="skip",
97
- message="ci.provider=none, C8 SKIP",
98
- passed=True,
132
+ status="fail",
133
+ severity="red",
134
+ block_deploy=True,
135
+ message=(
136
+ f"C8 ci_health: opt-out expired on "
137
+ f"{declaration.expires_at.isoformat()} "
138
+ f"(reason: {declaration.reason}); renew the entry or remove it."
139
+ ),
140
+ passed=False,
99
141
  )
142
+ return CiHealthResult(
143
+ status=OPT_OUT_STATUS,
144
+ severity=self.severity,
145
+ block_deploy=False,
146
+ message=(
147
+ f"C8 ci_health opt-out active "
148
+ f"(reason: {declaration.reason}, "
149
+ f"expires: {declaration.expires_at.isoformat()})"
150
+ ),
151
+ passed=False,
152
+ )
100
153
 
154
+ def check(self, project_root: Path, config: CiConfig) -> CiHealthResult:
155
+ project_root = Path(project_root).resolve()
156
+ if self._is_opt_out_provider(config):
157
+ declaration = (
158
+ self.opt_out_policy.lookup(self.check_name) if self.opt_out_policy else None
159
+ )
160
+ return self._make_opt_out_result(declaration)
101
161
  workflow_files = self._locate_workflows(project_root, config.workflow_glob)
102
162
  if not workflow_files:
103
163
  finding = CiHealthFinding(