diff --git a/adr_kit/cli.py b/adr_kit/cli.py index cb08d3c..f40d9bd 100644 --- a/adr_kit/cli.py +++ b/adr_kit/cli.py @@ -280,10 +280,10 @@ def mcp_health() -> None: # Test workflow system (the real business logic) try: - from .workflows.analyze import AnalyzeProjectWorkflow # noqa: F401 - from .workflows.approval import ApprovalWorkflow # noqa: F401 - from .workflows.creation import CreationWorkflow # noqa: F401 - from .workflows.preflight import PreflightWorkflow # noqa: F401 + from .decision.workflows.analyze import AnalyzeProjectWorkflow # noqa: F401 + from .decision.workflows.approval import ApprovalWorkflow # noqa: F401 + from .decision.workflows.creation import CreationWorkflow # noqa: F401 + from .decision.workflows.preflight import PreflightWorkflow # noqa: F401 console.print("✅ Workflow backend system: OK") workflow_available = True @@ -652,7 +652,7 @@ def info() -> None: def _setup_enforcement_hooks() -> None: """Set up git hooks for staged ADR enforcement (called from init --with-enforcement).""" - from .enforce.hooks import HookGenerator + from .enforcement.generation.hooks import HookGenerator gen = HookGenerator() results = gen.generate() @@ -744,7 +744,7 @@ def setup_enforcement( .git/hooks/pre-push. Safe on existing hooks — appends only. Re-running is idempotent. """ - from .enforce.hooks import HookGenerator + from .enforcement.generation.hooks import HookGenerator try: gen = HookGenerator() @@ -775,7 +775,7 @@ def enforce_status( ), ) -> None: """Show status of ADR enforcement hooks.""" - from .enforce.hooks import HookGenerator + from .enforcement.generation.hooks import HookGenerator try: gen = HookGenerator() @@ -1010,7 +1010,7 @@ def preflight( before implementation, helping enforce architectural governance. """ try: - from .gate import PolicyGate, create_technical_choice + from .decision.gate import PolicyGate, create_technical_choice gate = PolicyGate(adr_dir) @@ -1083,7 +1083,7 @@ def gate_status( ) -> None: """Show current preflight gate status and configuration.""" try: - from .gate import PolicyGate + from .decision.gate import PolicyGate gate = PolicyGate(adr_dir) status = gate.get_gate_status() @@ -1146,7 +1146,7 @@ def guardrail_apply( """Apply automatic guardrails based on ADR policies.""" try: - from .guardrail import GuardrailManager + from .enforcement.config.manager import GuardrailManager adr_path = Path(adr_dir) manager = GuardrailManager(adr_path) @@ -1188,7 +1188,7 @@ def guardrail_status( """Show status of the automatic guardrail system.""" try: - from .guardrail import GuardrailManager + from .enforcement.config.manager import GuardrailManager adr_path = Path(adr_dir) manager = GuardrailManager(adr_path) @@ -1275,8 +1275,8 @@ def enforce( Exit codes: 0 = pass, 1 = violations found, 2 = warnings only, 3 = error """ - from .enforce.stages import EnforcementLevel - from .enforce.validator import StagedValidator + from .enforcement.validation.staged import StagedValidator + from .enforcement.validation.stages import EnforcementLevel try: try: @@ -1292,7 +1292,7 @@ def enforce( # JSON output mode — structured report for agents and CI if output_format.lower() == "json": - from .enforce.reporter import build_report + from .enforcement.reporter import build_report report = build_report(result) # Print to stdout (not via Rich console) so JSON is clean @@ -1368,7 +1368,7 @@ def generate_scripts( Each script supports --quick (staged files) and --full (all files) modes and outputs JSON matching the EnforcementReport schema. """ - from .enforce.script_generator import ScriptGenerator + from .enforcement.generation.scripts import ScriptGenerator try: generator = ScriptGenerator(adr_dir=adr_dir) @@ -1408,7 +1408,7 @@ def generate_ci( Safe to re-run — only overwrites files it previously generated. """ - from .enforce.ci import CIWorkflowGenerator + from .enforcement.generation.ci import CIWorkflowGenerator try: generator = CIWorkflowGenerator() diff --git a/adr_kit/decision/__init__.py b/adr_kit/decision/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/adr_kit/gate/__init__.py b/adr_kit/decision/gate/__init__.py similarity index 100% rename from adr_kit/gate/__init__.py rename to adr_kit/decision/gate/__init__.py diff --git a/adr_kit/gate/models.py b/adr_kit/decision/gate/models.py similarity index 100% rename from adr_kit/gate/models.py rename to adr_kit/decision/gate/models.py diff --git a/adr_kit/gate/policy_engine.py b/adr_kit/decision/gate/policy_engine.py similarity index 99% rename from adr_kit/gate/policy_engine.py rename to adr_kit/decision/gate/policy_engine.py index 31234f8..94bc421 100644 --- a/adr_kit/gate/policy_engine.py +++ b/adr_kit/decision/gate/policy_engine.py @@ -4,7 +4,7 @@ from pathlib import Path from typing import Any -from ..contract import ConstraintsContractBuilder +from ...contract import ConstraintsContractBuilder from .models import GateConfig, GateDecision from .technical_choice import ChoiceType, TechnicalChoice diff --git a/adr_kit/gate/policy_gate.py b/adr_kit/decision/gate/policy_gate.py similarity index 100% rename from adr_kit/gate/policy_gate.py rename to adr_kit/decision/gate/policy_gate.py diff --git a/adr_kit/gate/technical_choice.py b/adr_kit/decision/gate/technical_choice.py similarity index 100% rename from adr_kit/gate/technical_choice.py rename to adr_kit/decision/gate/technical_choice.py diff --git a/adr_kit/decision/guidance/__init__.py b/adr_kit/decision/guidance/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/adr_kit/workflows/decision_guidance.py b/adr_kit/decision/guidance/decision_guidance.py similarity index 100% rename from adr_kit/workflows/decision_guidance.py rename to adr_kit/decision/guidance/decision_guidance.py diff --git a/adr_kit/decision/workflows/__init__.py b/adr_kit/decision/workflows/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/adr_kit/workflows/analyze.py b/adr_kit/decision/workflows/analyze.py similarity index 99% rename from adr_kit/workflows/analyze.py rename to adr_kit/decision/workflows/analyze.py index 4623b4f..42b7e29 100644 --- a/adr_kit/workflows/analyze.py +++ b/adr_kit/decision/workflows/analyze.py @@ -5,7 +5,7 @@ from pathlib import Path from typing import Any -from ..core.parse import find_adr_files +from ...core.parse import find_adr_files from .base import BaseWorkflow, WorkflowError, WorkflowResult, WorkflowStatus diff --git a/adr_kit/workflows/approval.py b/adr_kit/decision/workflows/approval.py similarity index 97% rename from adr_kit/workflows/approval.py rename to adr_kit/decision/workflows/approval.py index 2c2861e..63d7754 100644 --- a/adr_kit/workflows/approval.py +++ b/adr_kit/decision/workflows/approval.py @@ -7,14 +7,14 @@ from pathlib import Path from typing import Any -from ..contract.builder import ConstraintsContractBuilder -from ..core.model import ADR -from ..core.parse import find_adr_files, parse_adr_file -from ..core.validate import validate_adr -from ..enforce.eslint import generate_eslint_config -from ..enforce.ruff import generate_ruff_config -from ..guardrail.manager import GuardrailManager -from ..index.json_index import generate_adr_index +from ...contract.builder import ConstraintsContractBuilder +from ...core.model import ADR +from ...core.parse import find_adr_files, parse_adr_file +from ...core.validate import validate_adr +from ...enforcement.adapters.eslint import generate_eslint_config +from ...enforcement.adapters.ruff import generate_ruff_config +from ...enforcement.config.manager import GuardrailManager +from ...index.json_index import generate_adr_index from .base import BaseWorkflow, WorkflowResult @@ -284,7 +284,7 @@ def _update_adr_status( f.write(new_content) # Return updated ADR object - create a new one with updated status - from ..core.model import ADRStatus + from ...core.model import ADRStatus updated_front_matter = adr.front_matter.model_copy( update={"status": ADRStatus.ACCEPTED} @@ -380,7 +380,7 @@ def _generate_enforcement_rules(self, adr: ADR) -> dict[str, Any]: def _generate_validation_scripts(self, adr: ADR) -> dict[str, Any]: """Generate standalone validation scripts for an ADR's policies.""" try: - from ..enforce.script_generator import ScriptGenerator + from ...enforcement.generation.scripts import ScriptGenerator generator = ScriptGenerator(adr_dir=self.adr_dir) output_dir = Path.cwd() / "scripts" / "adr" @@ -407,7 +407,7 @@ def _generate_validation_scripts(self, adr: ADR) -> dict[str, Any]: def _update_git_hooks(self) -> dict[str, Any]: """Update git hooks to run staged enforcement checks.""" try: - from ..enforce.hooks import HookGenerator + from ...enforcement.generation.hooks import HookGenerator generator = HookGenerator() hook_results = generator.generate(project_root=Path.cwd()) diff --git a/adr_kit/workflows/base.py b/adr_kit/decision/workflows/base.py similarity index 100% rename from adr_kit/workflows/base.py rename to adr_kit/decision/workflows/base.py diff --git a/adr_kit/workflows/creation.py b/adr_kit/decision/workflows/creation.py similarity index 99% rename from adr_kit/workflows/creation.py rename to adr_kit/decision/workflows/creation.py index 5e48446..aab32df 100644 --- a/adr_kit/workflows/creation.py +++ b/adr_kit/decision/workflows/creation.py @@ -6,10 +6,10 @@ from pathlib import Path from typing import Any -from ..contract.builder import ConstraintsContractBuilder -from ..core.model import ADR, ADRFrontMatter, ADRStatus, PolicyModel -from ..core.parse import find_adr_files, parse_adr_file -from ..core.validate import validate_adr +from ...contract.builder import ConstraintsContractBuilder +from ...core.model import ADR, ADRFrontMatter, ADRStatus, PolicyModel +from ...core.parse import find_adr_files, parse_adr_file +from ...core.validate import validate_adr from .base import BaseWorkflow, WorkflowError, WorkflowResult, WorkflowStatus @@ -552,7 +552,7 @@ def _validate_policy_completeness( Note: This is a lightweight check. Policy construction guidance is provided via the policy_guidance promptlet, which agents can use to construct policies. """ - from ..core.policy_extractor import PolicyExtractor + from ...core.policy_extractor import PolicyExtractor extractor = PolicyExtractor() warnings = [] diff --git a/adr_kit/workflows/preflight.py b/adr_kit/decision/workflows/preflight.py similarity index 99% rename from adr_kit/workflows/preflight.py rename to adr_kit/decision/workflows/preflight.py index a41e455..eec9889 100644 --- a/adr_kit/workflows/preflight.py +++ b/adr_kit/decision/workflows/preflight.py @@ -3,8 +3,8 @@ from dataclasses import dataclass from typing import Any -from ..contract.builder import ConstraintsContractBuilder -from ..contract.models import ConstraintsContract +from ...contract.builder import ConstraintsContractBuilder +from ...contract.models import ConstraintsContract from .base import BaseWorkflow, WorkflowResult @@ -154,7 +154,7 @@ def _load_constraints_contract(self) -> ConstraintsContract: # If no contract exists, return empty contract from pathlib import Path - from ..contract.models import ConstraintsContract + from ...contract.models import ConstraintsContract # Use the proper create_empty method instead of incorrect constructor return ConstraintsContract.create_empty(Path(".")) diff --git a/adr_kit/workflows/supersede.py b/adr_kit/decision/workflows/supersede.py similarity index 99% rename from adr_kit/workflows/supersede.py rename to adr_kit/decision/workflows/supersede.py index 50e3ce0..dfef624 100644 --- a/adr_kit/workflows/supersede.py +++ b/adr_kit/decision/workflows/supersede.py @@ -6,8 +6,8 @@ from pathlib import Path from typing import Any -from ..core.model import ADR -from ..core.parse import find_adr_files, parse_adr_file +from ...core.model import ADR +from ...core.parse import find_adr_files, parse_adr_file from .approval import ApprovalInput, ApprovalWorkflow from .base import BaseWorkflow, WorkflowResult, WorkflowStatus from .creation import CreationInput, CreationWorkflow diff --git a/adr_kit/enforce/__init__.py b/adr_kit/enforce/__init__.py deleted file mode 100644 index 3b90a27..0000000 --- a/adr_kit/enforce/__init__.py +++ /dev/null @@ -1,6 +0,0 @@ -"""ADR enforcement functionality.""" - -from .ci import CIWorkflowGenerator -from .script_generator import ScriptGenerator - -__all__ = ["CIWorkflowGenerator", "ScriptGenerator"] diff --git a/adr_kit/enforcement/__init__.py b/adr_kit/enforcement/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/adr_kit/enforcement/adapters/__init__.py b/adr_kit/enforcement/adapters/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/adr_kit/enforce/eslint.py b/adr_kit/enforcement/adapters/eslint.py similarity index 98% rename from adr_kit/enforce/eslint.py rename to adr_kit/enforcement/adapters/eslint.py index 634203b..3673add 100644 --- a/adr_kit/enforce/eslint.py +++ b/adr_kit/enforcement/adapters/eslint.py @@ -12,9 +12,9 @@ from pathlib import Path from typing import Any, TypedDict -from ..core.model import ADR, ADRStatus -from ..core.parse import ParseError, find_adr_files, parse_adr_file -from ..core.policy_extractor import PolicyExtractor +from ...core.model import ADR, ADRStatus +from ...core.parse import ParseError, find_adr_files, parse_adr_file +from ...core.policy_extractor import PolicyExtractor class ADRMetadata(TypedDict): diff --git a/adr_kit/enforce/ruff.py b/adr_kit/enforcement/adapters/ruff.py similarity index 99% rename from adr_kit/enforce/ruff.py rename to adr_kit/enforcement/adapters/ruff.py index 4bf5b24..83dfdfe 100644 --- a/adr_kit/enforce/ruff.py +++ b/adr_kit/enforcement/adapters/ruff.py @@ -15,8 +15,8 @@ import toml -from ..core.model import ADR, ADRStatus -from ..core.parse import ParseError, find_adr_files, parse_adr_file +from ...core.model import ADR, ADRStatus +from ...core.parse import ParseError, find_adr_files, parse_adr_file class PythonRuleExtractor: diff --git a/adr_kit/enforcement/config/__init__.py b/adr_kit/enforcement/config/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/adr_kit/guardrail/manager.py b/adr_kit/enforcement/config/manager.py similarity index 98% rename from adr_kit/guardrail/manager.py rename to adr_kit/enforcement/config/manager.py index 82660c6..fcc033e 100644 --- a/adr_kit/guardrail/manager.py +++ b/adr_kit/enforcement/config/manager.py @@ -4,9 +4,7 @@ from pathlib import Path from typing import Any -from ..contract import ConstraintsContractBuilder -from .config_writer import ConfigWriter -from .file_monitor import ChangeEvent, ChangeType, FileMonitor +from ...contract import ConstraintsContractBuilder from .models import ( ApplicationStatus, ApplyResult, @@ -16,6 +14,8 @@ FragmentType, GuardrailConfig, ) +from .monitor import ChangeEvent, ChangeType, FileMonitor +from .writer import ConfigWriter class GuardrailManager: diff --git a/adr_kit/guardrail/models.py b/adr_kit/enforcement/config/models.py similarity index 100% rename from adr_kit/guardrail/models.py rename to adr_kit/enforcement/config/models.py diff --git a/adr_kit/guardrail/file_monitor.py b/adr_kit/enforcement/config/monitor.py similarity index 98% rename from adr_kit/guardrail/file_monitor.py rename to adr_kit/enforcement/config/monitor.py index 0fcccde..7518b79 100644 --- a/adr_kit/guardrail/file_monitor.py +++ b/adr_kit/enforcement/config/monitor.py @@ -6,8 +6,8 @@ from enum import Enum from pathlib import Path -from ..core.model import ADR -from ..core.parse import ParseError, find_adr_files, parse_adr_file +from ...core.model import ADR +from ...core.parse import ParseError, find_adr_files, parse_adr_file class ChangeType(str, Enum): diff --git a/adr_kit/guardrail/config_writer.py b/adr_kit/enforcement/config/writer.py similarity index 100% rename from adr_kit/guardrail/config_writer.py rename to adr_kit/enforcement/config/writer.py diff --git a/adr_kit/guard/__init__.py b/adr_kit/enforcement/detection/__init__.py similarity index 100% rename from adr_kit/guard/__init__.py rename to adr_kit/enforcement/detection/__init__.py diff --git a/adr_kit/guard/detector.py b/adr_kit/enforcement/detection/detector.py similarity index 98% rename from adr_kit/guard/detector.py rename to adr_kit/enforcement/detection/detector.py index d073a5b..cd0c195 100644 --- a/adr_kit/guard/detector.py +++ b/adr_kit/enforcement/detection/detector.py @@ -13,10 +13,10 @@ from pathlib import Path from typing import Any -from ..core.model import ADR -from ..core.parse import ParseError, find_adr_files, parse_adr_file -from ..core.policy_extractor import PolicyExtractor -from ..semantic.retriever import SemanticIndex, SemanticMatch +from ...core.model import ADR +from ...core.parse import ParseError, find_adr_files, parse_adr_file +from ...core.policy_extractor import PolicyExtractor +from ...semantic.retriever import SemanticIndex, SemanticMatch @dataclass diff --git a/adr_kit/enforcement/generation/__init__.py b/adr_kit/enforcement/generation/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/adr_kit/enforce/ci.py b/adr_kit/enforcement/generation/ci.py similarity index 100% rename from adr_kit/enforce/ci.py rename to adr_kit/enforcement/generation/ci.py diff --git a/adr_kit/enforce/hooks.py b/adr_kit/enforcement/generation/hooks.py similarity index 100% rename from adr_kit/enforce/hooks.py rename to adr_kit/enforcement/generation/hooks.py diff --git a/adr_kit/enforce/script_generator.py b/adr_kit/enforcement/generation/scripts.py similarity index 99% rename from adr_kit/enforce/script_generator.py rename to adr_kit/enforcement/generation/scripts.py index 2b5b567..ded19cd 100644 --- a/adr_kit/enforce/script_generator.py +++ b/adr_kit/enforcement/generation/scripts.py @@ -12,9 +12,9 @@ import stat from pathlib import Path -from ..core.model import ADR, ADRStatus -from ..core.parse import ParseError, find_adr_files, parse_adr_file -from .stages import StagedCheck, classify_adr_checks +from ...core.model import ADR, ADRStatus +from ...core.parse import ParseError, find_adr_files, parse_adr_file +from ..validation.stages import StagedCheck, classify_adr_checks class ScriptGenerator: diff --git a/adr_kit/enforce/reporter.py b/adr_kit/enforcement/reporter.py similarity index 98% rename from adr_kit/enforce/reporter.py rename to adr_kit/enforcement/reporter.py index cf2d6ca..18a752d 100644 --- a/adr_kit/enforce/reporter.py +++ b/adr_kit/enforcement/reporter.py @@ -16,7 +16,7 @@ from pydantic import BaseModel -from .validator import ValidationResult +from .validation.staged import ValidationResult class ViolationEntry(BaseModel): diff --git a/adr_kit/enforcement/validation/__init__.py b/adr_kit/enforcement/validation/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/adr_kit/enforce/validator.py b/adr_kit/enforcement/validation/staged.py similarity index 99% rename from adr_kit/enforce/validator.py rename to adr_kit/enforcement/validation/staged.py index 2bbe289..4de619b 100644 --- a/adr_kit/enforce/validator.py +++ b/adr_kit/enforcement/validation/staged.py @@ -16,8 +16,8 @@ from dataclasses import dataclass, field from pathlib import Path -from ..core.model import ADR, ADRStatus -from ..core.parse import ParseError, find_adr_files, parse_adr_file +from ...core.model import ADR, ADRStatus +from ...core.parse import ParseError, find_adr_files, parse_adr_file from .stages import EnforcementLevel, StagedCheck, checks_for_level, classify_adr_checks # Source file extensions scanned during CI full-codebase pass diff --git a/adr_kit/enforce/stages.py b/adr_kit/enforcement/validation/stages.py similarity index 100% rename from adr_kit/enforce/stages.py rename to adr_kit/enforcement/validation/stages.py diff --git a/adr_kit/guardrail/__init__.py b/adr_kit/guardrail/__init__.py deleted file mode 100644 index cfcb24c..0000000 --- a/adr_kit/guardrail/__init__.py +++ /dev/null @@ -1,32 +0,0 @@ -"""Automatic Guardrail Management System. - -This module implements automatic application of configuration fragments -when ADR policies change, providing the "Guardrail Manager" component -from the architectural vision. -""" - -from .config_writer import ConfigFragment, ConfigWriter, SentinelBlock -from .file_monitor import ChangeEvent, ChangeType, FileMonitor -from .manager import GuardrailManager -from .models import ( - ApplyResult, - ConfigTemplate, - FragmentTarget, - FragmentType, - GuardrailConfig, -) - -__all__ = [ - "GuardrailManager", - "ConfigWriter", - "ConfigFragment", - "SentinelBlock", - "FileMonitor", - "ChangeEvent", - "ChangeType", - "GuardrailConfig", - "FragmentTarget", - "ApplyResult", - "ConfigTemplate", - "FragmentType", -] diff --git a/adr_kit/mcp/server.py b/adr_kit/mcp/server.py index 297dc88..815147e 100644 --- a/adr_kit/mcp/server.py +++ b/adr_kit/mcp/server.py @@ -10,12 +10,12 @@ from fastmcp import FastMCP # Import the full workflow system (this is where the real business logic lives) -from ..workflows.analyze import AnalyzeProjectWorkflow -from ..workflows.approval import ApprovalInput, ApprovalWorkflow -from ..workflows.creation import CreationInput, CreationWorkflow +from ..decision.workflows.analyze import AnalyzeProjectWorkflow +from ..decision.workflows.approval import ApprovalInput, ApprovalWorkflow +from ..decision.workflows.creation import CreationInput, CreationWorkflow +from ..decision.workflows.preflight import PreflightInput, PreflightWorkflow +from ..decision.workflows.supersede import SupersedeInput, SupersedeWorkflow from ..workflows.planning import PlanningInput, PlanningWorkflow -from ..workflows.preflight import PreflightInput, PreflightWorkflow -from ..workflows.supersede import SupersedeInput, SupersedeWorkflow from .middleware import StringifiedParameterFixMiddleware from .models import ( AnalyzeProjectRequest, diff --git a/adr_kit/workflows/__init__.py b/adr_kit/workflows/__init__.py index a807960..7ac9e33 100644 --- a/adr_kit/workflows/__init__.py +++ b/adr_kit/workflows/__init__.py @@ -1,36 +1,19 @@ -"""Internal workflow orchestration system. +"""Workflow orchestration. Planning workflow stays here (context plane). +All other workflows have moved to adr_kit.decision.workflows.""" -This module contains the internal workflow orchestrators that are triggered by MCP entry points. -These workflows handle all the complex automation and orchestration that was previously exposed -as separate MCP tools. +from adr_kit.decision.workflows.base import ( + BaseWorkflow, + WorkflowError, + WorkflowResult, + WorkflowStatus, +) -Key Design Principles: -- Workflows are pure automation/orchestration (no intelligence) -- Intelligence comes only from agents calling entry points -- Each entry point triggers comprehensive internal workflows -- Workflows use existing components (contract, gate, context, guardrail systems) -- Rich status reporting guides agent next actions -""" - -from .analyze import AnalyzeProjectWorkflow -from .approval import ApprovalWorkflow -from .base import BaseWorkflow, WorkflowError, WorkflowResult, WorkflowStatus -from .creation import CreationWorkflow from .planning import PlanningWorkflow -from .preflight import PreflightWorkflow -from .supersede import SupersedeWorkflow __all__ = [ - # Base classes "BaseWorkflow", "WorkflowResult", "WorkflowError", "WorkflowStatus", - # Workflow implementations - "ApprovalWorkflow", - "CreationWorkflow", - "PreflightWorkflow", "PlanningWorkflow", - "SupersedeWorkflow", - "AnalyzeProjectWorkflow", ] diff --git a/adr_kit/workflows/planning.py b/adr_kit/workflows/planning.py index 5441fff..adaf65f 100644 --- a/adr_kit/workflows/planning.py +++ b/adr_kit/workflows/planning.py @@ -4,10 +4,11 @@ from dataclasses import dataclass from typing import Any +from adr_kit.decision.workflows.base import BaseWorkflow, WorkflowResult + from ..contract.builder import ConstraintsContractBuilder from ..contract.models import ConstraintsContract from ..core.model import ADR -from .base import BaseWorkflow, WorkflowResult @dataclass diff --git a/tests/integration/test_comprehensive_scenarios.py b/tests/integration/test_comprehensive_scenarios.py index f1c2dda..5f5dfcf 100644 --- a/tests/integration/test_comprehensive_scenarios.py +++ b/tests/integration/test_comprehensive_scenarios.py @@ -8,10 +8,10 @@ import pytest -from adr_kit.workflows.analyze import AnalyzeProjectWorkflow -from adr_kit.workflows.base import WorkflowError, WorkflowStatus -from adr_kit.workflows.creation import CreationInput, CreationWorkflow -from adr_kit.workflows.preflight import PreflightInput, PreflightWorkflow +from adr_kit.decision.workflows.analyze import AnalyzeProjectWorkflow +from adr_kit.decision.workflows.base import WorkflowError, WorkflowStatus +from adr_kit.decision.workflows.creation import CreationInput, CreationWorkflow +from adr_kit.decision.workflows.preflight import PreflightInput, PreflightWorkflow class TestErrorScenarios: diff --git a/tests/integration/test_decision_quality_assessment.py b/tests/integration/test_decision_quality_assessment.py index 9bce001..c53d74e 100644 --- a/tests/integration/test_decision_quality_assessment.py +++ b/tests/integration/test_decision_quality_assessment.py @@ -5,7 +5,7 @@ import pytest -from adr_kit.workflows.creation import CreationInput, CreationWorkflow +from adr_kit.decision.workflows.creation import CreationInput, CreationWorkflow class TestDecisionQualityAssessment: diff --git a/tests/integration/test_mcp_workflow_integration.py b/tests/integration/test_mcp_workflow_integration.py index adb86ae..d2a8922 100644 --- a/tests/integration/test_mcp_workflow_integration.py +++ b/tests/integration/test_mcp_workflow_integration.py @@ -49,8 +49,8 @@ def test_mcp_analyze_project_integration(self, temp_project_dir, temp_adr_dir): """Test MCP analyze project tool calls workflow correctly.""" # Import the actual MCP tool function # Note: We can't call the decorated function directly, so we test the workflow + from adr_kit.decision.workflows.analyze import AnalyzeProjectWorkflow from adr_kit.mcp.server import logger - from adr_kit.workflows.analyze import AnalyzeProjectWorkflow # Test request model validation request = AnalyzeProjectRequest( @@ -79,7 +79,10 @@ def test_mcp_analyze_project_integration(self, temp_project_dir, temp_adr_dir): def test_mcp_preflight_integration(self, temp_adr_dir): """Test MCP preflight tool calls workflow correctly.""" - from adr_kit.workflows.preflight import PreflightInput, PreflightWorkflow + from adr_kit.decision.workflows.preflight import ( + PreflightInput, + PreflightWorkflow, + ) # Test request model request = PreflightCheckRequest( @@ -113,7 +116,7 @@ def test_mcp_preflight_integration(self, temp_adr_dir): def test_mcp_create_integration(self, temp_adr_dir): """Test MCP create tool calls workflow correctly.""" - from adr_kit.workflows.creation import CreationInput, CreationWorkflow + from adr_kit.decision.workflows.creation import CreationInput, CreationWorkflow # Test request model request = CreateADRRequest( @@ -168,8 +171,8 @@ def test_mcp_create_integration(self, temp_adr_dir): def test_mcp_approve_integration(self, temp_adr_dir): """Test MCP approve tool integration.""" - from adr_kit.workflows.approval import ApprovalInput, ApprovalWorkflow - from adr_kit.workflows.creation import CreationInput, CreationWorkflow + from adr_kit.decision.workflows.approval import ApprovalInput, ApprovalWorkflow + from adr_kit.decision.workflows.creation import CreationInput, CreationWorkflow # First create an ADR to approve creation_workflow = CreationWorkflow(adr_dir=temp_adr_dir) @@ -217,8 +220,11 @@ def test_mcp_approve_integration(self, temp_adr_dir): def test_mcp_supersede_integration(self, temp_adr_dir): """Test MCP supersede tool integration.""" - from adr_kit.workflows.creation import CreationInput, CreationWorkflow - from adr_kit.workflows.supersede import SupersedeInput, SupersedeWorkflow + from adr_kit.decision.workflows.creation import CreationInput, CreationWorkflow + from adr_kit.decision.workflows.supersede import ( + SupersedeInput, + SupersedeWorkflow, + ) # Create original ADR creation_workflow = CreationWorkflow(adr_dir=temp_adr_dir) @@ -322,8 +328,8 @@ def test_mcp_planning_context_integration(self, temp_adr_dir): def test_response_format_consistency(self, temp_project_dir, temp_adr_dir): """Test that all workflows return consistent response formats for MCP.""" + from adr_kit.decision.workflows.analyze import AnalyzeProjectWorkflow from adr_kit.mcp.models import error_response, success_response - from adr_kit.workflows.analyze import AnalyzeProjectWorkflow # Test successful workflow response workflow = AnalyzeProjectWorkflow(adr_dir=temp_adr_dir) @@ -395,7 +401,7 @@ def test_request_model_validation(self): def test_error_propagation(self, temp_adr_dir): """Test that workflow errors are properly propagated to MCP responses.""" - from adr_kit.workflows.creation import CreationInput, CreationWorkflow + from adr_kit.decision.workflows.creation import CreationInput, CreationWorkflow # Create invalid input to trigger error invalid_input = CreationInput( @@ -419,9 +425,9 @@ def test_error_propagation(self, temp_adr_dir): def test_end_to_end_workflow_chain(self, temp_project_dir, temp_adr_dir): """Test complete workflow chain: analyze → create → approve.""" - from adr_kit.workflows.analyze import AnalyzeProjectWorkflow - from adr_kit.workflows.approval import ApprovalInput, ApprovalWorkflow - from adr_kit.workflows.creation import CreationInput, CreationWorkflow + from adr_kit.decision.workflows.analyze import AnalyzeProjectWorkflow + from adr_kit.decision.workflows.approval import ApprovalInput, ApprovalWorkflow + from adr_kit.decision.workflows.creation import CreationInput, CreationWorkflow # Step 1: Analyze project analyze_workflow = AnalyzeProjectWorkflow(adr_dir=temp_adr_dir) diff --git a/tests/integration/test_workflow_analyze.py b/tests/integration/test_workflow_analyze.py index a364231..a43f232 100644 --- a/tests/integration/test_workflow_analyze.py +++ b/tests/integration/test_workflow_analyze.py @@ -7,8 +7,8 @@ import pytest -from adr_kit.workflows.analyze import AnalyzeProjectWorkflow -from adr_kit.workflows.base import WorkflowStatus +from adr_kit.decision.workflows.analyze import AnalyzeProjectWorkflow +from adr_kit.decision.workflows.base import WorkflowStatus class TestAnalyzeProjectWorkflow: diff --git a/tests/integration/test_workflow_creation.py b/tests/integration/test_workflow_creation.py index 9c602f4..29c32a4 100644 --- a/tests/integration/test_workflow_creation.py +++ b/tests/integration/test_workflow_creation.py @@ -8,8 +8,8 @@ import pytest from adr_kit.core.model import ADRStatus -from adr_kit.workflows.base import WorkflowStatus -from adr_kit.workflows.creation import CreationInput, CreationWorkflow +from adr_kit.decision.workflows.base import WorkflowStatus +from adr_kit.decision.workflows.creation import CreationInput, CreationWorkflow class TestCreationWorkflow: diff --git a/tests/unit/test_ci_generator.py b/tests/unit/test_ci_generator.py index fefc94d..c41e55b 100644 --- a/tests/unit/test_ci_generator.py +++ b/tests/unit/test_ci_generator.py @@ -5,7 +5,7 @@ import pytest -from adr_kit.enforce.ci import _MANAGED_HEADER, CIWorkflowGenerator +from adr_kit.enforcement.generation.ci import _MANAGED_HEADER, CIWorkflowGenerator class TestCIWorkflowGenerator: diff --git a/tests/unit/test_decision_guidance.py b/tests/unit/test_decision_guidance.py index a25788e..07171d0 100644 --- a/tests/unit/test_decision_guidance.py +++ b/tests/unit/test_decision_guidance.py @@ -1,6 +1,9 @@ """Unit tests for decision quality guidance.""" -from adr_kit.workflows.decision_guidance import _build_examples, build_decision_guidance +from adr_kit.decision.guidance.decision_guidance import ( + _build_examples, + build_decision_guidance, +) class TestDecisionGuidance: diff --git a/tests/unit/test_hook_generator.py b/tests/unit/test_hook_generator.py index 95d8158..fc3bccf 100644 --- a/tests/unit/test_hook_generator.py +++ b/tests/unit/test_hook_generator.py @@ -6,7 +6,7 @@ import pytest -from adr_kit.enforce.hooks import ( +from adr_kit.enforcement.generation.hooks import ( MANAGED_END, MANAGED_START, HookGenerator, diff --git a/tests/unit/test_policy_validation.py b/tests/unit/test_policy_validation.py index 4cb0c0c..7020997 100644 --- a/tests/unit/test_policy_validation.py +++ b/tests/unit/test_policy_validation.py @@ -7,7 +7,7 @@ from adr_kit.core.model import ADR, ADRFrontMatter, ADRStatus from adr_kit.core.policy_extractor import PolicyExtractor -from adr_kit.workflows.creation import CreationInput, CreationWorkflow +from adr_kit.decision.workflows.creation import CreationInput, CreationWorkflow class TestPolicyValidation: diff --git a/tests/unit/test_reporter.py b/tests/unit/test_reporter.py index 2ce3a81..57c4b42 100644 --- a/tests/unit/test_reporter.py +++ b/tests/unit/test_reporter.py @@ -2,9 +2,9 @@ import json -from adr_kit.enforce.reporter import EnforcementReport, build_report -from adr_kit.enforce.stages import EnforcementLevel -from adr_kit.enforce.validator import ValidationResult, Violation +from adr_kit.enforcement.reporter import EnforcementReport, build_report +from adr_kit.enforcement.validation.staged import ValidationResult, Violation +from adr_kit.enforcement.validation.stages import EnforcementLevel # --------------------------------------------------------------------------- # build_report diff --git a/tests/unit/test_script_generator.py b/tests/unit/test_script_generator.py index dce6d4f..58f3da1 100644 --- a/tests/unit/test_script_generator.py +++ b/tests/unit/test_script_generator.py @@ -12,7 +12,7 @@ import pytest -from adr_kit.enforce.script_generator import ScriptGenerator +from adr_kit.enforcement.generation.scripts import ScriptGenerator # Reuse the _make_adr helper from test_staged_enforcement from tests.unit.test_staged_enforcement import _make_adr diff --git a/tests/unit/test_staged_enforcement.py b/tests/unit/test_staged_enforcement.py index 33fdc34..58d0148 100644 --- a/tests/unit/test_staged_enforcement.py +++ b/tests/unit/test_staged_enforcement.py @@ -6,13 +6,13 @@ import pytest -from adr_kit.enforce.stages import ( +from adr_kit.enforcement.validation.staged import StagedValidator, ValidationResult +from adr_kit.enforcement.validation.stages import ( EnforcementLevel, StagedCheck, checks_for_level, classify_adr_checks, ) -from adr_kit.enforce.validator import StagedValidator, ValidationResult # --------------------------------------------------------------------------- # Helpers @@ -440,8 +440,8 @@ def test_detects_pattern_violation(self): def test_invalid_regex_pattern_skipped_gracefully(self): """An invalid regex in an ADR policy should not crash the validator.""" - from adr_kit.enforce.stages import StagedCheck - from adr_kit.enforce.validator import StagedValidator + from adr_kit.enforcement.validation.staged import StagedValidator + from adr_kit.enforcement.validation.stages import StagedCheck check = StagedCheck( adr_id="ADR-0001", @@ -464,7 +464,7 @@ def test_passed_true_when_no_violations(self): assert result.passed def test_passed_false_when_error_violation_present(self): - from adr_kit.enforce.validator import Violation + from adr_kit.enforcement.validation.staged import Violation result = ValidationResult( level=EnforcementLevel.COMMIT, files_checked=5, checks_run=3 @@ -481,7 +481,7 @@ def test_passed_false_when_error_violation_present(self): assert not result.passed def test_passed_true_with_only_warnings(self): - from adr_kit.enforce.validator import Violation + from adr_kit.enforcement.validation.staged import Violation result = ValidationResult( level=EnforcementLevel.COMMIT, files_checked=5, checks_run=3 @@ -499,7 +499,7 @@ def test_passed_true_with_only_warnings(self): assert result.has_warnings def test_error_and_warning_counts(self): - from adr_kit.enforce.validator import Violation + from adr_kit.enforcement.validation.staged import Violation result = ValidationResult( level=EnforcementLevel.CI, files_checked=10, checks_run=5 diff --git a/tests/unit/test_workflow_base.py b/tests/unit/test_workflow_base.py index 2355515..24cbce0 100644 --- a/tests/unit/test_workflow_base.py +++ b/tests/unit/test_workflow_base.py @@ -7,7 +7,7 @@ import pytest -from adr_kit.workflows.base import ( +from adr_kit.decision.workflows.base import ( BaseWorkflow, WorkflowError, WorkflowResult,