Skip to content

Commit 37a9da0

Browse files
committed
refactor(orleans): organize vertical slices by responsibility
Move tracked source files without changing contents or namespaces. Require feature-local role folders and update source navigation. Local solution Release build, formatter and governance passed; runtime qualification remains incomplete, with RF3 local environment/image-proof failures recorded.
1 parent 2801b03 commit 37a9da0

114 files changed

Lines changed: 103 additions & 8 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

‎AGENTS.md‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@ This file defines how AI agents work in this solution.
7474
## Mandatory Solution Architecture (`MCAF-ARCH-001`)
7575
- This solution MUST be delivered as one repository. All solution-owned backend, frontend, contracts, tests, infrastructure, and documentation live here and are versioned together.
7676
- Vertical-slice architecture is mandatory across the entire repository.
77+
- Owner correction 2026-10-04 requires responsibility-based structure inside every vertical slice. A `Features/<SliceName>/` directory MUST NOT become a flat dump of unrelated grains, commands, queries, models, contracts, streaming and infrastructure helpers. Keep applicable roles in explicit child folders such as `Grains/`, `Commands/`, `Queries/`, `Models/`, `Contracts/`, `Streaming/`, `Identity/`, `Serialization/` and `Topology/`, all within the owning slice; create only folders with actual owned code. Feature-local role folders MUST NOT become repository-wide layers. Preserve stable namespaces, Orleans aliases/field IDs and runtime behavior during structural moves, and update source maps, path-bound checks and local policy in the same change.
7778
- Every feature MUST use one canonical `<SliceName>` across backend, frontend, contracts, tests, and `docs/Features/`.
7879
- Every technical root MUST organize feature-owned work under the same `Features/<SliceName>/` convention, or use one fully colocated executable-artifact convention; durable feature docs remain under `docs/Features/<SliceName>.md`.
7980
- A feature surface that does not apply MUST be recorded as `N/A` with a reason in the feature spec; it must not be silently omitted.

‎docs/ADR/ADR-032-mcaf-governance.md‎

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,3 +80,32 @@ flowchart LR
8080
Links --> Verify[Real Node validator and TUnit checks]
8181
Verify --> Deliver[Reviewed scoped Git delivery]
8282
```
83+
84+
## Owner-directed feature-local role migration, 2026-10-04
85+
86+
Decision: MCAF-ARCH-001 requires populated responsibility folders inside each owning
87+
feature. A flat collection of unrelated grains, commands, queries, models and helpers
88+
is not the target structure. Roles stay inside the canonical slice rather than becoming
89+
global layers. Requirements: REQ-MCAF-010; acceptance: AC-MCAF-010; execution:
90+
TASK-MCAF-LAYOUT-001/002 in RepositoryGovernance. This stage covers KeyLoad.Orleans.
91+
92+
Implementation contract: root first adds policy and captures exact current source bytes,
93+
then moves every feature source to its actual role, preserving dirty/untracked work,
94+
namespaces, API signatures, Orleans aliases/Ids and serialization. Routing owns Grains,
95+
Commands, Queries, Models, Contracts, Streaming, Identity, Serialization, Diagnostics and
96+
Topology. Replication owns GrainServices, Discovery, Transport, Authentication, Replay,
97+
Contracts and Models. ResourceExecution owns Models, Contracts, Serialization,
98+
Authentication and Validation. Small read-capability slices own Queries. The read-only
99+
reviewer verifies responsibility assignment and path consumers; root owns all writes,
100+
reference updates, combined checks and delivery. New API/data/dependencies/topology,
101+
behavior fixes and other projects' layout migrations are outside this stage.
102+
103+
Rollout is an exact-content physical move with current documentation path repair;
104+
MSBuild's existing recursive source glob includes the files. Rollback reverses physical
105+
paths without losing later code edits; it does not revoke the owner's mandatory rule.
106+
Verification compares every pre/post file byte and complete inventory, checks no flat
107+
feature C# file remains, reviews live links, and runs governance, formatter, Release
108+
build and AppHost unit/recovery/RF3 suites. Existing process-recovery and real SDK/MCP
109+
RF3 contracts remain mandatory. Missing infrastructure or unrelated concurrent compiler
110+
failures are reported and never relabelled as passing. This migration does not mark the
111+
ADR's other architecture debt or product qualification complete.

‎docs/Architecture.md‎

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -179,7 +179,7 @@ All KeyLoad-owned backend, clients, contracts, frontend, tests, infrastructure a
179179
| src/KeyLoad.Query | QueryEngine.cs, SqlParser.cs, SearchEngine.cs; Features/ChangeFeeds/LiveQueryExecutor.cs behind LiveQueries.cs facade | QueryExecution, Search, ChangeFeeds; one authorized typed AST and bounded read cut. |
180180
| src/KeyLoad.Artifacts | Features/BackupRestore/ArtifactTransfer.cs, BackupArtifact.cs | BackupRestore; verified artifact transport and format ownership. |
181181
| src/KeyLoad.Replication | Features/ClusterReplication/ClusterCoordinator.cs, DurableReplicaLog.cs, ReplicaMaterializer.cs | ClusterReplication, StorageRecovery; ordered durable apply and quorum authority behind the active Orleans server composition; delivered-SHA RF3 qualification pending. |
182-
| src/KeyLoad.Orleans | Features/ClusterRouting/RequestGrain.cs, DatabaseReadGrain.cs, CommandPartitionGrain.cs, ReplicaMembershipTable.cs | ClusterRouting; active server composition routes through grains while node-local hosts own storage; forced activation-migration qualification pending. |
182+
| src/KeyLoad.Orleans | Features/ClusterRouting/Grains/{RequestGrain,DatabaseReadGrain,CommandPartitionGrain}.cs; Topology/ReplicaMembershipTable.cs | ClusterRouting; active server composition routes through grains while node-local hosts own storage; forced activation-migration qualification pending. |
183183
| src/KeyLoad.Server | Program.cs, NodeOptions.cs, Features/ClientApi/, Features/ClusterRouting/OrleansNode.cs and feature API files | Composition root and public API; caller identity never supplies trusted roles. |
184184
| src/KeyLoad.Client | KeyLoadClient.cs, KeyLoadQuery.cs | ClientApi shared transport; business operations mirror the same canonical slices as core/contracts/API/tests. |
185185
| src/KeyLoad.Cli | Program.cs, Hosting/KeyLoadCliApplication.cs, Features/ClientApi/CliClientApi.cs and Features/BackupRestore/CliBackupRestore.cs | Composition-only administrative entry point and typed ClientApi/BackupRestore feature owners. |
@@ -224,6 +224,17 @@ classDiagram
224224

225225
## Feature convention and migration
226226

227+
Each vertical slice groups actual responsibilities in populated local role folders;
228+
`Features/<SliceName>/` is an ownership boundary, not a flat file collection.
229+
KeyLoad.Orleans now separates routing grains, commands, queries, models, contracts,
230+
streaming, identity, serialization, diagnostics and topology. Its replication slice
231+
separates grain services, discovery, transport, authentication, replay and wire models;
232+
ResourceExecution separates cache-control models, contracts, serialization,
233+
authentication and validation. AdminDashboard and BlobStorage own query capabilities
234+
in `Queries/`. The migration preserves namespaces, aliases/Ids and runtime behavior.
235+
The owner contract and checks are in [RepositoryGovernance](Features/RepositoryGovernance.md)
236+
and [ADR-032](ADR/ADR-032-mcaf-governance.md).
237+
227238
Canonical slice names use PascalCase consistently: RepositoryGovernance, BenchmarkComparisons, DocumentStorage, RelationalStorage, EventStreams, Messaging, GraphTraversal, TimeSeries, Search, QueryExecution, Authorization, ChangeFeeds, StorageRecovery, ClusterReplication, ClusterRouting, ClientApi, BackupRestore, BlobStorage, ResourceExecution, CodeQuality and TestInfrastructure. Their owning contracts and navigation are in the [Feature index](README.md).
228239

229240
The embedded microbenchmark boundary follows Accepted ADR-047; it is peripheral

‎docs/Features/ClusterReplication.md‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,7 @@ cleanup failures require source lifetime review rather than a synthetic injector
101101

102102
## Actors, entry points and failure boundaries
103103

104-
Actors are authenticated SDK/MCP callers, the node-local replica host, fixed voters, the membership provider and the recovery operator. Current source is composed by [ServerApplication](../../src/KeyLoad.Server/Features/ClientApi/ServerApplication.cs): it starts the node-local [PartitionHost](../../src/KeyLoad.Server/Features/StorageRecovery/PartitionHost.cs) and Orleans silo, whose [replica service](../../src/KeyLoad.Orleans/Features/ClusterReplication/PartitionReplicaGrainService.cs) routes peer operations. Aspire declares three Docker nodes with separate data mounts. This source is not yet qualified as a delivered RF3 deployment: current tests do not force request-activation migration and then verify storage ownership and a durable caller-visible outcome. Public HTTP/.NET transport belongs to ClientApi; required official MCP parity is pending. Frontend is N/A because replica consensus has no independent UI. Shared contracts stay in Abstractions and the exact ClusterReplication/StorageRecovery slice owners above.
104+
Actors are authenticated SDK/MCP callers, the node-local replica host, fixed voters, the membership provider and the recovery operator. Current source is composed by [ServerApplication](../../src/KeyLoad.Server/Features/ClientApi/ServerApplication.cs): it starts the node-local [PartitionHost](../../src/KeyLoad.Server/Features/StorageRecovery/PartitionHost.cs) and Orleans silo, whose [replica service](../../src/KeyLoad.Orleans/Features/ClusterReplication/GrainServices/PartitionReplicaGrainService.cs) routes peer operations. Aspire declares three Docker nodes with separate data mounts. This source is not yet qualified as a delivered RF3 deployment: current tests do not force request-activation migration and then verify storage ownership and a durable caller-visible outcome. Public HTTP/.NET transport belongs to ClientApi; required official MCP parity is pending. Frontend is N/A because replica consensus has no independent UI. Shared contracts stay in Abstractions and the exact ClusterReplication/StorageRecovery slice owners above.
105105

106106
Positive flow: an authorized command reaches its own request grain, the physical host orders and persists it, a majority crosses the declared acknowledgement barrier, and canonical apply returns the stable outcome. Negative flow: minority, stale term/owner, invalid peer MAC/replay or denied principal cannot establish committed success. Edge/error flow: an unknown response is resolved by stable command ID; interrupted/corrupt append or snapshot reopens one verified cut or fails explicitly; cancellation drains owned work without transferring locks to a migrating activation.
107107

‎docs/Features/ClusterRouting.md‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ with `TimeProvider.System` and the silo startup cancellation token. Later provid
4646
calls use independent bounded request deadlines, so cancellation of the startup
4747
token does not prevent membership shutdown. Membership never owns files and never
4848
resolves an Orleans client while constructing its provider. Source ownership is
49-
the new `Features/ClusterRouting/ReplicaMembershipTable.cs` and cohesive helpers;
49+
the new `Features/ClusterRouting/Topology/ReplicaMembershipTable.cs` and cohesive helpers;
5050
the lead replaces the old provider and composes the actual silo. The frozen primary
5151
constructor accepts database, coordinator, replica endpoint, cluster ID, internal
5252
principal ID, TimeProvider, and startup CancellationToken in that order.

‎docs/Features/RepositoryGovernance.md‎

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ All requirements are mandatory. IDs remain stable when implementation changes.
1717
| REQ-MCAF-007 | Evidence / P0 | Keep conflicts, migration gaps and CI qualification explicit; publish only GitHub Actions performance JSON. | AC-MCAF-007: no unsupported readiness or benchmark claim is introduced. |
1818
| REQ-MCAF-008 | Repository hygiene / P0 | Remove temporary planning Markdown files and keep requirements, acceptance and execution contracts in canonical Feature/ADR documents. | AC-MCAF-008: no tracked or checkout `*.plan.md`, `*.brainstorm.md` or `*.acceptance.md`; all three patterns are ignored without exceptions. |
1919
| REQ-MCAF-009 | Validation / P0 | Repository rules validate durable documents and reject reintroduced working planning files. | AC-MCAF-009: the real Node validator passes without planning files and fails for each suffix at root or nested paths; prefix, ownership and skill checks remain. |
20+
| REQ-MCAF-010 | Architecture / P0 | Organize each vertical slice by its actual responsibilities instead of placing mixed role files in a flat feature root. The immediate migration covers every KeyLoad.Orleans slice. | AC-MCAF-010: every Orleans feature C# file belongs to a populated role folder; the before/after file-content inventory is identical, namespaces/aliases/Ids remain unchanged, live references resolve and Release compilation includes the moved files. |
2021

2122
## Slice surfaces
2223

@@ -120,3 +121,52 @@ REQ-MCAF-008/009 and AC-MCAF-008/009 supersede only the earlier requirement for
120121
Testing methodology: AC-008 uses complete file/Git inventory and real `git check-ignore` checks at root/nested paths for every suffix. AC-009 uses TUnit/Microsoft.Testing.Platform to execute the original Node validator on real filesystem copies of the current repository's required policy/inventory documents, with no planning files (pass) and each suffix at root or nested paths (fail). Existing prefix, project/module, required document and skill rejection checks remain. Static review verifies live links and that only the explicitly authorized file-placement policy changed. Local development checks do not establish RF3, recovery, performance or production qualification.
121122

122123
Local verification, 2026-10-03: removed 59 tracked files and 123 additional checkout files; all three suffixes are ignored at root and nested paths, including the former governance exceptions. The live Node validator passes with 26 projects and four modules. The original nine TUnit cases pass with no failures or skips; their focused Release build has zero warnings/errors and the scoped formatter passes. Reference review preserves existing REQ/AC occurrences and Markdown fences and resolves every new local link. The shared solution build is blocked by concurrent, untracked scaled-storage tests requiring unfinished Fixture/Snapshot types; those files are outside this delivery.
124+
125+
## Feature-local responsibility structure, 2026-10-04
126+
127+
REQ-MCAF-010 / AC-MCAF-010 extend MCAF-ARCH-001 and [ADR-032](../ADR/ADR-032-mcaf-governance.md).
128+
A feature folder remains the ownership boundary; role folders inside it make grains,
129+
commands, queries, models and supporting protocols discoverable. Global layer folders,
130+
empty placeholder folders and namespace/wire-contract changes are outside this migration.
131+
132+
TASK-MCAF-LAYOUT-001: root owns policy, this specification, ADR-032, Architecture and
133+
all physical moves in `src/KeyLoad.Orleans/Features/`. TASK-MCAF-LAYOUT-002: read-only
134+
reviewer inventories responsibilities and path-bound consumers, then reviews the final
135+
map. Shared documentation and source moves have one integration owner because the
136+
current routing files contain concurrent CQRS changes. Reviewer starts after the root
137+
policy correction; integration joins only after its exact mapping and concerns are reviewed.
138+
139+
Ordered work: capture exact file contents; group routing, replication and cache metadata
140+
by actual role; move small read-capability slices into Queries; repair current source
141+
navigation; compare the complete byte inventory and ensure no flat C# files remain;
142+
run governance, formatter, solution Release build and relevant AppHost suites. Positive
143+
flow resolves a grain/query/model through its owning slice and role. Negative flow
144+
rejects lost, duplicated, flat or changed source files. Edge flow preserves dirty and new
145+
files byte for byte. Compiler/style failures and unavailable test infrastructure remain
146+
explicit blockers. No runtime behavior changes are intended, so no new behavior test
147+
is added: the structural criteria use explicit complete-inventory/manual role review
148+
plus existing compilation and runtime suites. Local checks do not qualify RF3 or durability.
149+
150+
```mermaid
151+
flowchart LR
152+
Slice[Owning feature] --> Grains[Grains]
153+
Slice --> Commands[Commands]
154+
Slice --> Queries[Queries]
155+
Slice --> Models[Models and contracts]
156+
Slice --> Protocols[Streaming and supporting roles]
157+
Grains --> Verify[Unchanged source and runtime contracts]
158+
Commands --> Verify
159+
Queries --> Verify
160+
Models --> Verify
161+
Protocols --> Verify
162+
```
163+
164+
Structural development verification, 2026-10-04: moved all108 current Orleans C#
165+
files (105 tracked files and three concurrent new source files) across all five slices;
166+
complete SHA-256 inventory and independent role review passed with unchanged source.
167+
Governance and the full solution formatter passed. Release solution build passed with
168+
zero warnings/errors (MSBuild servers disabled, single build worker after sandbox IPC
169+
blocked the initial attempt). RF3 attempt:14/93 passed,79 failed;76 reject macOS
170+
temporary reparse paths, two require authentic GitHub RF3 image identity and one requires
171+
genuine prior-server proof. Unit/recovery verification remains pending; no delivered
172+
Linux GitHub runtime, fault, performance or durability qualification is claimed.

‎docs/implementation/documentation-coverage.json‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13386,8 +13386,8 @@
1338613386
"fileOwnership": [
1338713387
"Directory.Packages.props",
1338813388
"src/KeyLoad.Orleans/KeyLoad.Orleans.csproj",
13389-
"src/KeyLoad.Orleans/Features/ClusterRouting/GrainRequestContextState.cs",
13390-
"src/KeyLoad.Orleans/Features/ClusterRouting/GrainIdentityContext.cs",
13389+
"src/KeyLoad.Orleans/Features/ClusterRouting/Identity/GrainRequestContextState.cs",
13390+
"src/KeyLoad.Orleans/Features/ClusterRouting/Identity/GrainIdentityContext.cs",
1339113391
"src/KeyLoad.Server/Features/ClientApi/PersistedPrincipalRequestContextScope.cs",
1339213392
"src/KeyLoad.Server/Features/ClientApi/CanonicalOperationGateway.cs",
1339313393
"src/KeyLoad.Server/Features/Authorization/DatabaseCredentialResolver.cs",

0 commit comments

Comments
 (0)