Repository navigation
Review mitigation for the q29p/n698/x0wf batch (nxf 6j6v.q29p, n698, x0wf) - #49
Merged
Merged
Conversation
…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
…e (nxf 6j6v.n698)
- Plugin: [ranking.list] takes the same keys as [ranking.next]: per-type tables
[ranking.list.<type>], the cross-type order types = [...], an optional default order.
Parsed and validated by the same code (errors name their section). Ranking::list is
always resolved at load: absent, or without its own order, it inherits the
[ranking.next] default order, so list --sort rank is unchanged for every plugin that
declares nothing (both bundled plugins).
- Ranking: NextRank becomes TypeRank over a &RankSpec; next ranks with
TypeRank::next, list --sort rank with TypeRank::list - one comparator for both, the
place derived keys (x0wf) plug in once.
- Paging: read::ListQuery + read::list_page reuse NextFilter (type alternatives,
container = belongs_to OR contributes_to, label) and q29p's Paging / Watermark /
page_through; the snapshot key names the read ("list"), status, sort, filter and a
fingerprint of [ranking.list], so tokens never cross reads or plugin orders.
- Engine::list_query(&ListQuery) -> NextPage and Engine::list_query_value (the
{"items","total"[,"next_token","restarted"]} envelope of list_value records).
- CLI: nxf list --type (repeatable) --in <id> --limit --paginate --token; plain array
without --limit, next's envelope with it; human view discloses the cut and prints
the token. Default order stays id.
- Tests at the seam (facade/tests/list_query.rs, plugin unit tests), CLI black-box
(cli/tests/list.rs), goldens under both plugins, guide EN/DE, generated docs.
Stacked on #46 (q29p).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016q5uMUkZJQW4fckJoA3FME
…idation and the type chain (nxf 6j6v.x0wf)
Builds docs/specs/derived-ranking-keys.md on the local SQL path. A per-type order
([ranking.next.<type>], [ranking.list.<type>], and the [ranking.list] default order)
takes three derived keys besides field keys: `related` (a value on the neighbours over
an outbound edge: `of = "rank"` or `of = { field }`, custom fields included, picked by
min/max), `count` (neighbours over an edge kind and direction, filtered by type/status/
label) and `sum` (counts with equal weight).
- Load-time rules (spec §7): kind exclusivity, edge kinds, parts per kind, declared
types/statuses/fields, `of = "rank"` needs a declared order, and the acyclic type chain
across both sections, the cycle named. Derived keys are refused in the [ranking.next]
default order (it also ranks blocked and the lanes).
- Bottom-up once per query (spec §4/§5): one edge pass (Store::present_edges_of_kinds),
the reverse mentions through q29p's read::mentioners_of (spec §11), one bulk read of
the neighbours, one sort and a dense rank per type in the chain, then the comparator
reads precomputed values. A plugin without derived keys pays nothing.
- `of = "rank"` reads the asking section's order, else the other's (spec §8: persons by
the projects next ranks); a list query then needs `now` (ListQuery::now, read::list_at;
the CLI and MCP pass the clock only for such a plugin).
- The store-free read::next_active refuses a plugin with derived next keys until 1c5s.
- Tests: plugin load validation (each refusal, cycles), the spec's orders at the Engine
seam (next_query, list_query), each kind, determinism, and a query-shape ratio guard
(EdgeReadStats) that the edge pass runs once per query.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016q5uMUkZJQW4fckJoA3FME
…x0wf) Mitigates the independent review of PR #48: - derived keys read `parent` from the `present_parent` projection, the single parent belongs_to/--in/show read (Integrity #1); - `list` narrows by status/type/container/label before ranking, so the type chain covers only the orders the kept rows need; the rank scope stays every live item (Code Quality #1, spec §12 decision 2); - `EdgeReadStats` counts every edge, label and custom-field read, and the ratio guard asserts none runs per item (Test Quality #1); - `[ranking]` refuses unknown tables; the `[ranking.list]` default order refuses an untyped `of = "rank"` key (Integrity #2, #3); - `nxf list` and the MCP list resolve `now` only for a ranked list; - `mentioned_by_bulk` deduplicates targets across chunks; - tests for the rank scope under --status, the cross-section paging fingerprint, a stale token after an outside reorder, a derived key in the list default order, a full tie, count = "parent", and the smaller gaps; stale spec/guide/rustdoc prose fixed; `NextRank` added to the retired-vocabulary sweep. The CLI/MCP `now` test gap is filed as 6j6v.4qga. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016q5uMUkZJQW4fckJoA3FME
This was referenced Oct 11, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Stacked on #48 (→ #47 → #46); this PR is the one to merge — it contains all four.
Mitigates the independent review of PR #48 (
.nxf/review/2026-10-11T05-26-00Z.md) for the q29p / n698 / x0wf batch. The eight decisions ofdocs/specs/derived-ranking-keys.md§12 are untouched: §12 gains one bullet clarification (the untyped rank key is refused in the[ranking.list]default order too), and thenowbullet now says the filters narrow the rows before they are ranked.Mitigation Summary
parentedges, not the projected single parent (Integrity #1 · Medium)Store::present_edges_of_kindsreadsparentfrom thepresent_parentLWW view (one query,UNION ALL); core test + facade test with two concurrent re-parents (count andrelated … pick = "max")list_queryranks before it filters (Code Quality #1 · Medium)read::list_selectedapplies status + type/container/label filters to the candidates beforederived::compute; the rank scope stays every live item (§12 decision 2). Seam test: a goal/project type filter needs nonow, person still doesNextRank/ n698 / "x0wf decides" lines (Code Quality #2 · Medium)docs/specs/next-finish-first-tiers.mdrewritten;NextRankadded toxtask/sweep-retired-vocabulary.sh; sweep run againstorigin/main: no file namesNextRankany morelist(Code Quality #3 · Low)next_cache.rsmodule doc,NextPage,Paging,page_throughEngine::list_queryrustdoc silent onnow(Code Quality #4 · Low)list_query/list_query_valuedocument whennowis needed and the malformed caseplugins.md: the[ranking.list]default order takes them; the untyped rank-key refusal there; onlylist --sort rankreads the timenxf listresolvesnoweven when sorting by id (Code Quality #6 · Low)nowonly for--sort rankunder a plugin with derived list keysEdgeReadStatsgainsper_itemandbulk; every edge/label/custom-field read is counted (core test enumerates them); the guard assertsper_item == 0and no growth across all four buckets--statusnot pinned (Test Quality #2 · Medium)a_list_rank_scope_ignores_the_status_filter(closed box still ranks); mutationlist: Some(&items)goes reda_derived_list_token_restarts_when_only_the_next_order_changes; dropping+othergoes reda_page_restarts_when_an_op_outside_the_snapshot_reorders_it(a goal'sordermoves the actions)[ranking.list]default order only tested at load (Test Quality #5 · Medium)a_derived_key_ranks_in_the_list_default_order_without_per_type_tablescount = "parent"has no positive case (Test Quality #7 · Low)count_reads_every_direction_and_kindnowin a test; malformednowuntested (Test Quality #8 · Low)a_malformed_now_is_refusedat the seam. The CLI/MCP branch can't be reached by a black-box test: the binaries link only the bundled plugins, and neither declares a derived key. Filed as 6j6v.4qga (P3)of = 3arm,OfFieldunknown part, "one read" asserted formentioners_of, CLI paginate refusals assert their message, archived mentioner atEngine::mentioned_byread::*notEngine::*(Test Quality #10 · Info)Engine::next_query/list_queryare thintry_with_statewrappers overread::next_page/list_page, and the §9 chain tests run at the Engine seamRankingTomllacksdeny_unknown_fields(Integrity #2 · Low)[ranking.lsit]is refused at load; testrelated … of = "rank"in[ranking.list]default order (Integrity #3 · Low)mentioned_by_bulkduplicates across chunks (Integrity #4 · Info)Quality gates
cargo fmt --allcargo test -p nexus-flow-facade --test derived_ranking --test list_query --test next_query --test mentioned_by --test next_rank_per_typecargo test -p nexus-flow-facade --lib plugin::and--lib readcargo test -p nexus-flow-core --lib store::cargo test -p nexus-flow-cli --test list --test mentioncargo xtask docs check,cargo xtask changelog check origin/mainpresent_parent, rank scope, cross-section fingerprint). Each reversion turned its test red.Clippy and the full suite are left to CI, by instruction.
🤖 Generated with Claude Code
https://claude.ai/code/session_016q5uMUkZJQW4fckJoA3FME