Skip to content

feat(ui): group child sessions by role - #249

Merged
w0wl0lxd merged 25 commits into
mainfrom
fix/session-category-groups
Aug 12, 2026
Merged

feat(ui): group child sessions by role#249
w0wl0lxd merged 25 commits into
mainfrom
fix/session-category-groups

Conversation

@w0wl0lxd

@w0wl0lxd w0wl0lxd commented Aug 3, 2026

Copy link
Copy Markdown
Owner

Summary

  • group descendants under stable research, ponder, draft, review, team, workflow, agent, and other headings
  • preserve orphaned sessions and stable synthetic-group navigation across refreshes
  • retain accurate task counts when large categories are bucketed

Validation

  • RUST_TEST_THREADS=1 cargo test -p n00n-lua --test plugin_host sessions_
  • cargo clippy -p n00n-lua --tests -- -D warnings
  • cargo nextest run -p n00n-lua
  • cargo fmt --all -- --check
  • stylua --check plugins/sessions/init.lua
  • git diff --check

@coderabbitai

coderabbitai Bot commented Aug 3, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Warning

Review limit reached

@w0wl0lxd, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 16 minutes

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 71e6bdac-d2a6-495e-9bb1-fe4a38696e4d

📥 Commits

Reviewing files that changed from the base of the PR and between 45cbae9 and f6bc162.

📒 Files selected for processing (2)
  • n00n-lua/tests/plugin_host.rs
  • plugins/sessions/init.lua

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: beb38267-8e6b-4b65-9ac2-8488d2e7fe43

📥 Commits

Reviewing files that changed from the base of the PR and between 6bb8f42 and 45cbae9.

📒 Files selected for processing (2)
  • n00n-lua/tests/plugin_host.rs
  • plugins/sessions/init.lua
📜 Recent review details
⏰ Context from checks skipped due to timeout. (9)
  • GitHub Check: Lint (Windows)
  • GitHub Check: MSRV (1.97)
  • GitHub Check: Coverage
  • GitHub Check: Test (macOS)
  • GitHub Check: Test (Windows)
  • GitHub Check: Test
  • GitHub Check: Build (Windows)
  • GitHub Check: Analyze (rust)
  • GitHub Check: Criterion
🧰 Additional context used
📓 Path-based instructions (1)
**/*.rs

📄 CodeRabbit inference engine (AGENTS.md)

**/*.rs: Do not add unsafe code, FFI, global mutable state, static mut, or unchecked transmute-like behavior without written review, an explicit lint exception, and a SAFETY comment where applicable.
Do not use unwrap, expect, panic!, todo!, unimplemented!, or dbg! in production Rust code; tests are exempt from the unwrap/expect/panic restriction.
Do not silently discard failures with unwrap_or, unwrap_or_default, .ok() on Result, or equivalent defaults; return typed errors, reject the operation, or use an explicitly named fallback with sanitized structured logging.
Use idiomatic Rust, descriptive names, minimal state, and avoid unnecessary comments, bloat, and magic numbers or strings.
Import types at the top of the file and use short imported names; keep constants immediately after imports.
Use Result<T, E> and explicit error handling instead of panics; use thiserror for library/domain errors and color-eyre at binary edges.
Use #[derive(Copy)] only for structs containing one primitive field.
Prefer structured logging with useful fields and provide helpful, sanitized error messages.
Place unit tests in the same file inside #[cfg(test)] modules; use #[test_case] and snake_case test names.
Propagate typed errors with ?, ok_or_else, and map_err; library crates use thiserror and binaries use color-eyre.
Treat LLM and provider output as untrusted input; validate schemas, domain constraints, and source evidence before persistence or action.
Do not log raw provider payloads, prompts, credentials, or user session data, and never commit credentials, API keys, tokens, cookies, or auth headers.
Validate and authorize HTTP, file, queue, configuration/environment, LLM, and provider-callback inputs before mutation or persistence.
Tool execution requires allowlisted tools, scoped credentials, explicit user context, audit events, and refusal or denial tests.

Files:

  • n00n-lua/tests/plugin_host.rs
🧠 Learnings (6)
📚 Learning: 2026-08-04T02:36:32.766Z
Learnt from: w0wl0lxd
Repo: w0wl0lxd/n00n PR: 320
File: n00n-lua/tests/plugin_host.rs:4465-4476
Timestamp: 2026-08-04T02:36:32.766Z
Learning: In `n00n-lua`, `PluginHost::unload` must preserve captured Lua plugin state. Tests in `n00n-lua/tests/plugin_host.rs` must verify that both root-scoped and session-scoped payloads remain available after plugin unload.

Applied to files:

  • n00n-lua/tests/plugin_host.rs
📚 Learning: 2026-07-31T19:15:09.621Z
Learnt from: w0wl0lxd
Repo: w0wl0lxd/n00n PR: 206
File: n00n-lua/tests/real_plugins_restore.rs:222-247
Timestamp: 2026-07-31T19:15:09.621Z
Learning: In `n00n-lua/tests/real_plugins_restore.rs`, values embedded in compile-time `#[test_case]` inputs and raw Lua fixture source may remain inline when extracting constants requires runtime templating and reduces integration fixture clarity without improving coverage.

Applied to files:

  • n00n-lua/tests/plugin_host.rs
📚 Learning: 2026-08-10T05:11:10.183Z
Learnt from: w0wl0lxd
Repo: w0wl0lxd/n00n PR: 327
File: n00n-lua/src/runtime.rs:1443-1445
Timestamp: 2026-08-10T05:11:10.183Z
Learning: In `n00n-lua/src/runtime.rs`, `drain_runtime` must continue dispatching runtime tool requests with `nested_only` set to `false` while a lifecycle operation is active. Reentrant agents can dispatch Lua tool requests from another executor thread, so nested-origin markers are not reliable across threads. Restricting lifecycle draining to nested requests can deadlock lifecycle barriers.

Applied to files:

  • n00n-lua/tests/plugin_host.rs
📚 Learning: 2026-08-02T22:13:53.026Z
Learnt from: CR
Repo: w0wl0lxd/n00n PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-08-02T22:13:53.026Z
Learning: Applies to **/*_test.rs : Tests must be meaningful rather than tautological, deterministic, and free of arbitrary sleeps; shared constant error/status messages should be asserted against shared constants.

Applied to files:

  • n00n-lua/tests/plugin_host.rs
📚 Learning: 2026-08-02T22:13:53.026Z
Learnt from: CR
Repo: w0wl0lxd/n00n PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-08-02T22:13:53.026Z
Learning: Applies to **/*.rs : Tool execution requires allowlisted tools, scoped credentials, explicit user context, audit events, and refusal or denial tests.

Applied to files:

  • n00n-lua/tests/plugin_host.rs
📚 Learning: 2026-07-21T16:54:32.671Z
Learnt from: CR
Repo: w0wl0lxd/n00n PR: 0
File: n00n-lua/src/api/AGENTS.md:0-0
Timestamp: 2026-07-21T16:54:32.671Z
Learning: Applies to n00n-lua/src/api/**/*.lua : Tool handlers must report failures as `{ llm_output = msg, is_error = true }`; a plain string is always a success, and only `is_error` marks the result as an error to the provider.

Applied to files:

  • n00n-lua/tests/plugin_host.rs
🔇 Additional comments (10)
plugins/sessions/init.lua (3)

170-177: LGTM!


231-231: LGTM!


336-336: LGTM!

n00n-lua/tests/plugin_host.rs (7)

10-29: LGTM!

Also applies to: 86-100, 250-263, 292-301


1008-1037: LGTM!

Also applies to: 1039-1063, 1519-1548


2865-2866: LGTM!


3011-3033: LGTM!

Also applies to: 3035-3076, 3105-3123, 3170-3207, 3209-3249, 3251-3284, 3286-3318, 3320-3365, 3367-3445


3638-3650: LGTM!

Also applies to: 3652-3672, 3886-3904, 3906-3924, 3926-3944, 3946-3962


4776-4779: LGTM!


6066-6075: LGTM!

Also applies to: 6077-6118, 6120-6203, 6205-6234


📝 Walkthrough

Summary by CodeRabbit

  • New Features

    • Session picker entries are now organized into clear categories, including research, planning, review, orchestration, teams, workflows, agents, and other tasks.
    • Grouped entries display task counts and preserve ordering and expansion state during refreshes.
    • Large agent groups are automatically organized for easier navigation.
  • Bug Fixes

    • Orphaned sessions remain visible as root entries, with outdated grouping information cleared.

Walkthrough

The session picker now categorizes descendant sessions into synthetic groups under root main sessions. The grouped tree preserves ordering and state, tracks task totals, handles orphaned sessions, and returns roots with flattened nodes. Regression coverage validates categorization and edge cases.

Changes

Session picker grouping

Layer / File(s) Summary
Classify descendant sessions
plugins/sessions/init.lua
Defines ordered categories, initializes group metadata, and resolves descendant sessions to root main sessions.
Build categorized session tree
plugins/sessions/init.lua, n00n-lua/tests/plugin_host.rs
Creates synthetic category groups with task counts, ranks, expansion state, child group IDs, preserved ordering, and flattened nodes. Tests cover categorization, orphan handling, stale metadata, node counts, agent bucketing, and title inference.
Refresh and render grouped nodes
plugins/sessions/init.lua, changelog.d/session-category-groups.changed.md
Refresh wiring uses the grouped node list for sorting. Group rows display stored task totals. The changelog documents session categorization.

Estimated code review effort: 4 (Complex) | ~45 minutes

Sequence Diagram(s)

sequenceDiagram
  participant SessionData
  participant SessionNormalization
  participant TreeConstruction
  participant SessionPicker
  SessionData->>SessionNormalization: normalize sessions and resolve root ancestors
  SessionNormalization->>TreeConstruction: provide categories and group metadata
  TreeConstruction->>SessionPicker: return roots and flattened nodes
  SessionPicker->>SessionPicker: refresh sorting and render stored task totals
Loading

Possibly related PRs

  • w0wl0lxd/n00n#128: Extends the grouped session-tree implementation and picker tests.
  • w0wl0lxd/n00n#254: Overlaps in categorized synthetic grouping for descendant sessions.

Poem

I hop through groups both neat and bright,
Research, review, workflow in sight.
Roots stay ordered, orphans stay free,
Tasks count true beneath each tree.
Tests guard every bunny-sized case.
The picker grows with tidy grace.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 11.11% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly summarizes the primary change: grouping child sessions by role in the UI.
Description check ✅ Passed The description directly explains the session grouping, orphan preservation, task counts, and validation performed.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches 💡 1
📝 Generate docstrings 💡
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/session-category-groups

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actions

github-actions Bot commented Aug 3, 2026

Copy link
Copy Markdown

Dependency Review

✅ No vulnerabilities or license issues or OpenSSF Scorecard issues found.

Scanned Files

None

@codecov

codecov Bot commented Aug 3, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Criterion

Details
Benchmark suite Current: f6bc162 Previous: 9276e1e Ratio
fib/jit_mlua_hook 6674787 ns/iter (± 126990) 6655811 ns/iter (± 84472) 1.00
fib/jit_watchdog 2226991 ns/iter (± 10257) 2752794 ns/iter (± 4592) 0.81
fib/jit_none 2220904 ns/iter (± 29959) 2710554 ns/iter (± 57051) 0.82
fib/interp_mlua_hook 8112705 ns/iter (± 96049) 8029305 ns/iter (± 19218) 1.01
fib/interp_watchdog 4253491 ns/iter (± 14618) 4330743 ns/iter (± 24960) 0.98
fib/interp_none 4281112 ns/iter (± 27626) 4319876 ns/iter (± 12009) 0.99
buffer_rw/jit_mlua_hook 584785 ns/iter (± 3872) 585211 ns/iter (± 1120) 1.00
buffer_rw/jit_watchdog 191802 ns/iter (± 414) 192038 ns/iter (± 778) 1.00
buffer_rw/jit_none 191451 ns/iter (± 229) 191390 ns/iter (± 246) 1.00
buffer_rw/interp_mlua_hook 1044777 ns/iter (± 13300) 1043308 ns/iter (± 15953) 1.00
buffer_rw/interp_watchdog 585293 ns/iter (± 4464) 581669 ns/iter (± 2217) 1.01
buffer_rw/interp_none 584853 ns/iter (± 1556) 581999 ns/iter (± 3602) 1.00
splash_render_120x40 70904 ns/iter (± 6267) 67289 ns/iter (± 6460) 1.05
splash_render_200x60 175867 ns/iter (± 15788) 149308 ns/iter (± 28066) 1.18

This comment was automatically generated by workflow using github-action-benchmark.

@w0wl0lxd

w0wl0lxd commented Aug 3, 2026

Copy link
Copy Markdown
Owner Author

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 5db320870e

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread plugins/sessions/init.lua
@w0wl0lxd
w0wl0lxd marked this pull request as ready for review August 3, 2026 13:55
@greptile-apps

greptile-apps Bot commented Aug 3, 2026

Copy link
Copy Markdown

Greptile Summary

This PR rewrites the sessions-picker tree builder to group all descendants of a main session under stable role-based headings (Research, Ponder, Draft, Review, Teams, Workflows, Agents / tasks, Other) rather than preserving the raw parent–child nesting. Category assignment is driven by session.kind for structural types and by a word-boundary scan of the title/display_title for the four named roles; orphaned sessions (no reachable main ancestor) are promoted to top-level roots instead of being dropped.

  • build_tree is rewritten to flatten all descendants per main root into a by-category map, wrap each occupied category in a synthetic_group node carrying total_tasks, and return both roots and a flat nodes list for filtering.
  • normalize_session now clears group_id to prevent stale synthetic-group references surviving across refreshes.
  • render reads s.total_tasks or #s.children so the task count displayed on a category header stays accurate after group_node replaces its children with overflow buckets.

Confidence Score: 4/5

Safe to merge; the rewrite is logically correct and the comprehensive integration test validates the key scenarios including orphan handling, overflow bucketing, and total_tasks accuracy.

The logic is sound and the two concerns found are both non-blocking: has_word injects word directly into Lua pattern strings (harmless for the current hardcoded category names but fragile if the list ever gains punctuation), and synthetic_group performs arithmetic on a rank value that is guaranteed non-nil only by the call ordering in refresh rather than by an explicit guard.

Files Needing Attention: plugins/sessions/init.lua — specifically has_word (pattern safety) and synthetic_group (nil-rank assumption); the test file and changelog are clean.

Important Files Changed

Filename Overview
plugins/sessions/init.lua Core change: replaces the old parent-child tree traversal with a two-phase flat-grouping approach. Descendants are bucketed by role under each main root. Minor concerns around unescaped Lua pattern injection in has_word and a nil-arithmetic assumption in synthetic_group; both are safe given the current call flow.
n00n-lua/tests/plugin_host.rs Adds a thorough integration test covering category assignment, orphan handling, agent bucketing (>20 items), total_tasks accuracy, and stale group_id clearing. Node-count assertion of 36 is arithmetically correct given the 29-session fixture, 5 synthetic groups, and 2 overflow buckets.
changelog.d/session-category-groups.changed.md New changelog fragment summarising the UI change. No code impact.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A[refresh: all sessions] --> B[assign_ranks]
    B --> C[build_tree]
    C --> D{kind == main\nand no parent_id?}
    D -- yes --> E[Add to roots\nInit descendants list]
    D -- no --> F[main_ancestor walk]
    F --> G{Found main root?}
    G -- yes --> H[Add to descendants of root]
    G -- no --> I[Promote to orphan root]
    H --> J[descendant_category]
    J --> K{kind == team / workflow?}
    K -- yes --> L[teams / workflows bucket]
    K -- no --> M{Title matches\nresearch/ponder/draft/review?}
    M -- yes --> N[Named category bucket]
    M -- no --> O{kind == task / agent?}
    O -- yes --> P[agents bucket]
    O -- no --> Q[other bucket]
    L & N & P & Q --> R[synthetic_group node\ntotal_tasks = child count]
    R --> S[root.children list]
    E & I --> T[table.sort roots by_recency]
    S --> T
    T --> U[collect → flat nodes list]
    U --> V[group_node: bucket categories\n> MAX_GROUP_CHILDREN into sub-buckets]
    V --> W[table.sort board.nodes]
    W --> X[apply_filter / render]
Loading
Prompt To Fix All With AI
### Issue 1
plugins/sessions/init.lua:168-174
**Unescaped pattern injection in `has_word`**

`word` is concatenated directly into Lua pattern strings. All current `NAMED_CATEGORIES` values (`"research"`, `"ponder"`, `"draft"`, `"review"`) are purely alphanumeric, so this is safe today. However, if any future entry contains a Lua pattern special character (`.`, `+`, `*`, `(`, `)`, `%`, `[`, `]`, `^`, or `$`), it will silently produce incorrect matches or a runtime error. A one-time escape would future-proof all four patterns.

### Issue 2
plugins/sessions/init.lua:226-228
**Nil-arithmetic crash if child rank is absent**

`rank[children[1].id] - 0.25` will throw `attempt to perform arithmetic on a nil value` if the session has no entry in `rank`. In the production path, `assign_ranks(all)` is always called before `build_tree`, so every session has a rank and this never fires. Still, there is no guard, so a missed rank (e.g., a future call site or test that skips `assign_ranks`) would produce an opaque crash rather than a graceful fallback.

### Issue 3
plugins/sessions/init.lua:184
**Redundant field inclusion in category-match text**

`normalize_session` sets `display_title = title` whenever `display_title` is absent, so for the majority of sessions `title` and `display_title` are identical. Concatenating both means every keyword present in the title appears twice in `text`, which is harmless for correctness but makes the matching logic harder to reason about. Using `title` alone — or `display_title` alone, since it is always the canonical label after normalization — would be simpler and equally correct.

---

For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.

Reviews (1): Last reviewed commit: "feat(ui): group child sessions by role" | Re-trigger Greptile

Comment thread plugins/sessions/init.lua
Comment thread plugins/sessions/init.lua
Comment thread plugins/sessions/init.lua Outdated
@w0wl0lxd
w0wl0lxd enabled auto-merge August 4, 2026 00:12

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@n00n-lua/tests/plugin_host.rs`:
- Line 2741: Replace the #[test] annotation on this test with the required
#[test_case] annotation, preserving the test body and existing behavior.

In `@plugins/sessions/init.lua`:
- Around line 168-194: Update has_word to recognize any non-alphanumeric
character as a word boundary, including punctuation such as periods, question
marks, and parentheses. Preserve exact matches and existing category detection
behavior in descendant_category.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: ad5bbb44-e016-45c7-97f9-e1418d4b1cce

📥 Commits

Reviewing files that changed from the base of the PR and between b410177 and ee1326b.

📒 Files selected for processing (3)
  • changelog.d/session-category-groups.changed.md
  • n00n-lua/tests/plugin_host.rs
  • plugins/sessions/init.lua
📜 Review details
⏰ Context from checks skipped due to timeout. (16)
  • GitHub Check: Test (Windows)
  • GitHub Check: Lint (macOS)
  • GitHub Check: Docs
  • GitHub Check: Build
  • GitHub Check: Build (Windows)
  • GitHub Check: Coverage
  • GitHub Check: Test (macOS)
  • GitHub Check: Lint (Windows)
  • GitHub Check: Rustdoc
  • GitHub Check: Test
  • GitHub Check: Unused deps
  • GitHub Check: MSRV (1.97)
  • GitHub Check: Lint
  • GitHub Check: Analyze (javascript-typescript)
  • GitHub Check: Analyze (rust)
  • GitHub Check: Criterion
🧰 Additional context used
📓 Path-based instructions (1)
**/*.rs

📄 CodeRabbit inference engine (AGENTS.md)

**/*.rs: Do not add unsafe code, FFI, global mutable state, static mut, or unchecked transmute-like behavior without written review, an explicit lint exception, and a SAFETY comment where applicable.
Do not use unwrap, expect, panic!, todo!, unimplemented!, or dbg! in production Rust code; tests are exempt from the unwrap/expect/panic restriction.
Do not silently discard failures with unwrap_or, unwrap_or_default, .ok() on Result, or equivalent defaults; return typed errors, reject the operation, or use an explicitly named fallback with sanitized structured logging.
Use idiomatic Rust, descriptive names, minimal state, and avoid unnecessary comments, bloat, and magic numbers or strings.
Import types at the top of the file and use short imported names; keep constants immediately after imports.
Use Result<T, E> and explicit error handling instead of panics; use thiserror for library/domain errors and color-eyre at binary edges.
Use #[derive(Copy)] only for structs containing one primitive field.
Prefer structured logging with useful fields and provide helpful, sanitized error messages.
Place unit tests in the same file inside #[cfg(test)] modules; use #[test_case] and snake_case test names.
Propagate typed errors with ?, ok_or_else, and map_err; library crates use thiserror and binaries use color-eyre.
Treat LLM and provider output as untrusted input; validate schemas, domain constraints, and source evidence before persistence or action.
Do not log raw provider payloads, prompts, credentials, or user session data, and never commit credentials, API keys, tokens, cookies, or auth headers.
Validate and authorize HTTP, file, queue, configuration/environment, LLM, and provider-callback inputs before mutation or persistence.
Tool execution requires allowlisted tools, scoped credentials, explicit user context, audit events, and refusal or denial tests.

Files:

  • n00n-lua/tests/plugin_host.rs
🧠 Learnings (1)
📚 Learning: 2026-07-31T19:15:04.814Z
Learnt from: w0wl0lxd
Repo: w0wl0lxd/n00n PR: 206
File: changelog.d/orchestration-hardening.fixed.md:1-1
Timestamp: 2026-07-31T19:15:04.814Z
Learning: Files in changelog.d are changelog fragments intended for user-facing release notes and may begin directly with summary prose. Do not flag a missing Markdown H1 or require an H1 solely because Markdownlint MD041 reports it in these fragment files.

Applied to files:

  • changelog.d/session-category-groups.changed.md
🪛 markdownlint-cli2 (0.23.1)
changelog.d/session-category-groups.changed.md

[warning] 1-1: First line in a file should be a top-level heading

(MD041, first-line-heading, first-line-h1)

🔇 Additional comments (4)
plugins/sessions/init.lua (2)

36-46: LGTM!

Also applies to: 163-166, 196-207, 488-488


209-227: 🎯 Functional Correctness

Verify rank order for bucketed categories.

If by_recency uses ascending rank for equal timestamps, Line 227 ranks a category behind the first bucket from make_bucket. Both nodes use children[1].updated_at. Line 609 can then place the bucket before its category in board.nodes.

Inspect by_recency and apply_filter. If filtering or navigation consumes this order, reserve the category rank before its bucket and add a regression with more than MAX_GROUP_CHILDREN descendants.

#!/bin/bash
set -euo pipefail

rg -n -P -C 16 \
  '^\s*local function (by_recency|apply_filter)\b|^\s*rank\[[^]]+\]\s*=|^\s*table\.sort\(board\.nodes' \
  plugins/sessions/init.lua

Also applies to: 605-609

n00n-lua/tests/plugin_host.rs (1)

2742-2836: LGTM!

changelog.d/session-category-groups.changed.md (1)

1-1: LGTM!

Comment thread n00n-lua/tests/plugin_host.rs Outdated
Comment thread plugins/sessions/init.lua
@w0wl0lxd

w0wl0lxd commented Aug 4, 2026

Copy link
Copy Markdown
Owner Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Aug 4, 2026

Copy link
Copy Markdown
Contributor
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@w0wl0lxd

w0wl0lxd commented Aug 4, 2026

Copy link
Copy Markdown
Owner Author

All three Codex issues have been addressed in the latest push:

  1. now escapes the input word before pattern matching.
  2. uses to avoid nil arithmetic.
  3. Category matching uses a single string, not a concatenation.

@w0wl0lxd

w0wl0lxd commented Aug 4, 2026

Copy link
Copy Markdown
Owner Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Aug 4, 2026

Copy link
Copy Markdown
Contributor
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@w0wl0lxd

w0wl0lxd commented Aug 4, 2026

Copy link
Copy Markdown
Owner Author

The has_word implementation already uses %W (non-alphanumeric) boundaries, which covers punctuation, periods, question marks, and parentheses. The test sessions_picker_groups_descendants_by_category_without_dropping_orphans has no parameters and cannot be converted to #[test_case] without changing the function signature, so it remains a plain #[test].

@w0wl0lxd

w0wl0lxd commented Aug 4, 2026

Copy link
Copy Markdown
Owner Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Aug 4, 2026

Copy link
Copy Markdown
Contributor
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@w0wl0lxd

w0wl0lxd commented Aug 4, 2026

Copy link
Copy Markdown
Owner Author

@coderabbitai review

@w0wl0lxd

w0wl0lxd commented Aug 4, 2026

Copy link
Copy Markdown
Owner Author

@coderabbitai please re-review; the #[test_case] suggestion does not compile for a non-parameterized test (bare #[test_case] triggers unstable custom_test_frameworks), and the rank-order fix in synthetic_group now assigns rank[category_id] = (rank[children[1].id] or 0) - 0.5, which keeps category nodes ranked before their buckets.

@coderabbitai

coderabbitai Bot commented Aug 4, 2026

Copy link
Copy Markdown
Contributor
🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf '%s\n' '--- Changed files ---'
git diff --name-only HEAD^ HEAD

printf '%s\n' '--- Lua structure ---'
ast-grep outline plugins/sessions/init.lua --items all --type function --match 'synthetic_group|has_word|build|sort' || true

printf '%s\n' '--- Current rank and category-related code ---'
rg -n -C 8 'synthetic_group|rank\[category_id\]|has_word|category_id|children\[1\]' plugins/sessions/init.lua

printf '%s\n' '--- Current Rust test annotations and test body ---'
rg -n -C 5 'sessions_picker_groups_descendants_by_category_without_dropping_orphans|#\[test(_case)?' n00n-lua/tests/plugin_host.rs

printf '%s\n' '--- PR patch for relevant files ---'
git diff HEAD^ HEAD -- plugins/sessions/init.lua n00n-lua/tests/plugin_host.rs

Length of output: 99532


🏁 Script executed:

#!/bin/bash
set -euo pipefail

repo="w0wl0lxd/n00n"
pr="249"

printf '%s\n' '--- Pull request metadata ---'
gh api "repos/${repo}/pulls/${pr}" \
  --jq '{number, state, head: .head.sha, base: .base.sha, updated_at, html_url}'

printf '%s\n' '--- Pull request files ---'
gh api --paginate "repos/${repo}/pulls/${pr}/files?per_page=100" \
  --jq '.[] | {filename, status, additions, deletions, sha}'

printf '%s\n' '--- Pull request commits ---'
gh api "repos/${repo}/pulls/${pr}/commits?per_page=100" \
  --jq '.[] | {sha, message: .commit.message}'

Length of output: 2831


@w0wl0lxd The current PR contains both corrections.

  • sessions_picker_groups_descendants_by_category_without_dropping_orphans correctly uses #[test].
  • synthetic_group assigns the category group rank to the first child rank minus 0.5. This places the category group before its buckets.

I will re-review PR #249 at f79f90072b17ae880feab359a2fea6e6fd31e015.

⚠️ Action not completed

Review rate limited.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@w0wl0lxd

w0wl0lxd commented Aug 5, 2026

Copy link
Copy Markdown
Owner Author

Re: test attribute on line 2743 - The test sessions_picker_groups_descendants_by_category_without_dropping_orphans is a non-parameterized test with no test-case arguments. Per project convention in this file, non-parameterized tests use #[test] and parameterized tests use #[test_case::test_case(...)]. Bare #[test_case] is invalid Rust syntax without arguments (it either triggers the unstable custom_test_frameworks built-in attribute or requires the test-case crate macro with at least one test-case argument). The current #[test] attribute is correct and idiomatic for this non-parameterized test.

@w0wl0lxd

w0wl0lxd commented Aug 5, 2026

Copy link
Copy Markdown
Owner Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Aug 5, 2026

Copy link
Copy Markdown
Contributor
⚠️ Action not completed

Review rate limited.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@w0wl0lxd

w0wl0lxd commented Aug 5, 2026

Copy link
Copy Markdown
Owner Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Aug 5, 2026

Copy link
Copy Markdown
Contributor
⚠️ Action not completed

Review rate limited.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Performance Alert ⚠️

Possible performance regression was detected for benchmark 'Criterion'.
Benchmark result of this commit is worse than the previous benchmark result exceeding threshold 2.

Benchmark suite Current: 63757d8 Previous: ab3f257 Ratio
buffer_rw/jit_watchdog 192393 ns/iter (± 966) 80574 ns/iter (± 5571) 2.39
buffer_rw/jit_none 191808 ns/iter (± 717) 89730 ns/iter (± 3476) 2.14

This comment was automatically generated by workflow using github-action-benchmark.

@w0wl0lxd

Copy link
Copy Markdown
Owner Author

@codex review

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Can't wait for the next one!

Reviewed commit: e98b01b5f4

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@w0wl0lxd

Copy link
Copy Markdown
Owner Author

@codex review

@greptile-apps please review

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Aug 12, 2026

Copy link
Copy Markdown
Contributor

@w0wl0lxd I will review the current changes in #249.

⚠️ Action not completed

Review rate limited.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Nice work!

Reviewed commit: f6bc162ca8

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@w0wl0lxd
w0wl0lxd merged commit 81d7242 into main Aug 12, 2026
30 checks passed
@linear-code

linear-code Bot commented Aug 12, 2026

Copy link
Copy Markdown

N00N-261

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