Phase 1: dual approval default, web-UI index jobs + merge review queue, thesis v2
- Dual sign-off is now the default (thesis_required_approvals defaults to 2).
- Entity-merge review queue (migration 0003): the fuzzy/Qwen tier no longer
auto-merges — it writes CANDIDATES (entity_merge_candidates) with a same/different
suggestion + confidence + reason for a human to approve (merge) or reject (keep
separate). entity_merge.py applies/rejects (durable via entity_merges, soft-delete,
repoint links+edges); decided pairs aren't re-surfaced.
- entity_jobs.py: UI-triggered background index jobs (rebuild/update/find-duplicates)
as subprocesses with a one-at-a-time lock; status in /api/system/status.
- server.py: /api/index/{rebuild,update}, /api/entities/find-duplicates,
/api/entities/merge-candidates [+ /{id} decide] — admin-gated.
- docs/thesis-seed-v2.md: concrete, plain-English rewrite per Grant's feedback.
Backend verified end-to-end on synthetic data (candidate gen -> approve/reject).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,2 @@
|
||||
DROP TABLE IF EXISTS entity_merge_candidates;
|
||||
DELETE FROM schema_migrations WHERE filename = '0003_entity_merge_review.sql';
|
||||
@@ -0,0 +1,25 @@
|
||||
-- Phase 1 — entity-merge review queue.
|
||||
--
|
||||
-- ADDITIVE/REVERSIBLE. The fuzzy (local-Qwen) tier no longer auto-merges; it
|
||||
-- writes CANDIDATES here for a human to approve (same entity -> merge) or reject
|
||||
-- (different entities -> keep separate), surfaced in the CRM web UI. Approved
|
||||
-- candidates apply the merge and are recorded in entity_merges (durable);
|
||||
-- rejected pairs are remembered so they are not re-surfaced.
|
||||
|
||||
CREATE TABLE IF NOT EXISTS entity_merge_candidates (
|
||||
id TEXT PRIMARY KEY,
|
||||
entity_a TEXT NOT NULL, -- survivor (kept) canonical id
|
||||
entity_b TEXT NOT NULL, -- would be merged INTO entity_a
|
||||
name_a TEXT, name_b TEXT,
|
||||
email_a TEXT, email_b TEXT,
|
||||
context TEXT, -- firm / surname context for the reviewer
|
||||
verdict TEXT, -- 'same' | 'different' (local-Qwen suggestion)
|
||||
confidence REAL,
|
||||
reason TEXT, -- Qwen's reasoning (why it thinks same/different)
|
||||
status TEXT NOT NULL DEFAULT 'pending', -- pending | approved | rejected
|
||||
decided_by TEXT, -- users.id of the partner who decided
|
||||
decided_at TEXT,
|
||||
created_at TEXT DEFAULT (datetime('now')),
|
||||
UNIQUE(entity_a, entity_b)
|
||||
);
|
||||
CREATE INDEX IF NOT EXISTS idx_merge_candidates_status ON entity_merge_candidates(status);
|
||||
Reference in New Issue
Block a user