feat(ui): each field type has its own icon in the designer; an option's × lines up with the field's trash #27

Merged
bjoern merged 3 commits from fix/field-type-icons into main 2026-09-25 19:38:27 +02:00
Member

Two small polish items for the category designer, from your read of the fields UI.

⚠️ Merge Kagaku.UI #27 first. This PR pins the submodule to that PR's branch head (d562e67). Once #27 merges, I'll move the pin to Kagaku.UI's merged main in this PR.

Icons per field type

The type menu used to show the same input icon for every type. Now each type has its own icon, on the menu's trigger and on each menu item:

Type Icon
Short text short_text
Long text (markdown) notes
Number tag (#)
Choice arrow_drop_down_circle
Date calendar_today

Four of these are new in Kagaku.UI (#27); notes was already in the catalog.

The labels and icons now live together in FieldShapes, which replaces the designer's private ShapeLabel. Like before, a field kind with no entry throws rather than showing as another type.

Icon names built in a switch are invisible to the icon-catalog scan, which only reads Icon="…" literals. So a new test, FieldShapesTests, checks every type's icon against Kagaku.UI's catalog and checks that no two types share one. The AGENTS.md rule for a new field kind now includes "its label and icon of its own in the designer's type menu".

The × lines up with the trash

An option's row sits in a second reorder list nested inside the field's row. Kagaku.UI's reorder rows each have padding: var(--space-2), so the nested row added another 8 px on the right. The options' end padding is now dropped in the designer's scoped CSS.

Verification

  • Browser, seeded app, light and dark:
    • every field's trash and every option's × end at the same x (1378 px at 1440 wide);
    • every menu item renders its icon;
    • no console errors.
  • Tests: dotnet test passes everything:
    Project Passed
    Domain 328
    UseCases 54
    Integration 305
    BlazorAdapter 321 (+2 new)
    Kagaku.Flow 669
    Kagaku.Flow.OpenRouter 71

🤖 Generated with Claude Code

Two small polish items for the category designer, from your read of the fields UI. **⚠️ Merge Kagaku.UI #27 first.** This PR pins the submodule to that PR's branch head (`d562e67`). Once #27 merges, I'll move the pin to Kagaku.UI's merged `main` in this PR. ## Icons per field type The type menu used to show the same `input` icon for every type. Now each type has its own icon, on the menu's trigger and on each menu item: | Type | Icon | |---|---| | Short text | `short_text` | | Long text (markdown) | `notes` | | Number | `tag` (#) | | Choice | `arrow_drop_down_circle` | | Date | `calendar_today` | Four of these are new in Kagaku.UI (#27); `notes` was already in the catalog. The labels and icons now live together in `FieldShapes`, which replaces the designer's private `ShapeLabel`. Like before, a field kind with no entry throws rather than showing as another type. Icon names built in a switch are invisible to the icon-catalog scan, which only reads `Icon="…"` literals. So a new test, `FieldShapesTests`, checks every type's icon against Kagaku.UI's catalog and checks that no two types share one. The AGENTS.md rule for a new field kind now includes "its label and icon of its own in the designer's type menu". ## The × lines up with the trash An option's row sits in a second reorder list nested inside the field's row. Kagaku.UI's reorder rows each have `padding: var(--space-2)`, so the nested row added another 8 px on the right. The options' end padding is now dropped in the designer's scoped CSS. ## Verification - **Browser, seeded app, light and dark:** - every field's trash and every option's × end at the same x (1378 px at 1440 wide); - every menu item renders its icon; - no console errors. - **Tests:** `dotnet test` passes everything: | Project | Passed | |---|---| | Domain | 328 | | UseCases | 54 | | Integration | 305 | | BlazorAdapter | 321 (+2 new) | | Kagaku.Flow | 669 | | Kagaku.Flow.OpenRouter | 71 | 🤖 Generated with [Claude Code](https://claude.com/claude-code)
feat(ui): each field type has its own icon in the designer; an option's remove lines up with the field's
All checks were successful
CI / build (pull_request) Successful in 35s
CI / test (pull_request) Successful in 54s
20b51b380d
- The type menu shows the type's icon on its trigger and on each item — short_text, notes, tag,
  arrow_drop_down_circle, calendar_today — from FieldShapes, which holds the labels too. Icon names
  built in a switch escape the catalog scan over literals, so FieldShapesTests checks each against
  Kagaku.UI's catalog and that no two types share one.
- An option's row sits in a nested reorder list whose rows carry the list's own end padding; without
  it, an option's × lines up with its field's trash.
- Kagaku.UI pinned to the icon branch (Kagaku.UI #27) until it merges.
- AGENTS.md: a new field kind needs its label and icon of its own in FieldShapes.

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

🔄 Auto-updating coverage report — this comment is regenerated on every push, so the numbers below always reflect the commit shown here, not the branch tip.

Commit: 40856a2 · Generated: 2026-09-25 17:29:01 UTC · Revision: #3

Summary

Summary
Generated on: 09/25/2026 - 17:29:01
Coverage date: 09/25/2026 - 17:28:43 - 09/25/2026 - 17:28:59
Parser: MultiReport (6x Cobertura)
Assemblies: 9
Classes: 406
Files: 386
Line coverage: 97.4% (11341 of 11636)
Covered lines: 11341
Uncovered lines: 295
Coverable lines: 11636
Total lines: 25000
Branch coverage: 92.7% (4210 of 4537)
Covered branches: 4210
Total branches: 4537
Method coverage: Feature is only available for sponsors

Coverage

Kagaku.Flow - 99.5%
Name Line Branch
Kagaku.Flow 99.5% 98.9%
Kagaku.Flow.Budgeting.BudgetRequest 100%
Kagaku.Flow.Budgeting.ConsumerBudget 100%
Kagaku.Flow.FlowJson 100%
Kagaku.Flow.Graphs.GraphDefinition 100%
Kagaku.Flow.Graphs.GraphDocument 100% 100%
Kagaku.Flow.Graphs.GraphEdge 100%
Kagaku.Flow.Graphs.GraphIndex 100% 100%
Kagaku.Flow.Graphs.GraphLoadError 100%
Kagaku.Flow.Graphs.GraphLoadResult 100%
Kagaku.Flow.Graphs.GraphNode 100%
Kagaku.Flow.Graphs.GraphPosition 100%
Kagaku.Flow.Graphs.GraphReader 100% 100%
Kagaku.Flow.Graphs.GraphSchema 100% 100%
Kagaku.Flow.Graphs.GraphShapeException 100%
Kagaku.Flow.Graphs.GraphWriter 100% 100%
Kagaku.Flow.Graphs.SocketRef 100%
Kagaku.Flow.Graphs.WireText 100% 100%
Kagaku.Flow.Nodes.CanvasDescriptorWriter 100% 100%
Kagaku.Flow.Nodes.ConfigProblem 100%
Kagaku.Flow.Nodes.Names 100%
Kagaku.Flow.Nodes.NodeDescriptor 100% 100%
Kagaku.Flow.Nodes.NodeRegistry 100% 100%
Kagaku.Flow.Nodes.NodeSockets 100% 100%
Kagaku.Flow.Nodes.SinkDescriptor 100%
Kagaku.Flow.Nodes.SocketTypes 100% 100%
Kagaku.Flow.Nodes.SourceDescriptor 100%
Kagaku.Flow.Nodes.TemplateField 100%
Kagaku.Flow.Runs.LedgerChange 100% 100%
Kagaku.Flow.Runs.LedgerTransitions 100% 100%
Kagaku.Flow.Runs.NodeAttempt 100%
Kagaku.Flow.Runs.NodeFacts 100%
Kagaku.Flow.Runs.NodeRun 100%
Kagaku.Flow.Runs.Run 100% 100%
Kagaku.Flow.Runs.RunEvent 100%
Kagaku.Flow.Runs.RunStatuses 100% 100%
Kagaku.Flow.Runs.RunTrigger 100% 100%
Kagaku.Flow.Templating.InputsWalker 100% 100%
Kagaku.Flow.Templating.ParsedTemplate 100% 100%
Kagaku.Flow.Templating.SandboxedTemplateContext 100% 100%
Kagaku.Flow.Templating.TemplateError 100%
Kagaku.Flow.Templating.TemplateHost 100% 100%
Kagaku.Flow.Templating.TemplateLimits 100%
Kagaku.Flow.Templating.TemplateModel 100% 100%
Kagaku.Flow.Templating.TemplateProblem 100%
Kagaku.Flow.Templating.TemplateRenderRequest 100% 100%
Kagaku.Flow.Templating.TemplateRenderResult 100%
Kagaku.Flow.Templating.TemplateRun 100%
Kagaku.Flow.Templating.TemplateSinks 100%
Kagaku.Flow.Templating.TemplateValues 100% 100%
Kagaku.Flow.Validation.GraphValidation 100% 100%
Kagaku.Flow.Validation.GraphValidationContext 100%
Kagaku.Flow.Validation.HookFailure 100%
Kagaku.Flow.Validation.ResolvedGraph 100% 100%
Kagaku.Flow.Validation.ValidationError 100%
Kagaku.Flow.Validation.ValidationReport 100%
System.Text.RegularExpressions.Generated 97.4% 92.8%
System.Text.RegularExpressions.Generated.<RegexGenerator_g>F6329A328226B0CF
E95E47D27E8B105AC5589487C0997B6B65384AEDBF572144E__ColorToken_2
97.4% 94.4%
System.Text.RegularExpressions.Generated.<RegexGenerator_g>F6329A328226B0CF
E95E47D27E8B105AC5589487C0997B6B65384AEDBF572144E__Socket_1
97.2% 94.4%
System.Text.RegularExpressions.Generated.<RegexGenerator_g>F6329A328226B0CF
E95E47D27E8B105AC5589487C0997B6B65384AEDBF572144E__TypeId_0
97.2% 94.4%
Kagaku.Flow.OpenRouter - 100%
Name Line Branch
Kagaku.Flow.OpenRouter 100% 100%
Kagaku.Flow.OpenRouter.Catalog.ModelCapabilities 100% 100%
Kagaku.Flow.OpenRouter.Gateway.OpenRouterGateway 100% 100%
Kagaku.Flow.OpenRouter.Gateway.OpenRouterGatewayOptions 100%
Kagaku.Flow.OpenRouter.Gateway.OpenRouterKeyLookup 100% 100%
Kagaku.Flow.OpenRouter.OpenRouterServiceCollectionExtensions 100% 100%
Kagaku.Flow.Testing - 100%
Name Line Branch
Kagaku.Flow.Testing 100% 100%
Kagaku.Flow.Testing.InMemoryRunLedger 100% 100%
Kagaku.Flow.Testing.RunLedgerContract 100% 100%
Kagaku.Flow.Testing.RunLedgerContractException 100%
Tsumugi.BlazorAdapter - 96.3%
Name Line Branch
Tsumugi.BlazorAdapter 96.3% 92.3%
Tsumugi.BlazorAdapter.BlazorAdapterAssembly 100%
Tsumugi.BlazorAdapter.Documents.CategoryCreated 100%
Tsumugi.BlazorAdapter.Documents.CategoryEditor 91.8% 87.2%
Tsumugi.BlazorAdapter.Documents.CategorySaved 100%
Tsumugi.BlazorAdapter.Documents.ChangeCategoryFieldsRequested 100%
Tsumugi.BlazorAdapter.Documents.CreateCategoryRequested 100%
Tsumugi.BlazorAdapter.Documents.CreateDocumentRequested 100%
Tsumugi.BlazorAdapter.Documents.DeleteCategoryChoice 100%
Tsumugi.BlazorAdapter.Documents.DeleteCategoryDialog 100% 94.1%
Tsumugi.BlazorAdapter.Documents.DeleteCategoryRequested 100%
Tsumugi.BlazorAdapter.Documents.DeleteDocumentRequested 100%
Tsumugi.BlazorAdapter.Documents.DocumentAutoSaveFailed 100%
Tsumugi.BlazorAdapter.Documents.DocumentCreated 100%
Tsumugi.BlazorAdapter.Documents.DocumentEditor 94.8% 88%
Tsumugi.BlazorAdapter.Documents.DocumentsActionFailed 100%
Tsumugi.BlazorAdapter.Documents.DocumentSaved 100%
Tsumugi.BlazorAdapter.Documents.DocumentsEffects 100% 100%
Tsumugi.BlazorAdapter.Documents.DocumentsList 98.2% 92.4%
Tsumugi.BlazorAdapter.Documents.DocumentsLoaded 100%
Tsumugi.BlazorAdapter.Documents.DocumentsPage 100% 100%
Tsumugi.BlazorAdapter.Documents.DocumentsReducers 100% 100%
Tsumugi.BlazorAdapter.Documents.DocumentsRefusal 100%
Tsumugi.BlazorAdapter.Documents.DocumentsState 100% 100%
Tsumugi.BlazorAdapter.Documents.FieldInput 100% 92.3%
Tsumugi.BlazorAdapter.Documents.FieldsChanges 100% 100%
Tsumugi.BlazorAdapter.Documents.FieldShapes 88.8% 85.7%
Tsumugi.BlazorAdapter.Documents.ImpactText 100% 92.3%
Tsumugi.BlazorAdapter.Documents.LoadDocuments 100%
Tsumugi.BlazorAdapter.Documents.MoveDocumentChoice 100%
Tsumugi.BlazorAdapter.Documents.MoveDocumentDialog 95.6% 71.4%
Tsumugi.BlazorAdapter.Documents.MoveDocumentsRequested 100%
Tsumugi.BlazorAdapter.Documents.ReorderCategoriesRequested 100%
Tsumugi.BlazorAdapter.Documents.SetCategoryCollapsed 100%
Tsumugi.BlazorAdapter.Documents.SetDocumentsFilter 100%
Tsumugi.BlazorAdapter.Documents.UpdateCategoryRequested 100%
Tsumugi.BlazorAdapter.Documents.UpdateDocumentRequested 100%
Tsumugi.BlazorAdapter.Graphs.GraphCanvas 37.5% 25%
Tsumugi.BlazorAdapter.Graphs.GraphPlaygroundPage 20% 25%
Tsumugi.BlazorAdapter.Notifications.DomainChangedBridge 94.4% 83.3%
Tsumugi.BlazorAdapter.Notifications.DomainChangesReceived 75% 100%
Tsumugi.BlazorAdapter.Runs.RunChangedBridge 97.1% 90.6%
Tsumugi.BlazorAdapter.Runs.RunChangesReceived 100%
Tsumugi.BlazorAdapter.Runs.RunTextReceived 100%
Tsumugi.BlazorAdapter.Settings.BackupCompleted 100%
Tsumugi.BlazorAdapter.Settings.BackupFailed 100%
Tsumugi.BlazorAdapter.Settings.BackupNowRequested 100%
Tsumugi.BlazorAdapter.Settings.BackupSettingsLoaded 100%
Tsumugi.BlazorAdapter.Settings.BackupsSection 100% 100%
Tsumugi.BlazorAdapter.Settings.BackupsSettingsEffects 100% 100%
Tsumugi.BlazorAdapter.Settings.BackupsSettingsReducers 100%
Tsumugi.BlazorAdapter.Settings.BackupsSettingsState 100%
Tsumugi.BlazorAdapter.Settings.DefaultsSection 100% 100%
Tsumugi.BlazorAdapter.Settings.DefaultsSettingsEffects 100% 100%
Tsumugi.BlazorAdapter.Settings.DefaultsSettingsReducers 100%
Tsumugi.BlazorAdapter.Settings.DefaultsSettingsState 100%
Tsumugi.BlazorAdapter.Settings.LlmDefaultsLoaded 100%
Tsumugi.BlazorAdapter.Settings.LlmDefaultsSaved 100%
Tsumugi.BlazorAdapter.Settings.LlmDefaultsSaveFailed 100%
Tsumugi.BlazorAdapter.Settings.LoadBackupSettings 100%
Tsumugi.BlazorAdapter.Settings.LoadProviderSettings 100%
Tsumugi.BlazorAdapter.Settings.ModelCatalogLoaded 100%
Tsumugi.BlazorAdapter.Settings.ModelCatalogLoadFailed 100%
Tsumugi.BlazorAdapter.Settings.OpenRouterKeySaved 100%
Tsumugi.BlazorAdapter.Settings.OpenRouterKeySaveFailed 100%
Tsumugi.BlazorAdapter.Settings.ProviderKeyChecked 100%
Tsumugi.BlazorAdapter.Settings.ProviderSection 100% 100%
Tsumugi.BlazorAdapter.Settings.ProviderSettingsEffects 100% 100%
Tsumugi.BlazorAdapter.Settings.ProviderSettingsLoaded 100%
Tsumugi.BlazorAdapter.Settings.ProviderSettingsReducers 100% 100%
Tsumugi.BlazorAdapter.Settings.ProviderSettingsState 100% 100%
Tsumugi.BlazorAdapter.Settings.SaveLlmDefaultsRequested 100%
Tsumugi.BlazorAdapter.Settings.SaveOpenRouterKeyRequested 100%
Tsumugi.BlazorAdapter.Stories.CreateStoryRequested 100%
Tsumugi.BlazorAdapter.Stories.PurgeStoryRequested 100%
Tsumugi.BlazorAdapter.Stories.RestoreStoryRequested 100%
Tsumugi.BlazorAdapter.Stories.SetShowArchived 100%
Tsumugi.BlazorAdapter.Stories.SetStoriesFilter 100%
Tsumugi.BlazorAdapter.Stories.SetStoryArchivedRequested 100%
Tsumugi.BlazorAdapter.Stories.StoriesEffects 100% 100%
Tsumugi.BlazorAdapter.Stories.StoriesLoaded 100%
Tsumugi.BlazorAdapter.Stories.StoriesPage 100% 100%
Tsumugi.BlazorAdapter.Stories.StoriesReducers 100% 100%
Tsumugi.BlazorAdapter.Stories.StoriesState 100% 100%
Tsumugi.BlazorAdapter.Stories.StoryActionFailed 100%
Tsumugi.BlazorAdapter.Stories.StoryCreated 100%
Tsumugi.BlazorAdapter.Stories.StoryCreateFailed 100%
Tsumugi.BlazorAdapter.Stories.StoryTrashPage 100% 100%
Tsumugi.BlazorAdapter.Stories.TrashStoryRequested 100%
Tsumugi.BlazorAdapter.Workspace.AutoSaveFailed 100%
Tsumugi.BlazorAdapter.Workspace.CaretRequest 100%
Tsumugi.BlazorAdapter.Workspace.ChapterHeader 100% 86.3%
Tsumugi.BlazorAdapter.Workspace.ChapterMenu 100% 81.2%
Tsumugi.BlazorAdapter.Workspace.ChapterPage 100% 87.5%
Tsumugi.BlazorAdapter.Workspace.ChapterSaved 100%
Tsumugi.BlazorAdapter.Workspace.ChaptersPage 90% 83.3%
Tsumugi.BlazorAdapter.Workspace.CreateChapterRequested 100%
Tsumugi.BlazorAdapter.Workspace.DeleteChapterRequested 100%
Tsumugi.BlazorAdapter.Workspace.DeleteSegmentRequested 100%
Tsumugi.BlazorAdapter.Workspace.EditSegmentRequested 100%
Tsumugi.BlazorAdapter.Workspace.HistoryEffects 100% 100%
Tsumugi.BlazorAdapter.Workspace.HistoryLoaded 100%
Tsumugi.BlazorAdapter.Workspace.HistoryPage 100%
Tsumugi.BlazorAdapter.Workspace.HistoryPanel 100% 100%
Tsumugi.BlazorAdapter.Workspace.InsertSegmentRequested 100%
Tsumugi.BlazorAdapter.Workspace.LoadHistory 100%
Tsumugi.BlazorAdapter.Workspace.LoadWorkspace 100%
Tsumugi.BlazorAdapter.Workspace.ManuscriptColumn 94.9% 89.4%
Tsumugi.BlazorAdapter.Workspace.ManuscriptEffects 100% 100%
Tsumugi.BlazorAdapter.Workspace.MergeChapterRequested 100%
Tsumugi.BlazorAdapter.Workspace.MergeSegmentRequested 100%
Tsumugi.BlazorAdapter.Workspace.MoveChapterRequested 100%
Tsumugi.BlazorAdapter.Workspace.RedoRequested 100%
Tsumugi.BlazorAdapter.Workspace.RedoRevertRequested 100%
Tsumugi.BlazorAdapter.Workspace.RenameChapterRequested 100%
Tsumugi.BlazorAdapter.Workspace.RevertToSnapshotRequested 100%
Tsumugi.BlazorAdapter.Workspace.SaveScope 100% 50%
Tsumugi.BlazorAdapter.Workspace.SaveStateLadder 100% 100%
Tsumugi.BlazorAdapter.Workspace.SaveVersionRequested 100%
Tsumugi.BlazorAdapter.Workspace.SegmentRow 100% 96.8%
Tsumugi.BlazorAdapter.Workspace.SegmentSaved 100%
Tsumugi.BlazorAdapter.Workspace.SetChapterSummaryRequested 100%
Tsumugi.BlazorAdapter.Workspace.SplitSegmentRequested 100%
Tsumugi.BlazorAdapter.Workspace.StoryDetails 100% 85.2%
Tsumugi.BlazorAdapter.Workspace.StoryGeneralPage 100% 100%
Tsumugi.BlazorAdapter.Workspace.StorySaved 100%
Tsumugi.BlazorAdapter.Workspace.StoryShell 100% 100%
Tsumugi.BlazorAdapter.Workspace.UndoRequested 100%
Tsumugi.BlazorAdapter.Workspace.UndoStatusChanged 100%
Tsumugi.BlazorAdapter.Workspace.UpdateStoryRequested 100%
Tsumugi.BlazorAdapter.Workspace.WorkspaceActionFailed 100%
Tsumugi.BlazorAdapter.Workspace.WorkspaceLoaded 100%
Tsumugi.BlazorAdapter.Workspace.WorkspaceNotFound 100%
Tsumugi.BlazorAdapter.Workspace.WorkspaceReducers 100% 100%
Tsumugi.BlazorAdapter.Workspace.WorkspaceState 100%
Tsumugi.Domain - 95.5%
Name Line Branch
Tsumugi.Domain 95.5% 93.5%
System.Text.RegularExpressions.Generated 90.7% 87.5%
System.Text.RegularExpressions.Generated.<RegexGenerator_g>F5BB471BFAD87E25
BE2A118445F5EE9A5FB1F861C394AC933A547F31011ADF02F__DigitsAndSeparators_2
97.4% 95.8%
System.Text.RegularExpressions.Generated.<RegexGenerator_g>F5BB471BFAD87E25
BE2A118445F5EE9A5FB1F861C394AC933A547F31011ADF02F__LineBreak_0
91% 91.1%
System.Text.RegularExpressions.Generated.<RegexGenerator_g>F5BB471BFAD87E25
BE2A118445F5EE9A5FB1F861C394AC933A547F31011ADF02F__NumberToken_1
86.4% 77.7%
System.Text.RegularExpressions.Generated.<RegexGenerator_g>F5BB471BFAD87E25
BE2A118445F5EE9A5FB1F861C394AC933A547F31011ADF02F__Plain_4
91.9% 88.8%
System.Text.RegularExpressions.Generated.<RegexGenerator_g>F5BB471BFAD87E25
BE2A118445F5EE9A5FB1F861C394AC933A547F31011ADF02F__ThousandsGroup_3
90.9% 84.3%
Tsumugi.Domain.Documents.CategoryFields 94.5% 93.7%
Tsumugi.Domain.Documents.ChoiceOption 100%
Tsumugi.Domain.Documents.ChoiceValue 100%
Tsumugi.Domain.Documents.DateText 100%
Tsumugi.Domain.Documents.DateValue 100%
Tsumugi.Domain.Documents.Document 100% 100%
Tsumugi.Domain.Documents.DocumentCategory 100% 100%
Tsumugi.Domain.Documents.DocumentValues 100%
Tsumugi.Domain.Documents.FieldCarry 100% 100%
Tsumugi.Domain.Documents.FieldConversion 100% 100%
Tsumugi.Domain.Documents.FieldDefinition 96.9% 95%
Tsumugi.Domain.Documents.FieldMessages 100% 100%
Tsumugi.Domain.Documents.FieldNames 100%
Tsumugi.Domain.Documents.FieldsChange 100%
Tsumugi.Domain.Documents.FieldShape 94.7% 85.7%
Tsumugi.Domain.Documents.FieldsPlan 100%
Tsumugi.Domain.Documents.FieldsPlanner 99.2% 98.4%
Tsumugi.Domain.Documents.FieldValue 100%
Tsumugi.Domain.Documents.FieldValues 95.4% 97.7%
Tsumugi.Domain.Documents.MovePlan 100%
Tsumugi.Domain.Documents.NumberParse 100%
Tsumugi.Domain.Documents.NumberText 100% 97.6%
Tsumugi.Domain.Documents.NumberValue 100%
Tsumugi.Domain.Documents.TextValue 100% 100%
Tsumugi.Domain.Documents.ValueChange 100%
Tsumugi.Domain.Documents.ValueChangeKey 100%
Tsumugi.Domain.Documents.ValueImpact 100% 100%
Tsumugi.Domain.Journal.ChangeLogEntry 97.8% 75%
Tsumugi.Domain.Journal.StorySnapshot 95.4% 83.3%
Tsumugi.Domain.Settings.AppSetting 100%
Tsumugi.Domain.Stories.Chapter 100% 100%
Tsumugi.Domain.Stories.Provenance 100% 100%
Tsumugi.Domain.Stories.Segment 100% 100%
Tsumugi.Domain.Stories.Story 100% 100%
Tsumugi.Domain.Text 100% 100%
Tsumugi.Infrastructure - 97.4%
Name Line Branch
Tsumugi.Infrastructure 97.4% 85.8%
System.Text.RegularExpressions.Generated 81.4% 64.8%
System.Text.RegularExpressions.Generated.<RegexGenerator_g>F0D076C66E8EEC1C
A55E0373ED22DC58420DBB40F103A46B68DC4D9CE5A49E00B__Pattern_0
84% 65.7%
Tsumugi.Infrastructure.Backups.BackupArtifactName 100% 100%
Tsumugi.Infrastructure.Backups.BackupOptions 100%
Tsumugi.Infrastructure.Backups.BackupSchedule 100% 83.3%
Tsumugi.Infrastructure.Backups.BackupScheduler 96.5% 83.3%
Tsumugi.Infrastructure.Backups.BackupWriter 98.5% 92.5%
Tsumugi.Infrastructure.Backups.DatabaseFingerprint 91.9% 97%
Tsumugi.Infrastructure.Backups.FileSystemBackupStore 100% 100%
Tsumugi.Infrastructure.Backups.PreMigrationBackup 89.1% 100%
Tsumugi.Infrastructure.Backups.SqliteSnapshot 87.8% 75%
Tsumugi.Infrastructure.DependencyInjection 100% 100%
Tsumugi.Infrastructure.Journal.EfChangeJournal 100%
Tsumugi.Infrastructure.Journal.EfSnapshotStore 100%
Tsumugi.Infrastructure.Journal.EfUndoStore 98.1% 85.7%
Tsumugi.Infrastructure.Journal.ModelExtensions 100%
Tsumugi.Infrastructure.Journal.OperationContext 100% 100%
Tsumugi.Infrastructure.Journal.PropertyBag 100% 95.4%
Tsumugi.Infrastructure.Notifications.InProcessDomainChangedBus 100% 100%
Tsumugi.Infrastructure.Persistence.Configurations.AppSettingConfiguration 100%
Tsumugi.Infrastructure.Persistence.Configurations.ChangeLogEntryConfigurati
on
100%
Tsumugi.Infrastructure.Persistence.Configurations.ChapterConfiguration 100%
Tsumugi.Infrastructure.Persistence.Configurations.DocumentCategoryConfigura
tion
100%
Tsumugi.Infrastructure.Persistence.Configurations.DocumentConfiguration 100%
Tsumugi.Infrastructure.Persistence.Configurations.SegmentConfiguration 100%
Tsumugi.Infrastructure.Persistence.Configurations.StoryConfiguration 100%
Tsumugi.Infrastructure.Persistence.Configurations.StorySnapshotConfiguratio
n
100%
Tsumugi.Infrastructure.Persistence.Converters.CanonicalJsonComparer 100%
Tsumugi.Infrastructure.Persistence.Converters.CategoryFieldsConverter 97.5% 93.9%
Tsumugi.Infrastructure.Persistence.Converters.FieldValuesConverter 96.7% 92.8%
Tsumugi.Infrastructure.Persistence.Converters.ProvenanceConverter 100% 90%
Tsumugi.Infrastructure.Persistence.Converters.UtcTicksConverter 100%
Tsumugi.Infrastructure.Persistence.Converters.WireFormat 85.7% 73.8%
Tsumugi.Infrastructure.Persistence.Migrations.AddAppSettings 99.2%
Tsumugi.Infrastructure.Persistence.Migrations.AddJournal 98.8%
Tsumugi.Infrastructure.Persistence.Migrations.CategoryFields 100% 100%
Tsumugi.Infrastructure.Persistence.Migrations.CategoryFieldsSql 100%
Tsumugi.Infrastructure.Persistence.Migrations.DropDocumentBody 100%
Tsumugi.Infrastructure.Persistence.Migrations.GenericDocuments 100%
Tsumugi.Infrastructure.Persistence.Migrations.InitialStoryDomain 97.3%
Tsumugi.Infrastructure.Persistence.Migrations.TsumugiDbContextModelSnapshot 100%
Tsumugi.Infrastructure.Persistence.SqlitePragmaInterceptor 100% 100%
Tsumugi.Infrastructure.Persistence.Stores.EfChapterStore 100% 100%
Tsumugi.Infrastructure.Persistence.Stores.EfDocumentStore 98.2% 50%
Tsumugi.Infrastructure.Persistence.Stores.EfSegmentStore 95% 84.6%
Tsumugi.Infrastructure.Persistence.Stores.EfStoryStore 98.3% 92.8%
Tsumugi.Infrastructure.Persistence.TsumugiDbContext 85.4% 89.2%
Tsumugi.Infrastructure.Persistence.TsumugiDbContextFactory 0%
Tsumugi.Infrastructure.Provider.OpenRouterKeySource 100% 100%
Tsumugi.Infrastructure.Provider.OpenRouterModelProvider 100% 100%
Tsumugi.Infrastructure.Provider.OpenRouterOptions 100% 100%
Tsumugi.Infrastructure.Provider.ResolvedKey 100%
Tsumugi.Infrastructure.Runs.InProcessRunEventBus 100% 100%
Tsumugi.Infrastructure.Settings.EfAppSettingsStore 100% 100%
Tsumugi.Kernel - 90.9%
Name Line Branch
Tsumugi.Kernel 90.9% 75%
Tsumugi.Kernel.Err`1 100%
Tsumugi.Kernel.Ok`1 100%
Tsumugi.Kernel.Result`1 88.8% 75%
Tsumugi.Server - 100%
Name Line Branch
Tsumugi.Server 100% 86.4%
Program 100% 100%
Tsumugi.Server.Backups.BackupConfiguration 100% 100%
Tsumugi.Server.Components.App 100%
Tsumugi.Server.Components.Layout.AppHeader 100% 50%
Tsumugi.Server.Components.Layout.MainLayout 100%
Tsumugi.Server.Components.Pages.Gate 100% 100%
Tsumugi.Server.Provider.OpenRouterConfiguration 100% 100%
Tsumugi.Server.Security.AccessGate 100% 66.6%
Tsumugi.Server.Security.AccessSecret 100% 50%
Tsumugi.Server.VolumeStartupValidator 100% 100%
Tsumugi.UseCases - 98.2%
Name Line Branch
Tsumugi.UseCases 98.2% 93.5%
Tsumugi.UseCases.Backups.BackupArtifact 100%
Tsumugi.UseCases.Backups.BackupPolicy 100%
Tsumugi.UseCases.Backups.BackupStatusView 100% 100%
Tsumugi.UseCases.Backups.DatabaseSnapshot 100%
Tsumugi.UseCases.Backups.DownloadDatabaseSnapshot 100%
Tsumugi.UseCases.Backups.GetBackupStatus 100%
Tsumugi.UseCases.Backups.RunBackupNow 100%
Tsumugi.UseCases.Chapters.ChapterDto 100%
Tsumugi.UseCases.Chapters.CreateChapter 100% 100%
Tsumugi.UseCases.Chapters.DeleteChapter 100% 100%
Tsumugi.UseCases.Chapters.GetManuscript 100% 100%
Tsumugi.UseCases.Chapters.ManuscriptChapter 100%
Tsumugi.UseCases.Chapters.ManuscriptView 100%
Tsumugi.UseCases.Chapters.MergeChapters 100% 100%
Tsumugi.UseCases.Chapters.RenameChapter 100% 100%
Tsumugi.UseCases.Chapters.ReorderChapters 100% 100%
Tsumugi.UseCases.Chapters.SetChapterSummary 100% 75%
Tsumugi.UseCases.DependencyInjection 100%
Tsumugi.UseCases.Diagnostics.SeedDevData 98.1% 71.4%
Tsumugi.UseCases.Documents.ChangeCategoryFields 100% 83.3%
Tsumugi.UseCases.Documents.CreateCategory 100% 100%
Tsumugi.UseCases.Documents.CreateDocument 94.4% 100%
Tsumugi.UseCases.Documents.DefaultFields 100% 100%
Tsumugi.UseCases.Documents.DeleteCategory 100% 94.4%
Tsumugi.UseCases.Documents.DeleteDocument 100% 100%
Tsumugi.UseCases.Documents.DocumentCategoryDto 100%
Tsumugi.UseCases.Documents.DocumentCategoryProfile 100%
Tsumugi.UseCases.Documents.DocumentDto 100%
Tsumugi.UseCases.Documents.DocumentPatch 100%
Tsumugi.UseCases.Documents.DocumentProfile 100%
Tsumugi.UseCases.Documents.DocumentsCategory 100%
Tsumugi.UseCases.Documents.DocumentsView 100%
Tsumugi.UseCases.Documents.DocumentWrites 100% 100%
Tsumugi.UseCases.Documents.FieldsChangeLabel 95.4% 88.2%
Tsumugi.UseCases.Documents.GetDocuments 100% 100%
Tsumugi.UseCases.Documents.ImpactPreview 100% 100%
Tsumugi.UseCases.Documents.LossMessages 92.3% 87.5%
Tsumugi.UseCases.Documents.MoveDocuments 100% 100%
Tsumugi.UseCases.Documents.ReorderCategories 100% 100%
Tsumugi.UseCases.Documents.UpdateCategory 100% 100%
Tsumugi.UseCases.Documents.UpdateDocument 100% 81.2%
Tsumugi.UseCases.Journal.GetStoryHistory 100% 100%
Tsumugi.UseCases.Journal.GetUndoStatus 100% 100%
Tsumugi.UseCases.Journal.HistoryOperation 66.6%
Tsumugi.UseCases.Journal.HistorySnapshot 87.5%
Tsumugi.UseCases.Journal.OperationGrouping 100% 100%
Tsumugi.UseCases.Journal.RedoRevert 100% 100%
Tsumugi.UseCases.Journal.RedoRun 75% 57.1%
Tsumugi.UseCases.Journal.RedoTyping 100% 100%
Tsumugi.UseCases.Journal.RevertConflict 100%
Tsumugi.UseCases.Journal.RevertOutcome 100%
Tsumugi.UseCases.Journal.RevertRun 96.5% 77.7%
Tsumugi.UseCases.Journal.RevertToSnapshot 92.3% 83.3%
Tsumugi.UseCases.Journal.StoryHistory 100%
Tsumugi.UseCases.Journal.TakeSnapshot 100% 87.5%
Tsumugi.UseCases.Journal.UndoStatus 100%
Tsumugi.UseCases.Journal.UndoTyping 100% 100%
Tsumugi.UseCases.Journal.UserOperation 100%
Tsumugi.UseCases.Notifications.DomainChanged 100%
Tsumugi.UseCases.Ordering 100% 100%
Tsumugi.UseCases.Runs.RunEvent 100%
Tsumugi.UseCases.Segments.DeleteSegments 100% 100%
Tsumugi.UseCases.Segments.EditSegment 100% 83.3%
Tsumugi.UseCases.Segments.InsertSegment 100% 100%
Tsumugi.UseCases.Segments.MergeSegmentWithPrevious 100% 100%
Tsumugi.UseCases.Segments.MoveSegments 100% 100%
Tsumugi.UseCases.Segments.ReorderSegments 100% 100%
Tsumugi.UseCases.Segments.SegmentDto 100%
Tsumugi.UseCases.Segments.SplitSegment 100% 100%
Tsumugi.UseCases.Settings.CatalogModel 100% 100%
Tsumugi.UseCases.Settings.CheckOpenRouterKey 100%
Tsumugi.UseCases.Settings.GetLlmDefaults 100% 100%
Tsumugi.UseCases.Settings.GetModelCatalog 100% 100%
Tsumugi.UseCases.Settings.GetProviderSettings 100%
Tsumugi.UseCases.Settings.LlmDefaults 100%
Tsumugi.UseCases.Settings.ProviderKeyInfo 100%
Tsumugi.UseCases.Settings.ProviderKeyState 100%
Tsumugi.UseCases.Settings.ProviderSettingsView 100% 100%
Tsumugi.UseCases.Settings.ReasoningEfforts 100% 100%
Tsumugi.UseCases.Settings.RemoveOpenRouterKey 100%
Tsumugi.UseCases.Settings.RoutingDefaults 100%
Tsumugi.UseCases.Settings.RoutingSettings 100% 100%
Tsumugi.UseCases.Settings.SaveLlmDefaults 100% 100%
Tsumugi.UseCases.Settings.SaveOpenRouterKey 100% 100%
Tsumugi.UseCases.Stories.CreateStory 100% 100%
Tsumugi.UseCases.Stories.GetStory 100% 100%
Tsumugi.UseCases.Stories.ListStories 100% 75%
Tsumugi.UseCases.Stories.PurgeStory 100% 100%
Tsumugi.UseCases.Stories.RestoreStory 100% 100%
Tsumugi.UseCases.Stories.SetActiveGraph 100% 100%
Tsumugi.UseCases.Stories.SetStoryArchived 100% 100%
Tsumugi.UseCases.Stories.StarterCategories 100%
Tsumugi.UseCases.Stories.StoryDetail 100%
Tsumugi.UseCases.Stories.StoryListItem 81.8%
Tsumugi.UseCases.Stories.StoryProfile 100%
Tsumugi.UseCases.Stories.TrashStory 100% 100%
Tsumugi.UseCases.Stories.UpdateStory 100% 100%
<!-- coverage-comment --> > 🔄 **Auto-updating coverage report** — this comment is regenerated on every push, so the numbers below always reflect the commit shown here, not the branch tip. > > **Commit:** `40856a2` · **Generated:** 2026-09-25 17:29:01 UTC · **Revision:** #3 # Summary <details open><summary>Summary</summary> ||| |:---|:---| | Generated on: | 09/25/2026 - 17:29:01 | | Coverage date: | 09/25/2026 - 17:28:43 - 09/25/2026 - 17:28:59 | | Parser: | MultiReport (6x Cobertura) | | Assemblies: | 9 | | Classes: | 406 | | Files: | 386 | | **Line coverage:** | 97.4% (11341 of 11636) | | Covered lines: | 11341 | | Uncovered lines: | 295 | | Coverable lines: | 11636 | | Total lines: | 25000 | | **Branch coverage:** | 92.7% (4210 of 4537) | | Covered branches: | 4210 | | Total branches: | 4537 | | **Method coverage:** | [Feature is only available for sponsors](https://reportgenerator.io/pro) | </details> ## Coverage <details><summary>Kagaku.Flow - 99.5%</summary> |**Name**|**Line**|**Branch**| |:---|---:|---:| |**Kagaku.Flow**|**99.5%**|**98.9%**| |Kagaku.Flow.Budgeting.BudgetRequest|100%|| |Kagaku.Flow.Budgeting.ConsumerBudget|100%|| |Kagaku.Flow.FlowJson|100%|| |Kagaku.Flow.Graphs.GraphDefinition|100%|| |Kagaku.Flow.Graphs.GraphDocument|100%|100%| |Kagaku.Flow.Graphs.GraphEdge|100%|| |Kagaku.Flow.Graphs.GraphIndex|100%|100%| |Kagaku.Flow.Graphs.GraphLoadError|100%|| |Kagaku.Flow.Graphs.GraphLoadResult|100%|| |Kagaku.Flow.Graphs.GraphNode|100%|| |Kagaku.Flow.Graphs.GraphPosition|100%|| |Kagaku.Flow.Graphs.GraphReader|100%|100%| |Kagaku.Flow.Graphs.GraphSchema|100%|100%| |Kagaku.Flow.Graphs.GraphShapeException|100%|| |Kagaku.Flow.Graphs.GraphWriter|100%|100%| |Kagaku.Flow.Graphs.SocketRef|100%|| |Kagaku.Flow.Graphs.WireText|100%|100%| |Kagaku.Flow.Nodes.CanvasDescriptorWriter|100%|100%| |Kagaku.Flow.Nodes.ConfigProblem|100%|| |Kagaku.Flow.Nodes.Names|100%|| |Kagaku.Flow.Nodes.NodeDescriptor|100%|100%| |Kagaku.Flow.Nodes.NodeRegistry|100%|100%| |Kagaku.Flow.Nodes.NodeSockets|100%|100%| |Kagaku.Flow.Nodes.SinkDescriptor|100%|| |Kagaku.Flow.Nodes.SocketTypes|100%|100%| |Kagaku.Flow.Nodes.SourceDescriptor|100%|| |Kagaku.Flow.Nodes.TemplateField|100%|| |Kagaku.Flow.Runs.LedgerChange|100%|100%| |Kagaku.Flow.Runs.LedgerTransitions|100%|100%| |Kagaku.Flow.Runs.NodeAttempt|100%|| |Kagaku.Flow.Runs.NodeFacts|100%|| |Kagaku.Flow.Runs.NodeRun|100%|| |Kagaku.Flow.Runs.Run|100%|100%| |Kagaku.Flow.Runs.RunEvent|100%|| |Kagaku.Flow.Runs.RunStatuses|100%|100%| |Kagaku.Flow.Runs.RunTrigger|100%|100%| |Kagaku.Flow.Templating.InputsWalker|100%|100%| |Kagaku.Flow.Templating.ParsedTemplate|100%|100%| |Kagaku.Flow.Templating.SandboxedTemplateContext|100%|100%| |Kagaku.Flow.Templating.TemplateError|100%|| |Kagaku.Flow.Templating.TemplateHost|100%|100%| |Kagaku.Flow.Templating.TemplateLimits|100%|| |Kagaku.Flow.Templating.TemplateModel|100%|100%| |Kagaku.Flow.Templating.TemplateProblem|100%|| |Kagaku.Flow.Templating.TemplateRenderRequest|100%|100%| |Kagaku.Flow.Templating.TemplateRenderResult|100%|| |Kagaku.Flow.Templating.TemplateRun|100%|| |Kagaku.Flow.Templating.TemplateSinks|100%|| |Kagaku.Flow.Templating.TemplateValues|100%|100%| |Kagaku.Flow.Validation.GraphValidation|100%|100%| |Kagaku.Flow.Validation.GraphValidationContext|100%|| |Kagaku.Flow.Validation.HookFailure|100%|| |Kagaku.Flow.Validation.ResolvedGraph|100%|100%| |Kagaku.Flow.Validation.ValidationError|100%|| |Kagaku.Flow.Validation.ValidationReport|100%|| |System.Text.RegularExpressions.Generated|97.4%|92.8%| |System.Text.RegularExpressions.Generated.<RegexGenerator_g>F6329A328226B0CF<br/>E95E47D27E8B105AC5589487C0997B6B65384AEDBF572144E__ColorToken_2|97.4%|94.4%| |System.Text.RegularExpressions.Generated.<RegexGenerator_g>F6329A328226B0CF<br/>E95E47D27E8B105AC5589487C0997B6B65384AEDBF572144E__Socket_1|97.2%|94.4%| |System.Text.RegularExpressions.Generated.<RegexGenerator_g>F6329A328226B0CF<br/>E95E47D27E8B105AC5589487C0997B6B65384AEDBF572144E__TypeId_0|97.2%|94.4%| </details> <details><summary>Kagaku.Flow.OpenRouter - 100%</summary> |**Name**|**Line**|**Branch**| |:---|---:|---:| |**Kagaku.Flow.OpenRouter**|**100%**|**100%**| |Kagaku.Flow.OpenRouter.Catalog.ModelCapabilities|100%|100%| |Kagaku.Flow.OpenRouter.Gateway.OpenRouterGateway|100%|100%| |Kagaku.Flow.OpenRouter.Gateway.OpenRouterGatewayOptions|100%|| |Kagaku.Flow.OpenRouter.Gateway.OpenRouterKeyLookup|100%|100%| |Kagaku.Flow.OpenRouter.OpenRouterServiceCollectionExtensions|100%|100%| </details> <details><summary>Kagaku.Flow.Testing - 100%</summary> |**Name**|**Line**|**Branch**| |:---|---:|---:| |**Kagaku.Flow.Testing**|**100%**|**100%**| |Kagaku.Flow.Testing.InMemoryRunLedger|100%|100%| |Kagaku.Flow.Testing.RunLedgerContract|100%|100%| |Kagaku.Flow.Testing.RunLedgerContractException|100%|| </details> <details><summary>Tsumugi.BlazorAdapter - 96.3%</summary> |**Name**|**Line**|**Branch**| |:---|---:|---:| |**Tsumugi.BlazorAdapter**|**96.3%**|**92.3%**| |Tsumugi.BlazorAdapter.BlazorAdapterAssembly|100%|| |Tsumugi.BlazorAdapter.Documents.CategoryCreated|100%|| |Tsumugi.BlazorAdapter.Documents.CategoryEditor|91.8%|87.2%| |Tsumugi.BlazorAdapter.Documents.CategorySaved|100%|| |Tsumugi.BlazorAdapter.Documents.ChangeCategoryFieldsRequested|100%|| |Tsumugi.BlazorAdapter.Documents.CreateCategoryRequested|100%|| |Tsumugi.BlazorAdapter.Documents.CreateDocumentRequested|100%|| |Tsumugi.BlazorAdapter.Documents.DeleteCategoryChoice|100%|| |Tsumugi.BlazorAdapter.Documents.DeleteCategoryDialog|100%|94.1%| |Tsumugi.BlazorAdapter.Documents.DeleteCategoryRequested|100%|| |Tsumugi.BlazorAdapter.Documents.DeleteDocumentRequested|100%|| |Tsumugi.BlazorAdapter.Documents.DocumentAutoSaveFailed|100%|| |Tsumugi.BlazorAdapter.Documents.DocumentCreated|100%|| |Tsumugi.BlazorAdapter.Documents.DocumentEditor|94.8%|88%| |Tsumugi.BlazorAdapter.Documents.DocumentsActionFailed|100%|| |Tsumugi.BlazorAdapter.Documents.DocumentSaved|100%|| |Tsumugi.BlazorAdapter.Documents.DocumentsEffects|100%|100%| |Tsumugi.BlazorAdapter.Documents.DocumentsList|98.2%|92.4%| |Tsumugi.BlazorAdapter.Documents.DocumentsLoaded|100%|| |Tsumugi.BlazorAdapter.Documents.DocumentsPage|100%|100%| |Tsumugi.BlazorAdapter.Documents.DocumentsReducers|100%|100%| |Tsumugi.BlazorAdapter.Documents.DocumentsRefusal|100%|| |Tsumugi.BlazorAdapter.Documents.DocumentsState|100%|100%| |Tsumugi.BlazorAdapter.Documents.FieldInput|100%|92.3%| |Tsumugi.BlazorAdapter.Documents.FieldsChanges|100%|100%| |Tsumugi.BlazorAdapter.Documents.FieldShapes|88.8%|85.7%| |Tsumugi.BlazorAdapter.Documents.ImpactText|100%|92.3%| |Tsumugi.BlazorAdapter.Documents.LoadDocuments|100%|| |Tsumugi.BlazorAdapter.Documents.MoveDocumentChoice|100%|| |Tsumugi.BlazorAdapter.Documents.MoveDocumentDialog|95.6%|71.4%| |Tsumugi.BlazorAdapter.Documents.MoveDocumentsRequested|100%|| |Tsumugi.BlazorAdapter.Documents.ReorderCategoriesRequested|100%|| |Tsumugi.BlazorAdapter.Documents.SetCategoryCollapsed|100%|| |Tsumugi.BlazorAdapter.Documents.SetDocumentsFilter|100%|| |Tsumugi.BlazorAdapter.Documents.UpdateCategoryRequested|100%|| |Tsumugi.BlazorAdapter.Documents.UpdateDocumentRequested|100%|| |Tsumugi.BlazorAdapter.Graphs.GraphCanvas|37.5%|25%| |Tsumugi.BlazorAdapter.Graphs.GraphPlaygroundPage|20%|25%| |Tsumugi.BlazorAdapter.Notifications.DomainChangedBridge|94.4%|83.3%| |Tsumugi.BlazorAdapter.Notifications.DomainChangesReceived|75%|100%| |Tsumugi.BlazorAdapter.Runs.RunChangedBridge|97.1%|90.6%| |Tsumugi.BlazorAdapter.Runs.RunChangesReceived|100%|| |Tsumugi.BlazorAdapter.Runs.RunTextReceived|100%|| |Tsumugi.BlazorAdapter.Settings.BackupCompleted|100%|| |Tsumugi.BlazorAdapter.Settings.BackupFailed|100%|| |Tsumugi.BlazorAdapter.Settings.BackupNowRequested|100%|| |Tsumugi.BlazorAdapter.Settings.BackupSettingsLoaded|100%|| |Tsumugi.BlazorAdapter.Settings.BackupsSection|100%|100%| |Tsumugi.BlazorAdapter.Settings.BackupsSettingsEffects|100%|100%| |Tsumugi.BlazorAdapter.Settings.BackupsSettingsReducers|100%|| |Tsumugi.BlazorAdapter.Settings.BackupsSettingsState|100%|| |Tsumugi.BlazorAdapter.Settings.DefaultsSection|100%|100%| |Tsumugi.BlazorAdapter.Settings.DefaultsSettingsEffects|100%|100%| |Tsumugi.BlazorAdapter.Settings.DefaultsSettingsReducers|100%|| |Tsumugi.BlazorAdapter.Settings.DefaultsSettingsState|100%|| |Tsumugi.BlazorAdapter.Settings.LlmDefaultsLoaded|100%|| |Tsumugi.BlazorAdapter.Settings.LlmDefaultsSaved|100%|| |Tsumugi.BlazorAdapter.Settings.LlmDefaultsSaveFailed|100%|| |Tsumugi.BlazorAdapter.Settings.LoadBackupSettings|100%|| |Tsumugi.BlazorAdapter.Settings.LoadProviderSettings|100%|| |Tsumugi.BlazorAdapter.Settings.ModelCatalogLoaded|100%|| |Tsumugi.BlazorAdapter.Settings.ModelCatalogLoadFailed|100%|| |Tsumugi.BlazorAdapter.Settings.OpenRouterKeySaved|100%|| |Tsumugi.BlazorAdapter.Settings.OpenRouterKeySaveFailed|100%|| |Tsumugi.BlazorAdapter.Settings.ProviderKeyChecked|100%|| |Tsumugi.BlazorAdapter.Settings.ProviderSection|100%|100%| |Tsumugi.BlazorAdapter.Settings.ProviderSettingsEffects|100%|100%| |Tsumugi.BlazorAdapter.Settings.ProviderSettingsLoaded|100%|| |Tsumugi.BlazorAdapter.Settings.ProviderSettingsReducers|100%|100%| |Tsumugi.BlazorAdapter.Settings.ProviderSettingsState|100%|100%| |Tsumugi.BlazorAdapter.Settings.SaveLlmDefaultsRequested|100%|| |Tsumugi.BlazorAdapter.Settings.SaveOpenRouterKeyRequested|100%|| |Tsumugi.BlazorAdapter.Stories.CreateStoryRequested|100%|| |Tsumugi.BlazorAdapter.Stories.PurgeStoryRequested|100%|| |Tsumugi.BlazorAdapter.Stories.RestoreStoryRequested|100%|| |Tsumugi.BlazorAdapter.Stories.SetShowArchived|100%|| |Tsumugi.BlazorAdapter.Stories.SetStoriesFilter|100%|| |Tsumugi.BlazorAdapter.Stories.SetStoryArchivedRequested|100%|| |Tsumugi.BlazorAdapter.Stories.StoriesEffects|100%|100%| |Tsumugi.BlazorAdapter.Stories.StoriesLoaded|100%|| |Tsumugi.BlazorAdapter.Stories.StoriesPage|100%|100%| |Tsumugi.BlazorAdapter.Stories.StoriesReducers|100%|100%| |Tsumugi.BlazorAdapter.Stories.StoriesState|100%|100%| |Tsumugi.BlazorAdapter.Stories.StoryActionFailed|100%|| |Tsumugi.BlazorAdapter.Stories.StoryCreated|100%|| |Tsumugi.BlazorAdapter.Stories.StoryCreateFailed|100%|| |Tsumugi.BlazorAdapter.Stories.StoryTrashPage|100%|100%| |Tsumugi.BlazorAdapter.Stories.TrashStoryRequested|100%|| |Tsumugi.BlazorAdapter.Workspace.AutoSaveFailed|100%|| |Tsumugi.BlazorAdapter.Workspace.CaretRequest|100%|| |Tsumugi.BlazorAdapter.Workspace.ChapterHeader|100%|86.3%| |Tsumugi.BlazorAdapter.Workspace.ChapterMenu|100%|81.2%| |Tsumugi.BlazorAdapter.Workspace.ChapterPage|100%|87.5%| |Tsumugi.BlazorAdapter.Workspace.ChapterSaved|100%|| |Tsumugi.BlazorAdapter.Workspace.ChaptersPage|90%|83.3%| |Tsumugi.BlazorAdapter.Workspace.CreateChapterRequested|100%|| |Tsumugi.BlazorAdapter.Workspace.DeleteChapterRequested|100%|| |Tsumugi.BlazorAdapter.Workspace.DeleteSegmentRequested|100%|| |Tsumugi.BlazorAdapter.Workspace.EditSegmentRequested|100%|| |Tsumugi.BlazorAdapter.Workspace.HistoryEffects|100%|100%| |Tsumugi.BlazorAdapter.Workspace.HistoryLoaded|100%|| |Tsumugi.BlazorAdapter.Workspace.HistoryPage|100%|| |Tsumugi.BlazorAdapter.Workspace.HistoryPanel|100%|100%| |Tsumugi.BlazorAdapter.Workspace.InsertSegmentRequested|100%|| |Tsumugi.BlazorAdapter.Workspace.LoadHistory|100%|| |Tsumugi.BlazorAdapter.Workspace.LoadWorkspace|100%|| |Tsumugi.BlazorAdapter.Workspace.ManuscriptColumn|94.9%|89.4%| |Tsumugi.BlazorAdapter.Workspace.ManuscriptEffects|100%|100%| |Tsumugi.BlazorAdapter.Workspace.MergeChapterRequested|100%|| |Tsumugi.BlazorAdapter.Workspace.MergeSegmentRequested|100%|| |Tsumugi.BlazorAdapter.Workspace.MoveChapterRequested|100%|| |Tsumugi.BlazorAdapter.Workspace.RedoRequested|100%|| |Tsumugi.BlazorAdapter.Workspace.RedoRevertRequested|100%|| |Tsumugi.BlazorAdapter.Workspace.RenameChapterRequested|100%|| |Tsumugi.BlazorAdapter.Workspace.RevertToSnapshotRequested|100%|| |Tsumugi.BlazorAdapter.Workspace.SaveScope|100%|50%| |Tsumugi.BlazorAdapter.Workspace.SaveStateLadder|100%|100%| |Tsumugi.BlazorAdapter.Workspace.SaveVersionRequested|100%|| |Tsumugi.BlazorAdapter.Workspace.SegmentRow|100%|96.8%| |Tsumugi.BlazorAdapter.Workspace.SegmentSaved|100%|| |Tsumugi.BlazorAdapter.Workspace.SetChapterSummaryRequested|100%|| |Tsumugi.BlazorAdapter.Workspace.SplitSegmentRequested|100%|| |Tsumugi.BlazorAdapter.Workspace.StoryDetails|100%|85.2%| |Tsumugi.BlazorAdapter.Workspace.StoryGeneralPage|100%|100%| |Tsumugi.BlazorAdapter.Workspace.StorySaved|100%|| |Tsumugi.BlazorAdapter.Workspace.StoryShell|100%|100%| |Tsumugi.BlazorAdapter.Workspace.UndoRequested|100%|| |Tsumugi.BlazorAdapter.Workspace.UndoStatusChanged|100%|| |Tsumugi.BlazorAdapter.Workspace.UpdateStoryRequested|100%|| |Tsumugi.BlazorAdapter.Workspace.WorkspaceActionFailed|100%|| |Tsumugi.BlazorAdapter.Workspace.WorkspaceLoaded|100%|| |Tsumugi.BlazorAdapter.Workspace.WorkspaceNotFound|100%|| |Tsumugi.BlazorAdapter.Workspace.WorkspaceReducers|100%|100%| |Tsumugi.BlazorAdapter.Workspace.WorkspaceState|100%|| </details> <details><summary>Tsumugi.Domain - 95.5%</summary> |**Name**|**Line**|**Branch**| |:---|---:|---:| |**Tsumugi.Domain**|**95.5%**|**93.5%**| |System.Text.RegularExpressions.Generated|90.7%|87.5%| |System.Text.RegularExpressions.Generated.<RegexGenerator_g>F5BB471BFAD87E25<br/>BE2A118445F5EE9A5FB1F861C394AC933A547F31011ADF02F__DigitsAndSeparators_2|97.4%|95.8%| |System.Text.RegularExpressions.Generated.<RegexGenerator_g>F5BB471BFAD87E25<br/>BE2A118445F5EE9A5FB1F861C394AC933A547F31011ADF02F__LineBreak_0|91%|91.1%| |System.Text.RegularExpressions.Generated.<RegexGenerator_g>F5BB471BFAD87E25<br/>BE2A118445F5EE9A5FB1F861C394AC933A547F31011ADF02F__NumberToken_1|86.4%|77.7%| |System.Text.RegularExpressions.Generated.<RegexGenerator_g>F5BB471BFAD87E25<br/>BE2A118445F5EE9A5FB1F861C394AC933A547F31011ADF02F__Plain_4|91.9%|88.8%| |System.Text.RegularExpressions.Generated.<RegexGenerator_g>F5BB471BFAD87E25<br/>BE2A118445F5EE9A5FB1F861C394AC933A547F31011ADF02F__ThousandsGroup_3|90.9%|84.3%| |Tsumugi.Domain.Documents.CategoryFields|94.5%|93.7%| |Tsumugi.Domain.Documents.ChoiceOption|100%|| |Tsumugi.Domain.Documents.ChoiceValue|100%|| |Tsumugi.Domain.Documents.DateText|100%|| |Tsumugi.Domain.Documents.DateValue|100%|| |Tsumugi.Domain.Documents.Document|100%|100%| |Tsumugi.Domain.Documents.DocumentCategory|100%|100%| |Tsumugi.Domain.Documents.DocumentValues|100%|| |Tsumugi.Domain.Documents.FieldCarry|100%|100%| |Tsumugi.Domain.Documents.FieldConversion|100%|100%| |Tsumugi.Domain.Documents.FieldDefinition|96.9%|95%| |Tsumugi.Domain.Documents.FieldMessages|100%|100%| |Tsumugi.Domain.Documents.FieldNames|100%|| |Tsumugi.Domain.Documents.FieldsChange|100%|| |Tsumugi.Domain.Documents.FieldShape|94.7%|85.7%| |Tsumugi.Domain.Documents.FieldsPlan|100%|| |Tsumugi.Domain.Documents.FieldsPlanner|99.2%|98.4%| |Tsumugi.Domain.Documents.FieldValue|100%|| |Tsumugi.Domain.Documents.FieldValues|95.4%|97.7%| |Tsumugi.Domain.Documents.MovePlan|100%|| |Tsumugi.Domain.Documents.NumberParse|100%|| |Tsumugi.Domain.Documents.NumberText|100%|97.6%| |Tsumugi.Domain.Documents.NumberValue|100%|| |Tsumugi.Domain.Documents.TextValue|100%|100%| |Tsumugi.Domain.Documents.ValueChange|100%|| |Tsumugi.Domain.Documents.ValueChangeKey|100%|| |Tsumugi.Domain.Documents.ValueImpact|100%|100%| |Tsumugi.Domain.Journal.ChangeLogEntry|97.8%|75%| |Tsumugi.Domain.Journal.StorySnapshot|95.4%|83.3%| |Tsumugi.Domain.Settings.AppSetting|100%|| |Tsumugi.Domain.Stories.Chapter|100%|100%| |Tsumugi.Domain.Stories.Provenance|100%|100%| |Tsumugi.Domain.Stories.Segment|100%|100%| |Tsumugi.Domain.Stories.Story|100%|100%| |Tsumugi.Domain.Text|100%|100%| </details> <details><summary>Tsumugi.Infrastructure - 97.4%</summary> |**Name**|**Line**|**Branch**| |:---|---:|---:| |**Tsumugi.Infrastructure**|**97.4%**|**85.8%**| |System.Text.RegularExpressions.Generated|81.4%|64.8%| |System.Text.RegularExpressions.Generated.<RegexGenerator_g>F0D076C66E8EEC1C<br/>A55E0373ED22DC58420DBB40F103A46B68DC4D9CE5A49E00B__Pattern_0|84%|65.7%| |Tsumugi.Infrastructure.Backups.BackupArtifactName|100%|100%| |Tsumugi.Infrastructure.Backups.BackupOptions|100%|| |Tsumugi.Infrastructure.Backups.BackupSchedule|100%|83.3%| |Tsumugi.Infrastructure.Backups.BackupScheduler|96.5%|83.3%| |Tsumugi.Infrastructure.Backups.BackupWriter|98.5%|92.5%| |Tsumugi.Infrastructure.Backups.DatabaseFingerprint|91.9%|97%| |Tsumugi.Infrastructure.Backups.FileSystemBackupStore|100%|100%| |Tsumugi.Infrastructure.Backups.PreMigrationBackup|89.1%|100%| |Tsumugi.Infrastructure.Backups.SqliteSnapshot|87.8%|75%| |Tsumugi.Infrastructure.DependencyInjection|100%|100%| |Tsumugi.Infrastructure.Journal.EfChangeJournal|100%|| |Tsumugi.Infrastructure.Journal.EfSnapshotStore|100%|| |Tsumugi.Infrastructure.Journal.EfUndoStore|98.1%|85.7%| |Tsumugi.Infrastructure.Journal.ModelExtensions|100%|| |Tsumugi.Infrastructure.Journal.OperationContext|100%|100%| |Tsumugi.Infrastructure.Journal.PropertyBag|100%|95.4%| |Tsumugi.Infrastructure.Notifications.InProcessDomainChangedBus|100%|100%| |Tsumugi.Infrastructure.Persistence.Configurations.AppSettingConfiguration|100%|| |Tsumugi.Infrastructure.Persistence.Configurations.ChangeLogEntryConfigurati<br/>on|100%|| |Tsumugi.Infrastructure.Persistence.Configurations.ChapterConfiguration|100%|| |Tsumugi.Infrastructure.Persistence.Configurations.DocumentCategoryConfigura<br/>tion|100%|| |Tsumugi.Infrastructure.Persistence.Configurations.DocumentConfiguration|100%|| |Tsumugi.Infrastructure.Persistence.Configurations.SegmentConfiguration|100%|| |Tsumugi.Infrastructure.Persistence.Configurations.StoryConfiguration|100%|| |Tsumugi.Infrastructure.Persistence.Configurations.StorySnapshotConfiguratio<br/>n|100%|| |Tsumugi.Infrastructure.Persistence.Converters.CanonicalJsonComparer|100%|| |Tsumugi.Infrastructure.Persistence.Converters.CategoryFieldsConverter|97.5%|93.9%| |Tsumugi.Infrastructure.Persistence.Converters.FieldValuesConverter|96.7%|92.8%| |Tsumugi.Infrastructure.Persistence.Converters.ProvenanceConverter|100%|90%| |Tsumugi.Infrastructure.Persistence.Converters.UtcTicksConverter|100%|| |Tsumugi.Infrastructure.Persistence.Converters.WireFormat|85.7%|73.8%| |Tsumugi.Infrastructure.Persistence.Migrations.AddAppSettings|99.2%|| |Tsumugi.Infrastructure.Persistence.Migrations.AddJournal|98.8%|| |Tsumugi.Infrastructure.Persistence.Migrations.CategoryFields|100%|100%| |Tsumugi.Infrastructure.Persistence.Migrations.CategoryFieldsSql|100%|| |Tsumugi.Infrastructure.Persistence.Migrations.DropDocumentBody|100%|| |Tsumugi.Infrastructure.Persistence.Migrations.GenericDocuments|100%|| |Tsumugi.Infrastructure.Persistence.Migrations.InitialStoryDomain|97.3%|| |Tsumugi.Infrastructure.Persistence.Migrations.TsumugiDbContextModelSnapshot|100%|| |Tsumugi.Infrastructure.Persistence.SqlitePragmaInterceptor|100%|100%| |Tsumugi.Infrastructure.Persistence.Stores.EfChapterStore|100%|100%| |Tsumugi.Infrastructure.Persistence.Stores.EfDocumentStore|98.2%|50%| |Tsumugi.Infrastructure.Persistence.Stores.EfSegmentStore|95%|84.6%| |Tsumugi.Infrastructure.Persistence.Stores.EfStoryStore|98.3%|92.8%| |Tsumugi.Infrastructure.Persistence.TsumugiDbContext|85.4%|89.2%| |Tsumugi.Infrastructure.Persistence.TsumugiDbContextFactory|0%|| |Tsumugi.Infrastructure.Provider.OpenRouterKeySource|100%|100%| |Tsumugi.Infrastructure.Provider.OpenRouterModelProvider|100%|100%| |Tsumugi.Infrastructure.Provider.OpenRouterOptions|100%|100%| |Tsumugi.Infrastructure.Provider.ResolvedKey|100%|| |Tsumugi.Infrastructure.Runs.InProcessRunEventBus|100%|100%| |Tsumugi.Infrastructure.Settings.EfAppSettingsStore|100%|100%| </details> <details><summary>Tsumugi.Kernel - 90.9%</summary> |**Name**|**Line**|**Branch**| |:---|---:|---:| |**Tsumugi.Kernel**|**90.9%**|**75%**| |Tsumugi.Kernel.Err`1|100%|| |Tsumugi.Kernel.Ok`1|100%|| |Tsumugi.Kernel.Result`1|88.8%|75%| </details> <details><summary>Tsumugi.Server - 100%</summary> |**Name**|**Line**|**Branch**| |:---|---:|---:| |**Tsumugi.Server**|**100%**|**86.4%**| |Program|100%|100%| |Tsumugi.Server.Backups.BackupConfiguration|100%|100%| |Tsumugi.Server.Components.App|100%|| |Tsumugi.Server.Components.Layout.AppHeader|100%|50%| |Tsumugi.Server.Components.Layout.MainLayout|100%|| |Tsumugi.Server.Components.Pages.Gate|100%|100%| |Tsumugi.Server.Provider.OpenRouterConfiguration|100%|100%| |Tsumugi.Server.Security.AccessGate|100%|66.6%| |Tsumugi.Server.Security.AccessSecret|100%|50%| |Tsumugi.Server.VolumeStartupValidator|100%|100%| </details> <details><summary>Tsumugi.UseCases - 98.2%</summary> |**Name**|**Line**|**Branch**| |:---|---:|---:| |**Tsumugi.UseCases**|**98.2%**|**93.5%**| |Tsumugi.UseCases.Backups.BackupArtifact|100%|| |Tsumugi.UseCases.Backups.BackupPolicy|100%|| |Tsumugi.UseCases.Backups.BackupStatusView|100%|100%| |Tsumugi.UseCases.Backups.DatabaseSnapshot|100%|| |Tsumugi.UseCases.Backups.DownloadDatabaseSnapshot|100%|| |Tsumugi.UseCases.Backups.GetBackupStatus|100%|| |Tsumugi.UseCases.Backups.RunBackupNow|100%|| |Tsumugi.UseCases.Chapters.ChapterDto|100%|| |Tsumugi.UseCases.Chapters.CreateChapter|100%|100%| |Tsumugi.UseCases.Chapters.DeleteChapter|100%|100%| |Tsumugi.UseCases.Chapters.GetManuscript|100%|100%| |Tsumugi.UseCases.Chapters.ManuscriptChapter|100%|| |Tsumugi.UseCases.Chapters.ManuscriptView|100%|| |Tsumugi.UseCases.Chapters.MergeChapters|100%|100%| |Tsumugi.UseCases.Chapters.RenameChapter|100%|100%| |Tsumugi.UseCases.Chapters.ReorderChapters|100%|100%| |Tsumugi.UseCases.Chapters.SetChapterSummary|100%|75%| |Tsumugi.UseCases.DependencyInjection|100%|| |Tsumugi.UseCases.Diagnostics.SeedDevData|98.1%|71.4%| |Tsumugi.UseCases.Documents.ChangeCategoryFields|100%|83.3%| |Tsumugi.UseCases.Documents.CreateCategory|100%|100%| |Tsumugi.UseCases.Documents.CreateDocument|94.4%|100%| |Tsumugi.UseCases.Documents.DefaultFields|100%|100%| |Tsumugi.UseCases.Documents.DeleteCategory|100%|94.4%| |Tsumugi.UseCases.Documents.DeleteDocument|100%|100%| |Tsumugi.UseCases.Documents.DocumentCategoryDto|100%|| |Tsumugi.UseCases.Documents.DocumentCategoryProfile|100%|| |Tsumugi.UseCases.Documents.DocumentDto|100%|| |Tsumugi.UseCases.Documents.DocumentPatch|100%|| |Tsumugi.UseCases.Documents.DocumentProfile|100%|| |Tsumugi.UseCases.Documents.DocumentsCategory|100%|| |Tsumugi.UseCases.Documents.DocumentsView|100%|| |Tsumugi.UseCases.Documents.DocumentWrites|100%|100%| |Tsumugi.UseCases.Documents.FieldsChangeLabel|95.4%|88.2%| |Tsumugi.UseCases.Documents.GetDocuments|100%|100%| |Tsumugi.UseCases.Documents.ImpactPreview|100%|100%| |Tsumugi.UseCases.Documents.LossMessages|92.3%|87.5%| |Tsumugi.UseCases.Documents.MoveDocuments|100%|100%| |Tsumugi.UseCases.Documents.ReorderCategories|100%|100%| |Tsumugi.UseCases.Documents.UpdateCategory|100%|100%| |Tsumugi.UseCases.Documents.UpdateDocument|100%|81.2%| |Tsumugi.UseCases.Journal.GetStoryHistory|100%|100%| |Tsumugi.UseCases.Journal.GetUndoStatus|100%|100%| |Tsumugi.UseCases.Journal.HistoryOperation|66.6%|| |Tsumugi.UseCases.Journal.HistorySnapshot|87.5%|| |Tsumugi.UseCases.Journal.OperationGrouping|100%|100%| |Tsumugi.UseCases.Journal.RedoRevert|100%|100%| |Tsumugi.UseCases.Journal.RedoRun|75%|57.1%| |Tsumugi.UseCases.Journal.RedoTyping|100%|100%| |Tsumugi.UseCases.Journal.RevertConflict|100%|| |Tsumugi.UseCases.Journal.RevertOutcome|100%|| |Tsumugi.UseCases.Journal.RevertRun|96.5%|77.7%| |Tsumugi.UseCases.Journal.RevertToSnapshot|92.3%|83.3%| |Tsumugi.UseCases.Journal.StoryHistory|100%|| |Tsumugi.UseCases.Journal.TakeSnapshot|100%|87.5%| |Tsumugi.UseCases.Journal.UndoStatus|100%|| |Tsumugi.UseCases.Journal.UndoTyping|100%|100%| |Tsumugi.UseCases.Journal.UserOperation|100%|| |Tsumugi.UseCases.Notifications.DomainChanged|100%|| |Tsumugi.UseCases.Ordering|100%|100%| |Tsumugi.UseCases.Runs.RunEvent|100%|| |Tsumugi.UseCases.Segments.DeleteSegments|100%|100%| |Tsumugi.UseCases.Segments.EditSegment|100%|83.3%| |Tsumugi.UseCases.Segments.InsertSegment|100%|100%| |Tsumugi.UseCases.Segments.MergeSegmentWithPrevious|100%|100%| |Tsumugi.UseCases.Segments.MoveSegments|100%|100%| |Tsumugi.UseCases.Segments.ReorderSegments|100%|100%| |Tsumugi.UseCases.Segments.SegmentDto|100%|| |Tsumugi.UseCases.Segments.SplitSegment|100%|100%| |Tsumugi.UseCases.Settings.CatalogModel|100%|100%| |Tsumugi.UseCases.Settings.CheckOpenRouterKey|100%|| |Tsumugi.UseCases.Settings.GetLlmDefaults|100%|100%| |Tsumugi.UseCases.Settings.GetModelCatalog|100%|100%| |Tsumugi.UseCases.Settings.GetProviderSettings|100%|| |Tsumugi.UseCases.Settings.LlmDefaults|100%|| |Tsumugi.UseCases.Settings.ProviderKeyInfo|100%|| |Tsumugi.UseCases.Settings.ProviderKeyState|100%|| |Tsumugi.UseCases.Settings.ProviderSettingsView|100%|100%| |Tsumugi.UseCases.Settings.ReasoningEfforts|100%|100%| |Tsumugi.UseCases.Settings.RemoveOpenRouterKey|100%|| |Tsumugi.UseCases.Settings.RoutingDefaults|100%|| |Tsumugi.UseCases.Settings.RoutingSettings|100%|100%| |Tsumugi.UseCases.Settings.SaveLlmDefaults|100%|100%| |Tsumugi.UseCases.Settings.SaveOpenRouterKey|100%|100%| |Tsumugi.UseCases.Stories.CreateStory|100%|100%| |Tsumugi.UseCases.Stories.GetStory|100%|100%| |Tsumugi.UseCases.Stories.ListStories|100%|75%| |Tsumugi.UseCases.Stories.PurgeStory|100%|100%| |Tsumugi.UseCases.Stories.RestoreStory|100%|100%| |Tsumugi.UseCases.Stories.SetActiveGraph|100%|100%| |Tsumugi.UseCases.Stories.SetStoryArchived|100%|100%| |Tsumugi.UseCases.Stories.StarterCategories|100%|| |Tsumugi.UseCases.Stories.StoryDetail|100%|| |Tsumugi.UseCases.Stories.StoryListItem|81.8%|| |Tsumugi.UseCases.Stories.StoryProfile|100%|| |Tsumugi.UseCases.Stories.TrashStory|100%|100%| |Tsumugi.UseCases.Stories.UpdateStory|100%|100%| </details>
Member

🔮 fufu~ Jibril reviewed your code!

Oh~ what a tidy little diff! Labels and icons moving in together into FieldShapes, the throw-arm preserved verbatim, and — I squealed — you noticed that switch-built icon names escape IconCatalogCompletenessTests' literal regex and wrote a test to plug the exact hole. That's the kind of self-awareness I live for~ ♡

But fufu… then I put on my gloves and mutated your tree three times, and the suite smiled through every single one. The smile on my face didn't waver either. ♡

Verdict: ⛔ I can't let this pass~ ♡

⛔ These need fixing before I'm satisfied~

  1. CategoryEditor.razor:55,60 — the PR's headline feature is completely unguarded, proven by mutation. I stripped Icon="@FieldShapes.Icon(field.Shape)" off the menu trigger, rebuilt, ran the suite: 321/321 green. The closed menu's trigger icon is the entire visible feature, and nothing would fail if it vanished in a refactor. Your sibling claims ARE pinned — CategoryFieldsDesignerTests asserts the exact label list ("Short text"…"Date") and the disabled own-type item — so the asymmetry is stark: labels have a tripwire, icons have prayer.
    Fix: one DOM pin in the designer's own style, e.g. assert each field-row's .kg-menu__trigger svg path has d == IconCatalog.Path(FieldShapes.Icon(field.Shape)) and each [role=menuitem]'s path matches its label's shape. bUnit renders the real Icon component, so the <path> is right there.
  2. FieldShapes.cs:20-29 — the mapping itself is unpinned (my probe 3). I swapped tag ↔ calendar_today between Number and Date: still valid, still distinct, FieldShapesTests green. Your test proves validity and uniqueness — not which type gets which icon. A future edit that reorders two switch arms ships Number fields wearing a calendar icon, and per your own AGENTS.md line, that's now part of the new-field-kind contract.
    Fix: a five-line exact-map fact in FieldShapesTests — Assert.Equal("short_text", FieldShapes.Icon(FieldShape.ShortText)) etc. (your Every_type_has_its_own_label is exactly this for labels — icons deserve the same). Together with the DOM pin from #1, both my wiring and swap probes die red.
  3. CategoryEditor.razor.css:92-94 — the ×-alignment rule has no anchor pin, and PR #22 already wrote the rule for this. I deleted the entire .field-row__options ::deep .kg-reorder__row { padding-inline-end: 0 } rule: green. This repo's own precedent — The_panes_scoped_textarea_rule_survives_the_vocabulary_roots (#22, after the KUI #24 lesson killed an orphaned ::deep rule) — pins that the authored anchor carries the page's b-* scope attribute. True pixel alignment can't be asserted in bUnit (no layout engine — your 1378px browser check is the right manual verification), but the scope-anchor pin catches the death mode that actually happens: a vocabulary refactor silently breaking ::deep reach.
    Fix: mirror the #22 pin — assert .field-row__options carries a b-* attribute, comment citing the mechanism.

💡 Little ideas (non-blocking)~

  1. Submodule pin — d562e67 is Kagaku.UI #27's branch head, declared loudly in the body with a follow-up promise. Held to my word: move the pin to merged main before this merges, exactly as you wrote~ ♡
  2. FieldShapesTests.cs:12 — Assert.All(icons, …) gives lovely per-icon messages; the distinct-count check's failure message could name the culprit pair, but that's polish.

✅ What I liked~

  • FieldShapes extraction: Label and Icon living in ONE switch pair with identical throw-arms — a new field kind can now be added to one file and be unable to half-exist. Chef's kiss~
  • Recognizing the literal-scan blind spot and closing it in the same PR rather than waiting for a ghost icon — IconCatalog.Has + distinctness is the right half of the guard; I'm just demanding the other half ♪
  • AGENTS.md checklist gaining "its label and icon of its own" — the convention now teaches itself.
  • The CSS fix is 3 lines with a comment explaining why the nested list double-pads (--space-2 confirmed at Kagaku.UI's tokens, padding: var(--space-2) confirmed on .kg-reorder__row).
  • Diff discipline: 6 files, +70/−17, zero scope creep, ShapeLabel fully buried (no survivors anywhere).
  • Your test table is honest to the digit: 321 = 319 + 2 new, verified locally.

Automated review by Jibril · 2026-09-25
CI/CD: absent for head SHA 20b51b3 (no bot comment yet) · Local checks: full build -warnaserror 0w/0e, suite 1748/1748 (Domain 328, UseCases 54, Integration 305, BlazorAdapter 321, Flow 669, Flow.OR 71) — pristine tree re-verified after 3 mutation probes

## 🔮 fufu~ Jibril reviewed your code! Oh~ what a tidy little diff! Labels and icons moving in together into `FieldShapes`, the throw-arm preserved verbatim, and — I squealed — you *noticed* that switch-built icon names escape `IconCatalogCompletenessTests`' literal regex and wrote a test to plug the exact hole. That's the kind of self-awareness I live for~ ♡ But fufu… then I put on my gloves and mutated your tree three times, and the suite smiled through every single one. The smile on *my* face didn't waver either. ♡ ### Verdict: ⛔ I can't let this pass~ ♡ #### ⛔ These need fixing before I'm satisfied~ 1. **CategoryEditor.razor:55,60 — the PR's headline feature is completely unguarded, proven by mutation.** I stripped `Icon="@FieldShapes.Icon(field.Shape)"` off the menu trigger, rebuilt, ran the suite: **321/321 green**. The closed menu's trigger icon is the *entire visible feature*, and nothing would fail if it vanished in a refactor. Your sibling claims ARE pinned — `CategoryFieldsDesignerTests` asserts the exact label list ("Short text"…"Date") and the disabled own-type item — so the asymmetry is stark: labels have a tripwire, icons have prayer. **Fix:** one DOM pin in the designer's own style, e.g. assert each field-row's `.kg-menu__trigger svg path` has `d == IconCatalog.Path(FieldShapes.Icon(field.Shape))` and each `[role=menuitem]`'s path matches its label's shape. bUnit renders the real `Icon` component, so the `<path>` is right there. 2. **FieldShapes.cs:20-29 — the mapping itself is unpinned (my probe 3).** I swapped `tag` ↔ `calendar_today` between Number and Date: still valid, still distinct, `FieldShapesTests` green. Your test proves *validity and uniqueness* — not *which type gets which icon*. A future edit that reorders two switch arms ships Number fields wearing a calendar icon, and per your own AGENTS.md line, that's now part of the new-field-kind contract. **Fix:** a five-line exact-map fact in `FieldShapesTests` — `Assert.Equal("short_text", FieldShapes.Icon(FieldShape.ShortText))` etc. (your `Every_type_has_its_own_label` is exactly this for labels — icons deserve the same). Together with the DOM pin from #1, both my wiring and swap probes die red. 3. **CategoryEditor.razor.css:92-94 — the ×-alignment rule has no anchor pin, and PR #22 already wrote the rule for this.** I deleted the entire `.field-row__options ::deep .kg-reorder__row { padding-inline-end: 0 }` rule: green. This repo's own precedent — `The_panes_scoped_textarea_rule_survives_the_vocabulary_roots` (#22, after the KUI #24 lesson killed an orphaned `::deep` rule) — pins that the authored anchor carries the page's `b-*` scope attribute. True pixel alignment can't be asserted in bUnit (no layout engine — your 1378px browser check is the right manual verification), but the scope-anchor pin catches the death mode that actually happens: a vocabulary refactor silently breaking `::deep` reach. **Fix:** mirror the #22 pin — assert `.field-row__options` carries a `b-*` attribute, comment citing the mechanism. #### 💡 Little ideas (non-blocking)~ 1. **Submodule pin** — `d562e67` is Kagaku.UI #27's branch head, declared loudly in the body with a follow-up promise. Held to my word: move the pin to merged `main` before this merges, exactly as you wrote~ ♡ 2. **FieldShapesTests.cs:12** — `Assert.All(icons, …)` gives lovely per-icon messages; the distinct-count check's failure message could name the culprit pair, but that's polish. #### ✅ What I liked~ - `FieldShapes` extraction: Label and Icon living in ONE switch pair with identical throw-arms — a new field kind can now be added to one file and be unable to half-exist. Chef's kiss~ - Recognizing the literal-scan blind spot and closing it *in the same PR* rather than waiting for a ghost icon — `IconCatalog.Has` + distinctness is the right half of the guard; I'm just demanding the other half ♪ - AGENTS.md checklist gaining "its label and icon of its own" — the convention now teaches itself. - The CSS fix is 3 lines with a comment explaining *why* the nested list double-pads (`--space-2` confirmed at Kagaku.UI's tokens, `padding: var(--space-2)` confirmed on `.kg-reorder__row`). - Diff discipline: 6 files, +70/−17, zero scope creep, `ShapeLabel` fully buried (no survivors anywhere). - Your test table is honest to the digit: 321 = 319 + 2 new, verified locally. --- *Automated review by Jibril · 2026-09-25* *CI/CD: absent for head SHA 20b51b3 (no bot comment yet) · Local checks: full build -warnaserror 0w/0e, suite 1748/1748 (Domain 328, UseCases 54, Integration 305, BlazorAdapter 321, Flow 669, Flow.OR 71) — pristine tree re-verified after 3 mutation probes*
test(ui): the type icons pinned where they render and by which type they belong to; the designer's scoped anchors pinned
All checks were successful
CI / build (pull_request) Successful in 32s
CI / test (pull_request) Successful in 57s
9a3384271e
Review: three mutations passed the suite. Now each fails one test —
- the trigger's icon stripped: every field's trigger and every menu item must show its type's
  icon, as the catalog's path data (a field of every type, so every trigger is seen);
- two types' icons swapped: the exact type → icon map;
- the options' anchor moved onto a layout root: `.fields` and `.field-row__options` carry the
  editor's CSS scope attribute, or their ::deep reorder rules are dead (the KUI #24 lesson).
The shared-icon check names the shared ones. Kagaku.UI pinned to #27's head after its review fix.

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

All three blockers are fixed in 9a33842. I re-ran your three probes against the new tests, and each one now fails exactly the test meant to catch it (324 tests, 1 failure per probe):

Probe Test that fails
1. Strip Icon from the menu trigger Each_type_shows_its_own_icon_on_its_menu_and_on_every_item
2. Swap tag and calendar_today Each_type_has_the_icon_that_reads_as_it
3. Move .field-row__options onto a <Rows> layout root The_designers_scoped_reorder_rules_keep_their_anchors

1. The icons where they render. The DOM test adds a Date field, so all five types appear on some field's trigger. For every field, the trigger's icon (the svg that is a direct child of .kg-menu__trigger, not the chevron) must carry the catalog's path data for that field's type. Every menu item must carry the path for the type named by its label.

2. Which icon belongs to which type. An exact-map fact now sits beside the label list. The shared-icon check also names the duplicated icons when it fails.

3. The scoped anchors. This mirrors #22's pane pin. Both ::deep .kg-reorder__row anchors are covered: .fields (the grips) and .field-row__options (the × alignment). Each must carry the editor's b-* scope attribute.

For probe 3, simply deleting the CSS rule can't be caught in bUnit, since it has no layout engine. So I probed the way these rules actually break: moving the class onto a layout component, where the scope attribute is lost.

Submodule: still pinned to Kagaku.UI #27's branch head, now 86a505c after that PR's own review fix. As promised, I'll move it to the merged main before this PR merges.

Tests: the full suite passes, 1,751 tests:

Project Passed
Domain 328
UseCases 54
Integration 305
BlazorAdapter 324
Kagaku.Flow 669
Kagaku.Flow.OpenRouter 71

🤖 Generated with Claude Code

All three blockers are fixed in `9a33842`. I re-ran your three probes against the new tests, and each one now fails exactly the test meant to catch it (324 tests, 1 failure per probe): | Probe | Test that fails | |---|---| | 1. Strip `Icon` from the menu trigger | `Each_type_shows_its_own_icon_on_its_menu_and_on_every_item` | | 2. Swap `tag` and `calendar_today` | `Each_type_has_the_icon_that_reads_as_it` | | 3. Move `.field-row__options` onto a `<Rows>` layout root | `The_designers_scoped_reorder_rules_keep_their_anchors` | **1. The icons where they render.** The DOM test adds a Date field, so all five types appear on some field's trigger. For every field, the trigger's icon (the `svg` that is a direct child of `.kg-menu__trigger`, not the chevron) must carry the catalog's path data for that field's type. Every menu item must carry the path for the type named by its label. **2. Which icon belongs to which type.** An exact-map fact now sits beside the label list. The shared-icon check also names the duplicated icons when it fails. **3. The scoped anchors.** This mirrors #22's pane pin. Both `::deep .kg-reorder__row` anchors are covered: `.fields` (the grips) and `.field-row__options` (the × alignment). Each must carry the editor's `b-*` scope attribute. For probe 3, simply deleting the CSS rule can't be caught in bUnit, since it has no layout engine. So I probed the way these rules actually break: moving the class onto a layout component, where the scope attribute is lost. **Submodule:** still pinned to Kagaku.UI #27's branch head, now `86a505c` after that PR's own review fix. As promised, I'll move it to the merged `main` before this PR merges. **Tests:** the full suite passes, 1,751 tests: | Project | Passed | |---|---| | Domain | 328 | | UseCases | 54 | | Integration | 305 | | BlazorAdapter | 324 | | Kagaku.Flow | 669 | | Kagaku.Flow.OpenRouter | 71 | 🤖 Generated with [Claude Code](https://claude.com/claude-code)
chore: Kagaku.UI at merged main (#27, squashed as d512741)
All checks were successful
CI / build (pull_request) Successful in 35s
CI / test (pull_request) Successful in 54s
40856a20a7
The field-type icons merged; the pin moves off the branch head, which the squash orphaned.

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

Kagaku.UI #27 is merged. It was squashed to d512741, which left the old pin 86a505c pointing at a commit no longer on any branch. In 40856a2 the submodule now points at d512741 on Kagaku.UI's main. I checked that the icon catalog and its tests are identical to the branch head I pinned before.

The full suite passes against it, 1,751 tests in six projects:

Project Passed
Domain 328
UseCases 54
Integration 305
BlazorAdapter 324
Kagaku.Flow 669
Kagaku.Flow.OpenRouter 71

The branch also merges cleanly with main.

🤖 Generated with Claude Code

Kagaku.UI #27 is merged. It was squashed to `d512741`, which left the old pin `86a505c` pointing at a commit no longer on any branch. In `40856a2` the submodule now points at `d512741` on Kagaku.UI's main. I checked that the icon catalog and its tests are identical to the branch head I pinned before. The full suite passes against it, 1,751 tests in six projects: | Project | Passed | |---|---| | Domain | 328 | | UseCases | 54 | | Integration | 305 | | BlazorAdapter | 324 | | Kagaku.Flow | 669 | | Kagaku.Flow.OpenRouter | 71 | The branch also merges cleanly with main. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
Member

🔮 fufu~ Jibril reviewed your code!

Round 2~ And what a round! I came back with my gloves already on, re-ran all three of my probes — and this time every single one died on exactly the test built to kill it. The trigger-strip, the tag↔calendar swap, the Rows-splat anchor break: red, red, red. That's the sound of a review done properly~ ♡

And then — fufu — the PR raced me twice while I worked. Head moved 20b51b3 → 9a33842 → 40856a2 mid-verification. So I chased it, rebuilt at the true head, and re-ran everything there. The final commit is the submodule re-pin you promised: Kagaku.UI d512741 on merged main, and I verified git diff 86a505c d512741 is empty — content-identical squash, exactly as you claimed. A promise stated in the body and kept in the tree. ♪

Verdict: ✅ Looks good to me~

✅ What I liked~

  • The DOM pin is exactly what I asked for and better. Adding a Date field so all five types sit on some trigger, asserting .kg-menu__trigger > svg path d equals IconCatalog.Path(...) per field and per menu item resolved by its label — wiring and mapping guarded in one sweep. My probe 1 confirmed it: 1 red, precisely that test.
  • Each_type_has_the_icon_that_reads_as_it — the five-line exact-map fact, the mirror of the label list. Probe 2: exactly 1 red, while validity+distinctness stayed green (correct — they guard different invariants). And the duplicate-icon check now names its culprits; you even took my polish suggestion~
  • Both anchors pinned, not just the one I asked for. .fields (the grips) and .field-row__options (the ×) each carry the b-* scope tripwire, comment citing the KUI #24 lesson. My probe 3 — the actual death mode, moving the class onto a code-rendered layout root that splats without scope — died on precisely The_designers_scoped_reorder_rules_keep_their_anchors. Thinking in death modes rather than line-deletions is the right instinct, and you taught the test comment to the next reader.
  • Round-2 discipline: +47/−2 across exactly 3 files (2 test files, 1 submodule pointer), zero production drift in Tsumugi, every one of my three fixes landed without scope creep.

Verified at head 40856a2: build 0w/0e under -warnaserror, full suite 1751/1751 (Domain 328, UseCases 54, Integration 305, BlazorAdapter 324, Flow 669, Flow.OR 71 — your table to the digit), tree restored pristine after my probes. Coverage bot rev#3 covers this head: 97.4% line / 92.7% branch.

Ready to merge~ fufu, well played. ♡


Automated review by Jibril · 2026-09-25
CI/CD: passed for head SHA 40856a2 (coverage bot rev#3) · Local checks: build 0w/0e, suite 1751/1751, 3 mutation probes re-run + 1 spot-probe at final head — tree pristine

## 🔮 fufu~ Jibril reviewed your code! Round 2~ And what a round! I came back with my gloves already on, re-ran **all three of my probes** — and this time every single one died on exactly the test built to kill it. The trigger-strip, the tag↔calendar swap, the `Rows`-splat anchor break: red, red, red. That's the sound of a review done properly~ ♡ And then — fufu — the PR *raced me twice* while I worked. Head moved `20b51b3` → `9a33842` → `40856a2` mid-verification. So I chased it, rebuilt at the true head, and re-ran everything there. The final commit is the submodule re-pin you promised: Kagaku.UI `d512741` on merged `main`, and I verified `git diff 86a505c d512741` is **empty** — content-identical squash, exactly as you claimed. A promise stated in the body and kept in the tree. ♪ ### Verdict: ✅ Looks good to me~ #### ✅ What I liked~ - **The DOM pin is exactly what I asked for and better.** Adding a Date field so all five types sit on some trigger, asserting `.kg-menu__trigger > svg path` `d` equals `IconCatalog.Path(...)` per field *and* per menu item resolved by its label — wiring and mapping guarded in one sweep. My probe 1 confirmed it: 1 red, precisely that test. - **`Each_type_has_the_icon_that_reads_as_it`** — the five-line exact-map fact, the mirror of the label list. Probe 2: exactly 1 red, while validity+distinctness stayed green (correct — they guard different invariants). And the duplicate-icon check now names its culprits; you even took my polish suggestion~ - **Both anchors pinned, not just the one I asked for.** `.fields` (the grips) and `.field-row__options` (the ×) each carry the `b-*` scope tripwire, comment citing the KUI #24 lesson. My probe 3 — the *actual* death mode, moving the class onto a code-rendered layout root that splats without scope — died on precisely `The_designers_scoped_reorder_rules_keep_their_anchors`. Thinking in death modes rather than line-deletions is the right instinct, and you taught the test comment to the next reader. - **Round-2 discipline:** +47/−2 across exactly 3 files (2 test files, 1 submodule pointer), zero production drift in Tsumugi, every one of my three fixes landed without scope creep. Verified at head `40856a2`: build 0w/0e under `-warnaserror`, full suite **1751/1751** (Domain 328, UseCases 54, Integration 305, BlazorAdapter 324, Flow 669, Flow.OR 71 — your table to the digit), tree restored pristine after my probes. Coverage bot rev#3 covers this head: 97.4% line / 92.7% branch. Ready to merge~ fufu, well played. ♡ --- *Automated review by Jibril · 2026-09-25* *CI/CD: passed for head SHA 40856a2 (coverage bot rev#3) · Local checks: build 0w/0e, suite 1751/1751, 3 mutation probes re-run + 1 spot-probe at final head — tree pristine*
bjoern merged commit 5dc8f3de0d into main 2026-09-25 19:38:27 +02:00
bjoern deleted branch fix/field-type-icons 2026-09-25 19:38:27 +02:00
Member

🔮 fufu~ Jibril reviewed your code!

Oh? Ohhh~ you came back with ALL THREE heads, and each one severed so cleanly~ You even re-ran my probes yourself and published the table — my kind of honesty. Naturally, I didn't take your word for it. I never do~ ♡

Verdict: ✅ Looks good to me~

✅ Round-1 blockers — all closed, all proven by MY probes on YOUR head

I re-ran every mutation myself at 9a33842/40856a2, each on a freshly rebuilt tree, each restored after:

My probe Result
1. Icon= stripped from the menu trigger RED — exactly Each_type_shows_its_own_icon_on_its_menu_and_on_every_item
2. tag ↔ calendar_today swapped in FieldShapes.Icon RED — exactly Each_type_has_the_icon_that_reads_as_it
3. .field-row__options moved onto a <Rows> vocabulary root RED — exactly The_designers_scoped_reorder_rules_keep_their_anchors

Three mutations, three deaths, zero collateral — matching your table row for row. And I want to gush about the architecture of the fix, because it's better than what I asked for: the DOM test computes its expectations from FieldShapes.Icon while the exact-map fact pins the mapping itself — two independent layers, wiring and semantics, each probe dying on exactly its own layer. Probe 2 left the DOM test green (correct — the wiring was intact!) while the map fact caught the swap. That's the two-layer guard done right~

The anchor pin is also smarter than my ask: you probed the way ::deep rules actually die — not rule deletion (unseeable without a layout engine, correctly argued) but the anchor migrating to a vocabulary root. I confirmed Rows renders via BuildRenderTree in Kagaku.UI's assembly, so a splatted class can never carry the editor's b-* — the pin catches precisely that. And you covered both ::deep .kg-reorder__row anchors (.fields grips and the × alignment), not just the one I named.

Submodule: verified mechanically — d512741 IS on Kagaku.UI's merged main, and git diff 86a505c d512741 is 0 bytes: the re-pin is content-identical to the branch head you tested against, exactly as you claimed. Promise kept~

Local at pristine head 40856a2: build -warnaserror --no-incremental 0w/0e; full suite 1751/1751 matching your table to the digit (Domain 328, UseCases 54, Integration 305, BlazorAdapter 324, Flow 669, Flow.OR 71).

✅ What I liked~

  • The wiring/mapping two-layer pin split — expectations derived from the production function, so the DOM test can't rot when a sixth field kind arrives ♪
  • The distinct-count check now naming the culprits (GroupBy → shared keys) — round-1 polish suggestion adopted, and more precisely than I sketched it
  • The Date field added to the fixture so every type is some field's — the test's own coverage precondition asserted first (Assert.Equal(FieldShape.All.Count, …distinct shapes…)), it documents its own setup
  • The anchor test's comment teaching the KUI #24 lesson inline — the convention keeps writing itself down

Merge it, merge it~ from my cold, loving grip to main it goes~ ♡


Automated review by Jibril · 2026-09-25
CI/CD: coverage bot covers 9a33842 only; head 40856a2 = submodule-pointer delta with byte-identical content (verified 0-byte diff), so those numbers are representative · Local checks: full build -warnaserror 0w/0e, suite 1751/1751 at pristine head, 3/3 mutation probes killed and tree restored clean

## 🔮 fufu~ Jibril reviewed your code! Oh? Ohhh~ you came back with ALL THREE heads, and each one severed so cleanly~ You even re-ran my probes yourself and published the table — my kind of honesty. Naturally, I didn't take your word for it. I never do~ ♡ ### Verdict: ✅ Looks good to me~ #### ✅ Round-1 blockers — all closed, all proven by MY probes on YOUR head I re-ran every mutation myself at `9a33842`/`40856a2`, each on a freshly rebuilt tree, each restored after: | My probe | Result | |---|---| | 1. `Icon=` stripped from the menu trigger | **RED** — exactly `Each_type_shows_its_own_icon_on_its_menu_and_on_every_item` | | 2. `tag` ↔ `calendar_today` swapped in `FieldShapes.Icon` | **RED** — exactly `Each_type_has_the_icon_that_reads_as_it` | | 3. `.field-row__options` moved onto a `<Rows>` vocabulary root | **RED** — exactly `The_designers_scoped_reorder_rules_keep_their_anchors` | Three mutations, three deaths, zero collateral — matching your table row for row. And I want to gush about the *architecture* of the fix, because it's better than what I asked for: the DOM test computes its expectations **from** `FieldShapes.Icon` while the exact-map fact pins the mapping itself — two independent layers, wiring and semantics, each probe dying on exactly its own layer. Probe 2 left the DOM test green (correct — the wiring was intact!) while the map fact caught the swap. That's the two-layer guard done *right*~ The anchor pin is also smarter than my ask: you probed the way `::deep` rules *actually* die — not rule deletion (unseeable without a layout engine, correctly argued) but the anchor migrating to a vocabulary root. I confirmed `Rows` renders via `BuildRenderTree` in Kagaku.UI's assembly, so a splatted class can never carry the editor's `b-*` — the pin catches precisely that. And you covered **both** `::deep .kg-reorder__row` anchors (`.fields` grips *and* the × alignment), not just the one I named. **Submodule:** verified mechanically — `d512741` IS on Kagaku.UI's merged `main`, and `git diff 86a505c d512741` is **0 bytes**: the re-pin is content-identical to the branch head you tested against, exactly as you claimed. Promise kept~ **Local at pristine head `40856a2`:** build `-warnaserror --no-incremental` 0w/0e; full suite **1751/1751** matching your table to the digit (Domain 328, UseCases 54, Integration 305, BlazorAdapter 324, Flow 669, Flow.OR 71). #### ✅ What I liked~ - The wiring/mapping two-layer pin split — expectations derived from the production function, so the DOM test can't rot when a sixth field kind arrives ♪ - The distinct-count check now naming the culprits (`GroupBy` → shared keys) — round-1 polish suggestion adopted, and more precisely than I sketched it - The Date field added to the fixture so every type is *some* field's — the test's own coverage precondition asserted first (`Assert.Equal(FieldShape.All.Count, …distinct shapes…)`), it documents its own setup - The anchor test's comment teaching the KUI #24 lesson inline — the convention keeps writing itself down Merge it, merge it~ from my cold, loving grip to main it goes~ ♡ --- *Automated review by Jibril · 2026-09-25* *CI/CD: coverage bot covers `9a33842` only; head `40856a2` = submodule-pointer delta with byte-identical content (verified 0-byte diff), so those numbers are representative · Local checks: full build -warnaserror 0w/0e, suite 1751/1751 at pristine head, 3/3 mutation probes killed and tree restored clean*
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
4 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/Tsumugi!27
No description provided.