Skip to content

Add cross-image identity/likeness scorer (generation vs locked reference) - #3

Merged
thorwhalen merged 1 commit into
mainfrom
claude/identity-likeness-scorer
Jun 25, 2026
Merged

thorwhalen merged 1 commit into
mainfrom
claude/identity-likeness-scorer

Conversation

@thorwhalen

Copy link
Copy Markdown
Collaborator

Adds a cross-image identity-similarity scorer reusing lookbook's existing ArcFace embedder:

lookbook.compare_to_reference(reference, candidate, *, threshold=0.85, aggregation="max", ...) -> SimilarityResult
# .score ∈ [0,1] (1 = same identity), .passed, .identity_cosine, .per_reference

Registered as the identity_similarity scorer; also surfaced over HTTP + MCP as compare_to_reference. The measurement substrate for reelee's reference supervisor (Noel's explicit ask). Part of epic thorwhalen/reelee-web#151.

The embedder is injectable (DI) so importing pulls in no torch/insightface; the cosine→[0,1] math, set-aggregation (reference may be one image or a pool), and threshold pass/fail are unit-tested offline. 28 new tests (+1 model-gated smoke); full suite 140 passed, 4 skipped — no regressions.

The reelee-side refactor of continuity.character_drift to reuse this is flagged as a follow-up, not in this PR.

Closes #2

https://claude.ai/code/session_01VpuLiVm21Wf3F3NUSveVwV

…nce)

Adds `IdentitySimilarity` scorer + `compare_to_reference` facade in
`lookbook/scorers/identity.py` — the measurement substrate for reelee's
reference supervisor. Compares a candidate against a locked reference (or
pool) by cosine over an injectable embedder, normalized to [0,1].

- Reuses existing embedders unchanged (arcface default; clip/dinov2 via the
  `embedder=` seam for non-face subjects). Embedder is injectable (name,
  object, or bare callable) so importing the module needs no heavy deps and
  the math is unit-testable with a fake embedder.
- Reference embedded ONCE at construction and cached; candidates never
  re-embed the reference.
- Set aggregation over a reference pool: max (default, "matches any locked
  view") | mean | min. Advisory `passed` flag against a defaulted threshold
  (0.85) — never hard-blocks; the consumer decides.
- Registered as scorer `identity_similarity`; facade `compare_to_reference`
  + `SimilarityResult` exported from `lookbook`. Surfaced over HTTP and MCP
  as `compare_to_reference` so reelee can call it as a sidecar.
- 28 offline tests (cosine math, normalization, aggregation, threshold gate,
  reference-caching, config_hash, JSON-ability) + 1 gated ArcFace smoke test.

Follow-up (not done here, deliberately): reelee's
transforms/continuity/character_drift.py hand-rolls CV face distance and
should be refactored to call this — flagged, not touched, to avoid breaking
its tests.

Closes #2
@thorwhalen
thorwhalen merged commit 328d54d into main Jun 25, 2026
12 checks passed
@thorwhalen
thorwhalen deleted the claude/identity-likeness-scorer branch July 30, 2026 16:53
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add a cross-image identity/likeness scorer (generation vs locked reference)

1 participant