atdd 0.2.1__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 (184) hide show
  1. atdd/__init__.py +6 -0
  2. atdd/__main__.py +4 -0
  3. atdd/cli.py +404 -0
  4. atdd/coach/__init__.py +0 -0
  5. atdd/coach/commands/__init__.py +0 -0
  6. atdd/coach/commands/add_persistence_metadata.py +215 -0
  7. atdd/coach/commands/analyze_migrations.py +188 -0
  8. atdd/coach/commands/consumers.py +720 -0
  9. atdd/coach/commands/infer_governance_status.py +149 -0
  10. atdd/coach/commands/initializer.py +177 -0
  11. atdd/coach/commands/interface.py +1078 -0
  12. atdd/coach/commands/inventory.py +565 -0
  13. atdd/coach/commands/migration.py +240 -0
  14. atdd/coach/commands/registry.py +1560 -0
  15. atdd/coach/commands/session.py +430 -0
  16. atdd/coach/commands/sync.py +405 -0
  17. atdd/coach/commands/test_interface.py +399 -0
  18. atdd/coach/commands/test_runner.py +141 -0
  19. atdd/coach/commands/tests/__init__.py +1 -0
  20. atdd/coach/commands/tests/test_telemetry_array_validation.py +235 -0
  21. atdd/coach/commands/traceability.py +4264 -0
  22. atdd/coach/conventions/session.convention.yaml +754 -0
  23. atdd/coach/overlays/__init__.py +2 -0
  24. atdd/coach/overlays/claude.md +2 -0
  25. atdd/coach/schemas/config.schema.json +34 -0
  26. atdd/coach/schemas/manifest.schema.json +101 -0
  27. atdd/coach/templates/ATDD.md +282 -0
  28. atdd/coach/templates/SESSION-TEMPLATE.md +327 -0
  29. atdd/coach/utils/__init__.py +0 -0
  30. atdd/coach/utils/graph/__init__.py +0 -0
  31. atdd/coach/utils/graph/urn.py +875 -0
  32. atdd/coach/validators/__init__.py +0 -0
  33. atdd/coach/validators/shared_fixtures.py +365 -0
  34. atdd/coach/validators/test_enrich_wagon_registry.py +167 -0
  35. atdd/coach/validators/test_registry.py +575 -0
  36. atdd/coach/validators/test_session_validation.py +1183 -0
  37. atdd/coach/validators/test_traceability.py +448 -0
  38. atdd/coach/validators/test_update_feature_paths.py +108 -0
  39. atdd/coach/validators/test_validate_contract_consumers.py +297 -0
  40. atdd/coder/__init__.py +1 -0
  41. atdd/coder/conventions/adapter.recipe.yaml +88 -0
  42. atdd/coder/conventions/backend.convention.yaml +460 -0
  43. atdd/coder/conventions/boundaries.convention.yaml +666 -0
  44. atdd/coder/conventions/commons.convention.yaml +460 -0
  45. atdd/coder/conventions/complexity.recipe.yaml +109 -0
  46. atdd/coder/conventions/component-naming.convention.yaml +178 -0
  47. atdd/coder/conventions/design.convention.yaml +327 -0
  48. atdd/coder/conventions/design.recipe.yaml +273 -0
  49. atdd/coder/conventions/dto.convention.yaml +660 -0
  50. atdd/coder/conventions/frontend.convention.yaml +542 -0
  51. atdd/coder/conventions/green.convention.yaml +1012 -0
  52. atdd/coder/conventions/presentation.convention.yaml +587 -0
  53. atdd/coder/conventions/refactor.convention.yaml +535 -0
  54. atdd/coder/conventions/technology.convention.yaml +206 -0
  55. atdd/coder/conventions/tests/__init__.py +0 -0
  56. atdd/coder/conventions/tests/test_adapter_recipe.py +302 -0
  57. atdd/coder/conventions/tests/test_complexity_recipe.py +289 -0
  58. atdd/coder/conventions/tests/test_component_taxonomy.py +278 -0
  59. atdd/coder/conventions/tests/test_component_urn_naming.py +165 -0
  60. atdd/coder/conventions/tests/test_thinness_recipe.py +286 -0
  61. atdd/coder/conventions/thinness.recipe.yaml +82 -0
  62. atdd/coder/conventions/train.convention.yaml +325 -0
  63. atdd/coder/conventions/verification.protocol.yaml +53 -0
  64. atdd/coder/schemas/design_system.schema.json +361 -0
  65. atdd/coder/validators/__init__.py +0 -0
  66. atdd/coder/validators/test_commons_structure.py +485 -0
  67. atdd/coder/validators/test_complexity.py +416 -0
  68. atdd/coder/validators/test_cross_language_consistency.py +431 -0
  69. atdd/coder/validators/test_design_system_compliance.py +413 -0
  70. atdd/coder/validators/test_dto_testing_patterns.py +268 -0
  71. atdd/coder/validators/test_green_cross_stack_layers.py +168 -0
  72. atdd/coder/validators/test_green_layer_dependencies.py +148 -0
  73. atdd/coder/validators/test_green_python_layer_structure.py +103 -0
  74. atdd/coder/validators/test_green_supabase_layer_structure.py +103 -0
  75. atdd/coder/validators/test_import_boundaries.py +396 -0
  76. atdd/coder/validators/test_init_file_urns.py +593 -0
  77. atdd/coder/validators/test_preact_layer_boundaries.py +221 -0
  78. atdd/coder/validators/test_presentation_convention.py +260 -0
  79. atdd/coder/validators/test_python_architecture.py +674 -0
  80. atdd/coder/validators/test_quality_metrics.py +420 -0
  81. atdd/coder/validators/test_station_master_pattern.py +244 -0
  82. atdd/coder/validators/test_train_infrastructure.py +454 -0
  83. atdd/coder/validators/test_train_urns.py +293 -0
  84. atdd/coder/validators/test_typescript_architecture.py +616 -0
  85. atdd/coder/validators/test_usecase_structure.py +421 -0
  86. atdd/coder/validators/test_wagon_boundaries.py +586 -0
  87. atdd/conftest.py +126 -0
  88. atdd/planner/__init__.py +1 -0
  89. atdd/planner/conventions/acceptance.convention.yaml +538 -0
  90. atdd/planner/conventions/appendix.convention.yaml +187 -0
  91. atdd/planner/conventions/artifact-naming.convention.yaml +852 -0
  92. atdd/planner/conventions/component.convention.yaml +670 -0
  93. atdd/planner/conventions/criteria.convention.yaml +141 -0
  94. atdd/planner/conventions/feature.convention.yaml +371 -0
  95. atdd/planner/conventions/interface.convention.yaml +382 -0
  96. atdd/planner/conventions/steps.convention.yaml +141 -0
  97. atdd/planner/conventions/train.convention.yaml +552 -0
  98. atdd/planner/conventions/wagon.convention.yaml +275 -0
  99. atdd/planner/conventions/wmbt.convention.yaml +258 -0
  100. atdd/planner/schemas/acceptance.schema.json +336 -0
  101. atdd/planner/schemas/appendix.schema.json +78 -0
  102. atdd/planner/schemas/component.schema.json +114 -0
  103. atdd/planner/schemas/feature.schema.json +197 -0
  104. atdd/planner/schemas/train.schema.json +192 -0
  105. atdd/planner/schemas/wagon.schema.json +281 -0
  106. atdd/planner/schemas/wmbt.schema.json +59 -0
  107. atdd/planner/validators/__init__.py +0 -0
  108. atdd/planner/validators/conftest.py +5 -0
  109. atdd/planner/validators/test_draft_wagon_registry.py +374 -0
  110. atdd/planner/validators/test_plan_cross_refs.py +240 -0
  111. atdd/planner/validators/test_plan_uniqueness.py +224 -0
  112. atdd/planner/validators/test_plan_urn_resolution.py +268 -0
  113. atdd/planner/validators/test_plan_wagons.py +174 -0
  114. atdd/planner/validators/test_train_validation.py +514 -0
  115. atdd/planner/validators/test_wagon_urn_chain.py +648 -0
  116. atdd/planner/validators/test_wmbt_consistency.py +327 -0
  117. atdd/planner/validators/test_wmbt_vocabulary.py +632 -0
  118. atdd/tester/__init__.py +1 -0
  119. atdd/tester/conventions/artifact.convention.yaml +257 -0
  120. atdd/tester/conventions/contract.convention.yaml +1009 -0
  121. atdd/tester/conventions/filename.convention.yaml +555 -0
  122. atdd/tester/conventions/migration.convention.yaml +509 -0
  123. atdd/tester/conventions/red.convention.yaml +797 -0
  124. atdd/tester/conventions/routing.convention.yaml +51 -0
  125. atdd/tester/conventions/telemetry.convention.yaml +458 -0
  126. atdd/tester/schemas/a11y.tmpl.json +17 -0
  127. atdd/tester/schemas/artifact.schema.json +189 -0
  128. atdd/tester/schemas/contract.schema.json +591 -0
  129. atdd/tester/schemas/contract.tmpl.json +95 -0
  130. atdd/tester/schemas/db.tmpl.json +20 -0
  131. atdd/tester/schemas/e2e.tmpl.json +17 -0
  132. atdd/tester/schemas/edge_function.tmpl.json +17 -0
  133. atdd/tester/schemas/event.tmpl.json +17 -0
  134. atdd/tester/schemas/http.tmpl.json +19 -0
  135. atdd/tester/schemas/job.tmpl.json +18 -0
  136. atdd/tester/schemas/load.tmpl.json +21 -0
  137. atdd/tester/schemas/metric.tmpl.json +19 -0
  138. atdd/tester/schemas/pack.schema.json +139 -0
  139. atdd/tester/schemas/realtime.tmpl.json +20 -0
  140. atdd/tester/schemas/rls.tmpl.json +18 -0
  141. atdd/tester/schemas/script.tmpl.json +16 -0
  142. atdd/tester/schemas/sec.tmpl.json +18 -0
  143. atdd/tester/schemas/storage.tmpl.json +18 -0
  144. atdd/tester/schemas/telemetry.schema.json +128 -0
  145. atdd/tester/schemas/telemetry_tracking_manifest.schema.json +143 -0
  146. atdd/tester/schemas/test_filename.schema.json +194 -0
  147. atdd/tester/schemas/test_intent.schema.json +179 -0
  148. atdd/tester/schemas/unit.tmpl.json +18 -0
  149. atdd/tester/schemas/visual.tmpl.json +18 -0
  150. atdd/tester/schemas/ws.tmpl.json +17 -0
  151. atdd/tester/utils/__init__.py +0 -0
  152. atdd/tester/utils/filename.py +300 -0
  153. atdd/tester/validators/__init__.py +0 -0
  154. atdd/tester/validators/cleanup_duplicate_headers.py +116 -0
  155. atdd/tester/validators/cleanup_duplicate_headers_v2.py +135 -0
  156. atdd/tester/validators/conftest.py +5 -0
  157. atdd/tester/validators/coverage_gap_report.py +321 -0
  158. atdd/tester/validators/fix_dual_ac_references.py +179 -0
  159. atdd/tester/validators/remove_duplicate_lines.py +93 -0
  160. atdd/tester/validators/test_acceptance_urn_filename_mapping.py +359 -0
  161. atdd/tester/validators/test_acceptance_urn_separator.py +166 -0
  162. atdd/tester/validators/test_artifact_naming_category.py +307 -0
  163. atdd/tester/validators/test_contract_schema_compliance.py +706 -0
  164. atdd/tester/validators/test_contracts_structure.py +200 -0
  165. atdd/tester/validators/test_coverage_adequacy.py +797 -0
  166. atdd/tester/validators/test_dual_ac_reference.py +225 -0
  167. atdd/tester/validators/test_fixture_validity.py +372 -0
  168. atdd/tester/validators/test_isolation.py +487 -0
  169. atdd/tester/validators/test_migration_coverage.py +204 -0
  170. atdd/tester/validators/test_migration_criteria.py +276 -0
  171. atdd/tester/validators/test_migration_generation.py +116 -0
  172. atdd/tester/validators/test_python_test_naming.py +410 -0
  173. atdd/tester/validators/test_red_layer_validation.py +95 -0
  174. atdd/tester/validators/test_red_python_layer_structure.py +87 -0
  175. atdd/tester/validators/test_red_supabase_layer_structure.py +90 -0
  176. atdd/tester/validators/test_telemetry_structure.py +634 -0
  177. atdd/tester/validators/test_typescript_test_naming.py +301 -0
  178. atdd/tester/validators/test_typescript_test_structure.py +84 -0
  179. atdd-0.2.1.dist-info/METADATA +221 -0
  180. atdd-0.2.1.dist-info/RECORD +184 -0
  181. atdd-0.2.1.dist-info/WHEEL +5 -0
  182. atdd-0.2.1.dist-info/entry_points.txt +2 -0
  183. atdd-0.2.1.dist-info/licenses/LICENSE +674 -0
  184. atdd-0.2.1.dist-info/top_level.txt +1 -0
@@ -0,0 +1,149 @@
1
+ #!/usr/bin/env python3
2
+ """
3
+ Infer and set governance.status for contract schemas.
4
+
5
+ Inference rules:
6
+ - version 0.x.x → "draft" (still iterating)
7
+ - wagon_ref = "plan/unknown/_unknown.yaml" → "draft" (no real wagon)
8
+ - version 1.x.x+ with real wagon → "active" (stable)
9
+
10
+ Usage:
11
+ python3 atdd/coach/commands/infer_governance_status.py [--dry-run]
12
+ """
13
+
14
+ import sys
15
+ import json
16
+ from pathlib import Path
17
+
18
+ REPO_ROOT = Path(__file__).resolve().parents[4]
19
+ CONTRACTS_DIR = REPO_ROOT / "contracts"
20
+
21
+
22
+ def infer_status(contract: dict) -> str:
23
+ """Infer governance status from contract metadata."""
24
+ version = contract.get("version", "0.0.0")
25
+ metadata = contract.get("x-artifact-metadata", {})
26
+ traceability = metadata.get("traceability", {})
27
+ wagon_ref = traceability.get("wagon_ref", "")
28
+
29
+ # Rule 1: Version-based
30
+ if version.startswith("0."):
31
+ return "draft"
32
+
33
+ # Rule 2: Traceability-based
34
+ if wagon_ref == "plan/unknown/_unknown.yaml" or not wagon_ref:
35
+ return "draft"
36
+
37
+ # Rule 3: Active (1.x.x+ with real wagon)
38
+ return "active"
39
+
40
+
41
+ def infer_stability(contract: dict, status: str) -> str:
42
+ """Infer governance stability."""
43
+ if status == "draft":
44
+ return "experimental"
45
+
46
+ # For active contracts, use stable (meta-schema only allows: experimental, stable, frozen)
47
+ return "stable"
48
+
49
+
50
+ def set_governance_status(contract_path: Path, dry_run: bool = False) -> dict:
51
+ """Set governance.status for a contract."""
52
+ try:
53
+ with open(contract_path) as f:
54
+ contract = json.load(f)
55
+
56
+ metadata = contract.get("x-artifact-metadata", {})
57
+ if not metadata:
58
+ return {"status": "skip", "reason": "No x-artifact-metadata"}
59
+
60
+ governance = metadata.get("governance", {})
61
+
62
+ # Infer status
63
+ inferred_status = infer_status(contract)
64
+ inferred_stability = infer_stability(contract, inferred_status)
65
+
66
+ current_status = governance.get("status")
67
+ current_stability = governance.get("stability")
68
+
69
+ # Check if update needed
70
+ changes = []
71
+ if current_status != inferred_status:
72
+ governance["status"] = inferred_status
73
+ changes.append(f"status: {current_status} → {inferred_status}")
74
+
75
+ if current_stability != inferred_stability:
76
+ governance["stability"] = inferred_stability
77
+ changes.append(f"stability: {current_stability} → {inferred_stability}")
78
+
79
+ if not changes:
80
+ return {"status": "skip", "reason": "Already correct"}
81
+
82
+ # Update contract
83
+ metadata["governance"] = governance
84
+ contract["x-artifact-metadata"] = metadata
85
+
86
+ if not dry_run:
87
+ with open(contract_path, 'w') as f:
88
+ json.dump(contract, f, indent=2)
89
+ f.write('\n')
90
+
91
+ return {
92
+ "status": "updated",
93
+ "changes": changes
94
+ }
95
+
96
+ except Exception as e:
97
+ return {"status": "error", "reason": str(e)}
98
+
99
+
100
+ def main():
101
+ """Infer governance status for all contracts."""
102
+ dry_run = "--dry-run" in sys.argv
103
+ mode = "DRY RUN" if dry_run else "APPLY CHANGES"
104
+
105
+ print("=" * 80)
106
+ print(f"Infer Governance Status for Contracts ({mode})")
107
+ print("=" * 80)
108
+ print()
109
+
110
+ contract_files = list(CONTRACTS_DIR.rglob("*.schema.json"))
111
+
112
+ updated = 0
113
+ skipped = 0
114
+ errors = 0
115
+
116
+ for contract_path in sorted(contract_files):
117
+ result = set_governance_status(contract_path, dry_run)
118
+
119
+ if result["status"] == "updated":
120
+ rel_path = contract_path.relative_to(REPO_ROOT)
121
+ print(f"✅ {rel_path}")
122
+ for change in result["changes"]:
123
+ print(f" {change}")
124
+ updated += 1
125
+ elif result["status"] == "skip":
126
+ skipped += 1
127
+ elif result["status"] == "error":
128
+ print(f"❌ {contract_path.relative_to(REPO_ROOT)}: {result['reason']}")
129
+ errors += 1
130
+
131
+ print()
132
+ print("=" * 80)
133
+ print("SUMMARY")
134
+ print("=" * 80)
135
+ print(f"Total contracts: {len(contract_files)}")
136
+ print(f"✅ Updated: {updated}")
137
+ print(f"⏭️ Skipped: {skipped}")
138
+ print(f"❌ Errors: {errors}")
139
+ print("=" * 80)
140
+
141
+ if dry_run:
142
+ print()
143
+ print("This was a DRY RUN. No files were modified.")
144
+ print("Run without --dry-run to apply changes:")
145
+ print(" python3 atdd/coach/commands/infer_governance_status.py")
146
+
147
+
148
+ if __name__ == "__main__":
149
+ main()
@@ -0,0 +1,177 @@
1
+ """
2
+ Project initializer for ATDD structure in consumer repos.
3
+
4
+ Creates the following structure:
5
+ consumer-repo/
6
+ ├── CLAUDE.md (with managed ATDD block)
7
+ ├── atdd-sessions/
8
+ │ ├── SESSION-TEMPLATE.md (copied from package)
9
+ │ └── archive/
10
+ └── .atdd/
11
+ ├── manifest.yaml (machine-readable session tracking)
12
+ └── config.yaml (agent sync configuration)
13
+
14
+ Usage:
15
+ atdd init # Initialize ATDD structure
16
+ atdd init --force # Overwrite existing files
17
+
18
+ Convention: src/atdd/coach/conventions/session.convention.yaml
19
+ """
20
+ import shutil
21
+ from datetime import date
22
+ from pathlib import Path
23
+ from typing import Optional
24
+
25
+ import yaml
26
+
27
+
28
+ class ProjectInitializer:
29
+ """Initialize ATDD structure in consumer repo."""
30
+
31
+ def __init__(self, target_dir: Optional[Path] = None):
32
+ """
33
+ Initialize the ProjectInitializer.
34
+
35
+ Args:
36
+ target_dir: Target directory for initialization. Defaults to cwd.
37
+ """
38
+ self.target_dir = target_dir or Path.cwd()
39
+ self.sessions_dir = self.target_dir / "atdd-sessions"
40
+ self.archive_dir = self.sessions_dir / "archive"
41
+ self.atdd_config_dir = self.target_dir / ".atdd"
42
+ self.manifest_file = self.atdd_config_dir / "manifest.yaml"
43
+ self.config_file = self.atdd_config_dir / "config.yaml"
44
+
45
+ # Package template location
46
+ self.package_root = Path(__file__).parent.parent # src/atdd/coach
47
+ self.template_source = self.package_root / "templates" / "SESSION-TEMPLATE.md"
48
+
49
+ def init(self, force: bool = False) -> int:
50
+ """
51
+ Create atdd-sessions/ and .atdd/ structure.
52
+
53
+ Args:
54
+ force: If True, overwrite existing files.
55
+
56
+ Returns:
57
+ 0 on success, 1 on error.
58
+ """
59
+ # Check if already initialized
60
+ if self.sessions_dir.exists() and not force:
61
+ print(f"ATDD already initialized at {self.target_dir}")
62
+ print("Use --force to reinitialize")
63
+ return 1
64
+
65
+ try:
66
+ # Create atdd-sessions/ directory
67
+ self.sessions_dir.mkdir(parents=True, exist_ok=True)
68
+ print(f"Created: {self.sessions_dir}")
69
+
70
+ # Create archive subdirectory
71
+ self.archive_dir.mkdir(parents=True, exist_ok=True)
72
+ print(f"Created: {self.archive_dir}")
73
+
74
+ # Create .atdd/ config directory
75
+ self.atdd_config_dir.mkdir(parents=True, exist_ok=True)
76
+ print(f"Created: {self.atdd_config_dir}")
77
+
78
+ # Copy SESSION-TEMPLATE.md to atdd-sessions/
79
+ template_dest = self.sessions_dir / "SESSION-TEMPLATE.md"
80
+ if self.template_source.exists():
81
+ shutil.copy2(self.template_source, template_dest)
82
+ print(f"Copied: SESSION-TEMPLATE.md -> {template_dest}")
83
+ else:
84
+ print(f"Warning: Template not found at {self.template_source}")
85
+
86
+ # Create manifest.yaml
87
+ self._create_manifest(force)
88
+
89
+ # Create config.yaml
90
+ self._create_config(force)
91
+
92
+ # Sync agent config files
93
+ from atdd.coach.commands.sync import AgentConfigSync
94
+ syncer = AgentConfigSync(self.target_dir)
95
+ syncer.sync()
96
+
97
+ # Print next steps
98
+ print("\n" + "=" * 60)
99
+ print("ATDD initialized successfully!")
100
+ print("=" * 60)
101
+ print("\nNext steps:")
102
+ print(" 1. Create a new session:")
103
+ print(" atdd session new my-feature")
104
+ print("")
105
+ print(" 2. List existing sessions:")
106
+ print(" atdd session list")
107
+ print("")
108
+ print(" 3. Archive completed sessions:")
109
+ print(" atdd session archive 01")
110
+ print("")
111
+ print("Structure created:")
112
+ print(f" {self.sessions_dir}/")
113
+ print(f" {self.sessions_dir}/archive/")
114
+ print(f" {self.sessions_dir}/SESSION-TEMPLATE.md")
115
+ print(f" {self.atdd_config_dir}/")
116
+ print(f" {self.manifest_file}")
117
+ print(f" {self.config_file}")
118
+ print(f" CLAUDE.md (with ATDD managed block)")
119
+
120
+ return 0
121
+
122
+ except PermissionError as e:
123
+ print(f"Error: Permission denied - {e}")
124
+ return 1
125
+ except OSError as e:
126
+ print(f"Error: {e}")
127
+ return 1
128
+
129
+ def _create_manifest(self, force: bool = False) -> None:
130
+ """
131
+ Create or update .atdd/manifest.yaml.
132
+
133
+ Args:
134
+ force: If True, overwrite existing manifest.
135
+ """
136
+ if self.manifest_file.exists() and not force:
137
+ print(f"Manifest already exists: {self.manifest_file}")
138
+ return
139
+
140
+ manifest = {
141
+ "version": "1.0",
142
+ "sessions_dir": "atdd-sessions",
143
+ "created": date.today().isoformat(),
144
+ "sessions": [],
145
+ }
146
+
147
+ with open(self.manifest_file, "w") as f:
148
+ yaml.dump(manifest, f, default_flow_style=False, sort_keys=False)
149
+
150
+ print(f"Created: {self.manifest_file}")
151
+
152
+ def _create_config(self, force: bool = False) -> None:
153
+ """
154
+ Create or update .atdd/config.yaml.
155
+
156
+ Args:
157
+ force: If True, overwrite existing config.
158
+ """
159
+ if self.config_file.exists() and not force:
160
+ print(f"Config already exists: {self.config_file}")
161
+ return
162
+
163
+ config = {
164
+ "version": "1.0",
165
+ "sync": {
166
+ "agents": ["claude"], # Default: only Claude
167
+ },
168
+ }
169
+
170
+ with open(self.config_file, "w") as f:
171
+ yaml.dump(config, f, default_flow_style=False, sort_keys=False)
172
+
173
+ print(f"Created: {self.config_file}")
174
+
175
+ def is_initialized(self) -> bool:
176
+ """Check if ATDD is already initialized in target directory."""
177
+ return self.sessions_dir.exists() and self.manifest_file.exists()