Skip to content

docs(c-01): measure what a deferred title does to FTS rank and ordering - #1704

Open
arkash20 wants to merge 1 commit into
mainfrom
docs/c01-title-fts-rank-movement
Open

arkash20 wants to merge 1 commit into
mainfrom
docs/c01-title-fts-rank-movement

Conversation

@arkash20

Copy link
Copy Markdown
Contributor

The row

pm-0918-c-01 (CRITICAL) argues PersonaMem's 85.4% record (8-10 Sep) was measured against a store that had not finished enriching, so it was never a reproducible baseline. Claimed mechanism: migration 034_memories_search_vector_title_weighting puts title into the FTS search_vector at content's weight and widens the trigger to UPDATE OF content, title, so a deferred-enrichment title rebuilds that row's vector after the row is already searchable — by a non-uniform amount, reordering neighbours.

The row's own decisive test needs prod read access. This PR tests the mechanism offline, read-only, at zero cost: no prod, no seed, no LLM call, no write to the shared local databases.

Verdict

claim verdict
034 puts title in the tsvector at content's weight true
a title-only UPDATE rebuilds search_vector true, demonstrated against Postgres
the rebuild is non-uniform across rows true — 188 distinct ratios among 411 moved rows
non-uniform ⇒ neighbours reorder true but not automatic (counterexample in the doc)
enrichment is deferred, titles land after the rows exist true — 27,794 local rows did exactly that
therefore the 8-10 Sep run scored a moving store untested — no local population reproduces that trajectory

Mechanism: SOUND. Cause of the 85.4%: still open, and this corpus cannot close it.

Numbers

Temp-table probe borrowing the real trigger function, content never touched:

state row 1 row 2
no title 0.033333 0.025000
echoing title 0.091667 (x2.75) 0.083333 (x3.33)
non-echoing title 0.033333 (x1.00)

Tenant dev-9ff0ca, 8,850 rows, 100% titled, 40 two-term queries per set:

content-derived title-derived
rows matching before → after 6,042 → 6,233 1,667 → 2,019
rank unchanged 93.2% 83.9%
top-K agreement (K = min(50, pool)) 0.970 0.921
top-10 agreement 0.921 0.779
Kendall tau-b 0.943 0.883
top-1 result changed 9 / 33 12 / 24

Reproduced on a disjoint query set (--seed c01-seedB): aggregate agreement stable to ~0.02; the top-1 rate is not (4/26 vs 9/33), so the doc reports 15-27%, not 27%.

Dose-response in title coveragedefault at 6.6% coverage shows zero movement of any kind; dev-9ff0ca at 100% shows the churn above. A store draining its enrichment backlog travels that curve with no deploy to blame.

Two corrections to the row

  • "Non-uniform therefore reorders" is not automatic. On default, the title-derived set moved every matched row (592/592, ratios 2.17-3.67) and reordered nothing — tau 1.000, top-1 unchanged on all 6 queries. They moved together, past nobody. Spread is necessary, not sufficient.
  • The decisive test is unrunnable as written. It asks for the gap between created_at and when the title was written; memories has no updated_at and no migration ever adds one. The doc gives the audit_log substitute (create-detail records the title at insert), which answers the count and the direction but still not the timestamp — so it cannot say whether titles landed before or after 10 Sep.

Stated limits

No PersonaMem data here (no %amb%/%persona% tenant; newest local row 2026-09-08). Neither measured tenant traverses bulk-write → deferred → fully-enriched: dev-9ff0ca is the destination without the transition (titled at insert), default is an early state that stalled. And the sign is unknown — 034 exists because content-only FTS could not find title-distinguished rows, so a finished store could plausibly score higher.

The search-path bisect the row lists as its fallback should not be cancelled on the strength of this document.

Changes

  • docs/fts-title-weighting/c01-title-rank-movement-findings.md — findings
  • benchmark/c01_title_fts_rank_movement.py — re-runnable measurement; read-only apart from a rolled-back ON COMMIT DROP temp table

No product code touched. ruff check and ruff format --check clean.

🤖 Generated with Claude Code

@arkash20
arkash20 requested a review from a team as a code owner September 23, 2026 11:40
@github-actions

Copy link
Copy Markdown
Contributor

Claude Code Review — skipped: PR author 'arkash20' is not a public member of the 'caura-ai' org

pm-0918-c-01 claims PersonaMem's 85.4% was scored against a store still
enriching: migration 034 put `title` in `memories.search_vector` and widened
the trigger to `UPDATE OF content, title`, so a deferred enrichment title
rebuilds that row's vector after it is already searchable and reorders it
against its neighbours.

Verified in code, then measured offline on the existing local corpus,
read-only: no prod access, no seed, no LLM call, no write to the shared DBs.

The mechanism is sound. The trigger fires on a title-only UPDATE and moves
different rows by different factors (x1.00 / x2.75 / x3.33 on a temp-table
probe borrowing the real trigger function). On a fully-titled tenant, 93% of
scored rows do not move, but top-10 agreement falls to 0.92, Kendall tau-b to
0.94, and the top-1 answer changes on 15-27% of queries. The effect scales with
title coverage: at 6.6% coverage it is exactly zero.

Two things the row gets wrong or cannot have:

- "Non-uniform therefore reorders" is not automatic. On `default`, every matched
  row moved (x2.17-x3.67) and nothing reordered at all - tau 1.000. The spread
  has to interleave, and the doc reports the counterexample.
- The row's decisive test asks for the gap between `created_at` and when the
  title was written. `memories` has no `updated_at` and no migration ever adds
  one, so that test is unrunnable even with the prod access it is blocked on.
  The doc gives the `audit_log` substitute, which answers the count and the
  direction but still not the timestamp.

What this corpus cannot do is say the mechanism explains 85.4%: it holds no
PersonaMem data, and neither measured tenant traverses the bulk-write ->
deferred -> fully-enriched path. Stated in the doc, along with the fact that
the sign is unknown - a finished store could score higher.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

Signed-off-by: Arkady Mankovsky <arkash20@gmail.com>
@arkash20
arkash20 force-pushed the docs/c01-title-fts-rank-movement branch from b71d08f to 433263f Compare September 23, 2026 11:51
@github-actions

Copy link
Copy Markdown
Contributor

Claude Code Review — skipped: PR author 'arkash20' is not a public member of the 'caura-ai' org

This branch has not been deployed

No deployments
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.

1 participant