---
phase: 02-kintsugi-yesterday-priority-queue
plan: 01
subsystem: kintsugi
tags: [kintsugi, signal-file, priority-queue, sidecar-handoff, startup]

# Dependency graph
requires:
  - phase: 01-yesterday-integrity-check-signal-file
    provides: write_yesterday_signal + read_yesterday_signal in yesterday_signal.py
provides:
  - clear_yesterday_signal() for safe signal file deletion
  - _load_yesterday_priority_shards() for signal-to-shard conversion
  - kintsugi_pass() yesterday priority injection with dedup and cleanup
affects: [03-sub-minute-sidecar-startup]

# Tech tracking
tech-stack:
  added: []
  patterns:
    [signal-file-handoff-with-cleanup, priority-queue-injection-before-sort]

key-files:
  created:
    - tests/test_yesterday_priority_queue.py
  modified:
    - python/opendeviationbar/sidecar/yesterday_signal.py
    - python/opendeviationbar/kintsugi/orchestrator.py

key-decisions:
  - "Yesterday shards prepended before sort (not given artificial sort key) -- simplest approach"
  - "Signal cleanup deferred until ALL yesterday shards processed (budget-safe)"
  - "Deduplication by (symbol, threshold) removes normal discovery duplicates"

patterns-established:
  - "Signal file lifecycle: write (sidecar) -> read+expand (kintsugi) -> clear (kintsugi after processing)"
  - "Priority injection: load priority items -> discover normal -> dedup -> merge -> sort"

requirements-completed: [STARTUP-03]

# Metrics
duration: 4m35s
completed: 2026-03-23
---

# Phase 2 Plan 1: Kintsugi Yesterday Priority Queue Summary

**Kintsugi consumes sidecar's yesterday-repair signal file, injects flagged symbols at HEAD of repair queue with dedup, and clears signal after all shards processed**

## Performance

- **Duration:** 4m 35s
- **Started:** 2026-03-23T08:31:07Z
- **Completed:** 2026-03-23T08:35:42Z
- **Tasks:** 2
- **Files modified:** 3

## Accomplishments

- `clear_yesterday_signal()` safely deletes signal file (race-safe via FileNotFoundError catch)
- `_load_yesterday_priority_shards()` reads signal, expands to Shard per (symbol, threshold), checks staleness (>24h), skips unregistered symbols
- `kintsugi_pass()` injects yesterday shards at HEAD, deduplicates against normal discovery, clears signal after all processed, preserves signal when budget exhausted
- 13 new tests (8 unit + 5 integration) covering all behaviors

## Task Commits

Each task was committed atomically:

1. **Task 1: Add clear_yesterday_signal + \_load_yesterday_priority_shards** - `b040880` (feat)
2. **Task 2: Wire priority queue into kintsugi_pass + signal cleanup** - `c084771` (feat)

## Files Created/Modified

- `python/opendeviationbar/sidecar/yesterday_signal.py` - Added clear_yesterday_signal()
- `python/opendeviationbar/kintsugi/orchestrator.py` - Added \_load_yesterday_priority_shards(), wired into kintsugi_pass()
- `tests/test_yesterday_priority_queue.py` - 13 tests for signal consumption, shard creation, queue ordering, cleanup

## Decisions Made

- Yesterday shards are prepended before sort rather than given an artificial sort key -- simpler and the sort naturally orders them by registry priority
- Signal cleanup checks which shards were actually processed (in results) vs which were loaded -- budget exhaustion preserves signal for next pass
- Deduplication uses (symbol, threshold_decimal_bps) tuple matching to remove normal discovery shards that overlap with yesterday priority shards

## Deviations from Plan

### Auto-fixed Issues

**1. [Rule 3 - Blocking] Fixed **import**("datetime") hack for timedelta**

- **Found during:** Task 2 (code review during wiring)
- **Issue:** \_load_yesterday_priority_shards used `__import__("datetime").timedelta` instead of proper import
- **Fix:** Added `timedelta` to the `from datetime import` at module top
- **Files modified:** python/opendeviationbar/kintsugi/orchestrator.py
- **Verification:** All tests pass
- **Committed in:** c084771 (Task 2 commit)

---

**Total deviations:** 1 auto-fixed (1 blocking)
**Impact on plan:** Minor import cleanup. No scope creep.

## Issues Encountered

None

## User Setup Required

None - no external service configuration required.

## Next Phase Readiness

- Signal file lifecycle complete: sidecar writes, kintsugi reads+processes+clears
- Ready for Phase 3 (sub-minute sidecar startup) -- the blocking yesterday repair path can now be replaced with signal file write + immediate proceed
- All success criteria met: SC-03a through SC-03e

## Self-Check: PASSED

- [x] python/opendeviationbar/sidecar/yesterday_signal.py exists
- [x] python/opendeviationbar/kintsugi/orchestrator.py exists
- [x] tests/test_yesterday_priority_queue.py exists
- [x] Commit b040880 exists
- [x] Commit c084771 exists

---

_Phase: 02-kintsugi-yesterday-priority-queue_
_Completed: 2026-03-23_
