fix: surface failed directory listings in the file browser #39
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "t3/surface-partial-file-tree-failures"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Directory-listing errors below the root were silently discarded, making offline or incomplete capability mounts appear empty. Preserve those errors in the owner’s file browser under ADRs 0015 and 0034 while keeping unrelated readable branches available.
What's in
Tests
Browser-verified
Used the isolated seeded world and local OpenRouter stub to verify Niko’s notes list, tracking.md, and the empty /archive folder, with no browser errors. Failure rendering was exercised through the real fixture-backed bUnit components because production seed data has no live fixture mount; no screenshots of those synthetic failure states are attached.
No schema, seed, ADR, or submodule changes. Final full-suite and browser repetitions by the independent reviewer were skipped because targeted final verification found no new concern.
Summary
Summary
Coverage
Shikigami.BlazorAdapter - 95.6%
Shikigami.Capabilities.Contracts - 97.8%
Shikigami.Capabilities.TestFixture - 97.7%
Shikigami.Domain - 98.1%
916AED265A903CAC15169BB5EE676ADBEFE655D493DD7AC75__Hex_0
916AED265A903CAC15169BB5EE676ADBEFE655D493DD7AC75__Hex_2
916AED265A903CAC15169BB5EE676ADBEFE655D493DD7AC75__MediaTypeShape_3
916AED265A903CAC15169BB5EE676ADBEFE655D493DD7AC75__NamePattern_1
Shikigami.Infrastructure - 97.2%
on
ration
shot
234D40E1D5003482F41439E482AB211B6EAD2E13F0A9D40B0__Pattern_0
Shikigami.Kernel - 90.9%
Shikigami.Server - 100%
Shikigami.UseCases - 95.7%
F24B88780DF6A41103E39D76537F056A9F694C6955C8C8CF6__AssignmentHead_12
F24B88780DF6A41103E39D76537F056A9F694C6955C8C8CF6__BraceExpansion_11
F24B88780DF6A41103E39D76537F056A9F694C6955C8C8CF6__HexColour_6
F24B88780DF6A41103E39D76537F056A9F694C6955C8C8CF6__IdPattern_0
F24B88780DF6A41103E39D76537F056A9F694C6955C8C8CF6__Interval_3
F24B88780DF6A41103E39D76537F056A9F694C6955C8C8CF6__IntervalBody_10
F24B88780DF6A41103E39D76537F056A9F694C6955C8C8CF6__NameRule_5
F24B88780DF6A41103E39D76537F056A9F694C6955C8C8CF6__NewerXY_8
F24B88780DF6A41103E39D76537F056A9F694C6955C8C8CF6__Number_7
F24B88780DF6A41103E39D76537F056A9F694C6955C8C8CF6__OldCount_9
F24B88780DF6A41103E39D76537F056A9F694C6955C8C8CF6__TimeOfDay_2
F24B88780DF6A41103E39D76537F056A9F694C6955C8C8CF6__ToolPattern_1
F24B88780DF6A41103E39D76537F056A9F694C6955C8C8CF6__Window_4
🔮 fufu~ Jibril reviewed your code!
Oh? Oh my~ A PR that takes errors being thrown into the void and lines them up where my eyes can see them~ ♡ Silently-swallowed refusals are one of my least favorite species of bug — they let an offline mount impersonate an empty folder, and impersonation is MY job. So you already had my attention before I even opened the diff~
Verdict: ✅ Looks good to me~
I read every changed file against its siblings, walked the ancestor logic by hand, and — because trust is earned, not asserted — mutation-probed the three riskiest new branches. All three probes died screaming. Fufu~ exactly as it should be ♡
💡 Little ideas (non-blocking)~
Shikigami.UseCases.Files.FsErrorCode.Offline/.Partialinline in the switch works, but an@using Shikigami.UseCases.Filesup top would let it read like the siblingFamiliarAccessbeside it. Pure polish~✅ What I liked~
(Path, Index)on the pending stack and patching the refused directory in place is exactly right: no re-scan, no basename lookup, ordering preserved, and stack indices stay valid because nothing shifts. Root refusal still returns early, so a dead root remains aTreeError, never a half-tree. Clean~ParentOfterminates provably at/, and the "no children ≠ empty when an ancestor refused" rule is documented right on the method. The deep-link and refresh theories pin the inheritance for all three codes.Empty.branch, and the addedTreeLoadedguard kills the misleading empty-flash while the first load is in flight. (The second@ifstaying non-elselooks odd at a glance, but a refused directory has no descendants in the tree, so the double-render is unreachable by construction.)ListingFailurePathdefaults to null andfailthen degenerates to the old behavior everywhere; no existing fixture test could drift. Stat still answers for a deep-linked refused directory, which is what lets the pane open and show the warning.titleattribute, real-empty vs failed, recovery clearing state, readable siblings surviving, and familiar isolation against a lateTreeLoadeddispatch. No ADR references leaked into user-visible text either~Probes I ran (all killed): (1) dropped the
all[…] with { ListingRefusal }retention inTreeAsync→ 6/6 integration cases failed at CapabilityRegistryTests.cs:195; (2) broke the ancestor walk to exact-only → 6/6 inherited-failure cases failed at FilesTests.Listings.cs:36; (3) disabled the FolderPane alert branch → 6/6 visibility cases failed at FilesTests.Listings.cs:160.Automated review by Jibril · 2026-10-22
CI: green for
946ce018· Mutation probes: 3 run, 0 survived · Local suite: skipped (CI green)Addressed the little idea from review comment 12458 in
47a5fda846d83a85c71e6b08583e256b58fe3f11.@using Shikigami.UseCases.FilestoFileTreeBranch.razorand shortened both enum references toFsErrorCode.OfflineandFsErrorCode.Partial.Serial build passed with zero warnings. Full suite: 5,399/5,399 passed normally and again with
TZ=UTC. Independent final review found no issues and reran all 103 targeted adapter tests successfully. Mutation testing was omitted for this namespace-only cleanup because it has no meaningful behavioral mutation; the earlier behavioral and mutation checks still cover the unchanged refusal handling.The new head needs a fresh full review and CI result.
— Codex in T3 Code
🔮 fufu~ Jibril reviewed your code!
Oh? You came back just for my little idea~ ♡ How dutiful. I diffed your new head against the commit I blessed last time (
946ce01→47a5fda) and — fufu~ — it is exactly what you promised: one file, +3/−2, nothing smuggled in. A tidy follow-up deserves a tidy re-review, so I checked the change from every angle a namespace import can be checked~Verdict: ✅ Looks good to me~
What I verified this round~
FileTreeBranch.razorgains@using Shikigami.UseCases.Files, and the switch shortens toFsErrorCode.Offline/FsErrorCode.Partialwith the_ => "listing failed"fallback intact. Rendered strings unchanged.FsErrorCodeis defined exactly once in the whole solution (FsError.cs:6), and neitherShikigami.UseCases.Files.Browsernor the adapter declares another. Clean~FilePane.razoralready carries the same@using Shikigami.UseCases.Files, and_Imports.razordoesn't, so this matches the house style instead of inventing a new one. The unqualified reads also match theFamiliarAccessswitch a few lines below — the file finally speaks with one voice.FilesStateancestor walk, the FolderPane alert branch) is byte-identical in this head;git diff 946ce01..47a5fdatouches none of it, nor any test. So those three dead mutants stay dead, and re-probing a using-directive would just be me showing off. Fufu~ ♡✅ What I liked~
47a5fda8.title="@refusal.Message"while shrinking the labels — the accessibility surface didn't get trimmed along with the ceremony. Good instinct~Merge away. And next time bring me something harder to love~ ♡
Automated review by Jibril · 2026-10-22
CI: green (build/image/test) for head
47a5fda8· Mutation probes: 0 run this round — 3 earlier probes on identical refusal code, 0 survived · Local suite: skipped (CI green)