atdd 0.5.0__tar.gz → 0.6.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.
- {atdd-0.5.0/src/atdd.egg-info → atdd-0.6.0}/PKG-INFO +1 -1
- {atdd-0.5.0 → atdd-0.6.0}/pyproject.toml +1 -1
- atdd-0.6.0/src/atdd/coach/schemas/config.schema.json +128 -0
- atdd-0.6.0/src/atdd/coach/utils/coverage_phase.py +97 -0
- {atdd-0.5.0 → atdd-0.6.0}/src/atdd/coach/validators/shared_fixtures.py +154 -0
- atdd-0.6.0/src/atdd/coder/conventions/coverage.convention.yaml +85 -0
- atdd-0.6.0/src/atdd/coder/validators/conftest.py +5 -0
- atdd-0.6.0/src/atdd/coder/validators/test_hierarchy_coverage.py +361 -0
- atdd-0.6.0/src/atdd/planner/conventions/coverage.convention.yaml +95 -0
- atdd-0.6.0/src/atdd/planner/validators/test_hierarchy_coverage.py +433 -0
- atdd-0.6.0/src/atdd/tester/conventions/coverage.convention.yaml +114 -0
- atdd-0.6.0/src/atdd/tester/validators/test_hierarchy_coverage.py +604 -0
- {atdd-0.5.0 → atdd-0.6.0/src/atdd.egg-info}/PKG-INFO +1 -1
- {atdd-0.5.0 → atdd-0.6.0}/src/atdd.egg-info/SOURCES.txt +8 -0
- atdd-0.5.0/src/atdd/coach/schemas/config.schema.json +0 -65
- {atdd-0.5.0 → atdd-0.6.0}/LICENSE +0 -0
- {atdd-0.5.0 → atdd-0.6.0}/README.md +0 -0
- {atdd-0.5.0 → atdd-0.6.0}/setup.cfg +0 -0
- {atdd-0.5.0 → atdd-0.6.0}/src/atdd/__init__.py +0 -0
- {atdd-0.5.0 → atdd-0.6.0}/src/atdd/__main__.py +0 -0
- {atdd-0.5.0 → atdd-0.6.0}/src/atdd/cli.py +0 -0
- {atdd-0.5.0 → atdd-0.6.0}/src/atdd/coach/__init__.py +0 -0
- {atdd-0.5.0 → atdd-0.6.0}/src/atdd/coach/commands/__init__.py +0 -0
- {atdd-0.5.0 → atdd-0.6.0}/src/atdd/coach/commands/add_persistence_metadata.py +0 -0
- {atdd-0.5.0 → atdd-0.6.0}/src/atdd/coach/commands/analyze_migrations.py +0 -0
- {atdd-0.5.0 → atdd-0.6.0}/src/atdd/coach/commands/consumers.py +0 -0
- {atdd-0.5.0 → atdd-0.6.0}/src/atdd/coach/commands/gate.py +0 -0
- {atdd-0.5.0 → atdd-0.6.0}/src/atdd/coach/commands/infer_governance_status.py +0 -0
- {atdd-0.5.0 → atdd-0.6.0}/src/atdd/coach/commands/initializer.py +0 -0
- {atdd-0.5.0 → atdd-0.6.0}/src/atdd/coach/commands/interface.py +0 -0
- {atdd-0.5.0 → atdd-0.6.0}/src/atdd/coach/commands/inventory.py +0 -0
- {atdd-0.5.0 → atdd-0.6.0}/src/atdd/coach/commands/migration.py +0 -0
- {atdd-0.5.0 → atdd-0.6.0}/src/atdd/coach/commands/registry.py +0 -0
- {atdd-0.5.0 → atdd-0.6.0}/src/atdd/coach/commands/session.py +0 -0
- {atdd-0.5.0 → atdd-0.6.0}/src/atdd/coach/commands/sync.py +0 -0
- {atdd-0.5.0 → atdd-0.6.0}/src/atdd/coach/commands/test_interface.py +0 -0
- {atdd-0.5.0 → atdd-0.6.0}/src/atdd/coach/commands/test_runner.py +0 -0
- {atdd-0.5.0 → atdd-0.6.0}/src/atdd/coach/commands/tests/__init__.py +0 -0
- {atdd-0.5.0 → atdd-0.6.0}/src/atdd/coach/commands/tests/test_telemetry_array_validation.py +0 -0
- {atdd-0.5.0 → atdd-0.6.0}/src/atdd/coach/commands/traceability.py +0 -0
- {atdd-0.5.0 → atdd-0.6.0}/src/atdd/coach/conventions/session.convention.yaml +0 -0
- {atdd-0.5.0 → atdd-0.6.0}/src/atdd/coach/overlays/__init__.py +0 -0
- {atdd-0.5.0 → atdd-0.6.0}/src/atdd/coach/overlays/claude.md +0 -0
- {atdd-0.5.0 → atdd-0.6.0}/src/atdd/coach/schemas/manifest.schema.json +0 -0
- {atdd-0.5.0 → atdd-0.6.0}/src/atdd/coach/templates/ATDD.md +0 -0
- {atdd-0.5.0 → atdd-0.6.0}/src/atdd/coach/templates/SESSION-TEMPLATE.md +0 -0
- {atdd-0.5.0 → atdd-0.6.0}/src/atdd/coach/utils/__init__.py +0 -0
- {atdd-0.5.0 → atdd-0.6.0}/src/atdd/coach/utils/config.py +0 -0
- {atdd-0.5.0 → atdd-0.6.0}/src/atdd/coach/utils/graph/__init__.py +0 -0
- {atdd-0.5.0 → atdd-0.6.0}/src/atdd/coach/utils/graph/urn.py +0 -0
- {atdd-0.5.0 → atdd-0.6.0}/src/atdd/coach/utils/repo.py +0 -0
- {atdd-0.5.0 → atdd-0.6.0}/src/atdd/coach/utils/train_spec_phase.py +0 -0
- {atdd-0.5.0 → atdd-0.6.0}/src/atdd/coach/validators/__init__.py +0 -0
- {atdd-0.5.0 → atdd-0.6.0}/src/atdd/coach/validators/test_enrich_wagon_registry.py +0 -0
- {atdd-0.5.0 → atdd-0.6.0}/src/atdd/coach/validators/test_registry.py +0 -0
- {atdd-0.5.0 → atdd-0.6.0}/src/atdd/coach/validators/test_release_versioning.py +0 -0
- {atdd-0.5.0 → atdd-0.6.0}/src/atdd/coach/validators/test_session_validation.py +0 -0
- {atdd-0.5.0 → atdd-0.6.0}/src/atdd/coach/validators/test_traceability.py +0 -0
- {atdd-0.5.0 → atdd-0.6.0}/src/atdd/coach/validators/test_train_registry.py +0 -0
- {atdd-0.5.0 → atdd-0.6.0}/src/atdd/coach/validators/test_update_feature_paths.py +0 -0
- {atdd-0.5.0 → atdd-0.6.0}/src/atdd/coach/validators/test_validate_contract_consumers.py +0 -0
- {atdd-0.5.0 → atdd-0.6.0}/src/atdd/coder/__init__.py +0 -0
- {atdd-0.5.0 → atdd-0.6.0}/src/atdd/coder/conventions/adapter.recipe.yaml +0 -0
- {atdd-0.5.0 → atdd-0.6.0}/src/atdd/coder/conventions/backend.convention.yaml +0 -0
- {atdd-0.5.0 → atdd-0.6.0}/src/atdd/coder/conventions/boundaries.convention.yaml +0 -0
- {atdd-0.5.0 → atdd-0.6.0}/src/atdd/coder/conventions/commons.convention.yaml +0 -0
- {atdd-0.5.0 → atdd-0.6.0}/src/atdd/coder/conventions/complexity.recipe.yaml +0 -0
- {atdd-0.5.0 → atdd-0.6.0}/src/atdd/coder/conventions/component-naming.convention.yaml +0 -0
- {atdd-0.5.0 → atdd-0.6.0}/src/atdd/coder/conventions/design.convention.yaml +0 -0
- {atdd-0.5.0 → atdd-0.6.0}/src/atdd/coder/conventions/design.recipe.yaml +0 -0
- {atdd-0.5.0 → atdd-0.6.0}/src/atdd/coder/conventions/dto.convention.yaml +0 -0
- {atdd-0.5.0 → atdd-0.6.0}/src/atdd/coder/conventions/frontend.convention.yaml +0 -0
- {atdd-0.5.0 → atdd-0.6.0}/src/atdd/coder/conventions/green.convention.yaml +0 -0
- {atdd-0.5.0 → atdd-0.6.0}/src/atdd/coder/conventions/presentation.convention.yaml +0 -0
- {atdd-0.5.0 → atdd-0.6.0}/src/atdd/coder/conventions/refactor.convention.yaml +0 -0
- {atdd-0.5.0 → atdd-0.6.0}/src/atdd/coder/conventions/technology.convention.yaml +0 -0
- {atdd-0.5.0 → atdd-0.6.0}/src/atdd/coder/conventions/tests/__init__.py +0 -0
- {atdd-0.5.0 → atdd-0.6.0}/src/atdd/coder/conventions/tests/test_adapter_recipe.py +0 -0
- {atdd-0.5.0 → atdd-0.6.0}/src/atdd/coder/conventions/tests/test_complexity_recipe.py +0 -0
- {atdd-0.5.0 → atdd-0.6.0}/src/atdd/coder/conventions/tests/test_component_taxonomy.py +0 -0
- {atdd-0.5.0 → atdd-0.6.0}/src/atdd/coder/conventions/tests/test_component_urn_naming.py +0 -0
- {atdd-0.5.0 → atdd-0.6.0}/src/atdd/coder/conventions/tests/test_thinness_recipe.py +0 -0
- {atdd-0.5.0 → atdd-0.6.0}/src/atdd/coder/conventions/thinness.recipe.yaml +0 -0
- {atdd-0.5.0 → atdd-0.6.0}/src/atdd/coder/conventions/train.convention.yaml +0 -0
- {atdd-0.5.0 → atdd-0.6.0}/src/atdd/coder/conventions/verification.protocol.yaml +0 -0
- {atdd-0.5.0 → atdd-0.6.0}/src/atdd/coder/schemas/design_system.schema.json +0 -0
- {atdd-0.5.0 → atdd-0.6.0}/src/atdd/coder/validators/__init__.py +0 -0
- {atdd-0.5.0 → atdd-0.6.0}/src/atdd/coder/validators/test_commons_structure.py +0 -0
- {atdd-0.5.0 → atdd-0.6.0}/src/atdd/coder/validators/test_complexity.py +0 -0
- {atdd-0.5.0 → atdd-0.6.0}/src/atdd/coder/validators/test_cross_language_consistency.py +0 -0
- {atdd-0.5.0 → atdd-0.6.0}/src/atdd/coder/validators/test_design_system_compliance.py +0 -0
- {atdd-0.5.0 → atdd-0.6.0}/src/atdd/coder/validators/test_dto_testing_patterns.py +0 -0
- {atdd-0.5.0 → atdd-0.6.0}/src/atdd/coder/validators/test_green_cross_stack_layers.py +0 -0
- {atdd-0.5.0 → atdd-0.6.0}/src/atdd/coder/validators/test_green_layer_dependencies.py +0 -0
- {atdd-0.5.0 → atdd-0.6.0}/src/atdd/coder/validators/test_green_python_layer_structure.py +0 -0
- {atdd-0.5.0 → atdd-0.6.0}/src/atdd/coder/validators/test_green_supabase_layer_structure.py +0 -0
- {atdd-0.5.0 → atdd-0.6.0}/src/atdd/coder/validators/test_import_boundaries.py +0 -0
- {atdd-0.5.0 → atdd-0.6.0}/src/atdd/coder/validators/test_init_file_urns.py +0 -0
- {atdd-0.5.0 → atdd-0.6.0}/src/atdd/coder/validators/test_preact_layer_boundaries.py +0 -0
- {atdd-0.5.0 → atdd-0.6.0}/src/atdd/coder/validators/test_presentation_convention.py +0 -0
- {atdd-0.5.0 → atdd-0.6.0}/src/atdd/coder/validators/test_python_architecture.py +0 -0
- {atdd-0.5.0 → atdd-0.6.0}/src/atdd/coder/validators/test_quality_metrics.py +0 -0
- {atdd-0.5.0 → atdd-0.6.0}/src/atdd/coder/validators/test_station_master_pattern.py +0 -0
- {atdd-0.5.0 → atdd-0.6.0}/src/atdd/coder/validators/test_train_infrastructure.py +0 -0
- {atdd-0.5.0 → atdd-0.6.0}/src/atdd/coder/validators/test_train_urns.py +0 -0
- {atdd-0.5.0 → atdd-0.6.0}/src/atdd/coder/validators/test_typescript_architecture.py +0 -0
- {atdd-0.5.0 → atdd-0.6.0}/src/atdd/coder/validators/test_usecase_structure.py +0 -0
- {atdd-0.5.0 → atdd-0.6.0}/src/atdd/coder/validators/test_wagon_boundaries.py +0 -0
- {atdd-0.5.0 → atdd-0.6.0}/src/atdd/conftest.py +0 -0
- {atdd-0.5.0 → atdd-0.6.0}/src/atdd/planner/__init__.py +0 -0
- {atdd-0.5.0 → atdd-0.6.0}/src/atdd/planner/conventions/acceptance.convention.yaml +0 -0
- {atdd-0.5.0 → atdd-0.6.0}/src/atdd/planner/conventions/appendix.convention.yaml +0 -0
- {atdd-0.5.0 → atdd-0.6.0}/src/atdd/planner/conventions/artifact-naming.convention.yaml +0 -0
- {atdd-0.5.0 → atdd-0.6.0}/src/atdd/planner/conventions/component.convention.yaml +0 -0
- {atdd-0.5.0 → atdd-0.6.0}/src/atdd/planner/conventions/criteria.convention.yaml +0 -0
- {atdd-0.5.0 → atdd-0.6.0}/src/atdd/planner/conventions/feature.convention.yaml +0 -0
- {atdd-0.5.0 → atdd-0.6.0}/src/atdd/planner/conventions/interface.convention.yaml +0 -0
- {atdd-0.5.0 → atdd-0.6.0}/src/atdd/planner/conventions/steps.convention.yaml +0 -0
- {atdd-0.5.0 → atdd-0.6.0}/src/atdd/planner/conventions/train.convention.yaml +0 -0
- {atdd-0.5.0 → atdd-0.6.0}/src/atdd/planner/conventions/wagon.convention.yaml +0 -0
- {atdd-0.5.0 → atdd-0.6.0}/src/atdd/planner/conventions/wmbt.convention.yaml +0 -0
- {atdd-0.5.0 → atdd-0.6.0}/src/atdd/planner/schemas/acceptance.schema.json +0 -0
- {atdd-0.5.0 → atdd-0.6.0}/src/atdd/planner/schemas/appendix.schema.json +0 -0
- {atdd-0.5.0 → atdd-0.6.0}/src/atdd/planner/schemas/component.schema.json +0 -0
- {atdd-0.5.0 → atdd-0.6.0}/src/atdd/planner/schemas/feature.schema.json +0 -0
- {atdd-0.5.0 → atdd-0.6.0}/src/atdd/planner/schemas/train.schema.json +0 -0
- {atdd-0.5.0 → atdd-0.6.0}/src/atdd/planner/schemas/wagon.schema.json +0 -0
- {atdd-0.5.0 → atdd-0.6.0}/src/atdd/planner/schemas/wmbt.schema.json +0 -0
- {atdd-0.5.0 → atdd-0.6.0}/src/atdd/planner/validators/__init__.py +0 -0
- {atdd-0.5.0 → atdd-0.6.0}/src/atdd/planner/validators/conftest.py +0 -0
- {atdd-0.5.0 → atdd-0.6.0}/src/atdd/planner/validators/test_draft_wagon_registry.py +0 -0
- {atdd-0.5.0 → atdd-0.6.0}/src/atdd/planner/validators/test_plan_cross_refs.py +0 -0
- {atdd-0.5.0 → atdd-0.6.0}/src/atdd/planner/validators/test_plan_uniqueness.py +0 -0
- {atdd-0.5.0 → atdd-0.6.0}/src/atdd/planner/validators/test_plan_urn_resolution.py +0 -0
- {atdd-0.5.0 → atdd-0.6.0}/src/atdd/planner/validators/test_plan_wagons.py +0 -0
- {atdd-0.5.0 → atdd-0.6.0}/src/atdd/planner/validators/test_train_validation.py +0 -0
- {atdd-0.5.0 → atdd-0.6.0}/src/atdd/planner/validators/test_wagon_urn_chain.py +0 -0
- {atdd-0.5.0 → atdd-0.6.0}/src/atdd/planner/validators/test_wmbt_consistency.py +0 -0
- {atdd-0.5.0 → atdd-0.6.0}/src/atdd/planner/validators/test_wmbt_vocabulary.py +0 -0
- {atdd-0.5.0 → atdd-0.6.0}/src/atdd/tester/__init__.py +0 -0
- {atdd-0.5.0 → atdd-0.6.0}/src/atdd/tester/conventions/artifact.convention.yaml +0 -0
- {atdd-0.5.0 → atdd-0.6.0}/src/atdd/tester/conventions/contract.convention.yaml +0 -0
- {atdd-0.5.0 → atdd-0.6.0}/src/atdd/tester/conventions/filename.convention.yaml +0 -0
- {atdd-0.5.0 → atdd-0.6.0}/src/atdd/tester/conventions/migration.convention.yaml +0 -0
- {atdd-0.5.0 → atdd-0.6.0}/src/atdd/tester/conventions/red.convention.yaml +0 -0
- {atdd-0.5.0 → atdd-0.6.0}/src/atdd/tester/conventions/routing.convention.yaml +0 -0
- {atdd-0.5.0 → atdd-0.6.0}/src/atdd/tester/conventions/security.convention.yaml +0 -0
- {atdd-0.5.0 → atdd-0.6.0}/src/atdd/tester/conventions/telemetry.convention.yaml +0 -0
- {atdd-0.5.0 → atdd-0.6.0}/src/atdd/tester/schemas/a11y.tmpl.json +0 -0
- {atdd-0.5.0 → atdd-0.6.0}/src/atdd/tester/schemas/artifact.schema.json +0 -0
- {atdd-0.5.0 → atdd-0.6.0}/src/atdd/tester/schemas/contract.schema.json +0 -0
- {atdd-0.5.0 → atdd-0.6.0}/src/atdd/tester/schemas/contract.tmpl.json +0 -0
- {atdd-0.5.0 → atdd-0.6.0}/src/atdd/tester/schemas/db.tmpl.json +0 -0
- {atdd-0.5.0 → atdd-0.6.0}/src/atdd/tester/schemas/e2e.tmpl.json +0 -0
- {atdd-0.5.0 → atdd-0.6.0}/src/atdd/tester/schemas/edge_function.tmpl.json +0 -0
- {atdd-0.5.0 → atdd-0.6.0}/src/atdd/tester/schemas/event.tmpl.json +0 -0
- {atdd-0.5.0 → atdd-0.6.0}/src/atdd/tester/schemas/http.tmpl.json +0 -0
- {atdd-0.5.0 → atdd-0.6.0}/src/atdd/tester/schemas/job.tmpl.json +0 -0
- {atdd-0.5.0 → atdd-0.6.0}/src/atdd/tester/schemas/load.tmpl.json +0 -0
- {atdd-0.5.0 → atdd-0.6.0}/src/atdd/tester/schemas/metric.tmpl.json +0 -0
- {atdd-0.5.0 → atdd-0.6.0}/src/atdd/tester/schemas/pack.schema.json +0 -0
- {atdd-0.5.0 → atdd-0.6.0}/src/atdd/tester/schemas/realtime.tmpl.json +0 -0
- {atdd-0.5.0 → atdd-0.6.0}/src/atdd/tester/schemas/rls.tmpl.json +0 -0
- {atdd-0.5.0 → atdd-0.6.0}/src/atdd/tester/schemas/script.tmpl.json +0 -0
- {atdd-0.5.0 → atdd-0.6.0}/src/atdd/tester/schemas/sec.tmpl.json +0 -0
- {atdd-0.5.0 → atdd-0.6.0}/src/atdd/tester/schemas/storage.tmpl.json +0 -0
- {atdd-0.5.0 → atdd-0.6.0}/src/atdd/tester/schemas/telemetry.schema.json +0 -0
- {atdd-0.5.0 → atdd-0.6.0}/src/atdd/tester/schemas/telemetry_tracking_manifest.schema.json +0 -0
- {atdd-0.5.0 → atdd-0.6.0}/src/atdd/tester/schemas/test_filename.schema.json +0 -0
- {atdd-0.5.0 → atdd-0.6.0}/src/atdd/tester/schemas/test_intent.schema.json +0 -0
- {atdd-0.5.0 → atdd-0.6.0}/src/atdd/tester/schemas/unit.tmpl.json +0 -0
- {atdd-0.5.0 → atdd-0.6.0}/src/atdd/tester/schemas/visual.tmpl.json +0 -0
- {atdd-0.5.0 → atdd-0.6.0}/src/atdd/tester/schemas/ws.tmpl.json +0 -0
- {atdd-0.5.0 → atdd-0.6.0}/src/atdd/tester/utils/__init__.py +0 -0
- {atdd-0.5.0 → atdd-0.6.0}/src/atdd/tester/utils/filename.py +0 -0
- {atdd-0.5.0 → atdd-0.6.0}/src/atdd/tester/validators/__init__.py +0 -0
- {atdd-0.5.0 → atdd-0.6.0}/src/atdd/tester/validators/cleanup_duplicate_headers.py +0 -0
- {atdd-0.5.0 → atdd-0.6.0}/src/atdd/tester/validators/cleanup_duplicate_headers_v2.py +0 -0
- {atdd-0.5.0 → atdd-0.6.0}/src/atdd/tester/validators/conftest.py +0 -0
- {atdd-0.5.0 → atdd-0.6.0}/src/atdd/tester/validators/coverage_gap_report.py +0 -0
- {atdd-0.5.0 → atdd-0.6.0}/src/atdd/tester/validators/fix_dual_ac_references.py +0 -0
- {atdd-0.5.0 → atdd-0.6.0}/src/atdd/tester/validators/remove_duplicate_lines.py +0 -0
- {atdd-0.5.0 → atdd-0.6.0}/src/atdd/tester/validators/test_acceptance_urn_filename_mapping.py +0 -0
- {atdd-0.5.0 → atdd-0.6.0}/src/atdd/tester/validators/test_acceptance_urn_separator.py +0 -0
- {atdd-0.5.0 → atdd-0.6.0}/src/atdd/tester/validators/test_artifact_naming_category.py +0 -0
- {atdd-0.5.0 → atdd-0.6.0}/src/atdd/tester/validators/test_contract_schema_compliance.py +0 -0
- {atdd-0.5.0 → atdd-0.6.0}/src/atdd/tester/validators/test_contract_security.py +0 -0
- {atdd-0.5.0 → atdd-0.6.0}/src/atdd/tester/validators/test_contracts_structure.py +0 -0
- {atdd-0.5.0 → atdd-0.6.0}/src/atdd/tester/validators/test_coverage_adequacy.py +0 -0
- {atdd-0.5.0 → atdd-0.6.0}/src/atdd/tester/validators/test_dual_ac_reference.py +0 -0
- {atdd-0.5.0 → atdd-0.6.0}/src/atdd/tester/validators/test_fixture_validity.py +0 -0
- {atdd-0.5.0 → atdd-0.6.0}/src/atdd/tester/validators/test_isolation.py +0 -0
- {atdd-0.5.0 → atdd-0.6.0}/src/atdd/tester/validators/test_migration_coverage.py +0 -0
- {atdd-0.5.0 → atdd-0.6.0}/src/atdd/tester/validators/test_migration_criteria.py +0 -0
- {atdd-0.5.0 → atdd-0.6.0}/src/atdd/tester/validators/test_migration_generation.py +0 -0
- {atdd-0.5.0 → atdd-0.6.0}/src/atdd/tester/validators/test_python_test_naming.py +0 -0
- {atdd-0.5.0 → atdd-0.6.0}/src/atdd/tester/validators/test_red_layer_validation.py +0 -0
- {atdd-0.5.0 → atdd-0.6.0}/src/atdd/tester/validators/test_red_python_layer_structure.py +0 -0
- {atdd-0.5.0 → atdd-0.6.0}/src/atdd/tester/validators/test_red_supabase_layer_structure.py +0 -0
- {atdd-0.5.0 → atdd-0.6.0}/src/atdd/tester/validators/test_telemetry_structure.py +0 -0
- {atdd-0.5.0 → atdd-0.6.0}/src/atdd/tester/validators/test_train_backend_e2e.py +0 -0
- {atdd-0.5.0 → atdd-0.6.0}/src/atdd/tester/validators/test_train_frontend_e2e.py +0 -0
- {atdd-0.5.0 → atdd-0.6.0}/src/atdd/tester/validators/test_train_frontend_python.py +0 -0
- {atdd-0.5.0 → atdd-0.6.0}/src/atdd/tester/validators/test_typescript_test_naming.py +0 -0
- {atdd-0.5.0 → atdd-0.6.0}/src/atdd/tester/validators/test_typescript_test_structure.py +0 -0
- {atdd-0.5.0 → atdd-0.6.0}/src/atdd/version_check.py +0 -0
- {atdd-0.5.0 → atdd-0.6.0}/src/atdd.egg-info/dependency_links.txt +0 -0
- {atdd-0.5.0 → atdd-0.6.0}/src/atdd.egg-info/entry_points.txt +0 -0
- {atdd-0.5.0 → atdd-0.6.0}/src/atdd.egg-info/requires.txt +0 -0
- {atdd-0.5.0 → atdd-0.6.0}/src/atdd.egg-info/top_level.txt +0 -0
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "http://json-schema.org/draft-07/schema#",
|
|
3
|
+
"$id": "https://atdd.dev/schemas/config.schema.json",
|
|
4
|
+
"title": "ATDD Config",
|
|
5
|
+
"description": "Schema for .atdd/config.yaml configuration file",
|
|
6
|
+
"type": "object",
|
|
7
|
+
"properties": {
|
|
8
|
+
"version": {
|
|
9
|
+
"type": "string",
|
|
10
|
+
"description": "Configuration schema version",
|
|
11
|
+
"pattern": "^[0-9]+\\.[0-9]+$",
|
|
12
|
+
"examples": ["1.0"]
|
|
13
|
+
},
|
|
14
|
+
"release": {
|
|
15
|
+
"type": "object",
|
|
16
|
+
"description": "Release/versioning settings",
|
|
17
|
+
"properties": {
|
|
18
|
+
"version_file": {
|
|
19
|
+
"type": "string",
|
|
20
|
+
"description": "Path to version file (relative to repo root)",
|
|
21
|
+
"examples": ["pyproject.toml", "package.json", "VERSION"]
|
|
22
|
+
},
|
|
23
|
+
"tag_prefix": {
|
|
24
|
+
"type": "string",
|
|
25
|
+
"description": "Prefix for git tags",
|
|
26
|
+
"default": "v",
|
|
27
|
+
"examples": ["v", ""]
|
|
28
|
+
}
|
|
29
|
+
},
|
|
30
|
+
"required": ["version_file"],
|
|
31
|
+
"additionalProperties": false
|
|
32
|
+
},
|
|
33
|
+
"sync": {
|
|
34
|
+
"type": "object",
|
|
35
|
+
"description": "Agent config file sync settings",
|
|
36
|
+
"properties": {
|
|
37
|
+
"agents": {
|
|
38
|
+
"type": "array",
|
|
39
|
+
"description": "List of agents to sync ATDD rules to",
|
|
40
|
+
"items": {
|
|
41
|
+
"type": "string",
|
|
42
|
+
"enum": ["claude", "codex", "gemini", "qwen"]
|
|
43
|
+
},
|
|
44
|
+
"uniqueItems": true,
|
|
45
|
+
"default": ["claude"]
|
|
46
|
+
}
|
|
47
|
+
},
|
|
48
|
+
"additionalProperties": false
|
|
49
|
+
},
|
|
50
|
+
"toolkit": {
|
|
51
|
+
"type": "object",
|
|
52
|
+
"description": "ATDD toolkit metadata",
|
|
53
|
+
"properties": {
|
|
54
|
+
"last_version": {
|
|
55
|
+
"type": "string",
|
|
56
|
+
"description": "Last installed ATDD toolkit version"
|
|
57
|
+
}
|
|
58
|
+
},
|
|
59
|
+
"required": ["last_version"],
|
|
60
|
+
"additionalProperties": false
|
|
61
|
+
},
|
|
62
|
+
"coverage": {
|
|
63
|
+
"type": "object",
|
|
64
|
+
"description": "Hierarchy coverage validation settings (ATDD Hierarchy Coverage Spec v0.1)",
|
|
65
|
+
"properties": {
|
|
66
|
+
"exceptions": {
|
|
67
|
+
"type": "object",
|
|
68
|
+
"description": "Allow-lists for coverage exceptions",
|
|
69
|
+
"properties": {
|
|
70
|
+
"wagons_not_in_train": {
|
|
71
|
+
"type": "array",
|
|
72
|
+
"items": {"type": "string"},
|
|
73
|
+
"description": "Wagon slugs allowed without train coverage"
|
|
74
|
+
},
|
|
75
|
+
"features_orphaned": {
|
|
76
|
+
"type": "array",
|
|
77
|
+
"items": {"type": "string"},
|
|
78
|
+
"description": "Feature URNs allowed without wagon manifest reference"
|
|
79
|
+
},
|
|
80
|
+
"wmbts_without_acceptance": {
|
|
81
|
+
"type": "array",
|
|
82
|
+
"items": {"type": "string"},
|
|
83
|
+
"description": "WMBT URNs allowed without acceptance criteria"
|
|
84
|
+
},
|
|
85
|
+
"acceptance_without_tests": {
|
|
86
|
+
"type": "array",
|
|
87
|
+
"items": {"type": "string"},
|
|
88
|
+
"description": "Acceptance URNs allowed without test coverage"
|
|
89
|
+
},
|
|
90
|
+
"contracts_unreferenced": {
|
|
91
|
+
"type": "array",
|
|
92
|
+
"items": {"type": "string"},
|
|
93
|
+
"description": "Contract URNs allowed without produce/consume"
|
|
94
|
+
},
|
|
95
|
+
"telemetry_unreferenced": {
|
|
96
|
+
"type": "array",
|
|
97
|
+
"items": {"type": "string"},
|
|
98
|
+
"description": "Telemetry URNs allowed without references"
|
|
99
|
+
},
|
|
100
|
+
"features_without_implementation": {
|
|
101
|
+
"type": "array",
|
|
102
|
+
"items": {"type": "string"},
|
|
103
|
+
"description": "Feature URNs allowed without code implementation"
|
|
104
|
+
}
|
|
105
|
+
},
|
|
106
|
+
"additionalProperties": false
|
|
107
|
+
},
|
|
108
|
+
"thresholds": {
|
|
109
|
+
"type": "object",
|
|
110
|
+
"description": "Coverage threshold settings",
|
|
111
|
+
"properties": {
|
|
112
|
+
"min_acceptance_coverage": {
|
|
113
|
+
"type": "number",
|
|
114
|
+
"minimum": 0,
|
|
115
|
+
"maximum": 100,
|
|
116
|
+
"default": 80,
|
|
117
|
+
"description": "Minimum percentage of acceptances that must have tests"
|
|
118
|
+
}
|
|
119
|
+
},
|
|
120
|
+
"additionalProperties": false
|
|
121
|
+
}
|
|
122
|
+
},
|
|
123
|
+
"additionalProperties": false
|
|
124
|
+
}
|
|
125
|
+
},
|
|
126
|
+
"required": ["version", "release"],
|
|
127
|
+
"additionalProperties": false
|
|
128
|
+
}
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
"""
|
|
2
|
+
ATDD Hierarchy Coverage Spec v0.1 Rollout Phase Controller.
|
|
3
|
+
|
|
4
|
+
Manages the phased rollout of coverage validation rules:
|
|
5
|
+
- Phase 1 (WARNINGS_ONLY): All validators emit warnings only
|
|
6
|
+
- Phase 2 (PLANNER_TESTER_ENFORCEMENT): Sections 2 + 3 validators strict
|
|
7
|
+
- Phase 3 (FULL_ENFORCEMENT): All validators (including Section 4) strict
|
|
8
|
+
|
|
9
|
+
Usage in validators:
|
|
10
|
+
from atdd.coach.utils.coverage_phase import CoveragePhase, should_enforce
|
|
11
|
+
|
|
12
|
+
if should_enforce(CoveragePhase.PLANNER_TESTER_ENFORCEMENT):
|
|
13
|
+
assert condition, "Error message"
|
|
14
|
+
else:
|
|
15
|
+
if not condition:
|
|
16
|
+
emit_coverage_warning("COVERAGE-PLAN-2.1", "Warning message", CoveragePhase.PLANNER_TESTER_ENFORCEMENT)
|
|
17
|
+
"""
|
|
18
|
+
|
|
19
|
+
from enum import IntEnum
|
|
20
|
+
from typing import Optional
|
|
21
|
+
import warnings
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
class CoveragePhase(IntEnum):
|
|
25
|
+
"""
|
|
26
|
+
Rollout phases for ATDD Hierarchy Coverage Spec v0.1.
|
|
27
|
+
|
|
28
|
+
Phases are ordered by strictness level:
|
|
29
|
+
- WARNINGS_ONLY (1): All new validators emit warnings, no assertions
|
|
30
|
+
- PLANNER_TESTER_ENFORCEMENT (2): Planner (Section 2) + Tester (Section 3) strict
|
|
31
|
+
- FULL_ENFORCEMENT (3): All validators including Coder (Section 4) strict
|
|
32
|
+
"""
|
|
33
|
+
WARNINGS_ONLY = 1
|
|
34
|
+
PLANNER_TESTER_ENFORCEMENT = 2
|
|
35
|
+
FULL_ENFORCEMENT = 3
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
# Current rollout phase - update this to advance through phases
|
|
39
|
+
CURRENT_PHASE = CoveragePhase.WARNINGS_ONLY
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
def should_enforce(validator_phase: CoveragePhase) -> bool:
|
|
43
|
+
"""
|
|
44
|
+
Check if a validator should enforce strict mode.
|
|
45
|
+
|
|
46
|
+
Args:
|
|
47
|
+
validator_phase: The phase at which this validator becomes strict
|
|
48
|
+
|
|
49
|
+
Returns:
|
|
50
|
+
True if current phase >= validator_phase (should enforce)
|
|
51
|
+
False if current phase < validator_phase (should warn only)
|
|
52
|
+
|
|
53
|
+
Example:
|
|
54
|
+
# This validator becomes strict in Phase 2
|
|
55
|
+
if should_enforce(CoveragePhase.PLANNER_TESTER_ENFORCEMENT):
|
|
56
|
+
assert wagon_in_train, "Wagon must be in at least one train"
|
|
57
|
+
else:
|
|
58
|
+
if not wagon_in_train:
|
|
59
|
+
emit_coverage_warning("COVERAGE-PLAN-2.1", "Wagon not in any train", CoveragePhase.PLANNER_TESTER_ENFORCEMENT)
|
|
60
|
+
"""
|
|
61
|
+
return CURRENT_PHASE >= validator_phase
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
def get_current_phase() -> CoveragePhase:
|
|
65
|
+
"""Get the current rollout phase."""
|
|
66
|
+
return CURRENT_PHASE
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
def get_phase_name(phase: Optional[CoveragePhase] = None) -> str:
|
|
70
|
+
"""Get human-readable name for a phase."""
|
|
71
|
+
phase = phase or CURRENT_PHASE
|
|
72
|
+
return {
|
|
73
|
+
CoveragePhase.WARNINGS_ONLY: "Phase 1: Warnings Only",
|
|
74
|
+
CoveragePhase.PLANNER_TESTER_ENFORCEMENT: "Phase 2: Planner+Tester Enforcement",
|
|
75
|
+
CoveragePhase.FULL_ENFORCEMENT: "Phase 3: Full Enforcement",
|
|
76
|
+
}.get(phase, "Unknown Phase")
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
def emit_coverage_warning(
|
|
80
|
+
spec_id: str,
|
|
81
|
+
message: str,
|
|
82
|
+
validator_phase: CoveragePhase = CoveragePhase.PLANNER_TESTER_ENFORCEMENT
|
|
83
|
+
) -> None:
|
|
84
|
+
"""
|
|
85
|
+
Emit a coverage validation warning with phase context.
|
|
86
|
+
|
|
87
|
+
Args:
|
|
88
|
+
spec_id: The SPEC ID (e.g., "COVERAGE-PLAN-2.1")
|
|
89
|
+
message: The warning message
|
|
90
|
+
validator_phase: Phase when this becomes an error
|
|
91
|
+
"""
|
|
92
|
+
phase_name = get_phase_name(validator_phase)
|
|
93
|
+
warnings.warn(
|
|
94
|
+
f"[{spec_id}] {message} (will become error in {phase_name})",
|
|
95
|
+
category=UserWarning,
|
|
96
|
+
stacklevel=3
|
|
97
|
+
)
|
|
@@ -445,3 +445,157 @@ def pytest_html_results_summary(prefix, summary, postfix):
|
|
|
445
445
|
'against platform schemas and conventions.</p>'
|
|
446
446
|
'</div>'
|
|
447
447
|
])
|
|
448
|
+
|
|
449
|
+
|
|
450
|
+
# ============================================================================
|
|
451
|
+
# COVERAGE VALIDATION FIXTURES (ATDD Hierarchy Coverage Spec v0.1)
|
|
452
|
+
# ============================================================================
|
|
453
|
+
|
|
454
|
+
|
|
455
|
+
@pytest.fixture(scope="module")
|
|
456
|
+
def coverage_exceptions(atdd_config: Dict[str, Any]) -> Dict[str, List[str]]:
|
|
457
|
+
"""
|
|
458
|
+
Load coverage exception allow-lists from .atdd/config.yaml.
|
|
459
|
+
|
|
460
|
+
Returns:
|
|
461
|
+
Dict mapping exception type to list of allowed URNs/slugs
|
|
462
|
+
"""
|
|
463
|
+
return atdd_config.get("coverage", {}).get("exceptions", {})
|
|
464
|
+
|
|
465
|
+
|
|
466
|
+
@pytest.fixture(scope="module")
|
|
467
|
+
def coverage_thresholds(atdd_config: Dict[str, Any]) -> Dict[str, Any]:
|
|
468
|
+
"""
|
|
469
|
+
Load coverage threshold settings from .atdd/config.yaml.
|
|
470
|
+
|
|
471
|
+
Returns:
|
|
472
|
+
Dict with threshold settings (min_acceptance_coverage, etc.)
|
|
473
|
+
"""
|
|
474
|
+
defaults = {"min_acceptance_coverage": 80}
|
|
475
|
+
thresholds = atdd_config.get("coverage", {}).get("thresholds", {})
|
|
476
|
+
return {**defaults, **thresholds}
|
|
477
|
+
|
|
478
|
+
|
|
479
|
+
@pytest.fixture(scope="module")
|
|
480
|
+
def feature_files() -> List[Tuple[Path, Dict[str, Any]]]:
|
|
481
|
+
"""
|
|
482
|
+
Discover all feature files in plan/*/features/.
|
|
483
|
+
|
|
484
|
+
Returns:
|
|
485
|
+
List of (path, feature_data) tuples
|
|
486
|
+
"""
|
|
487
|
+
import re
|
|
488
|
+
features = []
|
|
489
|
+
if not PLAN_DIR.exists():
|
|
490
|
+
return features
|
|
491
|
+
|
|
492
|
+
for wagon_dir in PLAN_DIR.iterdir():
|
|
493
|
+
if wagon_dir.is_dir() and not wagon_dir.name.startswith("_"):
|
|
494
|
+
features_dir = wagon_dir / "features"
|
|
495
|
+
if features_dir.exists():
|
|
496
|
+
for feature_file in features_dir.glob("*.yaml"):
|
|
497
|
+
try:
|
|
498
|
+
with open(feature_file) as f:
|
|
499
|
+
data = yaml.safe_load(f)
|
|
500
|
+
if data:
|
|
501
|
+
features.append((feature_file, data))
|
|
502
|
+
except Exception:
|
|
503
|
+
pass
|
|
504
|
+
return features
|
|
505
|
+
|
|
506
|
+
|
|
507
|
+
@pytest.fixture(scope="module")
|
|
508
|
+
def wmbt_files() -> List[Tuple[Path, Dict[str, Any]]]:
|
|
509
|
+
"""
|
|
510
|
+
Discover all WMBT files in plan/*/.
|
|
511
|
+
|
|
512
|
+
WMBT files match pattern: [DLPCEMYRK]NNN.yaml (e.g., D001.yaml, L010.yaml)
|
|
513
|
+
|
|
514
|
+
Returns:
|
|
515
|
+
List of (path, wmbt_data) tuples
|
|
516
|
+
"""
|
|
517
|
+
import re
|
|
518
|
+
wmbts = []
|
|
519
|
+
if not PLAN_DIR.exists():
|
|
520
|
+
return wmbts
|
|
521
|
+
|
|
522
|
+
wmbt_pattern = re.compile(r"^[DLPCEMYRK]\d{3}\.yaml$")
|
|
523
|
+
|
|
524
|
+
for wagon_dir in PLAN_DIR.iterdir():
|
|
525
|
+
if wagon_dir.is_dir() and not wagon_dir.name.startswith("_"):
|
|
526
|
+
for wmbt_file in wagon_dir.glob("*.yaml"):
|
|
527
|
+
if wmbt_pattern.match(wmbt_file.name):
|
|
528
|
+
try:
|
|
529
|
+
with open(wmbt_file) as f:
|
|
530
|
+
data = yaml.safe_load(f)
|
|
531
|
+
if data:
|
|
532
|
+
wmbts.append((wmbt_file, data))
|
|
533
|
+
except Exception:
|
|
534
|
+
pass
|
|
535
|
+
return wmbts
|
|
536
|
+
|
|
537
|
+
|
|
538
|
+
@pytest.fixture(scope="module")
|
|
539
|
+
def acceptance_urns_by_wagon(wmbt_files: List[Tuple[Path, Dict[str, Any]]]) -> Dict[str, List[str]]:
|
|
540
|
+
"""
|
|
541
|
+
Extract all acceptance URNs grouped by wagon slug.
|
|
542
|
+
|
|
543
|
+
Returns:
|
|
544
|
+
Dict mapping wagon slug to list of acceptance URNs
|
|
545
|
+
"""
|
|
546
|
+
by_wagon: Dict[str, List[str]] = {}
|
|
547
|
+
|
|
548
|
+
for path, wmbt_data in wmbt_files:
|
|
549
|
+
# Derive wagon slug from directory name (snake_case -> kebab-case)
|
|
550
|
+
wagon_slug = path.parent.name.replace("_", "-")
|
|
551
|
+
|
|
552
|
+
if wagon_slug not in by_wagon:
|
|
553
|
+
by_wagon[wagon_slug] = []
|
|
554
|
+
|
|
555
|
+
for acc in wmbt_data.get("acceptances", []):
|
|
556
|
+
if isinstance(acc, dict) and "identity" in acc:
|
|
557
|
+
urn = acc["identity"].get("urn", "")
|
|
558
|
+
if urn:
|
|
559
|
+
by_wagon[wagon_slug].append(urn)
|
|
560
|
+
elif isinstance(acc, str):
|
|
561
|
+
by_wagon[wagon_slug].append(acc)
|
|
562
|
+
|
|
563
|
+
return by_wagon
|
|
564
|
+
|
|
565
|
+
|
|
566
|
+
@pytest.fixture(scope="module")
|
|
567
|
+
def all_acceptance_urns(acceptance_urns_by_wagon: Dict[str, List[str]]) -> List[str]:
|
|
568
|
+
"""
|
|
569
|
+
Get flat list of all acceptance URNs across all wagons.
|
|
570
|
+
|
|
571
|
+
Returns:
|
|
572
|
+
List of all acceptance URNs
|
|
573
|
+
"""
|
|
574
|
+
all_urns = []
|
|
575
|
+
for urns in acceptance_urns_by_wagon.values():
|
|
576
|
+
all_urns.extend(urns)
|
|
577
|
+
return all_urns
|
|
578
|
+
|
|
579
|
+
|
|
580
|
+
@pytest.fixture(scope="module")
|
|
581
|
+
def wagon_to_train_mapping(train_files: List[Tuple[Path, Dict]]) -> Dict[str, List[str]]:
|
|
582
|
+
"""
|
|
583
|
+
Build mapping of wagon slugs to train IDs that reference them.
|
|
584
|
+
|
|
585
|
+
Returns:
|
|
586
|
+
Dict mapping wagon slug to list of train IDs
|
|
587
|
+
"""
|
|
588
|
+
mapping: Dict[str, List[str]] = {}
|
|
589
|
+
|
|
590
|
+
for train_path, train_data in train_files:
|
|
591
|
+
train_id = train_data.get("train_id", train_path.stem)
|
|
592
|
+
participants = train_data.get("participants", [])
|
|
593
|
+
|
|
594
|
+
for participant in participants:
|
|
595
|
+
if isinstance(participant, str) and participant.startswith("wagon:"):
|
|
596
|
+
wagon_slug = participant.replace("wagon:", "")
|
|
597
|
+
if wagon_slug not in mapping:
|
|
598
|
+
mapping[wagon_slug] = []
|
|
599
|
+
mapping[wagon_slug].append(train_id)
|
|
600
|
+
|
|
601
|
+
return mapping
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
version: "1.0"
|
|
2
|
+
name: "Coder Coverage Convention"
|
|
3
|
+
description: "Section 4 of ATDD Hierarchy Coverage Spec v0.1 - Ensures code implementation covers all features"
|
|
4
|
+
|
|
5
|
+
rules:
|
|
6
|
+
- id: "COVERAGE-CODE-4.1"
|
|
7
|
+
name: "Feature - Implementation Coverage"
|
|
8
|
+
description: "Every feature must have corresponding code implementation"
|
|
9
|
+
requirement: "Each feature's components must map to code paths"
|
|
10
|
+
exceptions: "features_without_implementation allow-list"
|
|
11
|
+
validator: "test_all_features_have_implementations"
|
|
12
|
+
|
|
13
|
+
- id: "COVERAGE-CODE-4.2"
|
|
14
|
+
name: "Implementation - Tests Coverage"
|
|
15
|
+
description: "Every implementation must have at least one linked test"
|
|
16
|
+
requirement: "Each implementation must have at least one linked test"
|
|
17
|
+
validator: "test_all_implementations_have_tests"
|
|
18
|
+
|
|
19
|
+
coverage_graph:
|
|
20
|
+
description: "The coder coverage graph ensures features are implemented and tested"
|
|
21
|
+
levels:
|
|
22
|
+
- name: "Feature"
|
|
23
|
+
implemented_by: "Code files in python/, supabase/, web/"
|
|
24
|
+
validators: ["COVERAGE-CODE-4.1"]
|
|
25
|
+
|
|
26
|
+
- name: "Implementation"
|
|
27
|
+
tested_by: "Test files referencing feature/component"
|
|
28
|
+
validators: ["COVERAGE-CODE-4.2"]
|
|
29
|
+
|
|
30
|
+
exception_handling:
|
|
31
|
+
description: "How exceptions are handled in coder coverage validation"
|
|
32
|
+
allow_lists:
|
|
33
|
+
features_without_implementation:
|
|
34
|
+
description: "Feature URNs that are allowed without code implementation"
|
|
35
|
+
use_case: "Planned features, design-only features, or features implemented externally"
|
|
36
|
+
config_path: "coverage.exceptions.features_without_implementation"
|
|
37
|
+
|
|
38
|
+
implementation_patterns:
|
|
39
|
+
description: "How features map to code implementations"
|
|
40
|
+
|
|
41
|
+
python:
|
|
42
|
+
location: "python/{wagon}/"
|
|
43
|
+
patterns:
|
|
44
|
+
- "use_case_{feature_slug}.py"
|
|
45
|
+
- "service_{feature_slug}.py"
|
|
46
|
+
- "{feature_slug}_handler.py"
|
|
47
|
+
example: "python/maintain_ux/use_case_provide_foundations.py"
|
|
48
|
+
|
|
49
|
+
typescript:
|
|
50
|
+
location: "supabase/functions/{wagon}/{feature}/"
|
|
51
|
+
patterns:
|
|
52
|
+
- "index.ts"
|
|
53
|
+
- "handler.ts"
|
|
54
|
+
- "{feature_slug}.ts"
|
|
55
|
+
example: "supabase/functions/maintain-ux/provide-foundations/index.ts"
|
|
56
|
+
|
|
57
|
+
web:
|
|
58
|
+
location: "web/src/features/{wagon}/{feature}/"
|
|
59
|
+
patterns:
|
|
60
|
+
- "index.tsx"
|
|
61
|
+
- "{feature_slug}.tsx"
|
|
62
|
+
- "components/"
|
|
63
|
+
example: "web/src/features/maintain-ux/provide-foundations/index.tsx"
|
|
64
|
+
|
|
65
|
+
test_patterns:
|
|
66
|
+
description: "How implementations map to tests"
|
|
67
|
+
|
|
68
|
+
python:
|
|
69
|
+
location: "python/{wagon}/"
|
|
70
|
+
filename: "test_*.py"
|
|
71
|
+
reference_method: "Import or reference to implementation module"
|
|
72
|
+
|
|
73
|
+
typescript:
|
|
74
|
+
location: "supabase/functions/{wagon}/{feature}/test/"
|
|
75
|
+
filename: "*.test.ts"
|
|
76
|
+
reference_method: "Import or reference to implementation"
|
|
77
|
+
|
|
78
|
+
web:
|
|
79
|
+
location: "web/tests/{wagon}/{feature}/"
|
|
80
|
+
filename: "*.test.tsx"
|
|
81
|
+
reference_method: "Import or reference to component"
|
|
82
|
+
|
|
83
|
+
rollout:
|
|
84
|
+
phase: "FULL_ENFORCEMENT"
|
|
85
|
+
description: "Section 4 validators become strict in Phase 3 (after planner+tester)"
|