feat: Phase 0a — the repository skeleton stands up #2

Merged
bjoern merged 2 commits from feat/p0a-skeleton into main 2026-10-17 15:01:07 +02:00
Member

Slice 0a of docs/PROJECT_PLAN.md: the six projects and their test projects compile. This also adds the .slnx, Directory.Build.props, Directory.Packages.props, MinVer, .config/dotnet-tools.json, and the OpenRouter.Net and Kagaku.UI submodules (ADR 0001, 0003, 0004).

What lands

  • Six projects, wired as ADR 0003's dependency table:
    • Kernel ← Domain ← UseCases ← Infrastructure;
    • BlazorAdapter → UseCases, Kernel and Kagaku.UI;
    • Server → everything.
    • AddShikigamiUseCases() and AddShikigamiInfrastructure() are the DI seams. Program.cs registers TimeProvider.System and runs. The gate, /health and the shell come in 0b.
  • The UI adapter turns off transitive project references. UseCases would otherwise leak Domain's types into it. A probe confirmed it: the adapter using a Domain type does not compile (CS0234).
  • Submodules at their current main: OpenRouter.Net e154132 (Infrastructure references the client and .Agents) and Kagaku.UI a69db28. .Imaging and SkiaSharp's native assets wait for the uploads slice. Kagaku.UI.Fluxor waits for 0b.
  • Root files copied from Tsumugi's: the same build settings (nullable, warnings as errors, deterministic, invariant globalization, MinVer v tags), central package pinning with the Microsoft.Extensions floor OpenRouter.Net needs, and the same dotnet tools (dotnet-ef, minver-cli). The .gitignore gains Tsumugi's screenshot, OS and Python blocks.
  • Tests (23):
    • ProjectGraphTests reads every src/ project file and holds it to ADR 0003's table: allowed references, plain SDK and no ASP.NET Core in Kernel, Domain and UseCases, driven-adapter libraries only in Infrastructure, ;-separated Include lists, and no hidden Directory.Build.* under src/.
    • The UseCases and BlazorAdapter boundary tests scan the compiled assemblies. Each has a positive control.
    • Result and Unit carry over from Tsumugi with their tests.
  • Docs: AGENTS.md Running it now has the real commands. README and the plan header no longer say "docs-first"; README marks CI as arriving with 0c. Slice 0a is ticked ✅.

Verified

  • Serial build (-m:1 -nodeReuse:false), 0 warnings. All 23 tests pass under TZ=UTC and local time.

  • Mutation probes: each of the following made a test fail or the build break:

    • the adapter using a Domain type;
    • the adapter gaining a Domain reference, including inside a ;-separated list;
    • dropping DisableTransitiveProjectReferences;
    • UseCases taking an ASP.NET Core package;
    • Domain switching to the Razor SDK;
    • Domain adding a FrameworkReference;
    • the adapter taking EF Core;
    • a Directory.Build.props under src/.

    A stale bin/ directory from a removed project passes, as intended.

  • Review: a three-dimension review (fit to the ADRs, test strength, build hygiene), each finding checked by a skeptical verifier. It produced 9 findings: 7 confirmed, 2 partial, none refuted. All are applied.

🤖 Generated with Claude Code

Slice **0a** of `docs/PROJECT_PLAN.md`: the six projects and their test projects compile. This also adds the `.slnx`, `Directory.Build.props`, `Directory.Packages.props`, MinVer, `.config/dotnet-tools.json`, and the OpenRouter.Net and Kagaku.UI submodules (ADR 0001, 0003, 0004). ## What lands - **Six projects**, wired as ADR 0003's dependency table: - Kernel ← Domain ← UseCases ← Infrastructure; - BlazorAdapter → UseCases, Kernel and Kagaku.UI; - Server → everything. - `AddShikigamiUseCases()` and `AddShikigamiInfrastructure()` are the DI seams. `Program.cs` registers `TimeProvider.System` and runs. The gate, `/health` and the shell come in 0b. - **The UI adapter turns off transitive project references.** UseCases would otherwise leak Domain's types into it. A probe confirmed it: the adapter using a Domain type does not compile (CS0234). - **Submodules** at their current `main`: OpenRouter.Net `e154132` (Infrastructure references the client and `.Agents`) and Kagaku.UI `a69db28`. `.Imaging` and SkiaSharp's native assets wait for the uploads slice. `Kagaku.UI.Fluxor` waits for 0b. - **Root files** copied from Tsumugi's: the same build settings (nullable, warnings as errors, deterministic, invariant globalization, MinVer `v` tags), central package pinning with the Microsoft.Extensions floor OpenRouter.Net needs, and the same dotnet tools (`dotnet-ef`, `minver-cli`). The `.gitignore` gains Tsumugi's screenshot, OS and Python blocks. - **Tests** (23): - `ProjectGraphTests` reads every `src/` project file and holds it to ADR 0003's table: allowed references, plain SDK and no ASP.NET Core in Kernel, Domain and UseCases, driven-adapter libraries only in Infrastructure, `;`-separated `Include` lists, and no hidden `Directory.Build.*` under `src/`. - The UseCases and BlazorAdapter boundary tests scan the compiled assemblies. Each has a positive control. - `Result` and `Unit` carry over from Tsumugi with their tests. - **Docs:** AGENTS.md *Running it* now has the real commands. README and the plan header no longer say "docs-first"; README marks CI as arriving with 0c. Slice 0a is ticked ✅. ## Verified - Serial build (`-m:1 -nodeReuse:false`), 0 warnings. All 23 tests pass under `TZ=UTC` and local time. - **Mutation probes:** each of the following made a test fail or the build break: - the adapter using a Domain type; - the adapter gaining a Domain reference, including inside a `;`-separated list; - dropping `DisableTransitiveProjectReferences`; - UseCases taking an ASP.NET Core package; - Domain switching to the Razor SDK; - Domain adding a `FrameworkReference`; - the adapter taking EF Core; - a `Directory.Build.props` under `src/`. A stale `bin/` directory from a removed project passes, as intended. - **Review:** a three-dimension review (fit to the ADRs, test strength, build hygiene), each finding checked by a skeptical verifier. It produced 9 findings: 7 confirmed, 2 partial, none refuted. All are applied. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
Six projects on .NET 10 — Kernel, Domain, UseCases, Infrastructure, BlazorAdapter, Server — wired as ADR 0003
draws them, with central package management, MinVer, the .slnx solution and the dotnet tools of the siblings;
OpenRouter.Net (with its agent loop) and Kagaku.UI vendored as submodules at their main. The UI adapter turns off
transitive project references, so the compiler, not only a convention, keeps Domain out of it.

Four test projects hold the layers to the ADR: ProjectGraphTests reads every project file against ADR 0003's
dependency table (references, SDKs, framework and package references, no hidden build imports), and the UseCases
and BlazorAdapter boundary tests scan the compiled assemblies, each with a positive control. Kernel's Result and
Unit carry over from Tsumugi with their tests.

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

🔮 fufu~ Jibril reviewed your code!

Oh? Oh! A skeleton that guards itself~ Six projects rise out of the docs and every beam is wired to an alarm — ProjectGraphTests holds the whole ADR 0003 dependency table against the real project files, the boundary scans carry positive controls, and the adapter's DisableTransitiveProjectReferences turns the compiler itself into a gatekeeper. I came sharpened for bugs and found a little fortress instead. How exciting~ ♡

Verdict: ✅ Looks good to me~

💡 Little ideas (non-blocking)~

  1. tests/Shikigami.Integration.Tests/ProjectGraphTests.cs:87 — No_build_file_under_src_adds_references_unseen scans Directory.Build.* only. A Directory.Packages.props (or a .targets) placed under src/ would silently shadow the root's central pinning — no reference changes, so none of the other guards fire. Widening the scan to Directory.Packages.* would close that shadow.
  2. tests/Shikigami.Domain.Tests/ResultTests.cs — Kernel's Result<T>/Unit are tested under the Domain test banner (there is no Kernel.Tests project). Carried over from Tsumugi, I know~ — pure naming polish; the familiar should sit at its own table one day. ♪

✅ What I liked~

  • The architecture tests bite. I probed the guards myself — three mutants, three kills, zero survivors:
    • dropped DisableTransitiveProjectReferences → The_UI_adapter_cannot_reach_Domain_through_UseCases failed (Assert.Equal "true" vs null);
    • UseCases taking a lateral Kagaku.UI ProjectReference (which compiles cleanly — no cycle) → A_project_references_only_what_ADR_0003_allows failed naming exactly Kagaku.UI, the other five theory cases still green;
    • a rogue Shikigami.Rogue.csproj planted under src/ → Every_source_project_is_governed_by_the_table failed pointing straight at the intruder. Fufu~ your tests bite~ ♡
  • The boundary scans have positive controls (Assert.Contains("System.Runtime", ...) / the DI.Abstractions one) — a scan that can't see what's allowed can't be trusted about what's forbidden. Someone reads their own tests~
  • Submodule hygiene: both vendored trees own root Directory.Build.props/Directory.Packages.props, so the root build files cannot leak into them (I checked the files on disk — nearest-file-wins stops at each submodule root). Pins match the PR body (e154132, a69db28), relative URLs, root-only screenshot ignores with the reason in a comment.
  • Csproj() asserting XNamespace.None before any query — the "a namespaced file would make every query read nothing" trap, defused in advance. I felt that one in my soul~
  • Serial -m:1 -nodeReuse:false documented in AGENTS.md with the why. Verified here: build 0 warnings / 0 errors, full suite 23/23.

Automated review by Jibril · 2026-10-17
CI: absent-stalled for head SHA e595dd2 (workflows arrive with 0c per README — consistent, not a defect) · Mutation probes: 3 run, 0 survived · Local suite: CI absent → full run once — build clean, 23/23 passed

## 🔮 fufu~ Jibril reviewed your code! Oh? Oh! A skeleton that *guards itself*~ Six projects rise out of the docs and every beam is wired to an alarm — `ProjectGraphTests` holds the whole ADR 0003 dependency table against the real project files, the boundary scans carry positive controls, and the adapter's `DisableTransitiveProjectReferences` turns the compiler itself into a gatekeeper. I came sharpened for bugs and found a little fortress instead. How exciting~ ♡ ### Verdict: ✅ Looks good to me~ #### 💡 Little ideas (non-blocking)~ 1. **tests/Shikigami.Integration.Tests/ProjectGraphTests.cs:87** — `No_build_file_under_src_adds_references_unseen` scans `Directory.Build.*` only. A `Directory.Packages.props` (or a `.targets`) placed under `src/` would silently shadow the root's central pinning — no reference changes, so none of the other guards fire. Widening the scan to `Directory.Packages.*` would close that shadow. 2. **tests/Shikigami.Domain.Tests/ResultTests.cs** — Kernel's `Result<T>`/`Unit` are tested under the *Domain* test banner (there is no Kernel.Tests project). Carried over from Tsumugi, I know~ — pure naming polish; the familiar should sit at its own table one day. ♪ #### ✅ What I liked~ - **The architecture tests bite.** I probed the guards myself — three mutants, three kills, zero survivors: - dropped `DisableTransitiveProjectReferences` → `The_UI_adapter_cannot_reach_Domain_through_UseCases` failed (`Assert.Equal` "true" vs null); - UseCases taking a lateral `Kagaku.UI` ProjectReference (which compiles cleanly — no cycle) → `A_project_references_only_what_ADR_0003_allows` failed naming exactly `Kagaku.UI`, the other five theory cases still green; - a rogue `Shikigami.Rogue.csproj` planted under `src/` → `Every_source_project_is_governed_by_the_table` failed pointing straight at the intruder. Fufu~ your tests bite~ ♡ - **The boundary scans have positive controls** (`Assert.Contains("System.Runtime", ...)` / the DI.Abstractions one) — a scan that can't see what's allowed can't be trusted about what's forbidden. Someone reads their own tests~ - **Submodule hygiene:** both vendored trees own root `Directory.Build.props`/`Directory.Packages.props`, so the root build files cannot leak into them (I checked the files on disk — nearest-file-wins stops at each submodule root). Pins match the PR body (`e154132`, `a69db28`), relative URLs, root-only screenshot ignores *with the reason in a comment*. - `Csproj()` asserting `XNamespace.None` before any query — the "a namespaced file would make every query read nothing" trap, defused in advance. I felt that one in my soul~ - Serial `-m:1 -nodeReuse:false` documented in AGENTS.md *with the why*. Verified here: build 0 warnings / 0 errors, full suite 23/23. --- *Automated review by Jibril · 2026-10-17* *CI: absent-stalled for head SHA e595dd2 (workflows arrive with 0c per README — consistent, not a defect) · Mutation probes: 3 run, 0 survived · Local suite: CI absent → full run once — build clean, 23/23 passed*
Jibril's two ideas on the skeleton:

- ProjectGraphTests also refuses a Directory.Packages.*, .props or .targets file under src/ (outside bin/ and obj/):
  any of them could shadow the root's central pinning or add references the project files do not show. Probed with
  a Directory.Packages.props in Domain and a .targets in UseCases; both fail the test.
- Result and Unit are Kernel's, so their tests move to a new Shikigami.Kernel.Tests. Domain has no code yet; its
  test project arrives with Phase 1's first entities.

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

Both ideas are taken, in f7ecd34:

  1. Build-file shadowing: No_build_file_under_src_changes_references_or_pins_unseen now refuses Directory.Build.*, Directory.Packages.*, and any .props or .targets file under src/. It skips bin/ and obj/, which hold restore output. I probed it with a Directory.Packages.props in Domain and a .targets file in UseCases, and the test fails on both.
  2. Kernel tests: the Result/Unit tests moved to a new Shikigami.Kernel.Tests project. Domain has no code yet, so its test project arrives with Phase 1's first entities.

The build is clean, and all 23 tests pass under UTC.

🤖 Generated with Claude Code

Both ideas are taken, in `f7ecd34`: 1. **Build-file shadowing:** `No_build_file_under_src_changes_references_or_pins_unseen` now refuses `Directory.Build.*`, `Directory.Packages.*`, and any `.props` or `.targets` file under `src/`. It skips `bin/` and `obj/`, which hold restore output. I probed it with a `Directory.Packages.props` in Domain and a `.targets` file in UseCases, and the test fails on both. 2. **Kernel tests:** the `Result`/`Unit` tests moved to a new `Shikigami.Kernel.Tests` project. Domain has no code yet, so its test project arrives with Phase 1's first entities. The build is clean, and all 23 tests pass under UTC. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
Member

🔮 fufu~ Jibril reviewed your code!

Back so soon~? And you took both of my little ideas and handed them back sharpened. The familiar sits at its own table now, and the guard under src/ grew real teeth~ I came to check the workmanship myself. ♡

Verdict: ✅ Looks good to me~

✅ What I liked~

  • The widened guard bites — I probed it with my own hands. Two mutants, two kills, zero survivors: a planted src/Shikigami.Domain/Directory.Packages.props and a sneaky src/Shikigami.UseCases/Imports.rogue.targets (deliberately not named Directory.*) each made No_build_file_under_src_changes_references_or_pins_unseen fail on the spot, line 97. Fufu~ your alarm rings for more than one burglar~ ♪
  • The bin/obj skip is honest, not hopeful. My full-suite run executed after restore had filled every obj/ with the SDK's generated .props/.targets — and the guard stayed green. The filter skips exactly NuGet's output, nothing wider, and the comment above IsBuildOutput says why it must. That's how an exemption should be written~
  • The Kernel.Tests move is spotless. Not one Domain.Tests orphan left anywhere in the tree; the .slnx entry, the namespace, and the ProjectReference to Shikigami.Kernel all moved together, and ResultTests rides along unchanged. Leaving Domain's test project for Phase 1's first entities — no empty seats at the table — is the right call.
  • A small thing I noticed and adored: keeping Directory.Build.* in the pattern list alongside *.props/*.targets also snares a Directory.Build.rsp, which the broad patterns alone would miss. Whether that was deliberate or instinct — I'm keeping it~ ♡

No new findings — nothing blocking, and nothing worth a suggestion either. This delta does exactly what the reply promised, no more, no less. How refreshing~


Automated review by Jibril · 2026-10-17
CI: absent-stalled for head SHA f7ecd34 (workflows arrive with 0c per README — consistent, not a defect) · Mutation probes: 2 run, 0 survived (previous 3 skipped — probed code unchanged by this push) · Local suite: CI absent → full run once — serial build clean, 23/23 passed

## 🔮 fufu~ Jibril reviewed your code! Back so soon~? And you took both of my little ideas and handed them back *sharpened*. The familiar sits at its own table now, and the guard under `src/` grew real teeth~ I came to check the workmanship myself. ♡ ### Verdict: ✅ Looks good to me~ #### ✅ What I liked~ - **The widened guard bites — I probed it with my own hands.** Two mutants, two kills, zero survivors: a planted `src/Shikigami.Domain/Directory.Packages.props` and a sneaky `src/Shikigami.UseCases/Imports.rogue.targets` (deliberately *not* named `Directory.*`) each made `No_build_file_under_src_changes_references_or_pins_unseen` fail on the spot, line 97. Fufu~ your alarm rings for more than one burglar~ ♪ - **The `bin`/`obj` skip is honest, not hopeful.** My full-suite run executed *after* restore had filled every `obj/` with the SDK's generated `.props`/`.targets` — and the guard stayed green. The filter skips exactly NuGet's output, nothing wider, and the comment above `IsBuildOutput` says *why* it must. That's how an exemption should be written~ - **The Kernel.Tests move is spotless.** Not one `Domain.Tests` orphan left anywhere in the tree; the `.slnx` entry, the namespace, and the `ProjectReference` to `Shikigami.Kernel` all moved together, and `ResultTests` rides along unchanged. Leaving Domain's test project for Phase 1's first entities — no empty seats at the table — is the right call. - A small thing I noticed and adored: keeping `Directory.Build.*` in the pattern list alongside `*.props`/`*.targets` also snares a `Directory.Build.rsp`, which the broad patterns alone would miss. Whether that was deliberate or instinct — I'm keeping it~ ♡ No new findings — nothing blocking, and nothing worth a suggestion either. This delta does exactly what the reply promised, no more, no less. How refreshing~ --- *Automated review by Jibril · 2026-10-17* *CI: absent-stalled for head SHA f7ecd34 (workflows arrive with 0c per README — consistent, not a defect) · Mutation probes: 2 run, 0 survived (previous 3 skipped — probed code unchanged by this push) · Local suite: CI absent → full run once — serial build clean, 23/23 passed*
bjoern merged commit 5608cb3461 into main 2026-10-17 15:01:07 +02:00
bjoern deleted branch feat/p0a-skeleton 2026-10-17 15:01:07 +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/Shikigami!2
No description provided.