# redmine contacts + project-standardization plan Scope: standardize this repository around the shared `PROJECT.md` workflow and improve `redmine_contacts.py` so contact review/update work can be done in controlled batches with less API/UI friction. Target stopping point for this phase: deliver tested CLI upgrades for filtering/show/update ergonomics, plus research documentation for duplicate-contact merge feasibility. ## Checklist ### Contact tooling foundation - [x] Apply shared project template to `/home/jason/projects/redmine/PROJECT.md` with redmine-specific rules. - [x] Create continuity docs (`PLAN.md`, `HANDOFF.md`) for ongoing milestone handoff. - [x] Add tests for new `redmine_contacts.py` contact-filter + tag/custom-field patch behavior. - [x] Implement date/tag contact filtering utilities used by `fetch` and `search`. - [x] Add `show` command with cache/api source control. - [x] Add `issue-full` command that composes full Redmine issue data with helpdesk ticket/messages. - [x] Add `update` enhancements: - [x] `--add-tag` - [x] `--remove-tag` - [x] `--set-custom-field =` - [x] Verify new unit tests pass and script compiles. - [x] Document duplicate-contact merge feasibility (API support vs scripted browser-equivalent merge path). - [x] Add config-vault project index entry for redmine workstream. - [x] Decide and implement default fetch cache behavior: `fetch` now caches full fetched contacts by default; `--cache-mode filtered` opt-in stores only filtered subset. - [x] Add live integration validation against LAN Redmine copy (`192.168.50.170`) for new commands requiring API responses. - [x] Add dry-run-first `batch-update` command for "N contacts matching filters" workflows. - [x] Add controlled ordering options for batch runs (`--order` including oldest-updated-first) to support systematic sweep-through campaigns. - [x] Expand argparse `--help` output with clearer descriptions/option help across commands. - [x] Add Bash completion script: `/home/jason/projects/redmine/redmine_contacts_completion.sh`. - [x] Capture the broader contact triage loop workflow in project docs (including scoring concept + diagram). - [x] Make `fetch` intuitive: with filters and default `--cache-mode auto`, cache filtered results by default (override with `--cache-mode full`). - [x] Implement Phase 1 contact loop tracer: per-contact evidence pull (3-5 recent tickets/messages) + scoring output in dry-run mode. ### Ticket-centric spam cleanup substrate - [x] Plan ticket-centric sync/search/action architecture in `docs/ticket_sync_tool_plan.md`. - [x] Implement `redmine_tickets.py` incremental sync using standard Redmine issue API with `include=journals,helpdesk`. - [x] Implement per-ticket JSON cache plus state-store abstraction (`ManifestTicketStateStore` now, SQLite-capable seam later). - [x] Implement cached `search` command. - [x] Implement idempotent `spam-check` action. - [x] Implement dry-run-first `close-if-spam` action with recent sender/contact lookback. - [x] Ensure Redmine write calls can impersonate users via `X-Redmine-Switch-User`. - [x] Default spam cleanup writes to `--impersonate-user rebot` (Harry Botter), while reads/dry-runs do not impersonate. - [x] Verify LAN dry-run against `192.168.50.170` / `customer-service`: `#41788` and `#41789` flagged and closure-planned. - [x] Document complete handoff in `docs/ticket_spam_cleanup_handoff_2026-07-09.md`. - [ ] Confirm LAN issue `status_id=5` is the desired closed status. - [ ] Run `close-if-spam --apply` on LAN for the currently planned spam tickets only. - [ ] Re-sync/inspect LAN tickets to verify status closed, activity author `rebot`, and second apply is idempotent. - [ ] After LAN apply verification, expand cache/sync batch size beyond the first 10 tickets.