Skip to content

Mention edges readable over the engine seam, both directions (nxf 6j6v.q29p) - #46

Closed
cabcookie wants to merge 1 commit into
mainfrom
feat/q29p-mention-reads
Closed

cabcookie wants to merge 1 commit into
mainfrom
feat/q29p-mention-reads

Conversation

@cabcookie

Copy link
Copy Markdown
Member

What

An embedding product can now read mention edges back over its seam, in both directions.

  • Engine::mentions(id) -> Result<Vec<String>> returns the outgoing targets. It is the existing read::mentions, put on the seam.
  • Engine::mentioned_by(id, &MentionedByQuery) -> Result<NextPage> and Engine::mentioned_by_value(id, &MentionedByQuery) -> Result<Value> return the live items that mention a target, in id order. Closed and archived mentioners count; deleted ones do not. The query takes a NextFilter (type, container = belongs_to OR contributes_to, label) and pages exactly like next_query.
  • CLI: nxf mention by <id> [--type T]... [--in ID] [--label L] [--limit N [--paginate [--token T]]].
    • --json gives list --json records (with presentation labels) as a plain array.
    • With --limit it gives {"items", "total"}, and with --paginate also next_token and restarted. This is the same flag-shaped rule as next.

Shared with x0wf (spec derived-ranking-keys section 11)

read::mentioners_of(store, targets: &[&str]) -> Result<BTreeMap<String, Vec<ItemRow>>> is the reverse lookup:

  • For each target it gives the live mentioners, id-sorted, in one edge query per 500 targets (Store::mentioned_by_bulk, new in core) plus one item read.
  • mentioned_by narrows its result with a NextFilter.
  • count = "mentioned_by" should count the rows per candidate that pass its type/status/label parts. That costs O(E + N) over a candidate set (spec section 5).

Paging reuse, not a copy

The paging half of next_page_at is factored into the private Paging (validation), Watermark and page_through (cut, resume, cache).

  • next_page and mentioned_by_page both call it, so they share the next_page_cache table, the 1h expiry, the 8-per-query and 64-total caps, the invalidation rules and the restart-on-stale-token behaviour.
  • The mentioned-by snapshot key names the read and the target ({"read":"mentioned_by","target":..,"filter":..}), so a token never crosses between next and mentioned_by or between targets. next's key format is unchanged, so existing tokens keep working.
  • The table keeps its name; no schema change.

Tests

  • crates/facade/tests/mentioned_by.rs (new, 12 tests at the Engine seam): outgoing read, live/closed/deleted/removed set, not_found, type and container filters, limit, paginate walk, restart on a removed mention, outside op that does not invalidate, cross-target/filter/read tokens restart, validation, value envelope, bulk mentioners_of.
  • read.rs unit test: a mentioned-by token expires on the injected clock.
  • store.rs unit test: mentioned_by_bulk.
  • crates/cli/tests/mention.rs: 4 black-box tests (records + filters, envelope + paging + stale restart, human view, errors). $HOME is pinned via cargo_bin.
  • Goldens under both plugins; guide EN/DE quotes them.
  • Verb-seam gate: Alias mention by -> mentioned_by.

Run locally: those test files, next_query (18, unchanged), the facade lib paging tests, verb_seam, golden, guide_examples, cargo xtask docs check / docs coverage, cargo xtask changelog check. No clippy and no full suite were run locally; CI is the gate.

Fragment: changes/q29p-mention-reads.md, facade: changed (additive).

🤖 Generated with Claude Code

https://claude.ai/code/session_016q5uMUkZJQW4fckJoA3FME

…v.q29p)

- Engine::mentions(id): the outgoing targets, the existing read::mentions put on the seam.
- Engine::mentioned_by(id, &MentionedByQuery) / mentioned_by_value: the live items that mention
  a target, in id order, filtered by NextFilter (type, container, label) and cut/paged exactly
  like next_query.
- read::mentioners_of(store, targets): THE bulk reverse lookup (over the new
  Store::mentioned_by_bulk) that the derived ranking key count = "mentioned_by" (x0wf) is to
  share, per docs/specs/derived-ranking-keys.md section 11.
- The paging half of next_page is factored into page_through/Paging/Watermark, so next and
  mentioned_by share one snapshot table, expiry, caps and invalidation; the snapshot key names
  the read, so tokens do not cross between them. next's keys are unchanged.
- CLI: nxf mention by <id> [--type]... [--in] [--label] [--limit [--paginate [--token]]], with
  list records and next's --json envelope; goldens under both plugins, guide EN/DE, generated
  docs, verb-seam alias.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016q5uMUkZJQW4fckJoA3FME
cabcookie added a commit that referenced this pull request Oct 11, 2026
…paging, local derived ranking keys (nxf 6j6v.q29p, n698, x0wf) (#49)

Folds #46 (q29p), #47 (n698) and #48 (x0wf) plus the mitigation of their combined independent review.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016q5uMUkZJQW4fckJoA3FME
@cabcookie

Copy link
Copy Markdown
Member Author

Contained in #49, which folds #46, #47 and #48 plus the review mitigation and was merged in one squash.

@cabcookie cabcookie closed this Oct 11, 2026
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