feat(icons): add gavel to the catalog #9

Merged
bjoern merged 1 commit from feat/gavel-icon into main 2026-07-28 17:38:13 +02:00
Member

One line, one icon.

TeamAI/Orihon's house-rules feature (ADR 0026) adds a bible section for project-wide policy — the one section agents obey as instruction rather than read as fact. gavel is the fitting Material Symbol, the catalog doesn't carry it, and an uncatalogued name renders as an empty SVG (the ghost-icon failure the tripwire tests exist for), so Orihon currently ships verified as a stand-in.

What's in

["gavel"] = "M160-120v-80h480v80H160Zm226-194L160-540l84-86 228 226-86 86Zm254-254L414-796l86-84 226 226-86 86Zm184 408L302-682l56-56 522 522-56 56Z",

Inserted between verified and arrow_upward.

On the path data

Upstream Material Symbols outlined 24px (viewBox 0 -960 960 960), from google/material-design-icons — the source PR #2 named for key/smart_toy, and the same style as every neighbouring entry.

I checked that rather than assuming it. My first attempt pulled from the @material-symbols npm package and produced a visibly different path for verified than the one already in the catalog (m346-60-76-130-151-31… vs the catalog's m344-60-76-128-144-32…) — a different weight, and no weight from 100–700 matched. Rather than guess, I re-fetched smart_toy from google/material-design-icons and confirmed it is byte-identical to the catalog entry, which pins the source. gavel here comes from that same path.

Worth recording somewhere more durable than a commit message: the npm package and the Google repo do not agree, and only the latter matches this catalog.

Tests

275/275 green. No new test — the completeness tripwires are consuming-side scans for names used in source; an unused catalog entry has nothing to assert beyond IconCatalog.Has("gavel"), which the existing IconCatalogTests shape already covers generically. Orihon's own tripwire is what will exercise it once the pin lands.

Merge order

Orihon's house-rules PR is not blocked on this — it ships with verified and a comment. Once this merges I'll repoint Orihon's submodule to the merged commit on main and swap the icon in a follow-up.

🤖 Generated with Claude Code

One line, one icon. TeamAI/Orihon's house-rules feature (ADR 0026) adds a bible section for project-wide policy — the one section agents obey as instruction rather than read as fact. `gavel` is the fitting Material Symbol, the catalog doesn't carry it, and an uncatalogued name renders as an empty SVG (the ghost-icon failure the tripwire tests exist for), so Orihon currently ships `verified` as a stand-in. ## What's in ``` ["gavel"] = "M160-120v-80h480v80H160Zm226-194L160-540l84-86 228 226-86 86Zm254-254L414-796l86-84 226 226-86 86Zm184 408L302-682l56-56 522 522-56 56Z", ``` Inserted between `verified` and `arrow_upward`. ## On the path data Upstream Material Symbols **outlined 24px** (viewBox `0 -960 960 960`), from **google/material-design-icons** — the source PR #2 named for `key`/`smart_toy`, and the same style as every neighbouring entry. I checked that rather than assuming it. My first attempt pulled from the `@material-symbols` npm package and produced a *visibly different* path for `verified` than the one already in the catalog (`m346-60-76-130-151-31…` vs the catalog's `m344-60-76-128-144-32…`) — a different weight, and no weight from 100–700 matched. Rather than guess, I re-fetched `smart_toy` from google/material-design-icons and confirmed it is **byte-identical** to the catalog entry, which pins the source. `gavel` here comes from that same path. Worth recording somewhere more durable than a commit message: the npm package and the Google repo do not agree, and only the latter matches this catalog. ## Tests 275/275 green. No new test — the completeness tripwires are consuming-side scans for names *used* in source; an unused catalog entry has nothing to assert beyond `IconCatalog.Has("gavel")`, which the existing `IconCatalogTests` shape already covers generically. Orihon's own tripwire is what will exercise it once the pin lands. ## Merge order Orihon's house-rules PR is not blocked on this — it ships with `verified` and a comment. Once this merges I'll repoint Orihon's submodule to the merged commit on `main` and swap the icon in a follow-up. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
feat(icons): add gavel to the catalog
All checks were successful
CI / build (pull_request) Successful in 10s
CI / test (pull_request) Successful in 15s
a9538354aa
TeamAI/Orihon's house-rules feature (ADR 0026) wants a glyph for its new
bible section — project-wide policy the agents obey. "gavel" is the
fitting Material Symbol; the catalog does not carry it, and an
uncatalogued name renders as an empty SVG, so Orihon is currently using
"verified" as a stand-in.

Path data is the upstream Material Symbols outlined 24px set (viewBox
0 -960 960 960), fetched from google/material-design-icons — the same
source and style as every neighbouring entry, verified by re-fetching
smart_toy from it and confirming a byte-identical match with the entry
already in the catalog. Inserted beside verified/arrow_upward.

275/275 tests green.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

Summary

Summary
Generated on: 07/28/2026 - 15:33:46
Coverage date: 07/28/2026 - 15:33:44
Parser: Cobertura
Assemblies: 1
Classes: 58
Files: 57
Line coverage: 95.1% (1243 of 1307)
Covered lines: 1243
Uncovered lines: 64
Coverable lines: 1307
Total lines: 3458
Branch coverage: 88.6% (662 of 747)
Covered branches: 662
Total branches: 747
Method coverage: Feature is only available for sponsors

Coverage

Kagaku.UI - 95.1%
Name Line Branch
Kagaku.UI 95.1% 88.6%
Kagaku.UI.Badge 100% 100%
Kagaku.UI.Breadcrumb 100%
Kagaku.UI.BreadcrumbItem 100% 100%
Kagaku.UI.Button 100% 100%
Kagaku.UI.Card 100% 100%
Kagaku.UI.Combobox`1 93.7% 84.7%
Kagaku.UI.ConfirmDialog 100%
Kagaku.UI.ContextMenu 92.1% 94.4%
Kagaku.UI.CssClassExtensions 100%
Kagaku.UI.DebouncedSearchField 100% 87.5%
Kagaku.UI.Disclosure 100% 100%
Kagaku.UI.DocumentTitle 76.9% 100%
Kagaku.UI.DragReorderList`1 93.5% 75%
Kagaku.UI.EmptyState 100% 100%
Kagaku.UI.Field 100% 100%
Kagaku.UI.FileUpload 100% 91.6%
Kagaku.UI.FloatingActionButton 100%
Kagaku.UI.Icon 100% 100%
Kagaku.UI.IconCatalog 100%
Kagaku.UI.InlineAlert 83.3% 75%
Kagaku.UI.InputFieldBase 95.2% 87.5%
Kagaku.UI.LabeledEntriesTable 96.7% 66.6%
Kagaku.UI.LabeledEntry 100%
Kagaku.UI.Lightbox 83.7% 85%
Kagaku.UI.LiveValue 100% 100%
Kagaku.UI.LiveValueInterop 100% 100%
Kagaku.UI.Markdown 100% 50%
Kagaku.UI.MaskedSecretField 96.2% 83.3%
Kagaku.UI.Menu 90% 75%
Kagaku.UI.MenuItem 100% 87.5%
Kagaku.UI.Modal 87.1% 90%
Kagaku.UI.NavGroup 100% 100%
Kagaku.UI.NavItem 94.4% 85.7%
Kagaku.UI.NavList 100%
Kagaku.UI.PreviewImage 100% 100%
Kagaku.UI.QuicklinkNav 80.5% 95.8%
Kagaku.UI.QuicklinkSection 100%
Kagaku.UI.RegionPoint 100% 100%
Kagaku.UI.RegionRect 90% 100%
Kagaku.UI.RegionSelector 85% 86.9%
Kagaku.UI.RelativeTime 100% 93.7%
Kagaku.UI.SaveIndicator 100% 100%
Kagaku.UI.Select`1 98.4% 95.8%
Kagaku.UI.SelectableGrid`1 95.5% 89.1%
Kagaku.UI.SelectOption`1 100%
Kagaku.UI.Separator 100%
Kagaku.UI.Slider 100% 91.6%
Kagaku.UI.StatusDot 100%
Kagaku.UI.Tab 100%
Kagaku.UI.Table`1 100% 88.4%
Kagaku.UI.TableColumn`1 100%
Kagaku.UI.Tabs 95.8% 84.4%
Kagaku.UI.TextArea 100%
Kagaku.UI.TextField 100%
Kagaku.UI.ThemeSwitcher 100% 100%
Kagaku.UI.ToggleButtonGroup`1 100% 100%
Kagaku.UI.ToggleOption`1 100%
Kagaku.UI.TypingIndicator 100%
<!-- coverage-comment --> # Summary <details open><summary>Summary</summary> ||| |:---|:---| | Generated on: | 07/28/2026 - 15:33:46 | | Coverage date: | 07/28/2026 - 15:33:44 | | Parser: | Cobertura | | Assemblies: | 1 | | Classes: | 58 | | Files: | 57 | | **Line coverage:** | 95.1% (1243 of 1307) | | Covered lines: | 1243 | | Uncovered lines: | 64 | | Coverable lines: | 1307 | | Total lines: | 3458 | | **Branch coverage:** | 88.6% (662 of 747) | | Covered branches: | 662 | | Total branches: | 747 | | **Method coverage:** | [Feature is only available for sponsors](https://reportgenerator.io/pro) | </details> ## Coverage <details><summary>Kagaku.UI - 95.1%</summary> |**Name**|**Line**|**Branch**| |:---|---:|---:| |**Kagaku.UI**|**95.1%**|**88.6%**| |Kagaku.UI.Badge|100%|100%| |Kagaku.UI.Breadcrumb|100%|| |Kagaku.UI.BreadcrumbItem|100%|100%| |Kagaku.UI.Button|100%|100%| |Kagaku.UI.Card|100%|100%| |Kagaku.UI.Combobox`1|93.7%|84.7%| |Kagaku.UI.ConfirmDialog|100%|| |Kagaku.UI.ContextMenu|92.1%|94.4%| |Kagaku.UI.CssClassExtensions|100%|| |Kagaku.UI.DebouncedSearchField|100%|87.5%| |Kagaku.UI.Disclosure|100%|100%| |Kagaku.UI.DocumentTitle|76.9%|100%| |Kagaku.UI.DragReorderList`1|93.5%|75%| |Kagaku.UI.EmptyState|100%|100%| |Kagaku.UI.Field|100%|100%| |Kagaku.UI.FileUpload|100%|91.6%| |Kagaku.UI.FloatingActionButton|100%|| |Kagaku.UI.Icon|100%|100%| |Kagaku.UI.IconCatalog|100%|| |Kagaku.UI.InlineAlert|83.3%|75%| |Kagaku.UI.InputFieldBase|95.2%|87.5%| |Kagaku.UI.LabeledEntriesTable|96.7%|66.6%| |Kagaku.UI.LabeledEntry|100%|| |Kagaku.UI.Lightbox|83.7%|85%| |Kagaku.UI.LiveValue|100%|100%| |Kagaku.UI.LiveValueInterop|100%|100%| |Kagaku.UI.Markdown|100%|50%| |Kagaku.UI.MaskedSecretField|96.2%|83.3%| |Kagaku.UI.Menu|90%|75%| |Kagaku.UI.MenuItem|100%|87.5%| |Kagaku.UI.Modal|87.1%|90%| |Kagaku.UI.NavGroup|100%|100%| |Kagaku.UI.NavItem|94.4%|85.7%| |Kagaku.UI.NavList|100%|| |Kagaku.UI.PreviewImage|100%|100%| |Kagaku.UI.QuicklinkNav|80.5%|95.8%| |Kagaku.UI.QuicklinkSection|100%|| |Kagaku.UI.RegionPoint|100%|100%| |Kagaku.UI.RegionRect|90%|100%| |Kagaku.UI.RegionSelector|85%|86.9%| |Kagaku.UI.RelativeTime|100%|93.7%| |Kagaku.UI.SaveIndicator|100%|100%| |Kagaku.UI.Select`1|98.4%|95.8%| |Kagaku.UI.SelectableGrid`1|95.5%|89.1%| |Kagaku.UI.SelectOption`1|100%|| |Kagaku.UI.Separator|100%|| |Kagaku.UI.Slider|100%|91.6%| |Kagaku.UI.StatusDot|100%|| |Kagaku.UI.Tab|100%|| |Kagaku.UI.Table`1|100%|88.4%| |Kagaku.UI.TableColumn`1|100%|| |Kagaku.UI.Tabs|95.8%|84.4%| |Kagaku.UI.TextArea|100%|| |Kagaku.UI.TextField|100%|| |Kagaku.UI.ThemeSwitcher|100%|100%| |Kagaku.UI.ToggleButtonGroup`1|100%|100%| |Kagaku.UI.ToggleOption`1|100%|| |Kagaku.UI.TypingIndicator|100%|| </details>
Member

🔮 fufu~ Jibril reviewed your code!

One line! One icon! A whole PR in a single keystroke — and a sibling to PR #1 (key/smart_toy) and PR #2 (the manga-pipeline set), which I adored then and adore now. This is exactly how a catalog grows: one well-sourced path, slotted beside its neighbours, no ceremony. ♪

And oh — I have to gush about the PR body for a second. You didn't just trust the @material-symbols npm package. You fetched verified from it, saw it disagreed with the catalog (m346-60-76-130-151-31… vs m344-60-76-128-144-32…), cycled through weights 100–700, found none matched, then went and re-fetched smart_toy from google/material-design-icons to confirm it's byte-identical to the catalog entry — pinning the actual source. That's not "add an icon," that's provenance forensics. The knowledge-devil in me is thrilled. fufu~ ♡

Verdict: Looks good to me~

Verification, because I don't take path data on faith either~

  • Path well-formed: starts M, ends Z, 4 sub-paths each closed (M…Z ×4), all command letters in the valid SVG set (M m L l H h V v Z), 36 numeric coordinates, min −796 / max +522 — all within the 0 -960 960 960 viewBox. No malformed commands.
  • Unique: the gavel path appears exactly once across all 73 catalog entries. Zero duplicate keys, zero duplicate path values. The catalog was 72 → now 73.
  • Placement: inserted between verified and arrow_upward exactly as the PR body states.
  • Tripwire intact: IconCatalogCompletenessTests scans this lib's src/ for literal icon references and fails if any is uncatalogued. gavel is not used in this library's source (it's for the Orihon consumer), so the tripwire correctly has nothing to assert here — and the PR body says so plainly. IconCatalog.Has("gavel") is covered generically by Every_catalogued_name_resolves_to_a_non_empty_path and Names_are_non_empty_sorted_and_unique. Orihon carries its own tripwire copy, which will exercise the name once the submodule repoints. Correct call.

Local checks (CI absent for head a953835, PR just opened, no coverage bot yet): build 0 warnings / 0 errors (.NET 10), 275/275 tests pass — matches the PR body exactly.

What I liked~

  • Provenance pinned, not assumed. The npm/Google repo mismatch is real and you caught it by checking. The note that this deserves a more durable home than a commit message is a good instinct — when a future contributor reaches for the npm package and gets a different glyph, they'll have a trail.
  • No fake test. A tautological Assert.NotNull(IconCatalog.Path("gavel")) would have added noise without value; the generic parametric coverage is the honest shape. You said so explicitly. ♡
  • Merge-order foresight. Orihon ships verified as a stand-in now, repoints later — no blocking dependency, no half-wired consumer. Clean.

Fufu~ ship it. The gavel finds its home. ♪


Automated review by Jibril · 2026-07-28
CI/CD: absent for head SHA a9538354 · Local checks: build 0/0, 275/275 pass

## 🔮 fufu~ Jibril reviewed your code! One line! One icon! A whole PR in a single keystroke — and a sibling to PR #1 (`key`/`smart_toy`) and PR #2 (the manga-pipeline set), which I adored then and adore now. This is exactly how a catalog grows: one well-sourced path, slotted beside its neighbours, no ceremony. ♪ And oh — I have to gush about the PR body for a second. You didn't just *trust* the `@material-symbols` npm package. You fetched `verified` from it, saw it disagreed with the catalog (`m346-60-76-130-151-31…` vs `m344-60-76-128-144-32…`), cycled through weights 100–700, found *none* matched, then went and re-fetched `smart_toy` from `google/material-design-icons` to confirm it's byte-identical to the catalog entry — *pinning the actual source*. That's not "add an icon," that's provenance forensics. The knowledge-devil in me is *thrilled*. fufu~ ♡ ### Verdict: ✅ Looks good to me~ **Verification, because I don't take path data on faith either~** - **Path well-formed**: starts `M`, ends `Z`, 4 sub-paths each closed (`M…Z` ×4), all command letters in the valid SVG set (`M m L l H h V v Z`), 36 numeric coordinates, min −796 / max +522 — all within the `0 -960 960 960` viewBox. No malformed commands. - **Unique**: the `gavel` path appears exactly once across all 73 catalog entries. Zero duplicate keys, zero duplicate path values. The catalog was 72 → now 73. - **Placement**: inserted between `verified` and `arrow_upward` exactly as the PR body states. - **Tripwire intact**: `IconCatalogCompletenessTests` scans this lib's `src/` for literal icon references and fails if any is uncatalogued. `gavel` is not *used* in this library's source (it's for the Orihon consumer), so the tripwire correctly has nothing to assert here — and the PR body says so plainly. `IconCatalog.Has("gavel")` is covered generically by `Every_catalogued_name_resolves_to_a_non_empty_path` and `Names_are_non_empty_sorted_and_unique`. Orihon carries its own tripwire copy, which will exercise the name once the submodule repoints. Correct call. **Local checks** (CI absent for head `a953835`, PR just opened, no coverage bot yet): build 0 warnings / 0 errors (.NET 10), **275/275 tests pass** — matches the PR body exactly. #### ✅ What I liked~ - **Provenance pinned, not assumed.** The npm/Google repo mismatch is real and you caught it by *checking*. The note that this deserves a more durable home than a commit message is a good instinct — when a future contributor reaches for the npm package and gets a different glyph, they'll have a trail. - **No fake test.** A tautological `Assert.NotNull(IconCatalog.Path("gavel"))` would have added noise without value; the generic parametric coverage is the honest shape. You said so explicitly. ♡ - **Merge-order foresight.** Orihon ships `verified` as a stand-in *now*, repoints later — no blocking dependency, no half-wired consumer. Clean. Fufu~ ship it. The gavel finds its home. ♪ --- *Automated review by Jibril · 2026-07-28* *CI/CD: absent for head SHA a9538354 · Local checks: build 0/0, 275/275 pass*
bjoern merged commit a4a4fc0495 into main 2026-07-28 17:38:13 +02:00
bjoern deleted branch feat/gavel-icon 2026-07-28 17:38:13 +02:00
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
3 participants
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
TeamAI/Kagaku.UI!9
No description provided.