Skip to content

feat(enforcement): adapter pattern with PolicyRouter (RTR)#15

Merged
kschlt merged 1 commit intomainfrom
feat/enforcement-adapter-registry
Mar 26, 2026
Merged

feat(enforcement): adapter pattern with PolicyRouter (RTR)#15
kschlt merged 1 commit intomainfrom
feat/enforcement-adapter-registry

Conversation

@kschlt
Copy link
Copy Markdown
Owner

@kschlt kschlt commented Mar 26, 2026

Summary

  • Introduces BaseAdapter ABC with capability declarations (supported_policy_keys, supported_languages, config_targets, supported_clause_kinds, output_modes, supported_stages) so the router can inspect adapters without running them
  • Wraps existing ESLint and Ruff generators as ESLintAdapter / RuffAdapter subclasses — no behaviour change, just the new interface layered on top
  • Adds StackDetector that scans project files by extension (*.py → python, *.ts/tsx → typescript, *.js/jsx → javascript) skipping build/cache dirs
  • Adds PolicyRouter that matches active constraint fields to adapters by capability AND detected stack, and reports unroutable policy keys (patterns, architecture, config_enforcement) as explicit skips
  • Refactors EnforcementPipeline.compile() to use the router; adds optional detected_stack override for tests and callers that already know the stack

Test plan

  • 44 new unit/integration tests in tests/unit/test_adapter_registry.py covering BaseAdapter contract, ESLintAdapter/RuffAdapter capabilities, StackDetector, PolicyRouter routing logic, unroutable key reporting, and all three integration scenarios (Python-only, JS-only, mixed)
  • Existing pipeline tests updated to pass detected_stack where needed (1 test)
  • 380 tests passing, ruff + mypy clean

- Add BaseAdapter ABC with capability declarations: supported_policy_keys,
  supported_languages, config_targets, supported_clause_kinds, output_modes,
  supported_stages (ENF-epic extension stubs included per spec)
- Add ConfigFragment dataclass as the in-memory artifact adapters produce
- Wrap existing ESLint generator in ESLintAdapter(BaseAdapter)
- Wrap existing Ruff generator in RuffAdapter(BaseAdapter)
- Add StackDetector that scans project files by extension to identify
  the technology stack (python, javascript, typescript); skips build/cache dirs
- Add PolicyRouter: matches active constraint fields to adapters by
  capability AND detected stack; reports unroutable policy keys
- Refactor EnforcementPipeline.compile() to use the router instead of
  hard-coded adapter calls; accepts optional detected_stack override
- Add 44 unit/integration tests covering all new components
- 380 tests passing, ruff + mypy clean
@kschlt kschlt merged commit 4269b8e into main Mar 26, 2026
8 checks passed
@kschlt kschlt deleted the feat/enforcement-adapter-registry branch March 26, 2026 18:13
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant