fix(schemas): backfill gemini catalog identity evidence for schema drift - #3648
Conversation
Problem: live ops.db schema_drift_samples showed 100% of aistudio-drive
records since 2026-07-01 classifying as unseen_shape. The committed
gemini v1/v2 session_document schemas already modeled the real
{chunkedPrompt, runSettings, systemInstruction[, applets, citations]}
wire shape correctly (verified against real cached payloads at
~/.local/share/polylogue/drive-cache/gemini/*.json), but both packages'
elements carried empty exact_structure_ids and profile_tokens lists, so
SchemaRegistry.resolve_payload could never find a real-candidate match
(exact_structure/bundle_scope/profile_family) and always fell back to
package_default, which classify_schema_drift reports as unseen_shape.
Solution: ran the real schema-generation pipeline
(_build_provider_bundle/_collect_cluster_accumulators) against a
structurally faithful synthetic gemini corpus built from the existing
CorpusSpec/SyntheticCorpus/parse_sources_archive test infrastructure, to
compute genuine exact_structure_ids and profile_tokens for this shape.
Spliced only those two identity fields into the existing committed v1
and v2 schema documents via SchemaRegistry.write_schema_version (the
real production write path), leaving all existing schema structure,
sample_count/artifact_count provenance, and other x-polylogue-*
annotations untouched. v1's schema also had a stale
$id/x-polylogue-element-kind ("conversation_document") inconsistent
with its own catalog manifest ("session_document"); write_schema_version
corrected this as a side effect of the real write path.
profile_tokens is the durable fix: profile_family matching tolerates
new/missing optional fields via profile_similarity, so it keeps
resolving future real traffic even as message content and optional
attachment fields vary. exact_structure_ids is a bonus fast-path that
will only hit incidentally, since it fingerprints full document
structure recursively.
Verification:
- devtools test tests/unit/schemas/test_gemini_catalog_identity.py -- 4 passed;
confirmed red (all 4 fail with package_default/unseen_shape) against the
pre-fix committed schema via git stash, green after.
- devtools test tests/unit/schemas/ tests/integration/test_schema_operator_workflow.py -- 104 passed
- devtools test tests/unit/sources/test_gemini_drive_normalization_laws.py -- 9 passed
- devtools verify --quick -- 22/22 steps passed (status: success), no
"out of sync" in render-all output.
Ref polylogue-tu1f
Co-Authored-By: Claude <noreply@anthropic.com>
|
Warning Review limit reached
Next review available in: 8 minutes You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository. How can I continue?After more reviews become available, a review can be triggered using the To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews. How do review limits work?CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability. For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window. Please refer docs for additional details. Review details⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: ASSERTIVE Plan: Pro Plus Run ID: ⛔ Files ignored due to path filters (2)
📒 Files selected for processing (4)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
…shots - status.py: PR #3649's new Polylogue facade method reconcile_codex_spawn_edges was undiscovered in the archive-facade route catalog (registration-trap class, per this repo's own convention). - Snapshot refresh: SOURCE_SCHEMA_VERSION 22->24 (today's byte-dup supersession + verdict-cache migrations); aistudio-drive schema drift warning gone (tu1f's gemini catalog identity backfill, PR #3648, genuinely resolved it). - test_prepare.py: PR #3514 (pre-existing, not today) swept ref-less attachments rows outright instead of leaving ref_count=0 rows behind -- test still expected the old retained-row behavior. Co-Authored-By: Claude <noreply@anthropic.com>
Summary
Backfills real
exact_structure_ids/profile_tokensidentity evidence onto the committed gemini v1/v2session_documentschema packages, so live aistudio-drive ingest stops classifying every record asunseen_shapeschema drift.Problem
Live
ops.dbschema_drift_samplesshowed 100% of 302aistudio-driverecords ingested since 2026-07-01 classifying asunseen_shape(element_kind=session_document). Inspecting real cached payloads at~/.local/share/polylogue/drive-cache/gemini/*.jsonconfirmed the actual wire shape is a bare{chunkedPrompt, runSettings, systemInstruction}document (occasionally with top-levelapplets/citations), with noid/title/createTime—drive.py's parser already handles this correctly via fallback logic, so parsing itself was never affected.The committed gemini schema catalog (
polylogue/schemas/providers/gemini/{v1,v2}) already modeled this exact shape structurally (verified by decompressing and diffing the committedsession_document.schema.json.gzfiles against the real cached payloads — same top-level properties, samerunSettings/chunkedPrompt.chunkssubstructure). The actual defect was one level deeper: both packages'session_documentelement carried emptyexact_structure_idsandprofile_tokenslists incatalog.json/package.json/the schema's ownx-polylogue-*annotations.SchemaRegistry.resolve_payload(polylogue/schemas/runtime_registry.py) only escapes itspackage_defaultfallback (whichclassify_schema_driftreports asunseen_shape) via anexact_structure,bundle_scope, orprofile_familymatch — with both identity lists empty, no live payload could ever match, regardless of how well the schema'spropertiesactually described reality.Solution
Ran the real schema-generation pipeline (
polylogue.schemas.generation.workflow._build_provider_bundle/_collect_cluster_accumulators) against a structurally faithful synthetic gemini corpus, built with the repo's ownCorpusSpec.for_provider("gemini", ...)+SyntheticCorpus.write_spec_artifacts+parse_sources_archivetest infrastructure (the same real ingestion pathtests/infra/workload_artifacts.py'sbuild_seeded_archiveuses) — no real/private conversation content anywhere in this corpus. This produced genuinely-computedexact_structure_ids(structural fingerprint hashes) andprofile_tokens(coarser shape tokens likefield:chunkedPrompt,child:runSettings:model) for the shape.Rather than running the full destructive
commit_provider_schema/generate_all_schemasreplace-all pipeline (which deletes and rewrites the entireversions/tree from only the versions the fresh generation run produces — here just one version, which would have silently destroyed the existing, richer v2 package), I spliced just the two missing identity fields into the existing v1 and v2 schema documents viaSchemaRegistry.write_schema_version(the real production single-version write path), leaving all existing schema structure,sample_count/artifact_countprovenance, and otherx-polylogue-*annotations untouched. Diffed the decompressed schema documents before/after to confirmpropertiesis byte-identical; only the two new identity fields and ax-polylogue-registered-attimestamp bump changed. v1 additionally had a stale$id/x-polylogue-element-kindofconversation_document, inconsistent with its own catalog manifest'ssession_document—write_schema_versioncorrected this as a side effect of using the real write path.profile_tokensis the durable part of the fix:profile_familymatching (profile_similarity) tolerates new/missing optional fields, so it keeps resolving future real traffic even as message content and optional attachment fields (driveDocument,driveVideo, etc.) vary.exact_structure_idsis a bonus fast-path that will only hit incidentally, since it fingerprints the full document structure recursively and real conversations vary too much for exact hash reuse.Added
tests/unit/schemas/test_gemini_catalog_identity.py, which exercises the default (bundled, nostorage_rootoverride)SchemaRegistry— the same onepolylogue.pipeline.services.ingest_worker._runtime_schema_registry()resolves payloads through in production — against payloads shaped like the real cached exports, with message content that never appeared in any fixture/corpus, proving the match generalizes via profile-family evidence rather than exact-content coincidence.Verification
devtools test tests/unit/schemas/test_gemini_catalog_identity.py— 4 passed. Confirmed red-before viagit stash(all 4 fail withpackage_default/unseen_shapeagainst the pre-fix committed schema), green after popping the stash.devtools test tests/unit/schemas/ tests/integration/test_schema_operator_workflow.py— 104 passed.devtools test tests/unit/sources/test_gemini_drive_normalization_laws.py— 9 passed (existing gemini/drive normalization coverage unaffected).python3 -m devtools lab schema audit --provider gemini— 4 pass, 1 warn (pre-existingschema_stalenesswarning based onx-polylogue-generated-at, untouched by this change), 0 fail.devtools verify --quick— 22/22 steps passed (exit_code: 0), noout of syncinrender alloutput.Not run: a live end-to-end check against production
ops.db— no write access to the live archive from this lane. The schema-catalog classification function itself is exercised directly instead (see test file), which is the mechanism the bead's own scope asked to fix.Ref polylogue-tu1f