chat: search_chat over the shared source collection, huginn chat search #57

Merged
eureka merged 4 commits from gamecult-chat/chat-search into main 2026-11-11 19:11:25 +00:00
Owner

Cut gamecult-chat:cut_spec:cut-chat-search.r2: chat search in the source organ, read side only.

Operator: expect one forge re-embed at the deploy of this cut. SourcesMeta.corpus changes from forge:GameCult to forge:GameCult+chat:rooms and every point gains a corpus payload, so the existing meta-mismatch rule rebuilds huginn_sources once. Schedule the huginn-sources run; do not let it surprise a Soul pass. Until that rebuild runs, every forge and chat read (listing included) answers a clear stale-index error ("built for corpus forge:GameCult ... the rebuild is pending") instead of an empty page.

What it adds

  • SearchChat / Chat on huginn.mind_request.v1 / huginn.mind_response.v1 (schemas regenerated). ChatHit has no optional room id, event id or timestamp.
  • Selectors compose as AND: --room (id ! or alias #, any-of), --after/--before (span overlap; boundary hits trimmed and their span and ids recomputed), texts (0..8; none is a listing oldest first by ts_start_ms scroll, truncated when more exist).
  • One collection, one queue, one identity check and one fuse; a forge search now filters corpus=forge.
  • ChatPayload is the single owner of the chat point shape and upsert_chat its only write; nothing calls it until the ingest cut. Until then a chat search answers empty.
  • huginn chat search [TEXT]... [--room R]... [--after T] [--before T] [--top-k N] [--json].

Probe: deployed Qdrant is 1.17.1 (integer range indexes and scroll order_by exist).

Verification: Yggdrasil local container, cargo check --locked --workspace and cargo test --no-fail-fast --locked -p huginn-mind -p huginn-daemon -p eureka-state --features eureka-state/cli: only the 36 desk-door tests fail (they refuse uid 0, unrelated, same 36 as on main).

Disclosures

  • chrono moved from dev-dependency to dependency in eureka-state: the CLI parses --after/--before ages with it.
  • crates/huginn-daemon/src/index/tests.rs keeps the base file's mixed CRLF endings; its diff is content only.
  • Known limit (fix owned by cut chat-window; behaviour unchanged, documented in docs/chat-retrieval-map.md): hits are ordered by trimmed start, and a long chunk trimmed across rooms can reappear on the listing continuation.
  • Review fixes: ages parse on char boundaries and overflow is an error; CLI help no longer claims DM/Discord exclusion (the ingest side owns it); mutation rows for span bounds, scroll order/filter, nearest filter and the corpus/ts_end_ms indexes are caught (10/10).

Not here: the ingest job, the event-id window (cut chat-window).

🤖 Generated with Claude Code

Cut `gamecult-chat:cut_spec:cut-chat-search.r2`: chat search in the source organ, read side only. **Operator: expect one forge re-embed at the deploy of this cut.** `SourcesMeta.corpus` changes from `forge:GameCult` to `forge:GameCult+chat:rooms` and every point gains a `corpus` payload, so the existing meta-mismatch rule rebuilds `huginn_sources` once. Schedule the `huginn-sources` run; do not let it surprise a Soul pass. Until that rebuild runs, every forge and chat read (listing included) answers a clear stale-index error ("built for corpus forge:GameCult ... the rebuild is pending") instead of an empty page. What it adds - `SearchChat` / `Chat` on `huginn.mind_request.v1` / `huginn.mind_response.v1` (schemas regenerated). `ChatHit` has no optional room id, event id or timestamp. - Selectors compose as AND: `--room` (id `!` or alias `#`, any-of), `--after`/`--before` (span overlap; boundary hits trimmed and their span and ids recomputed), texts (0..8; none is a listing oldest first by `ts_start_ms` scroll, `truncated` when more exist). - One collection, one queue, one identity check and one `fuse`; a forge search now filters `corpus=forge`. - `ChatPayload` is the single owner of the chat point shape and `upsert_chat` its only write; nothing calls it until the ingest cut. Until then a chat search answers empty. - `huginn chat search [TEXT]... [--room R]... [--after T] [--before T] [--top-k N] [--json]`. Probe: deployed Qdrant is 1.17.1 (integer range indexes and scroll `order_by` exist). Verification: Yggdrasil local container, `cargo check --locked --workspace` and `cargo test --no-fail-fast --locked -p huginn-mind -p huginn-daemon -p eureka-state --features eureka-state/cli`: only the 36 desk-door tests fail (they refuse uid 0, unrelated, same 36 as on main). Disclosures - `chrono` moved from dev-dependency to dependency in `eureka-state`: the CLI parses `--after`/`--before` ages with it. - `crates/huginn-daemon/src/index/tests.rs` keeps the base file's mixed CRLF endings; its diff is content only. - Known limit (fix owned by cut chat-window; behaviour unchanged, documented in `docs/chat-retrieval-map.md`): hits are ordered by trimmed start, and a long chunk trimmed across rooms can reappear on the listing continuation. - Review fixes: ages parse on char boundaries and overflow is an error; CLI help no longer claims DM/Discord exclusion (the ingest side owns it); mutation rows for span bounds, scroll order/filter, nearest filter and the corpus/ts_end_ms indexes are caught (10/10). Not here: the ingest job, the event-id window (cut chat-window). 🤖 Generated with [Claude Code](https://claude.com/claude-code)
Probe: the deployed Qdrant answers 1.17.1 at 127.0.0.1:6333 (>= 1.8: integer
range payload indexes and scroll order_by exist).

Wire: SearchChat / Chat, ChatQuery (door-checked by field), ChatHit with no
optional room_id, event ids or timestamps, published schemas regenerated.
Index: corpus payload on every point (forge searches must corpus=forge), chat
payload codec derived from the messages, keyword and integer indexes, upsert_chat
/ chat_nearest / chat_scroll on Qdrant and the fakes. CORPUS becomes
forge:GameCult+chat:rooms, so the existing meta mismatch rebuilds the forge index
once at deploy. sources::search_chat shares the identity check and fuse with
the forge search; chat rides the same queue (SourceAsk) and Found::Chat.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
`huginn chat search [TEXT]... [--room R]... [--after T] [--before T] [--top-k N] [--json]`;
T is an RFC 3339 instant or an age (6h, 2d), one parser. The render prints the
organ's header line per hit and each message verbatim with its event id, and a
truncated listing ends with the --after that continues it. chrono moves from
dev-dependency to dependency of eureka-state (already in the lock graph).

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
- A collection built for another corpus set is refused with a stale-index
  error on every read (listing included), not answered with an empty page.
- --after/--before ages parse on char boundaries and overflow is an error.
- Tests for inclusive span bounds, scroll order/filter, nearest filter and
  the corpus and ts_end_ms indexes; all ten surviving mutants now caught.
- index/tests.rs keeps the base file's CRLF endings (diff is content only).
- Drop the exclusion claim from the CLI help; document the listing limit.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
eureka merged commit 421ace5432 into main 2026-11-11 19:11:25 +00:00
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
GameCult/Huginn!57
No description provided.