Repository navigation
[stacked on #207] Write events as prose with the envelope in labels; let items opt out of derivation - #208
Conversation
…udget beliefs - Recall builds the chosen scope's pack again when /v1/answer answers 404 for use_pack_id, up to three answers. CortexDB 0.10.4 drops every pack it holds on any successful forget, even in another scope, so a concurrent forget made recall fail (CortexDB live at 9d40d5d). - get and list return a chunked document whole only when every piece agrees on one positive count, each index is below it, and all are present; an unchunked envelope of the same id is the whole body and wins over pieces. - The beliefs read sends max_tokens for each belief it asks for. - The live long-document test is two pieces, so its forget stays inside the request timeout, and after forget it polls fetch until no piece of the item is left. - The spec states the chunking threshold on the envelope as a piece.
- A 404 for use_pack_id now repeats the whole round: every scope's pack is built again and the answer asked from the new chosen pack, so the citations also come from packs read after the drop and cannot cite an item forgotten in between. At most three rounds. - docs/architecture/cortex-wire.md was over the 500-line limit; its "Chunked documents" section is now docs/architecture/cortex-chunks.md.
|
Warning Review limit reached
This review includes 26 billable files and costs up to $6.50. Or wait 58 minutes for your next included review. View limit detailsLimit details: You’ve used the included review currently available. Review configuration: ⚙️ Run configuration
📒 Files selected for processing (26)
Comment |
Tiny Sweeper reviewTiny Sweeper completed its review; deterministic results follow. State: Ready for maintainer review Review snapshot
Completeness: Complete What changedThe CortexDB event layout changes from v2 (the whole envelope as JSON in content.text) to v3: an event's content.text is the item's own text, and the rest of the envelope rides in numbered tm:e:<NN>: labels of at most 240 bytes each, beside readable kind:/file:/page:/section: labels (crates/tinymemory-integrations/src/cortex/envelope/mod.rs#impl Envelope {). Events with empty text, or whose labels would exceed 64, fall back to v2, and decode_event reads both layouts (crates/tinymemory-integrations/src/cortex/envelope/rebuild.rs#pub(crate) fn decode_event(event: &Value) -> Option<Decoded> {). A new public MemoryMeta.derive field lets items opt out of derivation; opted-out items and tool turns are written with directives.extract: [] (crates/tinymemory-api/src/meta/mod.rs#pub struct MemoryMeta {). Recall retries up to three rounds when the answer route 404s because CortexDB dropped its packs, with the round factored into answer_round and pack_id_of (crates/tinymemory-integrations/src/cortex/engine/recall.rs#impl CortexEngine {). rebuild_whole now rejects chunked documents whose pieces disagree on count or index and accepts a whole-body envelope mixed with pieces (crates/tinymemory-integrations/src/cortex/envelope/rebuild.rs#pub(crate) fn rebuild_whole(envelopes: &[Envelope]) -> Option<StoreItem> {). Replay detection matches events by text and labels together, since two v3 turns can share the same words (crates/tinymemory-integrations/src/cortex/log/write.rs#impl Log {). Belief reads set budgets.max_tokens from the beliefs limit (crates/tinymemory-integrations/src/cortex/engine/beliefs.rs#impl CortexEngine {). The testing double gains an expire_packs counter and its pack events no longer carry a role-marker prefix (crates/tinymemory-integrations/src/cortex/testing/routes.rs#async fn answer(, crates/tinymemory-integrations/src/cortex/testing/log.rs#impl CortexLog {). The live long-document test defaults to 12 pages with an opt-in for longer runs and adds a ranked-recall check that no piece outlives forget (crates/tinymemory-integrations/tests/live_cortexdb.rs#async fn a_long_document_round_trips_in_pieces() {). Chunked-document guidance moves to a new docs/architecture/cortex-chunks.md, and the wire/flows/spec/README pages describe v3, the fallback, the derive opt-out and the pack retry. Features
Tests
Findings
Resolved this pass
Before mergeNone. Agent review detailscritique
security
tests
commits
description
e2e
Evidence and run details
|
There was a problem hiding this comment.
Requesting changes: 2 lane(s) blocking, worst finding is critical.
Fix or reply to the findings below and push. The next review clears this automatically once they are gone — you should not need to dismiss anything by hand.
$0.0128 · 878,749 in / 45,091 out · 77,493 cached (9%) · gpt-5.6-luna, glm-5.3-flash
critique: $0.0058 · 451,698 in / 27,316 out · 48,859 cached (11%) · gpt-5.6-luna, glm-5.3-flash
security: $0.0035 · 283,338 in / 13,072 out · 28,634 cached (10%) · gpt-5.6-luna
tests: $0.0005 · 55,463 in / 786 out · 0 cached (0%) · glm-5.3-flash
description: $0.0003 · 28,421 in / 369 out · 0 cached (0%) · glm-5.3-flash
e2e: $0.0003 · 30,307 in / 399 out · 0 cached (0%) · glm-5.3-flash
There was a problem hiding this comment.
Requesting changes: 1 lane(s) blocking, worst finding is high.
Fix or reply to the findings below and push. The next review clears this automatically once they are gone — you should not need to dismiss anything by hand.
$0.0008 · 130,561 in / 7,775 out · 2,033 cached (2%) · gpt-5.6-luna, glm-5.3-flash
critique: $0.0001 · 13,621 in / 1,285 out · 2,033 cached (15%) · gpt-5.6-luna, glm-5.3-flash
tests: $0.0001 · 28,030 in / 2,854 out · 0 cached (0%) · glm-5.3-flash
description: $0.0003 · 28,833 in / 76 out · 0 cached (0%) · glm-5.3-flash
e2e: $0.0003 · 30,719 in / 75 out · 0 cached (0%) · glm-5.3-flash
There was a problem hiding this comment.
Requesting changes: 2 lane(s) blocking, worst finding is high.
Fix or reply to the findings below and push. The next review clears this automatically once they are gone — you should not need to dismiss anything by hand.
$0.0037 · 250,466 in / 10,850 out · 11,460 cached (5%) · gpt-5.6-luna, glm-5.3-flash
critique: $0.0018 · 63,969 in / 4,549 out · 6,096 cached (10%) · gpt-5.6-luna, glm-5.3-flash
security: $0.0004 · 34,738 in / 1,914 out · 5,364 cached (15%) · gpt-5.6-luna
tests: $0.0006 · 60,045 in / 606 out · 0 cached (0%) · glm-5.3-flash
description: $0.0003 · 29,150 in / 229 out · 0 cached (0%) · glm-5.3-flash
e2e: $0.0003 · 31,036 in / 1,026 out · 0 cached (0%) · glm-5.3-flash
Run together, one live test's forgets drop the packs another is about to answer from, and load the server enough that forgetting a ~700 KiB document (seconds per ~240 KiB event on CortexDB 0.10.4) outlasted the request timeout. Each live test now holds one async lock for its run, and the long document is back to 24 pages (three pieces, two boundaries).
…of derivation CortexDB extracts from an event's text and splits it for search at sentence boundaries, which a JSON text lacks, and counts that text toward its 1 MiB limit; labels are its app-metadata extension point. So events are now written as v3: - content.text is the item's own text: the body or piece, the turn's text, or the learning's statement; - context.labels hold the lookup labels, readable kind:/file:/page:/ section: labels (at most 256 bytes each, never lang:), and the rest of the envelope as compact JSON in tm:e:<NN>: parts of at most 240 bytes. An event with empty text, or whose labels would pass 64, is written as v2 (the whole envelope as JSON text) as every event was before. Readers take both, so existing stores need no rewrite. A recovered hosted write is matched on its labels as well as its text, since two v3 turns can say the same words. MemoryMeta gains derive: Option<bool>. Some(false) stores and indexes an item but asks CortexDB to derive nothing from it (directives.extract: []); every tool turn is sent the same way. Unset, it is not serialized, so fingerprints are unchanged. The test double's recall no longer prefixes a pack event's text with [role]: CortexDB 0.10.3 and 0.10.4 return the stored text there.
07f499a to
06f2763
Compare
There was a problem hiding this comment.
The previously-blocking findings are resolved. Clearing the changes request.
$0.0020 · 226,149 in / 15,381 out · 11,696 cached (5%) · gpt-5.6-luna, glm-5.3-flash
critique: $0.0011 · 86,210 in / 8,340 out · 8,118 cached (9%) · gpt-5.6-luna, glm-5.3-flash
security: $0.0003 · 18,335 in / 2,190 out · 3,578 cached (20%) · gpt-5.6-luna
tests: $0.0001 · 28,680 in / 1,548 out · 0 cached (0%) · glm-5.3-flash
description: $0.0001 · 29,490 in / 531 out · 0 cached (0%) · glm-5.3-flash
e2e: $0.0003 · 31,369 in / 259 out · 0 cached (0%) · glm-5.3-flash
[stacked on #208] Key each event by its own body; skip the lookup on the turn hot path
Summary
Events are now written as prose with the envelope in labels (v3), and an item can opt out of derivation.
Until now each CortexDB event's
content.textwas the whole JSON envelope: id, kind, full metadata and the item's text. The CortexDB team advises against that. JSON counts in full toward the 1 MiB limit, it extracts worse than plain sentences, and the ~500-byte search split happens at sentence boundaries, which JSON lacks. Their advice is the memory as natural-language text, with IDs and attributes in labels;context.labelsis the documented app-metadata extension point.Stacked on #207. It includes #207's two commits (it needs #207's split of
cortex-wire.mdto stay under the 500-line limit). Merge after #207; this PR's own change is the last commit.Related issue
None. This is TM-5 and D from the CortexDB scoping review.
API or behavior changes
Breaking (needs a major release):
tinymemory_api::MemoryMetagains a public field,derive: Option<bool>. Adding a field breaks struct literals in downstream code (openhuman buildsMemoryMeta { … }in places;..MemoryMeta::default()keeps compiling).#[serde(skip_serializing_if = "Option::is_none")], so an unset value is not serialized and existing fingerprints, item ids and stored envelopes are unchanged.Some(false)stores and indexes the item, so it stays searchable, but asks the engine to derive nothing from it. On CortexDB that isdirectives.extract: [](no facts, beliefs or concepts).Storage layout (v3), no API change:
content.textis the item's own text: the document body or piece, the turn's text, or the learning's statement.context.labelsholds, in order:tm:i:first);kind:<kind>,file:<path>, and a piece'spage:<n>/page:<a>-<b>andsection:<title>. Neverlang:(CortexDB reserves it);text, as compact JSON intm:e:<NN>:parts of at most 240 bytes each.tm:e:parts that join to a v3 envelope is v3; otherwise its text is tried as v2.[role]. CortexDB 0.10.3 and 0.10.4 return the stored text inlayers.events; the marker is only incontext_block(API §9.4). The v2 decoder still tolerates the prefix.Verified on the live harness (CortexDB 0.10.4):
Office pipeline marker 7391with labelstm:i:…,kind:document,file:/office/brief.docx,tm:e:00:{"v":3,…}.Validation
Local, at 73f5889, in a target dir of this worktree's own:
cargo fmt --all -- --check: okcargo clippy --all-targets --all-features -- -D warnings: okcargo build --all-targets --all-features: okcargo test --all-features: ok, 1123 passedcargo test: ok, 435 passedRUSTDOCFLAGS="-D warnings" cargo doc --no-deps --all-features: okcargo run -p tinymemory-integrations --example basic: okcargo llvm-cov … --fail-under-lines 80: ok, 94.14% linescargo hack --feature-powerset --depth 2 --workspace check --all-targets: okscripts/cortexdb-live.sh's three suites on a fresh local CortexDB v0.10.4: oklive_cortexdbon 3 fresh servers: 3/3 passedRevert-checks (each made its test fail, then restored; run before stacking on #207, on the same code):
every_piece_and_turn_round_trips_through_its_labelsfails;an_envelope_too_big_for_its_labels_or_with_no_text_is_written_as_v2fails;a_tool_turn_asks_to_extract_nothing_and_other_turns_do_notfails;recovery_does_not_take_another_turn_with_the_same_words_for_the_lost_onefails.Tests
kind:/file:/page:/section:; at most 64 labels of at most 256 bytes each; nolang:.[role]-prefixed text) are kept.derive: Some(false)sendsdirectives.extract: [], and an unsetderiveleaves the fingerprint as it was. Only the tool turn of a user/tool/assistant conversation is sent withextract: [].Documentation
docs/architecture/cortex-wire.md(the envelope, v3 and v2);docs/architecture/cortex-chunks.md(limits measured on v2; readable page and section labels);docs/architecture/cortex.md;docs/specs/memory-v2.md;crates/tinymemory-integrations/src/cortex/README.md;Checklist
#[allow(...)],#[ignore], or relaxed lints.envcontents in the diff or the description