Skip to content

Security: collapsed rule groups with 7-day counts, redaction exceptions; pin core v0.86.0 - #389

Merged
fylorn merged 2 commits into
devfrom
feat/rule-groups-collapsed
Oct 30, 2026
Merged

fylorn merged 2 commits into
devfrom
feat/rule-groups-collapsed

Conversation

@fylorn

@fylorn fylorn commented Oct 29, 2026 •

Copy link
Copy Markdown
Contributor

What

Pins core v0.86.0 (control API 57) and builds two UI pieces on it.

Rule groups (all three rule tables)

  • Groups start collapsed. Open groups are remembered per protection (localStorage).
  • Group head: name · N rules · N on · N matches in the last 7 days (zh: N 条 · 已开 N 条 · 最近 7 天命中 N 次). Groups without matches show no count.
  • Counts come from the new GET /security/counts (exact per-rule totals since the start of the 7-day window the log uses). They are read when the tab opens, not on every new request, so groups do not reorder while being read.
  • Built-in groups with matches come first; both parts keep core's order; the custom group stays last.
  • Search expands every matching group; collapsing one during a search lasts only for that search term.
  • Keyboard: Enter / Space toggle a head (Right expands, Left collapses); Up / Down move between heads and rows of expanded groups.

Redaction exceptions

  • Secrets & privacy tab: a section Exceptions · N values below the rule table shows the masked value, the rule that first found it (none for values added by hand), when it was added, and Remove. Removing asks for confirmation. Add exception opens a dialog with a hidden input and an eye toggle. At the limit the button is disabled and the limit is shown next to it. With no exceptions, the section shows one line and the button.
  • Security log: an expanded hit shows List as exception when core marks it exceptable. The confirmation states that the value will no longer be replaced or recorded, and shows the masked value and the rule. If core refuses (entry too old, saved secret, limit reached), its message is shown in the dialog. Values that are exceptions now are tagged Exception in the log row and in the hit detail.
  • Test: excepted values are not highlighted and read Exception, not handled.

Pin

  • All core crates at v0.86.0, regenerated TS bindings, Chinese sentences for the new message codes, and the new endpoints on both webview allow-lists.
  • Screenshot fixtures were regenerated against v0.86.0, and the screenshot mocks answer the new endpoints.

Notes

Tests

  • src/security/groups.test.tsx: counts, ordering, collapse state, search auto-expand, keyboard.
  • src/security/exceptions.test.tsx: section states (empty, list, at limit, English), the hit-detail button and tag, and the calls sent to core.
  • Typecheck, vitest, cargo fmt, clippy and the full Rust suite (including the control-plane handshake against twcore v0.86.0) pass locally.
  • The UI was checked in the full-mock preview (WKWebView, light / dark).

🤖 Generated with Claude Code

fylorn and others added 2 commits October 30, 2026 05:58
The rule tables (secrets & privacy, dangerous commands, content filter)
now start with every group collapsed. A group head reads
"name · N rules · N on · N matches in the last 7 days" and toggles on
click, Enter or Space (Right expands, Left collapses); Up/Down move
between heads and the rows of expanded groups. Which groups are open is
remembered per protection in localStorage.

Searching expands every matching group; a group collapsed during a
search stays collapsed only for that search term.

Built-in groups with matches in the last 7 days move to the front, each
part keeping core's order; the custom group stays last. Core has no
per-rule counts, so the counts come from one page (up to 500) of the
protection's security log over the same 7-day window the log uses; when
the window holds more than one page the count is a lower bound and is
written as "N+". The page is read when the tab opens, not on every new
request, so groups do not jump while being read. Groups without matches
show no count.

The "Built-in" label in group heads is dropped (the head format follows
the spec).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Core v0.86.0 (control API 57).

- Group heads take their 7-day counts from GET /security/counts: exact
  per-rule totals (the sum of each entry's count), so the one-page log
  read and the "N+" lower bound are gone.
- Redaction exceptions. Below the secrets & privacy rule table, a
  section "Exceptions · N values" lists each excepted value (masked),
  the rule that first found it (none for values added by hand), when it
  was added, and "Remove". "Add exception" opens a dialog with a hidden
  input and the eye toggle; it is disabled at the limit, with the
  limit written next to it. Without exceptions the section is one line
  and the button. Removing asks for confirmation (it cannot be undone
  without the value).
- Security log: an expanded redaction hit offers "List as exception"
  when core marks it exceptable; the confirmation shows the masked value
  and the rule. Values that are exceptions now carry an "Exception" tag
  in the log row and the hit detail. Core's refusal (entry too old,
  saved secret, limit reached) is shown in the dialog.
- Test: excepted values are not highlighted and read "Exception, not
  handled".
- New endpoints are on the webview allow-list (both sides); Chinese
  sentences for the new message codes; regenerated bindings and
  screenshot fixtures; screenshot mocks answer the new endpoints.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@fylorn fylorn changed the title Security rules: groups start collapsed, heads show 7-day matches Security: collapsed rule groups with 7-day counts, redaction exceptions; pin core v0.86.0 Oct 30, 2026
@fylorn
fylorn merged commit 0b07385 into dev Oct 30, 2026
6 checks passed
@fylorn
fylorn deleted the feat/rule-groups-collapsed branch October 30, 2026 01:32
@github-actions github-actions Bot locked and limited conversation to collaborators Oct 30, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant