codd-dev 2.88.0__tar.gz → 2.90.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.
- {codd_dev-2.88.0 → codd_dev-2.90.0}/PKG-INFO +1 -1
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/__init__.py +1 -1
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/cli.py +68 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/greenfield/pipeline.py +145 -0
- codd_dev-2.90.0/codd/stack/lock.py +366 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/stack/project.py +42 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/pyproject.toml +1 -1
- codd_dev-2.88.0/codd/stack/lock.py +0 -133
- {codd_dev-2.88.0 → codd_dev-2.90.0}/.gitignore +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/LICENSE +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/README.md +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/bench_fixture/README.md +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/__main__.py +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/_git_helper.py +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/action_outcome.py +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/ai_invoke.py +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/ai_patch.py +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/artifact_contract.py +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/artifact_ids.py +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/artifacts/catalog.yaml +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/ask_user_question_adapter.py +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/assembler.py +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/bridge.py +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/brownfield/__init__.py +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/brownfield/pipeline.py +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/capability_completeness.py +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/claude_cli.py +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/clustering.py +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/coherence_adapters.py +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/coherence_engine.py +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/confidence.py +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/config.py +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/config_schema.py +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/contracts.py +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/contracts_registry/__init__.py +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/contracts_registry/__main__.py +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/contracts_registry/certify.py +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/contracts_registry/generate_matrix.py +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/contracts_registry/registry.py +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/coverage_auditor.py +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/coverage_execution_coherence.py +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/coverage_metrics.py +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/dag/__init__.py +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/dag/auto_repair.py +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/dag/builder.py +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/dag/checks/__init__.py +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/dag/checks/_one_to_many_detection.py +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/dag/checks/artifact_contract_check.py +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/dag/checks/ci_health.py +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/dag/checks/dependency_freshness.py +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/dag/checks/depends_on_consistency.py +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/dag/checks/deployment_completeness.py +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/dag/checks/edge_validity.py +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/dag/checks/environment_coverage.py +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/dag/checks/implementation_coverage.py +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/dag/checks/node_completeness.py +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/dag/checks/opt_out.py +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/dag/checks/task_completion.py +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/dag/checks/transitive_closure.py +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/dag/checks/ui_coherence.py +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/dag/checks/user_journey_coherence.py +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/dag/coverage_axes.py +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/dag/defaults/cli.yaml +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/dag/defaults/cpp_embedded.yaml +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/dag/defaults/csharp.yaml +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/dag/defaults/elixir.yaml +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/dag/defaults/generic.yaml +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/dag/defaults/iot.yaml +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/dag/defaults/java.yaml +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/dag/defaults/kotlin.yaml +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/dag/defaults/mobile.yaml +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/dag/defaults/ruby.yaml +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/dag/defaults/rust.yaml +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/dag/defaults/scala.yaml +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/dag/defaults/swift.yaml +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/dag/defaults/test_frameworks.yaml +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/dag/defaults/web.yaml +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/dag/extractor.py +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/dag/impact.py +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/dag/runner.py +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/defaults.py +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/defaults.yaml +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/dependency_lock_coherence.py +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/deploy_targets/__init__.py +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/deploy_targets/app_service.py +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/deploy_targets/base.py +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/deploy_targets/docker_compose.py +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/deployer.py +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/deployment/__init__.py +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/deployment/checks/__init__.py +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/deployment/defaults/deploy_targets.yaml +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/deployment/defaults/runtime_capability_inference.yaml +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/deployment/defaults/schema_providers.yaml +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/deployment/defaults/verification_templates.yaml +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/deployment/extractor.py +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/deployment/providers/__init__.py +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/deployment/providers/ai_command.py +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/deployment/providers/ai_command_factory.py +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/deployment/providers/codex_app_server.py +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/deployment/providers/llm_consideration.py +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/deployment/providers/schema/__init__.py +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/deployment/providers/schema/prisma.py +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/deployment/providers/target/__init__.py +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/deployment/providers/target/docker_compose.py +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/deployment/providers/verification/__init__.py +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/deployment/providers/verification/assertion_handlers.py +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/deployment/providers/verification/cdp_browser.py +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/deployment/providers/verification/cdp_engines.py +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/deployment/providers/verification/cdp_launchers.py +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/deployment/providers/verification/cdp_wire.py +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/deployment/providers/verification/curl.py +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/deployment/providers/verification/form_strategies.py +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/deployment/providers/verification/means_catalog.py +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/deployment/providers/verification/playwright.py +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/deployment/providers/verification/pytest_http.py +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/deployment/providers/verification/vitest.py +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/design_md.py +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/diff/__init__.py +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/diff/apply.py +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/diff/engine.py +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/diff/persistence.py +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/diff/templates/diff_prompt.md +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/discovery.py +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/drift.py +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/e2e_contract_coherence.py +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/e2e_extractor.py +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/e2e_generator.py +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/e2e_harness.py +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/e2e_runner.py +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/elicit/__init__.py +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/elicit/apply.py +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/elicit/engine.py +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/elicit/finding.py +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/elicit/formatters/__init__.py +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/elicit/formatters/base.py +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/elicit/formatters/interactive.py +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/elicit/formatters/json_fmt.py +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/elicit/formatters/md.py +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/elicit/lexicon_loader.py +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/elicit/persistence.py +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/elicit/templates/elicit_prompt_L0.md +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/env_refs.py +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/extract_ai.py +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/extract_paths.py +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/extractor.py +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/fix/__init__.py +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/fix/candidate_selector.py +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/fix/design_updater.py +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/fix/impl_propagation.py +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/fix/interactive_prompt.py +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/fix/phenomenon_fixer.py +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/fix/phenomenon_parser.py +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/fix/risk_classifier.py +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/fix/templates/clarification_question.txt +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/fix/templates/design_update.txt +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/fix/templates/impl_update.txt +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/fix/templates/phenomenon_parse.txt +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/fix/templates/risk_assessment.txt +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/fix/templates_loader.py +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/fixer.py +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/fixup_drift.py +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/fixup_drift_strategies/__init__.py +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/fixup_drift_strategies/design_token_drift.py +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/fixup_drift_strategies/lexicon_violation.py +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/fixup_drift_strategies/url_drift.py +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/frontmatter.py +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/generator.py +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/git_evidence.py +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/graph.py +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/greenfield/__init__.py +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/hitl_session.py +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/hooks/__init__.py +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/hooks/pre-commit +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/hooks/recipes/claude_requirements_nudge.json +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/hooks/recipes/claude_settings_example.json +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/hooks/recipes/codex_hook.sh +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/hooks/recipes/git_post_commit.sh +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/hooks/recipes/git_pre_commit.sh +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/iac_nfr.py +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/implement_oracle.py +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/implement_oracle_scope.py +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/implement_oracle_types.py +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/implementer/__init__.py +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/implementer/chunked_runner.py +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/implementer/typecheck_loop.py +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/implementer.py +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/import_coherence.py +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/inheritance.py +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/init/__init__.py +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/init/lexicon_suggest.py +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/init/llm_lexicon_suggester.py +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/init/stack_detector.py +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/knowledge_fetcher.py +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/languages/__init__.py +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/languages/adapters/__init__.py +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/languages/adapters/implement_oracle.py +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/languages/adapters/oracle_go.py +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/languages/adapters/oracle_python.py +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/languages/adapters/oracle_typescript.py +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/languages/adapters/runner_report.py +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/languages/builtin_adapters.py +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/languages/compat.py +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/languages/contract.py +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/languages/loader.py +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/languages/oracle_executor.py +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/languages/path_planner.py +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/languages/profile.py +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/languages/profiles/go.yaml +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/languages/profiles/python.yaml +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/languages/profiles/typescript.yaml +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/languages/registry.py +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/languages/verify_executor.py +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/languages/verify_plan.py +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/lexicon.py +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/lexicon_cli/__init__.py +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/lexicon_cli/formatters/__init__.py +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/lexicon_cli/formatters/html.py +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/lexicon_cli/formatters/json_fmt.py +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/lexicon_cli/formatters/md.py +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/lexicon_cli/inspector.py +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/lexicon_cli/manager.py +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/lexicon_cli/reporter.py +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/lexicon_cli/threshold.py +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/llm/__init__.py +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/llm/approval.py +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/llm/best_practice_augmenter.py +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/llm/criteria_expander.py +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/llm/design_doc_extractor.py +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/llm/impl_step_deriver.py +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/llm/means_catalog_loader.py +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/llm/parser.py +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/llm/plan_deriver.py +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/llm/prompt_builder.py +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/llm/strategy_validator.py +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/llm/templates/best_practice_augment_meta.md +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/llm/templates/criteria_expand_meta.md +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/llm/templates/design_doc_extract_meta.md +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/llm/templates/impl_step_derive_meta.md +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/llm/templates/implementation_step_catalog.yaml +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/llm/templates/meta_instruction.md +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/llm/templates/plan_derive_meta.md +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/llm/templates/verification_means_catalog.yaml +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/mcp_server.py +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/measure.py +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/operational_e2e_audit.py +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/operations_derive.py +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/parsing/__init__.py +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/parsing/_shared.py +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/parsing/api_specs.py +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/parsing/extractor_registry.py +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/parsing/filesystem_routes.py +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/parsing/iac.py +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/parsing/python_ast.py +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/parsing/regex_strategies.py +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/parsing/schemas.py +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/parsing/tests_builddeps.py +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/parsing/treesitter.py +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/planner.py +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/policy.py +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/preflight/__init__.py +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/preflight/defaults/cli.yaml +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/preflight/defaults/generic.yaml +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/preflight/defaults/iot.yaml +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/preflight/defaults/mobile.yaml +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/preflight/defaults/web.yaml +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/project_types.py +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/propagate.py +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/propagation_common.py +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/propagator.py +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/reconciliation_ledger.py +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/reference_resolution.py +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/registry.py +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/repair/__init__.py +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/repair/approval_repair.py +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/repair/auto_scope_guard.py +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/repair/engine.py +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/repair/git_patcher.py +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/repair/history.py +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/repair/llm_repair_engine.py +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/repair/loop.py +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/repair/primary_picker.py +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/repair/proof_breaks.py +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/repair/repair_result.py +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/repair/repairability_classifier.py +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/repair/schema.py +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/repair/templates/analyze_meta.md +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/repair/templates/propose_meta.md +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/repair/templates/repair_strategy_meta.md +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/repair/templates/repairability_meta.md +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/repair/test_failure_attribution.py +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/repair/verify_runner.py +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/repair_slice.py +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/require.py +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/require_plugins.py +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/require_propagate.py +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/required_artifacts/defaults/cli.yaml +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/required_artifacts/defaults/generic.yaml +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/required_artifacts/defaults/iot.yaml +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/required_artifacts/defaults/mobile.yaml +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/required_artifacts/defaults/web.yaml +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/required_artifacts_deriver.py +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/requirement_completeness/defaults/cli.yaml +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/requirement_completeness/defaults/generic.yaml +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/requirement_completeness/defaults/iot.yaml +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/requirement_completeness/defaults/mobile.yaml +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/requirement_completeness/defaults/web.yaml +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/requirement_completeness_auditor.py +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/requirement_reconciliation.py +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/requirements_meta.py +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/restoration_report.py +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/restore.py +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/routes_extractor.py +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/runtime_smoke/__init__.py +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/runtime_smoke/checks.py +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/runtime_smoke/config.py +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/runtime_smoke/report.py +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/runtime_smoke/runner.py +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/scanner.py +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/schema_refs.py +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/screen_flow_validator.py +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/screen_transition_extractor.py +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/screen_transitions/defaults.yaml +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/skills_cli/__init__.py +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/skills_cli/discovery.py +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/skills_cli/manager.py +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/skills_cli/paths.py +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/stack/__init__.py +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/stack/adapters/__init__.py +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/stack/adapters/_base.py +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/stack/adapters/nextjs.py +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/stack/adapters/playwright.py +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/stack/compose.py +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/stack/loader.py +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/stack/obligations.py +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/stack/profile.py +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/stack/profiles/addons/playwright.yaml +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/stack/profiles/addons/prisma.yaml +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/stack/profiles/frameworks/nextjs.yaml +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/stack/registry.py +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/stack/resolve.py +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/surface_reconciliation.py +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/synth.py +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/templates/codd.yaml.tmpl +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/templates/conventions.yaml.tmpl +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/templates/data_dependencies.yaml.tmpl +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/templates/doc_links.yaml.tmpl +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/templates/extract_ai_prompt_baseline.md +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/templates/extracted/api-contract.md.j2 +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/templates/extracted/architecture-overview.md.j2 +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/templates/extracted/module-detail.md.j2 +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/templates/extracted/schema-design.md.j2 +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/templates/extracted/system-context.md.j2 +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/templates/gitignore.tmpl +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/templates/lexicon_questions.md +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/templates/lexicon_schema.yaml +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/templates/overrides.yaml.tmpl +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/test_detection.py +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/test_import_coherence.py +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/traceability.py +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/validator.py +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/vb_marker_authenticity.py +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/vb_rerun_scope.py +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/verifiable_behavior_audit.py +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/watch/__init__.py +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/watch/events.py +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/watch/propagation_log.py +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/watch/propagation_pipeline.py +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/watch/test_runner.py +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/watch/watcher.py +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd/wiring.py +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd_plugins/lexicons/ai_governance_eu_act/coverage_matrix.md +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd_plugins/lexicons/ai_governance_eu_act/elicit_extend.md +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd_plugins/lexicons/ai_governance_eu_act/lexicon.yaml +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd_plugins/lexicons/ai_governance_eu_act/manifest.yaml +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd_plugins/lexicons/ai_governance_eu_act/recommended_kinds.yaml +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd_plugins/lexicons/ai_governance_eu_act/severity_rules.yaml +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd_plugins/lexicons/api_rate_limiting_caching/coverage_matrix.md +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd_plugins/lexicons/api_rate_limiting_caching/elicit_extend.md +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd_plugins/lexicons/api_rate_limiting_caching/lexicon.yaml +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd_plugins/lexicons/api_rate_limiting_caching/manifest.yaml +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd_plugins/lexicons/api_rate_limiting_caching/recommended_kinds.yaml +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd_plugins/lexicons/api_rate_limiting_caching/severity_rules.yaml +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd_plugins/lexicons/api_rest_openapi/coverage_matrix.md +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd_plugins/lexicons/api_rest_openapi/elicit_extend.md +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd_plugins/lexicons/api_rest_openapi/lexicon.yaml +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd_plugins/lexicons/api_rest_openapi/manifest.yaml +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd_plugins/lexicons/api_rest_openapi/recommended_kinds.yaml +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd_plugins/lexicons/api_rest_openapi/severity_rules.yaml +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd_plugins/lexicons/babok/elicit_extend.md +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd_plugins/lexicons/babok/lexicon.yaml +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd_plugins/lexicons/babok/manifest.yaml +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd_plugins/lexicons/babok/recommended_kinds.yaml +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd_plugins/lexicons/babok/severity_rules.yaml +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd_plugins/lexicons/backend_event_cloudevents/coverage_matrix.md +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd_plugins/lexicons/backend_event_cloudevents/elicit_extend.md +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd_plugins/lexicons/backend_event_cloudevents/lexicon.yaml +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd_plugins/lexicons/backend_event_cloudevents/manifest.yaml +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd_plugins/lexicons/backend_event_cloudevents/recommended_kinds.yaml +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd_plugins/lexicons/backend_event_cloudevents/severity_rules.yaml +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd_plugins/lexicons/backend_graphql/coverage_matrix.md +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd_plugins/lexicons/backend_graphql/elicit_extend.md +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd_plugins/lexicons/backend_graphql/lexicon.yaml +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd_plugins/lexicons/backend_graphql/manifest.yaml +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd_plugins/lexicons/backend_graphql/recommended_kinds.yaml +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd_plugins/lexicons/backend_graphql/severity_rules.yaml +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd_plugins/lexicons/backend_grpc_proto/coverage_matrix.md +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd_plugins/lexicons/backend_grpc_proto/elicit_extend.md +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd_plugins/lexicons/backend_grpc_proto/lexicon.yaml +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd_plugins/lexicons/backend_grpc_proto/manifest.yaml +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd_plugins/lexicons/backend_grpc_proto/recommended_kinds.yaml +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd_plugins/lexicons/backend_grpc_proto/severity_rules.yaml +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd_plugins/lexicons/compliance_hipaa/coverage_matrix.md +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd_plugins/lexicons/compliance_hipaa/elicit_extend.md +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd_plugins/lexicons/compliance_hipaa/lexicon.yaml +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd_plugins/lexicons/compliance_hipaa/manifest.yaml +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd_plugins/lexicons/compliance_hipaa/recommended_kinds.yaml +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd_plugins/lexicons/compliance_hipaa/severity_rules.yaml +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd_plugins/lexicons/compliance_iso27001/coverage_matrix.md +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd_plugins/lexicons/compliance_iso27001/elicit_extend.md +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd_plugins/lexicons/compliance_iso27001/lexicon.yaml +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd_plugins/lexicons/compliance_iso27001/manifest.yaml +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd_plugins/lexicons/compliance_iso27001/recommended_kinds.yaml +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd_plugins/lexicons/compliance_iso27001/severity_rules.yaml +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd_plugins/lexicons/compliance_pci_dss_4/coverage_matrix.md +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd_plugins/lexicons/compliance_pci_dss_4/elicit_extend.md +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd_plugins/lexicons/compliance_pci_dss_4/lexicon.yaml +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd_plugins/lexicons/compliance_pci_dss_4/manifest.yaml +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd_plugins/lexicons/compliance_pci_dss_4/recommended_kinds.yaml +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd_plugins/lexicons/compliance_pci_dss_4/severity_rules.yaml +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd_plugins/lexicons/data_aggregation_policies/coverage_matrix.md +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd_plugins/lexicons/data_aggregation_policies/elicit_extend.md +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd_plugins/lexicons/data_aggregation_policies/lexicon.yaml +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd_plugins/lexicons/data_aggregation_policies/manifest.yaml +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd_plugins/lexicons/data_aggregation_policies/recommended_kinds.yaml +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd_plugins/lexicons/data_aggregation_policies/severity_rules.yaml +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd_plugins/lexicons/data_eventsourcing_es_cqrs/coverage_matrix.md +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd_plugins/lexicons/data_eventsourcing_es_cqrs/elicit_extend.md +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd_plugins/lexicons/data_eventsourcing_es_cqrs/lexicon.yaml +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd_plugins/lexicons/data_eventsourcing_es_cqrs/manifest.yaml +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd_plugins/lexicons/data_eventsourcing_es_cqrs/recommended_kinds.yaml +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd_plugins/lexicons/data_eventsourcing_es_cqrs/severity_rules.yaml +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd_plugins/lexicons/data_governance_appi_gdpr/coverage_matrix.md +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd_plugins/lexicons/data_governance_appi_gdpr/elicit_extend.md +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd_plugins/lexicons/data_governance_appi_gdpr/lexicon.yaml +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd_plugins/lexicons/data_governance_appi_gdpr/manifest.yaml +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd_plugins/lexicons/data_governance_appi_gdpr/recommended_kinds.yaml +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd_plugins/lexicons/data_governance_appi_gdpr/severity_rules.yaml +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd_plugins/lexicons/data_nosql_jsonschema/coverage_matrix.md +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd_plugins/lexicons/data_nosql_jsonschema/elicit_extend.md +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd_plugins/lexicons/data_nosql_jsonschema/lexicon.yaml +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd_plugins/lexicons/data_nosql_jsonschema/manifest.yaml +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd_plugins/lexicons/data_nosql_jsonschema/recommended_kinds.yaml +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd_plugins/lexicons/data_nosql_jsonschema/severity_rules.yaml +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd_plugins/lexicons/data_relational_iso_sql/coverage_matrix.md +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd_plugins/lexicons/data_relational_iso_sql/elicit_extend.md +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd_plugins/lexicons/data_relational_iso_sql/lexicon.yaml +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd_plugins/lexicons/data_relational_iso_sql/manifest.yaml +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd_plugins/lexicons/data_relational_iso_sql/recommended_kinds.yaml +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd_plugins/lexicons/data_relational_iso_sql/severity_rules.yaml +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd_plugins/lexicons/ddd_domain_driven_design/coverage_matrix.md +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd_plugins/lexicons/ddd_domain_driven_design/elicit_extend.md +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd_plugins/lexicons/ddd_domain_driven_design/lexicon.yaml +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd_plugins/lexicons/ddd_domain_driven_design/manifest.yaml +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd_plugins/lexicons/ddd_domain_driven_design/recommended_kinds.yaml +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd_plugins/lexicons/ddd_domain_driven_design/severity_rules.yaml +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd_plugins/lexicons/dora_sre_metrics/coverage_matrix.md +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd_plugins/lexicons/dora_sre_metrics/elicit_extend.md +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd_plugins/lexicons/dora_sre_metrics/lexicon.yaml +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd_plugins/lexicons/dora_sre_metrics/manifest.yaml +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd_plugins/lexicons/dora_sre_metrics/recommended_kinds.yaml +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd_plugins/lexicons/dora_sre_metrics/severity_rules.yaml +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd_plugins/lexicons/i18n_unicode_cldr/coverage_matrix.md +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd_plugins/lexicons/i18n_unicode_cldr/elicit_extend.md +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd_plugins/lexicons/i18n_unicode_cldr/lexicon.yaml +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd_plugins/lexicons/i18n_unicode_cldr/manifest.yaml +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd_plugins/lexicons/i18n_unicode_cldr/recommended_kinds.yaml +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd_plugins/lexicons/i18n_unicode_cldr/severity_rules.yaml +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd_plugins/lexicons/ml_model_cards/coverage_matrix.md +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd_plugins/lexicons/ml_model_cards/elicit_extend.md +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd_plugins/lexicons/ml_model_cards/lexicon.yaml +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd_plugins/lexicons/ml_model_cards/manifest.yaml +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd_plugins/lexicons/ml_model_cards/recommended_kinds.yaml +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd_plugins/lexicons/ml_model_cards/severity_rules.yaml +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd_plugins/lexicons/mobile_a11y_native/coverage_matrix.md +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd_plugins/lexicons/mobile_a11y_native/elicit_extend.md +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd_plugins/lexicons/mobile_a11y_native/lexicon.yaml +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd_plugins/lexicons/mobile_a11y_native/manifest.yaml +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd_plugins/lexicons/mobile_a11y_native/recommended_kinds.yaml +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd_plugins/lexicons/mobile_a11y_native/severity_rules.yaml +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd_plugins/lexicons/mobile_android_material3/coverage_matrix.md +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd_plugins/lexicons/mobile_android_material3/elicit_extend.md +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd_plugins/lexicons/mobile_android_material3/lexicon.yaml +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd_plugins/lexicons/mobile_android_material3/manifest.yaml +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd_plugins/lexicons/mobile_android_material3/recommended_kinds.yaml +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd_plugins/lexicons/mobile_android_material3/severity_rules.yaml +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd_plugins/lexicons/mobile_ios_hig/coverage_matrix.md +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd_plugins/lexicons/mobile_ios_hig/elicit_extend.md +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd_plugins/lexicons/mobile_ios_hig/lexicon.yaml +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd_plugins/lexicons/mobile_ios_hig/manifest.yaml +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd_plugins/lexicons/mobile_ios_hig/recommended_kinds.yaml +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd_plugins/lexicons/mobile_ios_hig/severity_rules.yaml +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd_plugins/lexicons/mobile_security_masvs/coverage_matrix.md +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd_plugins/lexicons/mobile_security_masvs/elicit_extend.md +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd_plugins/lexicons/mobile_security_masvs/lexicon.yaml +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd_plugins/lexicons/mobile_security_masvs/manifest.yaml +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd_plugins/lexicons/mobile_security_masvs/recommended_kinds.yaml +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd_plugins/lexicons/mobile_security_masvs/severity_rules.yaml +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd_plugins/lexicons/ops_cicd_pipeline/coverage_matrix.md +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd_plugins/lexicons/ops_cicd_pipeline/elicit_extend.md +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd_plugins/lexicons/ops_cicd_pipeline/lexicon.yaml +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd_plugins/lexicons/ops_cicd_pipeline/manifest.yaml +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd_plugins/lexicons/ops_cicd_pipeline/recommended_kinds.yaml +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd_plugins/lexicons/ops_cicd_pipeline/severity_rules.yaml +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd_plugins/lexicons/ops_iac_terraform/coverage_matrix.md +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd_plugins/lexicons/ops_iac_terraform/elicit_extend.md +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd_plugins/lexicons/ops_iac_terraform/lexicon.yaml +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd_plugins/lexicons/ops_iac_terraform/manifest.yaml +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd_plugins/lexicons/ops_iac_terraform/recommended_kinds.yaml +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd_plugins/lexicons/ops_iac_terraform/severity_rules.yaml +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd_plugins/lexicons/ops_kubernetes/coverage_matrix.md +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd_plugins/lexicons/ops_kubernetes/elicit_extend.md +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd_plugins/lexicons/ops_kubernetes/lexicon.yaml +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd_plugins/lexicons/ops_kubernetes/manifest.yaml +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd_plugins/lexicons/ops_kubernetes/recommended_kinds.yaml +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd_plugins/lexicons/ops_kubernetes/severity_rules.yaml +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd_plugins/lexicons/ops_observability_otel/coverage_matrix.md +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd_plugins/lexicons/ops_observability_otel/elicit_extend.md +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd_plugins/lexicons/ops_observability_otel/lexicon.yaml +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd_plugins/lexicons/ops_observability_otel/manifest.yaml +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd_plugins/lexicons/ops_observability_otel/recommended_kinds.yaml +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd_plugins/lexicons/ops_observability_otel/severity_rules.yaml +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd_plugins/lexicons/process_iso25010/coverage_matrix.md +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd_plugins/lexicons/process_iso25010/elicit_extend.md +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd_plugins/lexicons/process_iso25010/lexicon.yaml +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd_plugins/lexicons/process_iso25010/manifest.yaml +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd_plugins/lexicons/process_iso25010/recommended_kinds.yaml +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd_plugins/lexicons/process_iso25010/severity_rules.yaml +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd_plugins/lexicons/process_test_iso29119/coverage_matrix.md +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd_plugins/lexicons/process_test_iso29119/elicit_extend.md +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd_plugins/lexicons/process_test_iso29119/lexicon.yaml +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd_plugins/lexicons/process_test_iso29119/manifest.yaml +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd_plugins/lexicons/process_test_iso29119/recommended_kinds.yaml +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd_plugins/lexicons/process_test_iso29119/severity_rules.yaml +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd_plugins/lexicons/twelve_factor_app/coverage_matrix.md +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd_plugins/lexicons/twelve_factor_app/elicit_extend.md +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd_plugins/lexicons/twelve_factor_app/lexicon.yaml +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd_plugins/lexicons/twelve_factor_app/manifest.yaml +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd_plugins/lexicons/twelve_factor_app/recommended_kinds.yaml +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd_plugins/lexicons/twelve_factor_app/severity_rules.yaml +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd_plugins/lexicons/web_a11y_wcag22_aa/coverage_matrix.md +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd_plugins/lexicons/web_a11y_wcag22_aa/elicit_extend.md +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd_plugins/lexicons/web_a11y_wcag22_aa/lexicon.yaml +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd_plugins/lexicons/web_a11y_wcag22_aa/manifest.yaml +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd_plugins/lexicons/web_a11y_wcag22_aa/recommended_kinds.yaml +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd_plugins/lexicons/web_a11y_wcag22_aa/severity_rules.yaml +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd_plugins/lexicons/web_authn_webauthn/coverage_matrix.md +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd_plugins/lexicons/web_authn_webauthn/elicit_extend.md +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd_plugins/lexicons/web_authn_webauthn/lexicon.yaml +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd_plugins/lexicons/web_authn_webauthn/manifest.yaml +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd_plugins/lexicons/web_authn_webauthn/recommended_kinds.yaml +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd_plugins/lexicons/web_authn_webauthn/severity_rules.yaml +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd_plugins/lexicons/web_browser_compat/coverage_matrix.md +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd_plugins/lexicons/web_browser_compat/elicit_extend.md +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd_plugins/lexicons/web_browser_compat/lexicon.yaml +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd_plugins/lexicons/web_browser_compat/manifest.yaml +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd_plugins/lexicons/web_browser_compat/recommended_kinds.yaml +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd_plugins/lexicons/web_browser_compat/severity_rules.yaml +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd_plugins/lexicons/web_forms_html5/coverage_matrix.md +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd_plugins/lexicons/web_forms_html5/elicit_extend.md +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd_plugins/lexicons/web_forms_html5/lexicon.yaml +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd_plugins/lexicons/web_forms_html5/manifest.yaml +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd_plugins/lexicons/web_forms_html5/recommended_kinds.yaml +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd_plugins/lexicons/web_forms_html5/severity_rules.yaml +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd_plugins/lexicons/web_performance_core_web_vitals/coverage_matrix.md +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd_plugins/lexicons/web_performance_core_web_vitals/elicit_extend.md +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd_plugins/lexicons/web_performance_core_web_vitals/lexicon.yaml +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd_plugins/lexicons/web_performance_core_web_vitals/manifest.yaml +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd_plugins/lexicons/web_performance_core_web_vitals/recommended_kinds.yaml +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd_plugins/lexicons/web_performance_core_web_vitals/severity_rules.yaml +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd_plugins/lexicons/web_pwa_manifest/coverage_matrix.md +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd_plugins/lexicons/web_pwa_manifest/elicit_extend.md +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd_plugins/lexicons/web_pwa_manifest/lexicon.yaml +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd_plugins/lexicons/web_pwa_manifest/manifest.yaml +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd_plugins/lexicons/web_pwa_manifest/recommended_kinds.yaml +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd_plugins/lexicons/web_pwa_manifest/severity_rules.yaml +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd_plugins/lexicons/web_responsive/coverage_matrix.md +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd_plugins/lexicons/web_responsive/elicit_extend.md +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd_plugins/lexicons/web_responsive/lexicon.yaml +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd_plugins/lexicons/web_responsive/manifest.yaml +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd_plugins/lexicons/web_responsive/recommended_kinds.yaml +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd_plugins/lexicons/web_responsive/severity_rules.yaml +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd_plugins/lexicons/web_security_owasp/coverage_matrix.md +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd_plugins/lexicons/web_security_owasp/elicit_extend.md +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd_plugins/lexicons/web_security_owasp/lexicon.yaml +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd_plugins/lexicons/web_security_owasp/manifest.yaml +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd_plugins/lexicons/web_security_owasp/recommended_kinds.yaml +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd_plugins/lexicons/web_security_owasp/severity_rules.yaml +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd_plugins/lexicons/web_seo_schemaorg/coverage_matrix.md +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd_plugins/lexicons/web_seo_schemaorg/elicit_extend.md +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd_plugins/lexicons/web_seo_schemaorg/lexicon.yaml +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd_plugins/lexicons/web_seo_schemaorg/manifest.yaml +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd_plugins/lexicons/web_seo_schemaorg/recommended_kinds.yaml +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd_plugins/lexicons/web_seo_schemaorg/severity_rules.yaml +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/codd_plugins/stack_map.yaml +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/docs/cookbook/cdp_browser/README.md +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/docs/cookbook/presentation_aggregation/README.md +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/docs/requirements/README.md +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/dogfood/README.md +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/dogfood/fixtures/flat_py_app/README.md +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/examples/README.md +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/skills/codd-assemble/SKILL.md +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/skills/codd-evolve/SKILL.md +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/skills/codd-generate/SKILL.md +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/skills/codd-greenfield/SKILL.md +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/skills/codd-impact/SKILL.md +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/skills/codd-init/SKILL.md +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/skills/codd-propagate/SKILL.md +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/skills/codd-restore/SKILL.md +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/skills/codd-scan/SKILL.md +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.0}/skills/codd-validate/SKILL.md +0 -0
- {codd_dev-2.88.0 → codd_dev-2.90.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.
|
|
3
|
+
Version: 2.90.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
|
|
@@ -5023,6 +5023,15 @@ def verify(
|
|
|
5023
5023
|
if not runtime:
|
|
5024
5024
|
return
|
|
5025
5025
|
|
|
5026
|
+
# Stack contract intake + lock enforcement (Contract Kernel v2.77a/v2.77b) —
|
|
5027
|
+
# bring the project's declared framework-stack contract into the live verify
|
|
5028
|
+
# run's trace (v2.77a, mirroring the greenfield intake), then ENFORCE the stack
|
|
5029
|
+
# lock as a gate (v2.77b): a stack project whose committed lock has drifted from
|
|
5030
|
+
# the resolved contract — or that has no committed lock at all — is RED. A
|
|
5031
|
+
# project with no `stack:` block is unaffected; a declared-but-broken stack
|
|
5032
|
+
# fails HONESTLY (anti-false-green), never a silent skip.
|
|
5033
|
+
_intake_stack_contract_for_verify(Path(path).resolve())
|
|
5034
|
+
|
|
5026
5035
|
verify_kwargs: dict[str, Any] = {"path": path, "prefer_standalone": True}
|
|
5027
5036
|
if runtime_skip:
|
|
5028
5037
|
verify_kwargs["runtime_skip"] = runtime_skip
|
|
@@ -7591,6 +7600,65 @@ def _load_optional_project_config(project_root: Path) -> dict[str, Any]:
|
|
|
7591
7600
|
return {}
|
|
7592
7601
|
|
|
7593
7602
|
|
|
7603
|
+
def _intake_stack_contract_for_verify(project_root: Path) -> None:
|
|
7604
|
+
"""Resolve the project's declared stack contract into the verify run trace.
|
|
7605
|
+
|
|
7606
|
+
Contract Kernel v2.77a (intake only) — the verify-path mirror of the greenfield
|
|
7607
|
+
pipeline's :meth:`GreenfieldPipeline._intake_stack_contract`. Proves the
|
|
7608
|
+
framework-stack contract is LIVE-consumed by the verify path (the hash enters
|
|
7609
|
+
the run trace), WITHOUT enforcing any obligation or changing the verify verdict
|
|
7610
|
+
(obligation enforcement is v2.77b-e).
|
|
7611
|
+
|
|
7612
|
+
* No ``stack:`` block → no-op (the opt-in framework layer is unused; the vast
|
|
7613
|
+
majority of projects — emits a single trace line, no behaviour change).
|
|
7614
|
+
* A declared stack → its ``stack_contract_hash`` is echoed to the run trace.
|
|
7615
|
+
* A declared-but-BROKEN stack → honest failure (``SystemExit`` non-zero), never
|
|
7616
|
+
a silent skip (anti-false-green / no-silent-fallback).
|
|
7617
|
+
"""
|
|
7618
|
+
from codd.stack.project import stack_contract_intake, stack_contract_trace
|
|
7619
|
+
|
|
7620
|
+
try:
|
|
7621
|
+
contract = stack_contract_intake(project_root)
|
|
7622
|
+
except Exception as exc: # noqa: BLE001 — a declared-but-broken stack must fail HONESTLY.
|
|
7623
|
+
click.echo(
|
|
7624
|
+
"stack contract intake failed: the project declares a `stack:` block in "
|
|
7625
|
+
f"codd.yaml but it could not be resolved ({type(exc).__name__}: {exc}). "
|
|
7626
|
+
"A declared-but-unresolvable stack is an honest error, never a silent skip.",
|
|
7627
|
+
err=True,
|
|
7628
|
+
)
|
|
7629
|
+
raise SystemExit(1) from exc
|
|
7630
|
+
|
|
7631
|
+
if contract is None:
|
|
7632
|
+
# No `stack:` block → byte-identical, UNLESS a committed lock still exists
|
|
7633
|
+
# (a removed stack declaration on a still-pinned project = RED; closes the
|
|
7634
|
+
# "drop stack: to dodge the gate" bypass — v2.77b anti-false-green).
|
|
7635
|
+
from codd.stack.lock import orphan_stack_lock
|
|
7636
|
+
|
|
7637
|
+
orphan = orphan_stack_lock(project_root)
|
|
7638
|
+
if orphan is not None and orphan.red:
|
|
7639
|
+
click.echo(f"[verify] stack lock gate: {orphan.message}", err=True)
|
|
7640
|
+
raise SystemExit(1)
|
|
7641
|
+
return
|
|
7642
|
+
trace = stack_contract_trace(contract)
|
|
7643
|
+
click.echo(
|
|
7644
|
+
f"[verify] stack contract intake: {trace['resolved_stack_id']} "
|
|
7645
|
+
f"stack_contract_hash={trace['stack_contract_hash']}"
|
|
7646
|
+
)
|
|
7647
|
+
|
|
7648
|
+
# Stack lock ENFORCEMENT (Contract Kernel v2.77b) — verify is always an
|
|
7649
|
+
# enforcement context (it never CREATES a project), so it uses the strictly
|
|
7650
|
+
# READ-ONLY gate: a stack project with no committed lock, or a lock that has
|
|
7651
|
+
# drifted from (or cannot be parsed against) the resolved contract, is RED
|
|
7652
|
+
# (honest non-zero exit). The gate never writes or refreshes the lock, so a
|
|
7653
|
+
# drift cannot be silenced on the verify path.
|
|
7654
|
+
from codd.stack.lock import enforce_stack_lock
|
|
7655
|
+
|
|
7656
|
+
gate = enforce_stack_lock(contract, project_root)
|
|
7657
|
+
click.echo(f"[verify] stack lock gate: {gate.message}", err=gate.red)
|
|
7658
|
+
if gate.red:
|
|
7659
|
+
raise SystemExit(1)
|
|
7660
|
+
|
|
7661
|
+
|
|
7594
7662
|
def _run_verify_once(
|
|
7595
7663
|
path: str,
|
|
7596
7664
|
*,
|
|
@@ -440,6 +440,66 @@ class GreenfieldPipeline:
|
|
|
440
440
|
|
|
441
441
|
self._notify(options, f"greenfield start: {project_root.name}")
|
|
442
442
|
|
|
443
|
+
# Stack contract intake (Contract Kernel v2.77a) — bring the project's
|
|
444
|
+
# declared framework-stack contract into the LIVE run (in the run record +
|
|
445
|
+
# trace) so the framework layer is consumed by production, not only tests.
|
|
446
|
+
# INTAKE ONLY: no obligation is enforced here and NO verdict changes (that
|
|
447
|
+
# is v2.77b-e). A project with no ``stack:`` block is byte-identical (the
|
|
448
|
+
# opt-in framework layer is unused). A declared-but-broken stack is an
|
|
449
|
+
# HONEST failure (anti-false-green), never a silent skip. Done once, early,
|
|
450
|
+
# before the stage loop, so the hash covers the whole run. Routed through
|
|
451
|
+
# _fail (like every stage) so the autopilot REPORTS the honest error via a
|
|
452
|
+
# failed GreenfieldResult instead of raising to the caller. Its own
|
|
453
|
+
# pseudo-stage name (not a real STAGES entry) so the failure is attributed
|
|
454
|
+
# honestly to intake, not to ``init``.
|
|
455
|
+
# Whether THIS run is a genuine first generation (the project is being
|
|
456
|
+
# created now) vs a re-run/resume of an already-progressed project. This is
|
|
457
|
+
# the ONLY context in which the stack-lock gate may bootstrap a missing lock
|
|
458
|
+
# (anti-gaming). It is read from the ON-DISK session INDEPENDENTLY of the
|
|
459
|
+
# ``resume`` flag — because a re-run WITHOUT ``--resume`` builds a fresh
|
|
460
|
+
# in-memory ``session`` (all-pending), which must NOT be mistaken for a first
|
|
461
|
+
# generation on an already-built project (GPT-consult leak: "absence of
|
|
462
|
+
# session ≠ first generation"). Fail-closed: any persisted completed stage ⇒
|
|
463
|
+
# not first-gen, so a deleted lock on a built project is RED, never silently
|
|
464
|
+
# re-bootstrapped to green.
|
|
465
|
+
on_disk = load_session(project_root)
|
|
466
|
+
first_generation = on_disk is None or not any(
|
|
467
|
+
rec.get("status") in _COMPLETE_STATUSES
|
|
468
|
+
for rec in on_disk.get("stages", {}).values()
|
|
469
|
+
)
|
|
470
|
+
|
|
471
|
+
try:
|
|
472
|
+
contract = self._intake_stack_contract(project_root, session)
|
|
473
|
+
except StageError as exc:
|
|
474
|
+
return self._fail(
|
|
475
|
+
project_root, session, options, "stack_intake",
|
|
476
|
+
{"status": STATUS_PENDING, "detail": ""}, str(exc),
|
|
477
|
+
)
|
|
478
|
+
|
|
479
|
+
# Stack lock ENFORCEMENT (Contract Kernel v2.77b) — turn the already-live
|
|
480
|
+
# stack contract into a red/green GATE. For stack-declared projects
|
|
481
|
+
# (contract is not None): drift / missing-in-resume = RED (anti-false-green);
|
|
482
|
+
# a first-generation missing lock is bootstrapped once (never overwritten —
|
|
483
|
+
# anti-gaming). For projects with NO stack block: byte-identical UNLESS a
|
|
484
|
+
# committed lock still exists (a removed declaration on a still-pinned
|
|
485
|
+
# project = RED, closing the "drop stack: to dodge the gate" bypass).
|
|
486
|
+
# Routed through _fail like intake so the autopilot reports it honestly.
|
|
487
|
+
try:
|
|
488
|
+
if contract is not None:
|
|
489
|
+
self._enforce_stack_lock(project_root, session, contract, first_generation)
|
|
490
|
+
else:
|
|
491
|
+
from codd.stack.lock import orphan_stack_lock
|
|
492
|
+
|
|
493
|
+
orphan = orphan_stack_lock(project_root)
|
|
494
|
+
if orphan is not None and orphan.red:
|
|
495
|
+
self.echo(f"[greenfield] stack lock gate: {orphan.message}")
|
|
496
|
+
raise StageError(orphan.message)
|
|
497
|
+
except StageError as exc:
|
|
498
|
+
return self._fail(
|
|
499
|
+
project_root, session, options, "stack_lock",
|
|
500
|
+
{"status": STATUS_PENDING, "detail": ""}, str(exc),
|
|
501
|
+
)
|
|
502
|
+
|
|
443
503
|
runners: dict[str, Callable[[Path, dict[str, Any], dict[str, Any]], None]] = {
|
|
444
504
|
"init": self._stage_init,
|
|
445
505
|
"elicit": self._stage_elicit,
|
|
@@ -522,6 +582,91 @@ class GreenfieldPipeline:
|
|
|
522
582
|
self._notify(options, f"greenfield {project_root.name}: FAILED at {stage_name} — {error}")
|
|
523
583
|
return result
|
|
524
584
|
|
|
585
|
+
# ── stack contract intake (Contract Kernel v2.77a, intake only) ──
|
|
586
|
+
|
|
587
|
+
def _intake_stack_contract(self, project_root: Path, session: dict[str, Any]):
|
|
588
|
+
"""Resolve the project's declared stack contract into the live run record + trace.
|
|
589
|
+
|
|
590
|
+
See the call site in :meth:`run`. INTAKE ONLY — proves the framework-stack
|
|
591
|
+
contract is LIVE-consumed (it enters the run record and the trace); it does
|
|
592
|
+
NOT enforce any obligation and does NOT change any pass/fail verdict
|
|
593
|
+
(obligation enforcement is v2.77b-e).
|
|
594
|
+
|
|
595
|
+
* No ``stack:`` block → no-op: nothing is added to the record and only a
|
|
596
|
+
single debug ``self.echo`` is emitted, so a non-stack project (the vast
|
|
597
|
+
majority) is behaviour-preserving. Returns ``None``.
|
|
598
|
+
* A declared stack → its :func:`stack_contract_trace` payload (incl.
|
|
599
|
+
``stack_contract_hash``) is written to ``session["stack_contract"]`` and
|
|
600
|
+
echoed to the run trace. Returns the resolved ``ResolvedStackContract`` so
|
|
601
|
+
the v2.77b lock-enforcement gate (run after intake) can pin it.
|
|
602
|
+
* A declared-but-BROKEN stack → :class:`StageError` (honest error), never a
|
|
603
|
+
silent skip (anti-false-green / no-silent-fallback).
|
|
604
|
+
"""
|
|
605
|
+
from codd.stack.project import stack_contract_intake, stack_contract_trace
|
|
606
|
+
|
|
607
|
+
try:
|
|
608
|
+
contract = stack_contract_intake(project_root)
|
|
609
|
+
except Exception as exc: # noqa: BLE001 — a declared-but-broken stack must fail HONESTLY.
|
|
610
|
+
raise StageError(
|
|
611
|
+
"stack contract intake failed: the project declares a `stack:` block in "
|
|
612
|
+
f"codd.yaml but it could not be resolved ({type(exc).__name__}: {exc}). "
|
|
613
|
+
"A declared-but-unresolvable stack is an honest error, never a silent skip "
|
|
614
|
+
"(check the language / frameworks / addons ids against the curated stack "
|
|
615
|
+
"profiles, or remove the `stack:` block to opt out of the framework layer)."
|
|
616
|
+
) from exc
|
|
617
|
+
|
|
618
|
+
if contract is None:
|
|
619
|
+
# The opt-in framework layer is unused — byte-identical behaviour.
|
|
620
|
+
self.echo("[greenfield] stack contract intake: no `stack:` block (framework layer opt-out)")
|
|
621
|
+
return None
|
|
622
|
+
|
|
623
|
+
trace = stack_contract_trace(contract)
|
|
624
|
+
session["stack_contract"] = dict(trace)
|
|
625
|
+
self.echo(
|
|
626
|
+
"[greenfield] stack contract intake: "
|
|
627
|
+
f"{trace['resolved_stack_id']} "
|
|
628
|
+
f"stack_contract_hash={trace['stack_contract_hash']}"
|
|
629
|
+
)
|
|
630
|
+
return contract
|
|
631
|
+
|
|
632
|
+
# ── stack lock enforcement (Contract Kernel v2.77b) ──
|
|
633
|
+
|
|
634
|
+
def _enforce_stack_lock(self, project_root: Path, session: dict[str, Any], contract, first_generation: bool) -> None:
|
|
635
|
+
"""Enforce the project's stack lock as a red/green gate (v2.77b).
|
|
636
|
+
|
|
637
|
+
Only called for stack-declared projects (``contract is not None``); non-stack
|
|
638
|
+
projects never reach here, so they are byte-identical (no lock gate at all).
|
|
639
|
+
|
|
640
|
+
Design B′ (split read-only gate vs. creation-path bootstrap):
|
|
641
|
+
|
|
642
|
+
* genuine FIRST GENERATION (``first_generation`` True — no prior completed
|
|
643
|
+
stage) → :func:`bootstrap_stack_lock` writes the first lock (exclusive
|
|
644
|
+
create) and immediately enforces it read-only; ``generated`` is traced.
|
|
645
|
+
* otherwise (RESUME / already-progressed project) → read-only
|
|
646
|
+
:func:`enforce_stack_lock`: a missing lock is RED (an already-progressed
|
|
647
|
+
stack project with no committed pin is unverifiable; a deleted lock cannot
|
|
648
|
+
be silently regenerated), drift is RED, a valid lock is GREEN.
|
|
649
|
+
|
|
650
|
+
Anti-gaming (exit gate 3): the read-only gate NEVER writes/refreshes a lock;
|
|
651
|
+
``bootstrap_stack_lock`` writes only when the lock is ABSENT (exclusive
|
|
652
|
+
create) on this creation path, so a drift cannot be silenced by regenerating
|
|
653
|
+
the lock. See :func:`enforce_stack_lock` / :func:`bootstrap_stack_lock`.
|
|
654
|
+
"""
|
|
655
|
+
from codd.stack.lock import bootstrap_stack_lock, enforce_stack_lock
|
|
656
|
+
|
|
657
|
+
if first_generation:
|
|
658
|
+
gate = bootstrap_stack_lock(contract, project_root)
|
|
659
|
+
else:
|
|
660
|
+
gate = enforce_stack_lock(contract, project_root)
|
|
661
|
+
# Record the lock verdict in the run trace (observable, like the intake hash).
|
|
662
|
+
record = session.get("stack_contract")
|
|
663
|
+
if isinstance(record, dict):
|
|
664
|
+
record["stack_lock_status"] = gate.status
|
|
665
|
+
record["stack_lock_path"] = gate.lock_path
|
|
666
|
+
self.echo(f"[greenfield] stack lock gate: {gate.message}")
|
|
667
|
+
if gate.red:
|
|
668
|
+
raise StageError(gate.message)
|
|
669
|
+
|
|
525
670
|
# ── option resolution ───────────────────────────────────
|
|
526
671
|
|
|
527
672
|
def _resolve_options(self, project_root: Path) -> dict[str, Any]:
|
|
@@ -0,0 +1,366 @@
|
|
|
1
|
+
"""``codd.stack.lock`` — pin a resolved stack for deterministic CI (design §2/§決定性).
|
|
2
|
+
|
|
3
|
+
Auto-detection (package.json has ``next`` → use the Next.js profile) is convenient
|
|
4
|
+
for ``local init`` only. In CI the lock is the SOURCE OF TRUTH: the resolved
|
|
5
|
+
contract is recomputed and any divergence from the lock (a layer version bump, a
|
|
6
|
+
profile edit changing a digest, a different resolved-contract hash) is RED, so a
|
|
7
|
+
profile change can never silently alter a project's contract.
|
|
8
|
+
"""
|
|
9
|
+
|
|
10
|
+
from __future__ import annotations
|
|
11
|
+
|
|
12
|
+
from dataclasses import dataclass, field
|
|
13
|
+
from pathlib import Path
|
|
14
|
+
from typing import Any, Mapping
|
|
15
|
+
|
|
16
|
+
import yaml
|
|
17
|
+
|
|
18
|
+
from .compose import ResolvedStackContract
|
|
19
|
+
|
|
20
|
+
#: The lock file lives next to ``codd.yaml`` inside the project's CoDD config dir
|
|
21
|
+
#: (so ``<project>/codd/stack.lock`` or ``<project>/.codd/stack.lock``). The
|
|
22
|
+
#: module docstring's ``codd.stack.lock`` is this file.
|
|
23
|
+
LOCK_FILENAME = "stack.lock"
|
|
24
|
+
|
|
25
|
+
LOCK_SCHEMA_VERSION = 1
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
@dataclass(frozen=True)
|
|
29
|
+
class LockedLayer:
|
|
30
|
+
id: str
|
|
31
|
+
kind: str
|
|
32
|
+
version: str
|
|
33
|
+
digest: str
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
@dataclass(frozen=True)
|
|
37
|
+
class StackLock:
|
|
38
|
+
schema_version: int
|
|
39
|
+
stack_id: str
|
|
40
|
+
layers: tuple[LockedLayer, ...]
|
|
41
|
+
resolved_contract_digest: str
|
|
42
|
+
adapter_digests: Mapping[str, str] = field(default_factory=dict)
|
|
43
|
+
permissions: Mapping[str, Any] = field(default_factory=dict)
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
def build_lock(
|
|
47
|
+
contract: ResolvedStackContract,
|
|
48
|
+
*,
|
|
49
|
+
adapter_digests: Mapping[str, str] | None = None,
|
|
50
|
+
permissions: Mapping[str, Any] | None = None,
|
|
51
|
+
) -> StackLock:
|
|
52
|
+
"""Derive a :class:`StackLock` from a resolved contract."""
|
|
53
|
+
return StackLock(
|
|
54
|
+
schema_version=LOCK_SCHEMA_VERSION,
|
|
55
|
+
stack_id=contract.stack_id,
|
|
56
|
+
layers=tuple(
|
|
57
|
+
LockedLayer(id=l.id, kind=l.kind, version=l.profile_version, digest=l.digest)
|
|
58
|
+
for l in contract.layers
|
|
59
|
+
),
|
|
60
|
+
resolved_contract_digest=contract.content_hash,
|
|
61
|
+
adapter_digests=dict(adapter_digests or {}),
|
|
62
|
+
permissions=dict(permissions or {}),
|
|
63
|
+
)
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
def lock_to_dict(lock: StackLock) -> dict[str, Any]:
|
|
67
|
+
return {
|
|
68
|
+
"schema_version": lock.schema_version,
|
|
69
|
+
"stack_id": lock.stack_id,
|
|
70
|
+
"layers": [
|
|
71
|
+
{"id": l.id, "kind": l.kind, "version": l.version, "digest": l.digest}
|
|
72
|
+
for l in lock.layers
|
|
73
|
+
],
|
|
74
|
+
"resolved_contract_digest": lock.resolved_contract_digest,
|
|
75
|
+
"adapter_digests": dict(lock.adapter_digests),
|
|
76
|
+
"permissions": dict(lock.permissions),
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
def dump_lock(lock: StackLock) -> str:
|
|
81
|
+
"""Serialize a lock to YAML (stable key order for clean diffs)."""
|
|
82
|
+
return yaml.safe_dump(lock_to_dict(lock), sort_keys=True, default_flow_style=False)
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
def parse_lock(data: str | Mapping[str, Any]) -> StackLock:
|
|
86
|
+
doc = yaml.safe_load(data) if isinstance(data, str) else dict(data)
|
|
87
|
+
if not isinstance(doc, Mapping):
|
|
88
|
+
raise ValueError("codd.stack.lock must be a mapping at the top level")
|
|
89
|
+
layers = tuple(
|
|
90
|
+
LockedLayer(
|
|
91
|
+
id=str(l["id"]),
|
|
92
|
+
kind=str(l.get("kind", "")),
|
|
93
|
+
version=str(l.get("version", "")),
|
|
94
|
+
digest=str(l.get("digest", "")),
|
|
95
|
+
)
|
|
96
|
+
for l in (doc.get("layers") or [])
|
|
97
|
+
)
|
|
98
|
+
return StackLock(
|
|
99
|
+
schema_version=int(doc.get("schema_version", LOCK_SCHEMA_VERSION)),
|
|
100
|
+
stack_id=str(doc.get("stack_id", "")),
|
|
101
|
+
layers=layers,
|
|
102
|
+
resolved_contract_digest=str(doc.get("resolved_contract_digest", "")),
|
|
103
|
+
adapter_digests=dict(doc.get("adapter_digests") or {}),
|
|
104
|
+
permissions=dict(doc.get("permissions") or {}),
|
|
105
|
+
)
|
|
106
|
+
|
|
107
|
+
|
|
108
|
+
def verify_lock(contract: ResolvedStackContract, lock: StackLock) -> tuple[bool, list[str]]:
|
|
109
|
+
"""Check a freshly-resolved contract against a pinned lock (CI gate).
|
|
110
|
+
|
|
111
|
+
Returns ``(ok, diffs)``. ``ok`` is False (CI RED) when the resolved contract
|
|
112
|
+
diverges from the lock — a layer set/version/digest change, or a different
|
|
113
|
+
resolved-contract digest (a profile edit that silently changed the contract).
|
|
114
|
+
"""
|
|
115
|
+
diffs: list[str] = []
|
|
116
|
+
if contract.stack_id != lock.stack_id:
|
|
117
|
+
diffs.append(f"stack_id: contract={contract.stack_id!r} lock={lock.stack_id!r}")
|
|
118
|
+
|
|
119
|
+
contract_layers = {l.id: l for l in contract.layers}
|
|
120
|
+
lock_layers = {l.id: l for l in lock.layers}
|
|
121
|
+
for lid in sorted(set(contract_layers) | set(lock_layers)):
|
|
122
|
+
if lid not in contract_layers:
|
|
123
|
+
diffs.append(f"layer {lid!r}: in lock but not resolved")
|
|
124
|
+
continue
|
|
125
|
+
if lid not in lock_layers:
|
|
126
|
+
diffs.append(f"layer {lid!r}: resolved but not in lock")
|
|
127
|
+
continue
|
|
128
|
+
c, k = contract_layers[lid], lock_layers[lid]
|
|
129
|
+
if c.profile_version != k.version:
|
|
130
|
+
diffs.append(f"layer {lid!r} version: contract={c.profile_version} lock={k.version}")
|
|
131
|
+
if c.digest and k.digest and c.digest != k.digest:
|
|
132
|
+
diffs.append(f"layer {lid!r} digest changed (profile edited)")
|
|
133
|
+
|
|
134
|
+
if contract.content_hash != lock.resolved_contract_digest:
|
|
135
|
+
diffs.append(
|
|
136
|
+
"resolved_contract_digest changed "
|
|
137
|
+
f"(contract={contract.content_hash[:23]}… lock={lock.resolved_contract_digest[:23]}…)"
|
|
138
|
+
)
|
|
139
|
+
return (not diffs, diffs)
|
|
140
|
+
|
|
141
|
+
|
|
142
|
+
# ── enforcement gate (Contract Kernel v2.77b — Stack Lock Enforcement) ───────
|
|
143
|
+
#
|
|
144
|
+
# v2.77a brought the stack contract LIVE (intake-only). v2.77b turns the
|
|
145
|
+
# already-existing lock logic above into a GATE so stack-contract drift is RED.
|
|
146
|
+
#
|
|
147
|
+
# Anti-false-green is the entire point of this step. The design (B′, confirmed by
|
|
148
|
+
# a GPT-5.5 Pro consult — see the task report) SPLITS the two responsibilities so
|
|
149
|
+
# the gate has NO "verify-or-create" mixed semantics — the one and only thing that
|
|
150
|
+
# could turn a drift-RED into green:
|
|
151
|
+
#
|
|
152
|
+
# * :func:`enforce_stack_lock` is STRICTLY READ-ONLY. It NEVER writes/refreshes
|
|
153
|
+
# a lock. missing → RED, parse-error → RED, drift → RED, valid → GREEN. Both
|
|
154
|
+
# the verify path and the greenfield path call THIS for the verdict.
|
|
155
|
+
# * :func:`bootstrap_stack_lock` is the ONLY writer, and it uses EXCLUSIVE
|
|
156
|
+
# create (``open(..., "x")``): it writes only when the lock is ABSENT and is
|
|
157
|
+
# invoked only on a positively-identified project-creation path (greenfield
|
|
158
|
+
# first generation). It refuses to overwrite, so it cannot refresh a drift.
|
|
159
|
+
#
|
|
160
|
+
# ANTI-GAMING (exit gate 3, the crux): ``verify_lock(contract,
|
|
161
|
+
# build_lock(contract))`` is ALWAYS ok by construction — a drift can be MASKED by
|
|
162
|
+
# rewriting the lock to match. So the verify path can't detect gaming; the control
|
|
163
|
+
# is "who may WRITE a lock, and when". Here: the read-only gate writes nothing
|
|
164
|
+
# ever, and bootstrap writes only on exclusive-create in the creation path. A
|
|
165
|
+
# drift against a committed lock is RED on every path and is never refreshed by
|
|
166
|
+
# either function; auto-repair re-running the gate keeps seeing drift-RED.
|
|
167
|
+
# Refreshing a drifted lock requires an explicit out-of-band proof
|
|
168
|
+
# (``replace_with_proof``-style; full repair governance is v2.77f).
|
|
169
|
+
#
|
|
170
|
+
# WHY NOT "missing + absent-session ⇒ generate": absence of a session is NOT
|
|
171
|
+
# proof of first generation (it can be a deleted session, a copied project, an
|
|
172
|
+
# existing repo, or auto-repair having cleaned local state). Generation therefore
|
|
173
|
+
# belongs to an explicit creation path (bootstrap), and the gate fails CLOSED
|
|
174
|
+
# (missing = RED) everywhere else — the delete-and-regenerate attack cannot
|
|
175
|
+
# silence a drift because the gate never participates in regeneration.
|
|
176
|
+
|
|
177
|
+
#: ``StackLockGate.status`` values.
|
|
178
|
+
LOCK_OK = "ok" # a committed lock matches the resolved contract (GREEN).
|
|
179
|
+
LOCK_DRIFT = "drift" # a committed lock diverges / is unparseable (RED).
|
|
180
|
+
LOCK_MISSING = "missing" # no committed lock where one must exist (RED).
|
|
181
|
+
LOCK_GENERATED = "generated" # bootstrap wrote the first lock (GREEN, traced).
|
|
182
|
+
|
|
183
|
+
|
|
184
|
+
def stack_lock_path(project_root: str | Path) -> Path:
|
|
185
|
+
"""Return the path of a project's stack lock file (next to ``codd.yaml``).
|
|
186
|
+
|
|
187
|
+
Resolved from the canonical project root via the same config-dir discovery as
|
|
188
|
+
:func:`codd.config.load_project_config` (``codd/`` then ``.codd/``), NOT from a
|
|
189
|
+
mutable CWD. If no config dir is discoverable yet, defaults to
|
|
190
|
+
``<project_root>/codd/stack.lock`` so a first-generation greenfield run (which
|
|
191
|
+
has just created ``codd/``) bootstraps the lock in the canonical place.
|
|
192
|
+
"""
|
|
193
|
+
from codd.config import find_codd_dir
|
|
194
|
+
|
|
195
|
+
root = Path(project_root)
|
|
196
|
+
codd_dir = find_codd_dir(root)
|
|
197
|
+
if codd_dir is None:
|
|
198
|
+
codd_dir = root / "codd"
|
|
199
|
+
return codd_dir / LOCK_FILENAME
|
|
200
|
+
|
|
201
|
+
|
|
202
|
+
@dataclass(frozen=True)
|
|
203
|
+
class StackLockGate:
|
|
204
|
+
"""The verdict of the (read-only) stack-lock enforcement gate (v2.77b).
|
|
205
|
+
|
|
206
|
+
``red`` is the single anti-false-green signal the pipeline/verify call-sites
|
|
207
|
+
act on: ``drift`` and ``missing`` are RED; ``ok`` is GREEN; ``generated`` is the
|
|
208
|
+
GREEN result returned right after :func:`bootstrap_stack_lock` writes the first
|
|
209
|
+
lock. ``reasons`` carry the human-readable drift diffs.
|
|
210
|
+
"""
|
|
211
|
+
|
|
212
|
+
status: str
|
|
213
|
+
red: bool
|
|
214
|
+
reasons: tuple[str, ...] = ()
|
|
215
|
+
lock_path: str = ""
|
|
216
|
+
|
|
217
|
+
@property
|
|
218
|
+
def message(self) -> str:
|
|
219
|
+
if self.status == LOCK_OK:
|
|
220
|
+
return f"stack lock OK ({self.lock_path})"
|
|
221
|
+
if self.status == LOCK_GENERATED:
|
|
222
|
+
return f"stack lock generated (first generation) at {self.lock_path}"
|
|
223
|
+
if self.status == LOCK_MISSING:
|
|
224
|
+
return (
|
|
225
|
+
f"stack lock MISSING at {self.lock_path}: a project that declares a "
|
|
226
|
+
"`stack:` block must commit a stack lock — an unpinned stack contract is "
|
|
227
|
+
"unverifiable (anti-false-green). It is generated once on a first "
|
|
228
|
+
"`codd greenfield` run; the enforcement gate is read-only and will never "
|
|
229
|
+
"silently create it (a missing lock outside first generation is RED, so a "
|
|
230
|
+
"deleted lock cannot be silently regenerated to green)."
|
|
231
|
+
)
|
|
232
|
+
# drift (incl. present-but-unparseable lock)
|
|
233
|
+
joined = "; ".join(self.reasons) if self.reasons else "resolved contract diverges from the lock"
|
|
234
|
+
return (
|
|
235
|
+
f"stack lock DRIFT ({self.lock_path}): the resolved stack contract no longer "
|
|
236
|
+
f"matches the committed lock [{joined}]. This is RED. Rewriting the lock to "
|
|
237
|
+
"match does NOT clear this — the gate is read-only and never refreshes a lock; "
|
|
238
|
+
"a drift requires reverting the contract change or an explicit proof-backed "
|
|
239
|
+
"lock update (replace_with_proof)."
|
|
240
|
+
)
|
|
241
|
+
|
|
242
|
+
|
|
243
|
+
def enforce_stack_lock(
|
|
244
|
+
contract: ResolvedStackContract, project_root: str | Path
|
|
245
|
+
) -> StackLockGate:
|
|
246
|
+
"""Read-only stack-lock gate for a resolved contract (the v2.77b enforcement).
|
|
247
|
+
|
|
248
|
+
``contract`` is the freshly-resolved :class:`ResolvedStackContract` (the caller
|
|
249
|
+
has already intaken it — v2.77a). This function reads the project's committed
|
|
250
|
+
lock and returns a verdict; it NEVER writes or refreshes the lock (so it cannot
|
|
251
|
+
turn a drift-RED into green — exit gate 3):
|
|
252
|
+
|
|
253
|
+
* **missing** — no committed lock → ``red=True`` (``status=missing``). A stack
|
|
254
|
+
project with no pin is unverifiable; generation is the separate
|
|
255
|
+
:func:`bootstrap_stack_lock` responsibility (creation path only).
|
|
256
|
+
* **parse error** — a present-but-unparseable lock → ``red=True``
|
|
257
|
+
(``status=drift``). A broken lock is NEVER treated as "missing" (which could
|
|
258
|
+
invite regeneration).
|
|
259
|
+
* **drift** — a committed lock exists but :func:`verify_lock` reports
|
|
260
|
+
divergence → ``red=True`` (``status=drift``).
|
|
261
|
+
* **valid** — a committed lock matches → ``status=ok``, ``red=False``.
|
|
262
|
+
"""
|
|
263
|
+
path = stack_lock_path(project_root)
|
|
264
|
+
path_str = str(path)
|
|
265
|
+
|
|
266
|
+
if not path.exists():
|
|
267
|
+
return StackLockGate(status=LOCK_MISSING, red=True, lock_path=path_str)
|
|
268
|
+
|
|
269
|
+
try:
|
|
270
|
+
lock = parse_lock(path.read_text(encoding="utf-8"))
|
|
271
|
+
except Exception as exc: # noqa: BLE001 — any read/parse failure is RED, never "missing".
|
|
272
|
+
# A present-but-unreadable/corrupt lock is NOT a pass and is NOT "missing"
|
|
273
|
+
# (which could invite regeneration): it is drift (RED).
|
|
274
|
+
return StackLockGate(
|
|
275
|
+
status=LOCK_DRIFT,
|
|
276
|
+
red=True,
|
|
277
|
+
reasons=(f"lock file present but unparseable: {type(exc).__name__}: {exc}",),
|
|
278
|
+
lock_path=path_str,
|
|
279
|
+
)
|
|
280
|
+
|
|
281
|
+
ok, diffs = verify_lock(contract, lock)
|
|
282
|
+
if ok:
|
|
283
|
+
return StackLockGate(status=LOCK_OK, red=False, lock_path=path_str)
|
|
284
|
+
# DRIFT — RED. Read-only: the lock is left untouched (anti-gaming, exit gate 3).
|
|
285
|
+
return StackLockGate(status=LOCK_DRIFT, red=True, reasons=tuple(diffs), lock_path=path_str)
|
|
286
|
+
|
|
287
|
+
|
|
288
|
+
def bootstrap_stack_lock(
|
|
289
|
+
contract: ResolvedStackContract,
|
|
290
|
+
project_root: str | Path,
|
|
291
|
+
*,
|
|
292
|
+
adapter_digests: Mapping[str, str] | None = None,
|
|
293
|
+
permissions: Mapping[str, Any] | None = None,
|
|
294
|
+
) -> StackLockGate:
|
|
295
|
+
"""Write a project's FIRST stack lock (creation path only) — the ONLY writer.
|
|
296
|
+
|
|
297
|
+
Invoked ONLY on a positively-identified project-creation path (greenfield first
|
|
298
|
+
generation), never by the enforcement gate, never by verify/resume, never by
|
|
299
|
+
repair. Uses EXCLUSIVE create (``open(..., "x")``): it writes the lock iff it is
|
|
300
|
+
ABSENT and refuses to overwrite an existing lock. This is what makes the
|
|
301
|
+
delete-and-regenerate / drift-refresh attacks impossible — bootstrap cannot
|
|
302
|
+
refresh a drifted (existing) lock, and a missing lock outside the creation path
|
|
303
|
+
is RED at the read-only gate.
|
|
304
|
+
|
|
305
|
+
Returns the read-only :func:`enforce_stack_lock` verdict computed AFTER the
|
|
306
|
+
write (so the freshly-written lock is immediately verified — ``status=ok`` on
|
|
307
|
+
success). If the lock already exists, NOTHING is written and the existing lock
|
|
308
|
+
is enforced as-is (so a pre-existing drift stays RED).
|
|
309
|
+
"""
|
|
310
|
+
path = stack_lock_path(project_root)
|
|
311
|
+
if not path.exists():
|
|
312
|
+
lock = build_lock(contract, adapter_digests=adapter_digests, permissions=permissions)
|
|
313
|
+
path.parent.mkdir(parents=True, exist_ok=True)
|
|
314
|
+
try:
|
|
315
|
+
# Exclusive create — refuse to clobber an existing lock (TOCTOU-safe).
|
|
316
|
+
with open(path, "x", encoding="utf-8") as fh:
|
|
317
|
+
fh.write(dump_lock(lock))
|
|
318
|
+
except FileExistsError:
|
|
319
|
+
# Raced: a lock appeared between the check and the create. Fall through
|
|
320
|
+
# to enforce the now-existing lock read-only (never overwrite it).
|
|
321
|
+
pass
|
|
322
|
+
else:
|
|
323
|
+
# Immediately enforce the freshly-written lock (read-only); on success
|
|
324
|
+
# surface it as GENERATED (traced) rather than a plain OK.
|
|
325
|
+
gate = enforce_stack_lock(contract, project_root)
|
|
326
|
+
if gate.status == LOCK_OK:
|
|
327
|
+
return StackLockGate(status=LOCK_GENERATED, red=False, lock_path=gate.lock_path)
|
|
328
|
+
return gate
|
|
329
|
+
|
|
330
|
+
# Lock already exists (or appeared in a race) — enforce it read-only, NEVER
|
|
331
|
+
# overwrite. A pre-existing drift therefore stays RED.
|
|
332
|
+
return enforce_stack_lock(contract, project_root)
|
|
333
|
+
|
|
334
|
+
|
|
335
|
+
def orphan_stack_lock(project_root: str | Path) -> StackLockGate | None:
|
|
336
|
+
"""Catch a removed ``stack:`` declaration that still has a committed lock.
|
|
337
|
+
|
|
338
|
+
Closes the "drop the ``stack:`` block to dodge the gate" bypass (GPT-consult
|
|
339
|
+
point #1): a project with a committed ``stack.lock`` is demonstrably
|
|
340
|
+
stack-governed, so silently removing its declaration would convert it to an
|
|
341
|
+
ungoverned project (false-green). This is called ONLY when the project has NO
|
|
342
|
+
resolved stack contract (``stack_contract_intake`` returned ``None``):
|
|
343
|
+
|
|
344
|
+
* a committed lock still present → RED (``status=drift``): the declaration was
|
|
345
|
+
removed but the project is still pinned. Decommission explicitly (delete the
|
|
346
|
+
lock) to opt out.
|
|
347
|
+
* no lock → ``None`` (a genuine non-stack project — byte-identical, no gate).
|
|
348
|
+
|
|
349
|
+
Returning ``None`` is the byte-identical path that preserves the "non-stack
|
|
350
|
+
projects are completely unaffected" guarantee (those have no lock file).
|
|
351
|
+
"""
|
|
352
|
+
path = stack_lock_path(project_root)
|
|
353
|
+
if not path.exists():
|
|
354
|
+
return None
|
|
355
|
+
return StackLockGate(
|
|
356
|
+
status=LOCK_DRIFT,
|
|
357
|
+
red=True,
|
|
358
|
+
reasons=(
|
|
359
|
+
"a committed stack.lock exists but the project no longer declares a "
|
|
360
|
+
"`stack:` block — the stack declaration was removed while the lock "
|
|
361
|
+
"remains. A stack-governed project cannot silently become ungoverned "
|
|
362
|
+
"(anti-false-green). Restore the `stack:` block, or decommission "
|
|
363
|
+
"explicitly by deleting the lock.",
|
|
364
|
+
),
|
|
365
|
+
lock_path=str(path),
|
|
366
|
+
)
|
|
@@ -68,3 +68,45 @@ def verify_project_stack(
|
|
|
68
68
|
if contract is None:
|
|
69
69
|
return None
|
|
70
70
|
return enforce_obligations(contract, project_root=project_root, **checker_inputs)
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
def stack_contract_trace(contract: ResolvedStackContract) -> dict[str, Any]:
|
|
74
|
+
"""Run-trace fields proving a run consumed the resolved stack contract.
|
|
75
|
+
|
|
76
|
+
Mirrors :meth:`codd.languages.contract.ResolvedLanguageContract.to_trace`: the
|
|
77
|
+
minimal, deterministic facts a run record / trace records so the live-consumption
|
|
78
|
+
of the framework-stack contract is observable (the v2.77a intake exit gate).
|
|
79
|
+
``stack_contract_hash`` is the deterministic :attr:`ResolvedStackContract.content_hash`;
|
|
80
|
+
``resolved_stack_id`` / ``resolved_stack_layers`` make "changing the profile changes
|
|
81
|
+
the plan" visible in the record itself.
|
|
82
|
+
"""
|
|
83
|
+
return {
|
|
84
|
+
"resolved_stack_id": contract.stack_id,
|
|
85
|
+
"stack_contract_hash": contract.content_hash,
|
|
86
|
+
"resolved_stack_layers": [f"{ref.kind}:{ref.id}" for ref in contract.layers],
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
def stack_contract_intake(project_root: str | Path) -> ResolvedStackContract | None:
|
|
91
|
+
"""Resolve a project's declared stack contract for LIVE consumption (intake only).
|
|
92
|
+
|
|
93
|
+
This is the production seam the greenfield/verify pipeline calls EARLY in a run
|
|
94
|
+
to bring the (previously dormant) framework-stack contract into the live run —
|
|
95
|
+
*without* enforcing any obligation yet (enforcement is v2.77b-e). It is exactly
|
|
96
|
+
:func:`resolve_project_stack`, named for the intake call-site so the
|
|
97
|
+
"no non-test caller = 0 state" is eliminated by an unambiguous production caller.
|
|
98
|
+
|
|
99
|
+
Contract:
|
|
100
|
+
|
|
101
|
+
* No ``stack:`` block (the opt-in framework layer is unused) → ``None``. The
|
|
102
|
+
vast majority of projects; behaviour is byte-identical, never an error.
|
|
103
|
+
* A declared ``stack:`` block → the :class:`ResolvedStackContract` (its
|
|
104
|
+
``content_hash`` is the run-trace hash; see :func:`stack_contract_trace`).
|
|
105
|
+
* A declared-but-BROKEN block (unknown language/framework/addon, malformed
|
|
106
|
+
mapping) → the resolver RAISES (``ValueError`` / ``UnknownLanguageError`` /
|
|
107
|
+
``UnknownLayerError``). The intake NEVER swallows this: anti-false-green
|
|
108
|
+
forbids a declared-but-unresolvable stack from silently proceeding as if no
|
|
109
|
+
stack were declared. The pipeline call-site turns the raise into an honest
|
|
110
|
+
stage/command failure.
|
|
111
|
+
"""
|
|
112
|
+
return resolve_project_stack(project_root)
|