atdd 0.3.2__py3-none-any.whl → 0.4.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (72) hide show
  1. atdd/cli.py +229 -78
  2. atdd/coach/commands/add_persistence_metadata.py +3 -1
  3. atdd/coach/commands/infer_governance_status.py +3 -1
  4. atdd/coach/commands/initializer.py +10 -0
  5. atdd/coach/commands/interface.py +3 -1
  6. atdd/coach/commands/inventory.py +2 -2
  7. atdd/coach/commands/migration.py +11 -6
  8. atdd/coach/commands/sync.py +7 -0
  9. atdd/coach/commands/test_runner.py +66 -27
  10. atdd/coach/commands/traceability.py +3 -1
  11. atdd/coach/conventions/session.convention.yaml +26 -26
  12. atdd/coach/templates/ATDD.md +15 -15
  13. atdd/coach/templates/SESSION-TEMPLATE.md +12 -12
  14. atdd/coach/utils/repo.py +24 -8
  15. atdd/coach/validators/shared_fixtures.py +8 -3
  16. atdd/coach/validators/test_session_validation.py +4 -4
  17. atdd/coder/conventions/tests/test_component_taxonomy.py +4 -3
  18. atdd/coder/conventions/tests/test_component_urn_naming.py +3 -1
  19. atdd/coder/validators/test_commons_structure.py +3 -1
  20. atdd/coder/validators/test_complexity.py +3 -1
  21. atdd/coder/validators/test_cross_language_consistency.py +3 -1
  22. atdd/coder/validators/test_design_system_compliance.py +3 -1
  23. atdd/coder/validators/test_dto_testing_patterns.py +4 -2
  24. atdd/coder/validators/test_green_cross_stack_layers.py +3 -1
  25. atdd/coder/validators/test_green_layer_dependencies.py +3 -1
  26. atdd/coder/validators/test_green_python_layer_structure.py +3 -1
  27. atdd/coder/validators/test_green_supabase_layer_structure.py +2 -1
  28. atdd/coder/validators/test_import_boundaries.py +3 -1
  29. atdd/coder/validators/test_init_file_urns.py +3 -1
  30. atdd/coder/validators/test_preact_layer_boundaries.py +3 -1
  31. atdd/coder/validators/test_presentation_convention.py +3 -1
  32. atdd/coder/validators/test_python_architecture.py +3 -1
  33. atdd/coder/validators/test_quality_metrics.py +2 -1
  34. atdd/coder/validators/test_station_master_pattern.py +4 -2
  35. atdd/coder/validators/test_train_infrastructure.py +3 -1
  36. atdd/coder/validators/test_train_urns.py +3 -1
  37. atdd/coder/validators/test_typescript_architecture.py +3 -1
  38. atdd/coder/validators/test_usecase_structure.py +3 -1
  39. atdd/coder/validators/test_wagon_boundaries.py +2 -1
  40. atdd/planner/validators/test_plan_urn_resolution.py +3 -1
  41. atdd/planner/validators/test_wagon_urn_chain.py +3 -1
  42. atdd/planner/validators/test_wmbt_consistency.py +3 -1
  43. atdd/planner/validators/test_wmbt_vocabulary.py +2 -1
  44. atdd/tester/conventions/contract.convention.yaml +1 -1
  45. atdd/tester/conventions/migration.convention.yaml +5 -5
  46. atdd/tester/validators/cleanup_duplicate_headers.py +3 -1
  47. atdd/tester/validators/cleanup_duplicate_headers_v2.py +3 -1
  48. atdd/tester/validators/coverage_gap_report.py +3 -1
  49. atdd/tester/validators/fix_dual_ac_references.py +3 -1
  50. atdd/tester/validators/remove_duplicate_lines.py +3 -1
  51. atdd/tester/validators/test_acceptance_urn_filename_mapping.py +3 -1
  52. atdd/tester/validators/test_acceptance_urn_separator.py +3 -1
  53. atdd/tester/validators/test_contract_schema_compliance.py +3 -1
  54. atdd/tester/validators/test_contracts_structure.py +3 -1
  55. atdd/tester/validators/test_coverage_adequacy.py +3 -1
  56. atdd/tester/validators/test_dual_ac_reference.py +3 -1
  57. atdd/tester/validators/test_fixture_validity.py +2 -1
  58. atdd/tester/validators/test_isolation.py +3 -1
  59. atdd/tester/validators/test_migration_coverage.py +4 -2
  60. atdd/tester/validators/test_migration_generation.py +3 -1
  61. atdd/tester/validators/test_python_test_naming.py +3 -1
  62. atdd/tester/validators/test_red_layer_validation.py +2 -1
  63. atdd/tester/validators/test_red_python_layer_structure.py +2 -1
  64. atdd/tester/validators/test_red_supabase_layer_structure.py +3 -1
  65. atdd/tester/validators/test_telemetry_structure.py +3 -1
  66. atdd/version_check.py +111 -3
  67. {atdd-0.3.2.dist-info → atdd-0.4.0.dist-info}/METADATA +41 -12
  68. {atdd-0.3.2.dist-info → atdd-0.4.0.dist-info}/RECORD +72 -72
  69. {atdd-0.3.2.dist-info → atdd-0.4.0.dist-info}/WHEEL +0 -0
  70. {atdd-0.3.2.dist-info → atdd-0.4.0.dist-info}/entry_points.txt +0 -0
  71. {atdd-0.3.2.dist-info → atdd-0.4.0.dist-info}/licenses/LICENSE +0 -0
  72. {atdd-0.3.2.dist-info → atdd-0.4.0.dist-info}/top_level.txt +0 -0
@@ -9,6 +9,8 @@ import yaml
9
9
  from pathlib import Path
10
10
  from typing import Dict, Any, List
11
11
 
12
+ from atdd.coach.utils.repo import find_repo_root
13
+
12
14
 
13
15
  # Utility functions for loading YAML files
14
16
  def load_yaml(file_path: Path) -> Dict[str, Any]:
@@ -18,9 +20,8 @@ def load_yaml(file_path: Path) -> Dict[str, Any]:
18
20
 
19
21
 
20
22
  def get_project_root() -> Path:
21
- """Get the project root directory."""
22
- # From tests/ directory, go up 4 levels: tests -> conventions -> coder -> atdd -> root
23
- return Path(__file__).parent.parent.parent.parent.parent
23
+ """Get the consumer project root directory."""
24
+ return find_repo_root()
24
25
 
25
26
 
26
27
  def load_convention_backend() -> Dict[str, Any]:
@@ -7,7 +7,9 @@ import pytest
7
7
  import yaml
8
8
  from pathlib import Path
9
9
 
10
- REPO_ROOT = Path(__file__).resolve().parents[5]
10
+ from atdd.coach.utils.repo import find_repo_root
11
+
12
+ REPO_ROOT = find_repo_root()
11
13
  COMPONENT_NAMING_PATH = REPO_ROOT / "atdd/coder/conventions/component-naming.convention.yaml"
12
14
  GREEN_CONV_PATH = REPO_ROOT / "atdd/coder/conventions/green.convention.yaml"
13
15
 
@@ -18,8 +18,10 @@ import re
18
18
  from pathlib import Path
19
19
  from typing import List
20
20
 
21
+ from atdd.coach.utils.repo import find_repo_root
21
22
 
22
- REPO_ROOT = Path(__file__).resolve().parents[4]
23
+
24
+ REPO_ROOT = find_repo_root()
23
25
  PYTHON_COMMONS = REPO_ROOT / "python" / "commons"
24
26
  WEB_COMMONS = REPO_ROOT / "web" / "src" / "commons"
25
27
  WEB_SRC = REPO_ROOT / "web" / "src"
@@ -16,9 +16,11 @@ import re
16
16
  from pathlib import Path
17
17
  from typing import List, Tuple
18
18
 
19
+ from atdd.coach.utils.repo import find_repo_root
20
+
19
21
 
20
22
  # Path constants
21
- REPO_ROOT = Path(__file__).resolve().parents[3]
23
+ REPO_ROOT = find_repo_root()
22
24
  PYTHON_DIR = REPO_ROOT / "python"
23
25
 
24
26
 
@@ -17,9 +17,11 @@ import json
17
17
  from pathlib import Path
18
18
  from typing import Dict, List, Set
19
19
 
20
+ from atdd.coach.utils.repo import find_repo_root
21
+
20
22
 
21
23
  # Path constants
22
- REPO_ROOT = Path(__file__).resolve().parents[3]
24
+ REPO_ROOT = find_repo_root()
23
25
  PYTHON_DIR = REPO_ROOT / "python"
24
26
  LIB_DIR = REPO_ROOT / "lib"
25
27
  SUPABASE_DIR = REPO_ROOT / "supabase"
@@ -15,9 +15,11 @@ import re
15
15
  from pathlib import Path
16
16
  from typing import List, Set, Dict, Tuple
17
17
 
18
+ from atdd.coach.utils.repo import find_repo_root
19
+
18
20
 
19
21
  # Path constants
20
- REPO_ROOT = Path(__file__).resolve().parents[4]
22
+ REPO_ROOT = find_repo_root()
21
23
  WEB_SRC = REPO_ROOT / "web" / "src"
22
24
  MAINTAIN_UX = WEB_SRC / "maintain-ux"
23
25
  PRIMITIVES_DIR = MAINTAIN_UX / "primitives"
@@ -25,9 +25,11 @@ import ast
25
25
  from pathlib import Path
26
26
  from typing import List, Tuple, Set
27
27
 
28
+ from atdd.coach.utils.repo import find_repo_root
29
+
28
30
 
29
31
  # Path constants
30
- REPO_ROOT = Path(__file__).resolve().parents[4]
32
+ REPO_ROOT = find_repo_root()
31
33
  PYTHON_DIR = REPO_ROOT / "python"
32
34
  DTO_CONVENTION = REPO_ROOT / "atdd" / "coder" / "conventions" / "dto.convention.yaml"
33
35
 
@@ -264,5 +266,5 @@ class TestDTOTestingPatterns:
264
266
 
265
267
 
266
268
  if __name__ == '__main__':
267
- # Run with: pytest atdd/coder/test_dto_testing_patterns.py -v
269
+ # Run with: atdd validate coder
268
270
  pytest.main([__file__, '-v'])
@@ -8,8 +8,10 @@ import pytest
8
8
  from pathlib import Path
9
9
  import yaml
10
10
 
11
+ from atdd.coach.utils.repo import find_repo_root
11
12
 
12
- REPO_ROOT = Path(__file__).resolve().parents[4]
13
+
14
+ REPO_ROOT = find_repo_root()
13
15
  BACKEND_CONVENTION = REPO_ROOT / "atdd" / "coder" / "conventions" / "backend.convention.yaml"
14
16
  FRONTEND_CONVENTION = REPO_ROOT / "atdd" / "coder" / "conventions" / "frontend.convention.yaml"
15
17
 
@@ -8,8 +8,10 @@ import pytest
8
8
  from pathlib import Path
9
9
  import yaml
10
10
 
11
+ from atdd.coach.utils.repo import find_repo_root
11
12
 
12
- REPO_ROOT = Path(__file__).resolve().parents[4]
13
+
14
+ REPO_ROOT = find_repo_root()
13
15
  BACKEND_CONVENTION = REPO_ROOT / "atdd" / "coder" / "conventions" / "backend.convention.yaml"
14
16
  FRONTEND_CONVENTION = REPO_ROOT / "atdd" / "coder" / "conventions" / "frontend.convention.yaml"
15
17
 
@@ -8,8 +8,10 @@ import pytest
8
8
  from pathlib import Path
9
9
  import yaml
10
10
 
11
+ from atdd.coach.utils.repo import find_repo_root
11
12
 
12
- REPO_ROOT = Path(__file__).resolve().parents[4]
13
+
14
+ REPO_ROOT = find_repo_root()
13
15
  BACKEND_CONVENTION = REPO_ROOT / "atdd" / "coder" / "conventions" / "backend.convention.yaml"
14
16
 
15
17
 
@@ -8,8 +8,9 @@ import pytest
8
8
  from pathlib import Path
9
9
  import yaml
10
10
 
11
+ from atdd.coach.utils.repo import find_repo_root
11
12
 
12
- REPO_ROOT = Path(__file__).resolve().parents[4]
13
+ REPO_ROOT = find_repo_root()
13
14
  BACKEND_CONVENTION = REPO_ROOT / "atdd" / "coder" / "conventions" / "backend.convention.yaml"
14
15
  FRONTEND_CONVENTION = REPO_ROOT / "atdd" / "coder" / "conventions" / "frontend.convention.yaml"
15
16
 
@@ -15,9 +15,11 @@ import re
15
15
  from pathlib import Path
16
16
  from typing import Dict, List, Set
17
17
 
18
+ from atdd.coach.utils.repo import find_repo_root
19
+
18
20
 
19
21
  # Path constants
20
- REPO_ROOT = Path(__file__).resolve().parents[3]
22
+ REPO_ROOT = find_repo_root()
21
23
  PYTHON_DIR = REPO_ROOT / "python"
22
24
 
23
25
 
@@ -23,9 +23,11 @@ import re
23
23
  from pathlib import Path
24
24
  from typing import List, Tuple, Optional
25
25
 
26
+ from atdd.coach.utils.repo import find_repo_root
27
+
26
28
 
27
29
  # Path constants
28
- REPO_ROOT = Path(__file__).resolve().parents[3]
30
+ REPO_ROOT = find_repo_root()
29
31
  PYTHON_DIR = REPO_ROOT / "python"
30
32
  DART_DIR = REPO_ROOT / "lib"
31
33
  TS_DIR = REPO_ROOT / "typescript"
@@ -18,9 +18,11 @@ import re
18
18
  from pathlib import Path
19
19
  from typing import List
20
20
 
21
+ from atdd.coach.utils.repo import find_repo_root
22
+
21
23
 
22
24
  # Path constants
23
- REPO_ROOT = Path(__file__).resolve().parents[4] # Go up 3 levels: file -> audits -> coder -> atdd -> repo
25
+ REPO_ROOT = find_repo_root()
24
26
  WEB_SRC = REPO_ROOT / "web" / "src"
25
27
  WEB_TESTS = REPO_ROOT / "web" / "tests"
26
28
 
@@ -16,8 +16,10 @@ from pathlib import Path
16
16
  from typing import List, Tuple, Optional
17
17
  import re
18
18
 
19
+ from atdd.coach.utils.repo import find_repo_root
20
+
19
21
  # Project root constant (pytest pythonpath handles imports)
20
- REPO_ROOT = Path(__file__).resolve().parents[4]
22
+ REPO_ROOT = find_repo_root()
21
23
 
22
24
 
23
25
  class PresentationValidator:
@@ -22,9 +22,11 @@ import yaml
22
22
  from pathlib import Path
23
23
  from typing import Dict, List, Tuple
24
24
 
25
+ from atdd.coach.utils.repo import find_repo_root
26
+
25
27
 
26
28
  # Path constants
27
- REPO_ROOT = Path(__file__).resolve().parents[4]
29
+ REPO_ROOT = find_repo_root()
28
30
  PYTHON_DIR = REPO_ROOT / "python"
29
31
  BACKEND_CONVENTION = REPO_ROOT / "atdd" / "coder" / "conventions" / "backend.convention.yaml"
30
32
 
@@ -16,9 +16,10 @@ import re
16
16
  from pathlib import Path
17
17
  from typing import List, Tuple
18
18
 
19
+ from atdd.coach.utils.repo import find_repo_root
19
20
 
20
21
  # Path constants
21
- REPO_ROOT = Path(__file__).resolve().parents[3]
22
+ REPO_ROOT = find_repo_root()
22
23
  PYTHON_DIR = REPO_ROOT / "python"
23
24
 
24
25
 
@@ -14,10 +14,12 @@ import os
14
14
  from pathlib import Path
15
15
  from typing import List, Dict, Any, Tuple
16
16
 
17
+ from atdd.coach.utils.repo import find_repo_root
18
+
17
19
 
18
20
  def get_python_dir() -> Path:
19
- """Get the python directory path."""
20
- return Path(__file__).parent.parent.parent.parent / "python"
21
+ """Get the python directory path in the consumer repo."""
22
+ return find_repo_root() / "python"
21
23
 
22
24
 
23
25
  def test_composition_accepts_shared_dependencies():
@@ -24,9 +24,11 @@ import re
24
24
  from pathlib import Path
25
25
  from typing import List, Dict, Set, Tuple
26
26
 
27
+ from atdd.coach.utils.repo import find_repo_root
28
+
27
29
 
28
30
  # Path constants
29
- REPO_ROOT = Path(__file__).resolve().parents[4]
31
+ REPO_ROOT = find_repo_root()
30
32
  TRAINS_DIR = REPO_ROOT / "python" / "trains"
31
33
  WAGONS_DIR = REPO_ROOT / "python"
32
34
  GAME_PY = REPO_ROOT / "python" / "game.py"
@@ -21,9 +21,11 @@ import yaml
21
21
  from pathlib import Path
22
22
  from typing import List, Dict, Set, Tuple
23
23
 
24
+ from atdd.coach.utils.repo import find_repo_root
25
+
24
26
 
25
27
  # Path constants
26
- REPO_ROOT = Path(__file__).resolve().parents[4]
28
+ REPO_ROOT = find_repo_root()
27
29
  PYTHON_SHARED_DIR = REPO_ROOT / "python" / "shared"
28
30
  TRAINS_DIR = REPO_ROOT / "plan" / "_trains"
29
31
  TRAIN_CONVENTION = REPO_ROOT / "atdd" / "planner" / "conventions" / "train.convention.yaml"
@@ -23,9 +23,11 @@ import yaml
23
23
  from pathlib import Path
24
24
  from typing import Dict, List, Set, Tuple
25
25
 
26
+ from atdd.coach.utils.repo import find_repo_root
27
+
26
28
 
27
29
  # Path constants
28
- REPO_ROOT = Path(__file__).resolve().parents[4]
30
+ REPO_ROOT = find_repo_root()
29
31
  TS_DIRS = [
30
32
  REPO_ROOT / "supabase" / "functions",
31
33
  REPO_ROOT / "typescript",
@@ -18,9 +18,11 @@ import ast
18
18
  from pathlib import Path
19
19
  from typing import List, Tuple, Set
20
20
 
21
+ from atdd.coach.utils.repo import find_repo_root
22
+
21
23
 
22
24
  # Path constants
23
- REPO_ROOT = Path(__file__).resolve().parents[3]
25
+ REPO_ROOT = find_repo_root()
24
26
  PYTHON_DIR = REPO_ROOT / "python"
25
27
  DART_DIRS = [REPO_ROOT / "lib", REPO_ROOT / "dart"]
26
28
  TS_DIRS = [REPO_ROOT / "supabase" / "functions", REPO_ROOT / "typescript"]
@@ -27,9 +27,10 @@ from pathlib import Path
27
27
  from typing import List, Tuple, Set
28
28
  import ast
29
29
 
30
+ from atdd.coach.utils.repo import find_repo_root
30
31
 
31
32
  # Path constants
32
- REPO_ROOT = Path(__file__).resolve().parents[4]
33
+ REPO_ROOT = find_repo_root()
33
34
  PYTHON_DIR = REPO_ROOT / "python"
34
35
  PYPROJECT_TOML = PYTHON_DIR / "pyproject.toml"
35
36
  BOUNDARIES_CONVENTION = REPO_ROOT / "atdd" / "coder" / "conventions" / "boundaries.convention.yaml"
@@ -8,8 +8,10 @@ import pytest
8
8
  from pathlib import Path
9
9
  from typing import Tuple
10
10
 
11
+ from atdd.coach.utils.repo import find_repo_root
12
+
11
13
  # Path constants
12
- REPO_ROOT = Path(__file__).resolve().parents[4]
14
+ REPO_ROOT = find_repo_root()
13
15
  CONTRACTS_DIR = REPO_ROOT / "contracts"
14
16
  TELEMETRY_DIR = REPO_ROOT / "telemetry"
15
17
 
@@ -23,8 +23,10 @@ import json
23
23
  from pathlib import Path
24
24
  from typing import Dict, Any, List, Set
25
25
 
26
+ from atdd.coach.utils.repo import find_repo_root
27
+
26
28
  # Path constants
27
- REPO_ROOT = Path(__file__).resolve().parents[4]
29
+ REPO_ROOT = find_repo_root()
28
30
  PLAN_DIR = REPO_ROOT / "plan"
29
31
  CONTRACTS_DIR = REPO_ROOT / "contracts"
30
32
  TELEMETRY_DIR = REPO_ROOT / "telemetry"
@@ -11,8 +11,10 @@ from pathlib import Path
11
11
  from typing import Dict, Set, List, Tuple
12
12
  import yaml
13
13
 
14
+ from atdd.coach.utils.repo import find_repo_root
15
+
14
16
  # Path constants
15
- REPO_ROOT = Path(__file__).resolve().parents[4]
17
+ REPO_ROOT = find_repo_root()
16
18
  PLAN_DIR = REPO_ROOT / "plan"
17
19
 
18
20
 
@@ -23,9 +23,10 @@ import re
23
23
  from pathlib import Path
24
24
  from typing import Dict, List, Tuple, Set, Optional
25
25
 
26
+ from atdd.coach.utils.repo import find_repo_root
26
27
 
27
28
  # Path constants
28
- REPO_ROOT = Path(__file__).resolve().parents[4]
29
+ REPO_ROOT = find_repo_root()
29
30
  PLAN_DIR = REPO_ROOT / "plan"
30
31
  WMBT_CONVENTION = REPO_ROOT / "atdd" / "planner" / "conventions" / "wmbt.convention.yaml"
31
32
 
@@ -444,7 +444,7 @@ persistence_traceability:
444
444
 
445
445
  workflow:
446
446
  1_identify_persistent_contracts:
447
- command: "python atdd/coach/commands/migration.py"
447
+ command: "python -m atdd.coach.commands.migration"
448
448
  output: "List of contracts needing persistence"
449
449
 
450
450
  2_create_migration:
@@ -16,7 +16,7 @@ workflow:
16
16
  automation_level: "template_generation"
17
17
  requires_human_review: true
18
18
 
19
- command: "python atdd/coach/command/migration.py"
19
+ command: "python -m atdd.coach.commands.migration"
20
20
 
21
21
  # Table Naming Convention
22
22
  table_naming:
@@ -171,16 +171,16 @@ references:
171
171
  # Command Usage
172
172
  usage: |
173
173
  # Generate all missing migrations
174
- python atdd/coach/command/migration.py
174
+ python -m atdd.coach.commands.migration
175
175
 
176
176
  # Generate for specific contract
177
- python atdd/coach/command/migration.py --contract contracts/match/dilemma/current.schema.json
177
+ python -m atdd.coach.commands.migration --contract contracts/match/dilemma/current.schema.json
178
178
 
179
179
  # Validate coverage
180
- python atdd/coach/command/migration.py --validate
180
+ python -m atdd.coach.commands.migration --validate
181
181
 
182
182
  # Check for unreviewed TODOs
183
- pytest atdd/tester/test_migration_coverage.py::test_migration_templates_reviewed
183
+ atdd validate tester
184
184
 
185
185
  # JSONB-First Storage Strategy
186
186
  jsonb_strategy:
@@ -9,8 +9,10 @@ and keeps only the new standardized ones.
9
9
  import re
10
10
  from pathlib import Path
11
11
 
12
+ from atdd.coach.utils.repo import find_repo_root
12
13
 
13
- REPO_ROOT = Path(__file__).resolve().parents[4]
14
+
15
+ REPO_ROOT = find_repo_root()
14
16
  PYTHON_DIR = REPO_ROOT / "python"
15
17
 
16
18
 
@@ -9,8 +9,10 @@ keeping only the new standardized header at the top.
9
9
  import re
10
10
  from pathlib import Path
11
11
 
12
+ from atdd.coach.utils.repo import find_repo_root
12
13
 
13
- REPO_ROOT = Path(__file__).resolve().parents[4]
14
+
15
+ REPO_ROOT = find_repo_root()
14
16
  PYTHON_DIR = REPO_ROOT / "python"
15
17
 
16
18
 
@@ -17,9 +17,11 @@ from pathlib import Path
17
17
  from collections import defaultdict
18
18
  from typing import Dict, List, Set, Tuple
19
19
 
20
+ from atdd.coach.utils.repo import find_repo_root
21
+
20
22
 
21
23
  # Path constants
22
- REPO_ROOT = Path(__file__).resolve().parents[4]
24
+ REPO_ROOT = find_repo_root()
23
25
  PLAN_DIR = REPO_ROOT / "plan"
24
26
  PYTHON_DIR = REPO_ROOT / "python"
25
27
  LIB_DIR = REPO_ROOT / "lib"
@@ -10,8 +10,10 @@ Fixes:
10
10
  import re
11
11
  from pathlib import Path
12
12
 
13
+ from atdd.coach.utils.repo import find_repo_root
13
14
 
14
- REPO_ROOT = Path(__file__).resolve().parents[4]
15
+
16
+ REPO_ROOT = find_repo_root()
15
17
  PYTHON_DIR = REPO_ROOT / "python"
16
18
 
17
19
 
@@ -5,8 +5,10 @@ Simple script to remove consecutive duplicate lines in test files.
5
5
 
6
6
  from pathlib import Path
7
7
 
8
+ from atdd.coach.utils.repo import find_repo_root
8
9
 
9
- REPO_ROOT = Path(__file__).resolve().parents[4]
10
+
11
+ REPO_ROOT = find_repo_root()
10
12
  PYTHON_DIR = REPO_ROOT / "python"
11
13
 
12
14
 
@@ -13,8 +13,10 @@ import re
13
13
  from pathlib import Path
14
14
  import pytest
15
15
 
16
+ from atdd.coach.utils.repo import find_repo_root
16
17
 
17
- REPO_ROOT = Path(__file__).parent.parent.parent
18
+
19
+ REPO_ROOT = find_repo_root()
18
20
 
19
21
 
20
22
  # SPEC-TESTER-CONV-0069: Dart URN to filename mapping
@@ -24,8 +24,10 @@ import yaml
24
24
  import re
25
25
  from pathlib import Path
26
26
 
27
+ from atdd.coach.utils.repo import find_repo_root
28
+
27
29
  # Path constants
28
- REPO_ROOT = Path(__file__).resolve().parents[4]
30
+ REPO_ROOT = find_repo_root()
29
31
  CONVENTIONS_DIR = REPO_ROOT / "atdd" / "planner" / "conventions"
30
32
  SCHEMAS_DIR = REPO_ROOT / "atdd" / "planner" / "schemas"
31
33
 
@@ -12,8 +12,10 @@ import re
12
12
  from pathlib import Path
13
13
  from jsonschema import validate, ValidationError, Draft7Validator
14
14
 
15
+ from atdd.coach.utils.repo import find_repo_root
16
+
15
17
  # Path constants
16
- REPO_ROOT = Path(__file__).resolve().parents[4]
18
+ REPO_ROOT = find_repo_root()
17
19
  CONTRACTS_DIR = REPO_ROOT / "contracts"
18
20
  PLAN_DIR = REPO_ROOT / "plan"
19
21
  META_SCHEMA_PATH = REPO_ROOT / "atdd" / "tester" / "schemas" / "contract.schema.json"
@@ -9,8 +9,10 @@ import re
9
9
  from pathlib import Path
10
10
  from typing import Optional
11
11
 
12
+ from atdd.coach.utils.repo import find_repo_root
13
+
12
14
  # Path constants
13
- REPO_ROOT = Path(__file__).resolve().parents[4]
15
+ REPO_ROOT = find_repo_root()
14
16
  CONTRACTS_DIR = REPO_ROOT / "contracts"
15
17
 
16
18
 
@@ -25,9 +25,11 @@ from typing import Dict, List, Set, Tuple, Optional
25
25
  from dataclasses import dataclass, field
26
26
  from collections import defaultdict
27
27
 
28
+ from atdd.coach.utils.repo import find_repo_root
29
+
28
30
 
29
31
  # Path constants
30
- REPO_ROOT = Path(__file__).resolve().parents[4]
32
+ REPO_ROOT = find_repo_root()
31
33
  PLAN_DIR = REPO_ROOT / "plan"
32
34
  PYTHON_DIR = REPO_ROOT / "python"
33
35
  LIB_DIR = REPO_ROOT / "lib"
@@ -17,7 +17,7 @@ from pathlib import Path
17
17
 
18
18
 
19
19
  # Path constants
20
- REPO_ROOT = Path(__file__).resolve().parents[4]
20
+ REPO_ROOT = find_repo_root()
21
21
  PYTHON_DIR = REPO_ROOT / "python"
22
22
 
23
23
 
@@ -210,6 +210,8 @@ Purpose: Verify timebank decrements during active decision
210
210
 
211
211
  import pytest
212
212
 
213
+ from atdd.coach.utils.repo import find_repo_root
214
+
213
215
 
214
216
  def test_e001_unit_001_timebank_decrements_during_decision():
215
217
  """Test implementation..."""
@@ -17,9 +17,10 @@ import yaml
17
17
  from pathlib import Path
18
18
  from typing import Dict, List, Any
19
19
 
20
+ from atdd.coach.utils.repo import find_repo_root
20
21
 
21
22
  # Path constants
22
- REPO_ROOT = Path(__file__).resolve().parents[4]
23
+ REPO_ROOT = find_repo_root()
23
24
  PYTHON_DIR = REPO_ROOT / "python"
24
25
  CONTRACTS_DIR = REPO_ROOT / "contracts"
25
26
 
@@ -17,9 +17,11 @@ import ast
17
17
  from pathlib import Path
18
18
  from typing import List, Set, Tuple
19
19
 
20
+ from atdd.coach.utils.repo import find_repo_root
21
+
20
22
 
21
23
  # Path constants
22
- REPO_ROOT = Path(__file__).resolve().parents[4]
24
+ REPO_ROOT = find_repo_root()
23
25
  TEST_DIRS = [
24
26
  REPO_ROOT / "test",
25
27
  REPO_ROOT / "tests",
@@ -7,8 +7,10 @@ SPEC-TESTER-CONV-0032: Reject migrations with unresolved TODOs
7
7
  import pytest
8
8
  from pathlib import Path
9
9
 
10
+ from atdd.coach.utils.repo import find_repo_root
11
+
10
12
  # Path constants
11
- REPO_ROOT = Path(__file__).resolve().parents[4]
13
+ REPO_ROOT = find_repo_root()
12
14
  CONTRACTS_DIR = REPO_ROOT / "contracts"
13
15
  MIGRATIONS_DIR = REPO_ROOT / "supabase" / "migrations"
14
16
 
@@ -145,7 +147,7 @@ def test_all_contracts_have_migrations():
145
147
  error_msg += f"\n ... and {len(missing) - 20} more"
146
148
  if skipped > 0:
147
149
  error_msg += f"\n\nℹ️ Skipped {skipped} internal/transient contracts"
148
- error_msg += "\n\nRun: python atdd/coach/commands/migration.py to generate"
150
+ error_msg += "\n\nRun: python -m atdd.coach.commands.migration to generate"
149
151
  pytest.fail(error_msg)
150
152
 
151
153
 
@@ -9,8 +9,10 @@ import json
9
9
  import tempfile
10
10
  from pathlib import Path
11
11
 
12
+ from atdd.coach.utils.repo import find_repo_root
13
+
12
14
  # Path constants
13
- REPO_ROOT = Path(__file__).resolve().parents[4]
15
+ REPO_ROOT = find_repo_root()
14
16
  CONTRACTS_DIR = REPO_ROOT / "contracts"
15
17
 
16
18
 
@@ -16,9 +16,11 @@ import pytest
16
16
  import re
17
17
  from pathlib import Path
18
18
 
19
+ from atdd.coach.utils.repo import find_repo_root
20
+
19
21
 
20
22
  # Path constants
21
- REPO_ROOT = Path(__file__).resolve().parents[4]
23
+ REPO_ROOT = find_repo_root()
22
24
  PYTHON_DIR = REPO_ROOT / "python"
23
25
 
24
26