Skip to content

Commit cb032aa

Browse files
committed
fix: make constitution check adapter-specific (Spec-Kit only)
- Constitution check now only applies to Spec-Kit adapter - OpenSpec sync no longer blocked by constitution requirement - OpenSpec adapter uses has_custom_hooks to indicate active changes, not constitution - Constitution validation and bootstrap only run for Spec-Kit Fixes review finding: P1 Badge - OpenSpec sync blocked by constitution check
1 parent 761d3ed commit cb032aa

File tree

1 file changed

+56
-52
lines changed

1 file changed

+56
-52
lines changed

src/specfact_cli/commands/sync.py

Lines changed: 56 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -95,63 +95,67 @@ def _perform_sync_operation(
9595
# Generate bridge config using adapter
9696
bridge_config = adapter_instance.generate_bridge_config(repo)
9797

98-
# Step 1.5: Validate constitution exists and is not empty (adapter-specific)
98+
# Step 1.5: Validate constitution exists and is not empty (Spec-Kit only)
99+
# Note: Constitution is required for Spec-Kit but not for other adapters (e.g., OpenSpec)
99100
capabilities = adapter_instance.get_capabilities(repo, bridge_config)
100-
has_constitution = capabilities.has_custom_hooks
101-
if not has_constitution:
102-
console.print("[bold red]✗[/bold red] Constitution required")
103-
console.print("[red]Constitution file not found or is empty[/red]")
104-
console.print("\n[bold yellow]Next Steps:[/bold yellow]")
105-
console.print("1. Run 'specfact sdd constitution bootstrap --repo .' to auto-generate constitution")
106-
console.print("2. Or run tool-specific constitution command in your AI assistant")
107-
console.print("3. Then run 'specfact sync bridge --adapter <adapter>' again")
108-
raise typer.Exit(1)
101+
if adapter_type == AdapterType.SPECKIT:
102+
has_constitution = capabilities.has_custom_hooks
103+
if not has_constitution:
104+
console.print("[bold red]✗[/bold red] Constitution required")
105+
console.print("[red]Constitution file not found or is empty[/red]")
106+
console.print("\n[bold yellow]Next Steps:[/bold yellow]")
107+
console.print("1. Run 'specfact sdd constitution bootstrap --repo .' to auto-generate constitution")
108+
console.print("2. Or run tool-specific constitution command in your AI assistant")
109+
console.print("3. Then run 'specfact sync bridge --adapter <adapter>' again")
110+
raise typer.Exit(1)
109111

110-
# Check if constitution is minimal and suggest bootstrap
111-
constitution_path = repo / ".specify" / "memory" / "constitution.md"
112-
if constitution_path.exists():
113-
from specfact_cli.commands.sdd import is_constitution_minimal
114-
115-
if is_constitution_minimal(constitution_path):
116-
# Auto-generate in test mode, prompt in interactive mode
117-
# Check for test environment (TEST_MODE or PYTEST_CURRENT_TEST)
118-
is_test_env = os.environ.get("TEST_MODE") == "true" or os.environ.get("PYTEST_CURRENT_TEST") is not None
119-
if is_test_env:
120-
# Auto-generate bootstrap constitution in test mode
121-
from specfact_cli.enrichers.constitution_enricher import ConstitutionEnricher
122-
123-
enricher = ConstitutionEnricher()
124-
enriched_content = enricher.bootstrap(repo, constitution_path)
125-
constitution_path.write_text(enriched_content, encoding="utf-8")
126-
else:
127-
# Check if we're in an interactive environment
128-
if runtime.is_interactive():
129-
console.print("[yellow]⚠[/yellow] Constitution is minimal (essentially empty)")
130-
suggest_bootstrap = typer.confirm(
131-
"Generate bootstrap constitution from repository analysis?",
132-
default=True,
133-
)
134-
if suggest_bootstrap:
135-
from specfact_cli.enrichers.constitution_enricher import ConstitutionEnricher
136-
137-
console.print("[dim]Generating bootstrap constitution...[/dim]")
138-
enricher = ConstitutionEnricher()
139-
enriched_content = enricher.bootstrap(repo, constitution_path)
140-
constitution_path.write_text(enriched_content, encoding="utf-8")
141-
console.print("[bold green]✓[/bold green] Bootstrap constitution generated")
142-
console.print("[dim]Review and adjust as needed before syncing[/dim]")
112+
# Check if constitution is minimal and suggest bootstrap (Spec-Kit only)
113+
if adapter_type == AdapterType.SPECKIT:
114+
constitution_path = repo / ".specify" / "memory" / "constitution.md"
115+
if constitution_path.exists():
116+
from specfact_cli.commands.sdd import is_constitution_minimal
117+
118+
if is_constitution_minimal(constitution_path):
119+
# Auto-generate in test mode, prompt in interactive mode
120+
# Check for test environment (TEST_MODE or PYTEST_CURRENT_TEST)
121+
is_test_env = os.environ.get("TEST_MODE") == "true" or os.environ.get("PYTEST_CURRENT_TEST") is not None
122+
if is_test_env:
123+
# Auto-generate bootstrap constitution in test mode
124+
from specfact_cli.enrichers.constitution_enricher import ConstitutionEnricher
125+
126+
enricher = ConstitutionEnricher()
127+
enriched_content = enricher.bootstrap(repo, constitution_path)
128+
constitution_path.write_text(enriched_content, encoding="utf-8")
129+
else:
130+
# Check if we're in an interactive environment
131+
if runtime.is_interactive():
132+
console.print("[yellow]⚠[/yellow] Constitution is minimal (essentially empty)")
133+
suggest_bootstrap = typer.confirm(
134+
"Generate bootstrap constitution from repository analysis?",
135+
default=True,
136+
)
137+
if suggest_bootstrap:
138+
from specfact_cli.enrichers.constitution_enricher import ConstitutionEnricher
139+
140+
console.print("[dim]Generating bootstrap constitution...[/dim]")
141+
enricher = ConstitutionEnricher()
142+
enriched_content = enricher.bootstrap(repo, constitution_path)
143+
constitution_path.write_text(enriched_content, encoding="utf-8")
144+
console.print("[bold green]✓[/bold green] Bootstrap constitution generated")
145+
console.print("[dim]Review and adjust as needed before syncing[/dim]")
146+
else:
147+
console.print(
148+
"[dim]Skipping bootstrap. Run 'specfact sdd constitution bootstrap' manually if needed[/dim]"
149+
)
143150
else:
151+
# Non-interactive mode: skip prompt
152+
console.print("[yellow]⚠[/yellow] Constitution is minimal (essentially empty)")
144153
console.print(
145-
"[dim]Skipping bootstrap. Run 'specfact sdd constitution bootstrap' manually if needed[/dim]"
154+
"[dim]Run 'specfact sdd constitution bootstrap --repo .' to generate constitution[/dim]"
146155
)
147-
else:
148-
# Non-interactive mode: skip prompt
149-
console.print("[yellow]⚠[/yellow] Constitution is minimal (essentially empty)")
150-
console.print(
151-
"[dim]Run 'specfact sdd constitution bootstrap --repo .' to generate constitution[/dim]"
152-
)
153-
154-
console.print("[bold green]✓[/bold green] Constitution found and validated")
156+
else:
157+
# Constitution exists and is not minimal
158+
console.print("[bold green]✓[/bold green] Constitution found and validated")
155159

156160
# Step 2: Detect SpecFact structure
157161
specfact_exists = (repo / SpecFactStructure.ROOT).exists()

0 commit comments

Comments
 (0)