docs(05-01): complete config diff service plan

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Jason Staack
2026-03-12 22:34:16 -05:00
parent eb76343d04
commit 4e083a9606
4 changed files with 141 additions and 23 deletions

View File

@@ -0,0 +1,115 @@
---
phase: 05-diff-engine
plan: 01
subsystem: api
tags: [difflib, unified-diff, openbao, transit, prometheus, nats]
requires:
- phase: 03-snapshot-ingestion
provides: "config snapshot subscriber and router_config_snapshots table"
- phase: 01-database-schema
provides: "router_config_diffs table schema"
provides:
- "generate_and_store_diff() for unified diff between consecutive snapshots"
- "Prometheus metrics for diff generation success/failure/timing"
- "Subscriber integration calling diff after snapshot INSERT"
affects: [06-change-parser, 07-timeline-api]
tech-stack:
added: [difflib]
patterns: [best-effort-secondary-operation, tdd-red-green]
key-files:
created:
- backend/app/services/config_diff_service.py
- backend/tests/test_config_diff_service.py
modified:
- backend/app/services/config_snapshot_subscriber.py
- backend/tests/test_config_snapshot_subscriber.py
key-decisions:
- "Diff service instantiates its own OpenBaoTransitService per-call with close() for clean lifecycle"
- "RETURNING id added to snapshot INSERT to capture new_snapshot_id for diff generation"
- "Subscriber tests mock generate_and_store_diff to isolate snapshot logic from diff logic"
patterns-established:
- "Best-effort secondary operations: wrap in try/except, log+count errors, never block primary flow"
- "Line counting excludes unified diff headers (+++ and --- lines)"
requirements-completed: [DIFF-01, DIFF-02]
duration: 3min
completed: 2026-03-13
---
# Phase 5 Plan 1: Config Diff Service Summary
**Unified diff generation between consecutive config snapshots using difflib with Transit decrypt and best-effort error handling**
## Performance
- **Duration:** 3 min
- **Started:** 2026-03-13T03:30:07Z
- **Completed:** 2026-03-13T03:33:Z
- **Tasks:** 2
- **Files modified:** 4
## Accomplishments
- Config diff service generates unified diffs between consecutive snapshots per device
- Transit decrypt of both old and new ciphertext before diffing in memory
- Best-effort pattern: decrypt/DB failures logged and counted, never block snapshot ack
- Prometheus metrics track diff success, errors (by type), and generation duration
- Subscriber wired to call diff generation after every successful snapshot INSERT
## Task Commits
Each task was committed atomically:
1. **Task 1: Diff generation service (TDD RED)** - `79453fa` (test)
2. **Task 1: Diff generation service (TDD GREEN)** - `72d0ae2` (feat)
3. **Task 2: Wire diff into subscriber** - `eb76343` (feat)
_TDD task had separate RED and GREEN commits_
## Files Created/Modified
- `backend/app/services/config_diff_service.py` - Diff generation with Transit decrypt, difflib, Prometheus metrics
- `backend/tests/test_config_diff_service.py` - 5 unit tests covering diff, first-snapshot, decrypt failure, line counts, empty diff
- `backend/app/services/config_snapshot_subscriber.py` - Added RETURNING id, generate_and_store_diff call after commit
- `backend/tests/test_config_snapshot_subscriber.py` - Updated to mock generate_and_store_diff
## Decisions Made
- Diff service instantiates its own OpenBaoTransitService per-call (clean lifecycle, consistent with subscriber pattern)
- RETURNING id added to snapshot INSERT SQL to capture the new_snapshot_id without a separate query
- Subscriber tests mock generate_and_store_diff to keep snapshot tests isolated and unchanged in assertion counts
## Deviations from Plan
### Auto-fixed Issues
**1. [Rule 1 - Bug] Updated subscriber test assertions for diff integration**
- **Found during:** Task 2 (wire diff into subscriber)
- **Issue:** Existing subscriber tests failed because generate_and_store_diff made additional DB calls through the shared mock session
- **Fix:** Added patch for generate_and_store_diff in subscriber tests that successfully INSERT (test 1 and test 6)
- **Files modified:** backend/tests/test_config_snapshot_subscriber.py
- **Verification:** All 11 tests pass
- **Committed in:** eb76343 (Task 2 commit)
---
**Total deviations:** 1 auto-fixed (1 bug)
**Impact on plan:** Necessary to maintain test isolation. No scope creep.
## Issues Encountered
None
## User Setup Required
None - no external service configuration required.
## Next Phase Readiness
- Diff generation is active and will produce diffs for every new non-duplicate snapshot
- router_config_diffs table populated with diff_text, line counts, and snapshot references
- Ready for change parser (Phase 6) to parse semantic changes from diff_text
---
*Phase: 05-diff-engine*
*Completed: 2026-03-13*