Why:
- The helper turning a SeedSpec into an upsertable ChunkPoint lived inside one
integration test. A second suite now needs to seed real Qdrant the same way,
and a copy would let the two drift.
Changes:
- Move `_chunk_point` into tests/support/point_contract.py as `chunk_point_for`,
beside the `build_point` read model it derives its payload from.
Impact:
- Pure move. No behaviour change; enables the API suite that follows.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Why:
- Two parallel test files let a fake drift more permissive than the store it
stands in for, so unit tests stay green while production diverges. Plan 002
Phase 1's exit criterion is precisely that the two agree.
Changes:
- One scenario suite in tests/support/point_contract.py, run against
FakePointRepository (unit) and QdrantPointRepository (integration). A
divergence fails one of the two runs rather than hiding.
- The fake models the behaviours services branch on: the implied is_active read
filter, value-based cursor pagination, and a stale version guard that matches
nothing rather than raising -- the no-op Qdrant's filtered set_payload actually
has, and the reason a service must read back to know its write landed.
- Patched points are re-validated rather than model_copy'd, so the fake holds a
datetime where a read from real Qdrant returns one.
- The seeded corpus gives each tenant its own file: point IDs derive from
file_id plus chunk_index alone, so two tenants in one file would collide on a
single ID and the fixture would assert an impossible state.
Impact:
- 15 scenarios pass against both implementations.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>