feat(decomposition): add merge pass, enrichment, and Pass 0b refinements
Some checks failed
CI/CD / go-lint (push) Has been skipped
CI/CD / python-lint (push) Has been skipped
CI/CD / nodejs-lint (push) Has been skipped
CI/CD / test-go-ai-compliance (push) Failing after 51s
CI/CD / test-python-backend-compliance (push) Successful in 34s
CI/CD / test-python-document-crawler (push) Successful in 23s
CI/CD / test-python-dsms-gateway (push) Successful in 20s
CI/CD / validate-canonical-controls (push) Successful in 12s
CI/CD / Deploy (push) Has been skipped

Add obligation refinement pipeline between Pass 0a and 0b:
- Merge pass: rule-based dedup of implementation-level duplicate obligations
  within the same parent control (Jaccard similarity on action+object)
- Enrich pass: classify trigger_type (event/periodic/continuous) and detect
  is_implementation_specific from obligation text (regex-based, no LLM)
- Pass 0b: skip merged obligations, cap severity for impl-specific, override
  category to 'testing' for test obligations
- Migration 075: merged_into_id, trigger_type, is_implementation_specific
- Two new API endpoints: merge-obligations, enrich-obligations
- 30+ new tests (122 total, all passing)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Benjamin Admin
2026-03-21 22:27:09 +01:00
parent 71b8c33270
commit a14e2f3a00
4 changed files with 804 additions and 12 deletions

View File

@@ -0,0 +1,38 @@
-- Migration 075: Obligation Refinement Fields
-- Supports Merge Pass (implementation-level dedup) and metadata enrichment.
--
-- New fields:
-- merged_into_id — points to survivor obligation when merged
-- trigger_type — event / periodic / continuous
-- is_implementation_specific — true if obligation references concrete tool/protocol
-- =============================================================================
-- 1. Add merge tracking
-- =============================================================================
ALTER TABLE obligation_candidates
ADD COLUMN IF NOT EXISTS merged_into_id UUID
REFERENCES obligation_candidates(id);
CREATE INDEX IF NOT EXISTS idx_oc_merged_into
ON obligation_candidates(merged_into_id)
WHERE merged_into_id IS NOT NULL;
-- Allow 'merged' as release_state
ALTER TABLE obligation_candidates
DROP CONSTRAINT IF EXISTS obligation_candidates_release_state_check;
ALTER TABLE obligation_candidates
ADD CONSTRAINT obligation_candidates_release_state_check
CHECK (release_state IN ('extracted', 'validated', 'rejected', 'composed', 'merged'));
-- =============================================================================
-- 2. Add enrichment metadata
-- =============================================================================
ALTER TABLE obligation_candidates
ADD COLUMN IF NOT EXISTS trigger_type VARCHAR(20) DEFAULT NULL
CHECK (trigger_type IS NULL OR trigger_type IN ('event', 'periodic', 'continuous'));
ALTER TABLE obligation_candidates
ADD COLUMN IF NOT EXISTS is_implementation_specific BOOLEAN DEFAULT FALSE;