Skip to content

Add reviewable person identities that survive re-indexing (#85) - #149

Open
ik020 wants to merge 2 commits into
grayhatdevelopers:mainfrom
ik020:feature/reviewable-people
Open

Add reviewable person identities that survive re-indexing (#85)#149
ik020 wants to merge 2 commits into
grayhatdevelopers:mainfrom
ik020:feature/reviewable-people

Conversation

@ik020

@ik020 ik020 commented Sep 5, 2026

Copy link
Copy Markdown

Closes #85

What this does

Adds a repository-level "reviewed person" identity that is independent of
any single index generation. A PersonRecord is a durable, user-approved
identity; a PersonClusterLink is evidence tying that person to a specific
anonymous actor cluster produced by one media item + one index generation.

This is the core guarantee the issue asked for: when a video is re-indexed
and produces a brand-new anonymous cluster ID under a new generation ID,
the person, their aliases, and their reference images all survive untouched,
and lookup by the new cluster still resolves to the same person.

What's included

  • Domain models (core/people.py, core/identifiers.py): PersonRecord,
    PersonAlias, PersonReference, PersonClusterLink, plus PersonId /
    PersonReferenceId.
  • Schema: people, person_aliases, person_references,
    person_cluster_links tables, registered in local_catalog.py. Schema
    version bumped 4 → 5.
  • CRUD (infrastructure/sql_catalog.py): put/get/list/delete for people,
    add/remove/list for aliases and reference images, link/unlink/query for
    cluster links.
  • Alembic migration (20260803_01_reviewed_people.py): brings an
    existing SQLite catalog or a PostgreSQL deployment up to the same schema,
    for anyone not creating a catalog fresh via LocalCatalog.create_all().
    Verified column-for-column against the actual read/write code in
    sql_catalog.py before merging, not just against the table CREATE
    statements.
  • Tests (tests/test_people_catalog.py, 12 cases), including:
    • test_cluster_links_survive_reindexing_with_a_new_generation — the
      scenario from the issue: link a person to a cluster, re-index (new
      generation, new cluster ID), confirm the person and old link survive,
      confirm the new link resolves correctly.
    • test_deleting_a_person_cascades_aliases_references_and_links_only
      confirms removing a person cleans up only their own aliases/references/
      links, and never touches the underlying video/media/index data.
    • test_unlink_cluster_corrects_an_accidental_merge_without_touching_media
      — confirms a bad cluster link can be corrected without side effects.
  • Updated tests/test_database_cli.py and tests/test_media_catalog.py,
    which hardcoded the previous migration head and schema version.
  • Fixed database_cli.py: upgrade_database() previously assumed its
    target directory already existed and failed with unable to open database file on a fresh environment. It now calls
    settings.layout.ensure_local_directories() first.

Verification

  • pytest tests/test_people_catalog.py tests/test_database_cli.py tests/test_media_catalog.py — all green.
  • Applied 20260803_01 end-to-end against a real local SQLite catalog
    (not just an in-memory test DB) and confirmed the resulting tables and
    alembic_version by inspection.
  • Full pytest suite run for regressions outside the touched area: the
    only failures are pre-existing, unrelated missing optional dependencies
    in this dev environment (chromadb, uvicorn, PIL, av, mcp,
    fastapi, streamlit, srt, cryptography) — confirmed by reproducing
    the same failures with this branch's changes stashed out.

Not yet verified - needs reviewer follow-up

This PR was validated entirely against the local SQLite path
(ApplicationMode.local). The PostgreSQL / ApplicationMode.server
path has not been exercised
- I don't have network access to the
bundled Postgres service from this environment. Someone with access to
that deployment should run the migration there and confirm it applies
cleanly before this is considered fully verified end-to-end.

- PersonRecord/PersonAlias/PersonReference/PersonClusterLink domain models
- CRUD layer in sql_catalog.py, schema version bumped to 5
- Alembic migration 20260803_01 for existing/Postgres catalogs
- Regression tests covering reindex-survival and non-destructive delete
- Update test_database_cli.py and test_media_catalog.py for new head/schema version
- Fix database_cli.py to ensure local directories exist before migrating
Fresh environments hit 'unable to open database file' because
upgrade_database() assumes the target directory tree already exists.
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 reviewable person identities and labels

1 participant