Skip to content

A role word speaks while its chunk is live, so a re-push that changes a value reads back only the new one - #1450

Open
gedaiu wants to merge 2 commits into
deeplethe:devfrom
re-cinq:feat/role-words-speak-while-live
Open

gedaiu wants to merge 2 commits into
deeplethe:devfrom
re-cinq:feat/role-words-speak-while-live

Conversation

@gedaiu

@gedaiu gedaiu commented Oct 26, 2026

Copy link
Copy Markdown
Contributor

Part of #1267, PR 2 of 3, stacked on #1428 (only the last commit is new).

This builds decisions 2 and 3 of ADR 0070. Role words are now read through one predicate, record_axis::role_word_speaks_at, which sits next to chunk_live_at. A row speaks when its chunk and that chunk's document are live at the read's as_of. When a fact has no live evidence at all, the rows on the evidence chunks that were superseded last speak instead, as of as_of. A deleted document's chunks are dated by deleted_at, and chunks superseded at the same moment all count. With no as_of, the predicate uses the single-branch forms that the module header asks for. The only reader, graph::statement_qualifiers_for, now takes as_of, and edges_among and entity_detail pass theirs, so the entity panel, graph edges and MCP entity_facts all follow it. As agreed, live rows are not ordered against each other, so two live chunks that disagree both speak.

The read shape grows by one field. Each statement_qualifiers entry keeps role, value, entity_id and entity_name and adds chunk_ids, the chunks that say that value. Two live values come back as two entries, each with its own chunk. StatementQualifier, web/src/api.ts and the MCP docs describe the new field. Typed rows read through the same rule. Since #1428 a typed row's role word sits only on the chunk of the statement that said it, so the typed row speaks when that chunk does. Until PR 3 re-syncs materialize, a typed row whose source was re-pushed still holds the old chunk. It shows the old value while it has no live evidence, and the role drops if its only live evidence comes from a source that never said it.

Tests: six small store tests in an_open_statement_keeps_the_documents_words.rs. They cover a superseded chunk going quiet once a live chunk gives a new value, two live chunks that disagree, a role the live chunk drops, a stale statement showing its last-superseded chunk, a deleted document dated by deleted_at, and an as_of read between two pushes through entity_detail. There is also an end-to-end test in sources_statements_tests.rs for the ADR's own example: a re-push that moves lines from 40-52 to 58-70 reads back only 58-70. The read tests from #1428 only gain chunk_ids. Thanks for taking a look!

…can say something new

Signed-off-by: Bogdan Szabo <bogdan@re-cinq.com>
… a value reads back only the new one

Signed-off-by: Bogdan Szabo <bogdan@re-cinq.com>

@WaylandYang WaylandYang left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, the fragment reads well and the fallback follows the agreed rule, including deleted_at and the as_of limit. Three things: (1) the three mood checks in materialize.rs still accept any row, so a re-push that drops mood shows no mood but still holds the typed row back. Please wire them through role_word_speaks_at("q", None) here, or note in the description and the 0070 status line that they move to PR 3. (2) Please add a restore test (clear deleted_at, the live chunk speaks again) and an as_of read of a stale statement where the latest chunk didn't exist yet. (3) The fallback subqueries run once per superseded row, so a statement re-pushed hundreds of times may get slow. Could you EXPLAIN ANALYZE one with about 200 pushes, and compute live evidence and the latest end once per fact if it shows? I'll merge this after #1428; it needs update-branch then.

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.

2 participants