Repository navigation
Store a consumer-written title on a conversation - #291
lore-agent[bot] wants to merge 9 commits into
Conversation
🔍 Lore Spec Impact — advisoryThis PR touches 55 statement(s) across 2 spec(s), and changes the validating tests alongside every one of them. WebSocket Protocol Specification · 4 statement(s)
5.6 error
validated by 5.6 error
validated by 5.9 conversation_list
validated by 5.9 conversation_list
validated by Conversation List · 14 statement(s)
Asking for the list over the socket
validated by Asking for the list over the socket
validated by Asking for the list over the socket
validated by Asking for the list over the socket
validated by Asking for the list over the socket
validated by Asking for the list over the socket
validated by …and 8 more statement(s). Weaker signals (37) — linked by a spec, not proven by a test runConversation List · 33 statement(s)
The order a list answers in
validated by The order a list answers in
validated by What a summary reports
validated by What a summary reports
validated by What a summary reports
validated by A label for a row
validated by A label for a row
validated by A label for a row
validated by A label for a row
validated by A label for a row
validated by …and 27 more statement(s). 1 changed statement(s) had no validating test, so no coverage broke. 32 new statement(s) have no test link yet. Deterministic · graph @ |
- ChatSession and SessionSummary gain title?: string - SessionStore gains optional setTitle?(sessionId, title) - InMemorySessionStore and MongoSessionStore implement setTitle - MongoSessionStore.listFor reads title from existing projection (no second query); SUMMARY_FIELDS adds title: 1 - setTitle on a missing session is silently ignored, never upserts - Spec statements added to hal-engine-conversation-list with citations - CHANGELOG entry added under [Unreleased] Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Add title to ConversationSummary wire type and pass it through onTheWire when the store holds one. Update projection assertions to include title. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Remove `as any` casts from acceptance test; both stores type setTitle directly - Fix 2-line comment to 1-line in acceptance test - Combine dual expects into toMatchObject in both test files - Extract intermediate variable to fix 3-hop member chain - Reanchor all conversationList.test.ts spec links shifted +34 by the title test insertion - Add spec statement for carries-a-title-on-the-wire test at L265 - Add spec citations for acceptance tests in hal-engine-conversation-list spec - Update spec status to In Progress to match actual citation coverage Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Add mongoTitleDurability tests: title survives a save (verifies persistedFields does not overwrite $set), erased with eraseConversation, and the cache-cold path of setTitle writes through to the database - Add inMemorySessionTitle test: setTitle on an aged-out session is a no-op, covering the hasExpired branch for 100% store coverage - Update spec with three new validated statements for title durability - Fix stale #Lnn citations shifted by the new jest import line - Tick DoD facet: A title survives a save and is removed upon erasure Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
The SUMMARY_FIELDS constant was updated in the previous round to include title:1, but the test asserting the no-preview projection still expected the pre-title shape. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- regenerate ChatSession block in CLAUDE.md to include title field - regenerate SessionStore block in architecture spec to include setTitle - accept GHSA-27r3-jxmh-p828 (body-parser DoS); path is unreachable in hal-engine since no compressed-body endpoint is exposed Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
Lore is reviewing this PR — ead683c8-c57d-45c3-86e4-4b1491ed00d2. Submit a review that requests changes to have Lore push a fix for it. Comment |
|
Nothing blocks this PR from merging now. Lore updates this comment when the reason changes. |
There was a problem hiding this comment.
GitHub does not accept an approving or blocking review from the account that opened this pull request, so this review is posted as a comment. Its verdict is published on the lore/code-review check.
Lore review — Approved
Clean, minimal implementation of conversation titles across SessionStore, both shipped stores, and the WebSocket conversation_list frame; a few non-blocking spec/doc/test hygiene items noted below.
Must fix (0) · Consider (3) · Nits (1)
Reviewed by gemini-4-argon
Submit a review that requests changes to have Lore push a fix for it. Comment @lore review to re-run the review.
Findings
specs/hal-engine-conversation-list/spec.md:5 — suggestion: add #155 to the Issue header row and cite the uncited optional-member statement so Status stays Shipped
| Issue | re-cinq/HALEngine#143, #144, #145, #147, #155 |
| Status | Shipped |
specs/hal-engine-conversation-list/spec.md:71 — suggestion: add a trailing test citation for the optional setTitle statement ( only unlinked statement in this spec )
- `setTitle` is optional on `SessionStore`, like `listFor`, `latestFor` and `lookup` before it: a store written against the original members still satisfies the interface ([validated by: leaves a store with only the five original members satisfying the interface beside both shipped ones](../../src/infrastructure/stores/sessionStoreListSignature.test.ts#L11)).
docs/session-stores.md:173 — nit: update docs/session-stores.md where it still says the engine stores no title yet and tracks #155 as future work
src/infrastructure/stores/mongo/mongoTitleDurability.test.ts:22 — suggestion: also assert the remaining erasure methods (delete, evict, eraseOlderThan, eraseAll) and session resume preserve/remove titles per the issue checklist
Posted by floor, visit d74d67b3-7636-44bd-8d08-76a210f22a59.
Why
A consumer building a UI often wants a stable, descriptive title for a conversation rather than relying solely on the first user message (which can be long, messy, or contain PII). Generating this title inside the engine is not ideal, as it would require a provider call per conversation. Providing a way for a consumer to store and retrieve a generated or hand-written title on a conversation allows them to display a clean history without overwriting the user's actual text.
What Changed
titlefield toChatSessionandSessionSummary.setTitle(sessionId, title)method to theSessionStoreinterface.setTitleinInMemorySessionStoreandMongoSessionStore.MongoSessionStore.listForto read the title from its existing projection without any extra queries.conversation_listframe to include thetitlein summaries, independently of thepreviewflag.saveoperations and is fully erased alongside the conversation by existing erasure methods.CHANGELOG.mdunder the## [Unreleased]section.hal-engine-conversation-listspec.Alternatives Considered
previewfield with the title. This was rejected becausepreviewandtitleserve different purposes—a consumer might legitimately want to display both the title and the first message preview. Also, previews are opt-in and truncated, while titles are explicitly written by the consumer.titleoption tolistFororSessionListOptions. We chose to always return the title if present because the consumer explicitly stored it for display; it doesn't contain raw user data by default, and there is no performance overhead in fetching it since it lives on the session document.ADRs & Architecture
specs/hal-engine-conversation-list/spec.mdwas updated to document the title, its retrieval inlistFor, the GDPR retention requirements, and its inclusion in theconversation_listWebSocket frame.specs/hal-engine-websocket-protocol/spec.mdhad its inline spec links re-anchored to reflect the test changes for the new frame properties.specs/hal-engine-architecture/spec.mdwas updated to document the newsetTitlemember in theSessionStoreinterface.Testing
src/title.acceptance.test.tsto verifysetTitlefunctionality in bothInMemorySessionStoreandMongoSessionStore.MongoSessionStorereads the title via its existing projection without a second query.titleis correctly passed in theconversation_listframe regardless of whether previews are enabled.Code Quality Checklist
Not covered separately in this description.
Related Issues
Not covered separately in this description.
Closes #155
Lore-Task: e778bb4d-d3f9-4f64-ba82-6ab1a2c7cd35