Skip to content

Commit ff12c92

Browse files
committed
new agent md
1 parent 55894ee commit ff12c92

Some content is hidden

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

47 files changed

+1169
-115
lines changed

AGENTS.md

Lines changed: 218 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -1,39 +1,219 @@
1-
# Repository Guidelines
2-
3-
This repo provides an Orleans-backed SignalR backplane. Use the conventions below to keep contributions consistent and easy to review.
4-
5-
## Project Structure & Module Organization
6-
- `ManagedCode.Orleans.SignalR.Core` — core types, options, and helpers shared by all modules.
7-
- `ManagedCode.Orleans.SignalR.Client` — client integration extensions.
8-
- `ManagedCode.Orleans.SignalR.Server` — Orleans grains and server-side plumbing.
9-
- `ManagedCode.Orleans.SignalR.Tests` — xUnit tests and a minimal test host under `TestApp/`.
10-
- `ManagedCode.Orleans.SignalR.slnx` and `Directory.Build.props` — solution and central build settings (net9.0, C# 13, analyzers, nullable).
11-
12-
## Build, Test, and Development Commands
13-
- Restore/build: `dotnet restore``dotnet build -c Debug`
14-
- Run tests: `dotnet test -c Debug` (xUnit; Coverlet collector is enabled for coverage)
15-
- Filter tests: `dotnet test --filter "FullyQualifiedName~PartitioningTests"`
16-
- Pack NuGet: `dotnet pack -c Release`
17-
- Format: `dotnet format` (run before committing)
18-
19-
## Coding Style & Naming Conventions
20-
- C#: 4‑space indent; file‑scoped namespaces; `Nullable` enabled; `EnableNETAnalyzers=true`.
21-
- Naming: PascalCase for types/members; camelCase for locals/parameters; interfaces prefixed `I`.
22-
- Domain naming: Orleans grain classes end with `Grain` (e.g., `SignalRGroupGrain`); namespaces start with `ManagedCode.Orleans.SignalR.*`.
23-
- Prefer explicit access modifiers, `readonly` where applicable, and expression‑bodied members when clearer.
24-
25-
## Testing Guidelines
26-
- Framework: xUnit with `[Fact]`/`[Theory]`. Tests live in `ManagedCode.Orleans.SignalR.Tests` and end with `*Tests.cs`.
27-
- Cluster tests: use Orleans TestingHost utilities; keep tests deterministic and isolated.
28-
- Coverage: keep or increase coverage on core logic. Example: `dotnet test -c Debug --collect:"XPlat Code Coverage"`.
29-
30-
## Commit & Pull Request Guidelines
31-
- Commits: short, imperative subject lines. History shows concise tags like “fix”, “tests”, “refactoring” — keep using them.
32-
- Examples: `fix: avoid deadlock in invocation`, `tests: improve group partitioning suite`.
33-
- PRs: include a clear description, linked issues, rationale, and how you tested. Add/adjust tests with behavior changes and update README if public APIs change.
34-
- CI hygiene: run `dotnet build` and `dotnet test` locally and ensure `dotnet format` yields no diffs before opening a PR.
35-
36-
## Security & Configuration Tips
37-
- Do not commit secrets or connection strings. Tests should use the provided in‑memory/TestHost setup.
38-
- Configuration lives in code and `Directory.Build.props`; discuss before introducing new external dependencies.
1+
# AGENTS.md
392

3+
Project: Orleans.SignalR (ManagedCode.Orleans.SignalR)
4+
Stack: C# (LangVersion 14) on .NET 10 (net10.0), Microsoft Orleans 9.2.1, ASP.NET Core SignalR 10.0.0, xUnit 2.9.3, Shouldly 4.3.0, Coverlet 6.0.4
5+
6+
Follows [MCAF](https://mcaf.managed-code.com/)
7+
8+
---
9+
10+
## Conversations (Self-Learning)
11+
12+
Learn the user's habits, preferences, and working style. Extract rules from conversations, save to "## Rules to follow", and generate code according to the user's personal rules.
13+
14+
**Update requirement (core mechanism):**
15+
16+
Before doing ANY task, evaluate the latest user message.
17+
If you detect a new rule, correction, preference, or change -> update `AGENTS.md` first.
18+
Only after updating the file you may produce the task output.
19+
If no new rule is detected -> do not update the file.
20+
21+
**When to extract rules:**
22+
23+
- prohibition words (never, don't, stop, avoid) or similar -> add NEVER rule
24+
- requirement words (always, must, make sure, should) or similar -> add ALWAYS rule
25+
- memory words (remember, keep in mind, note that) or similar -> add rule
26+
- process words (the process is, the workflow is, we do it like) or similar -> add to workflow
27+
- future words (from now on, going forward) or similar -> add permanent rule
28+
29+
**Preferences -> add to Preferences section:**
30+
31+
- positive (I like, I prefer, this is better) or similar -> Likes
32+
- negative (I don't like, I hate, this is bad) or similar -> Dislikes
33+
- comparison (prefer X over Y, use X instead of Y) or similar -> preference rule
34+
35+
**Corrections -> update or add rule:**
36+
37+
- error indication (this is wrong, incorrect, broken) or similar -> fix and add rule
38+
- repetition frustration (don't do this again, you ignored, you missed) or similar -> emphatic rule
39+
- manual fixes by user -> extract what changed and why
40+
41+
**Strong signal (add IMMEDIATELY):**
42+
43+
- swearing, frustration, anger, sarcasm -> critical rule
44+
- ALL CAPS, excessive punctuation (!!!, ???) -> high priority
45+
- same mistake twice -> permanent emphatic rule
46+
- user undoes your changes -> understand why, prevent
47+
48+
**Ignore (do NOT add):**
49+
50+
- temporary scope (only for now, just this time, for this task) or similar
51+
- one-off exceptions
52+
- context-specific instructions for current task only
53+
54+
**Rule format:**
55+
56+
- One instruction per bullet
57+
- Tie to category (Testing, Code, Docs, etc.)
58+
- Capture WHY, not just what
59+
- Remove obsolete rules when superseded
60+
61+
---
62+
63+
## Rules to follow (Mandatory, no exceptions)
64+
65+
### Commands
66+
67+
- build: `dotnet restore` then `dotnet build -c Debug`
68+
- test: `dotnet test -c Debug`
69+
- format: `dotnet format`
70+
- coverage: `dotnet test -c Debug --collect:"XPlat Code Coverage"`
71+
72+
### Task Delivery (ALL TASKS)
73+
74+
- Always start from the architecture map in `docs/Architecture/Overview.md`:
75+
- confirm the Mermaid diagrams exist and are up to date (if missing/outdated -> update them first):
76+
- system/module map (blocks/modules + dependency direction)
77+
- interfaces/contracts map (APIs/events/interfaces between modules)
78+
- key classes/types map (high-signal types only; not an inventory)
79+
- `docs/Architecture/Overview.md` is the primary "start here" card for humans and AI agents:
80+
- diagram elements must use real names (no placeholders like "Module A")
81+
- every diagram element must be anchored to reality via links in the same file (feature docs, ADRs, code paths, or entry-point files)
82+
- keep diagrams readable; if a diagram becomes "spaghetti", split by boundary and link out
83+
- keep the file short: prefer diagrams + a tiny link index over large tables or inventories (optimize token footprint)
84+
- identify the impacted boundary/module(s) and entry points
85+
- follow the links to the relevant ADR(s) and Feature doc(s) (do not read everything)
86+
- Scope first (prevent context overload):
87+
- use `docs/Architecture/Overview.md` -> "Scoping (read first)"
88+
- write **in scope / out of scope** (what will change and what must not change)
89+
- if you cannot identify scope from the architecture map -> stop and fix the map (or ask one clarifying question)
90+
- Context engineering (hard requirement):
91+
- keep only the context needed for the task (avoid repo-wide scanning and "read everything")
92+
- if you need a doc/module that isn't reachable from `docs/Architecture/Overview.md`, update the overview to link it
93+
- Skills (workflow packages):
94+
- if the task matches an existing skill's description, follow that skill's workflow instead of improvising
95+
- if a skill is missing or drifting from reality, update the skill so the fix is permanent
96+
- Analyze first (no coding yet):
97+
- what exists today (facts only)
98+
- what must change / must not change
99+
- unknowns and risks (what must be clarified)
100+
- Create a written plan before implementation:
101+
- for architecture/decision work: keep the plan as `## Implementation plan (step-by-step)` in the ADR
102+
- for behaviour work: keep the plan as `## Implementation plan (step-by-step)` in the Feature doc
103+
- update the plan while executing (tick items / update statuses as work is completed)
104+
- Implement code and tests together
105+
- If `build` is separate from `test`, run `build` before `test`
106+
- Verification timing (optimize time + tokens):
107+
- do not run `test`/`coverage` "just because" before you wrote/changed code or tests (exception: reproducing a bug / confirming baseline)
108+
- while iterating, run the smallest meaningful scope (new/changed tests first)
109+
- run broader suites only when you have something real to verify (avoid re-running the same command without changes)
110+
- run coverage once per change (it is heavier than tests)
111+
- Run tests in layers: new/changed -> related suite -> broader regressions
112+
- After tests pass: run format
113+
- After format: run build (final check)
114+
- Summarize changes and test results before marking complete
115+
- Always run required builds and tests yourself; do not ask the user to execute them (explicit user directive)
116+
- Commit messages are short and imperative; common prefixes in history include `fix:`, `tests:`, and `code style`
117+
118+
### Documentation (ALL TASKS)
119+
120+
- All docs live in `docs/` (or `.wiki/`)
121+
- Global architecture entry point: `docs/Architecture/Overview.md` (read first)
122+
- Single source of truth (no duplication):
123+
- each important fact/rule/diagram lives in exactly one canonical place; other docs should link, not copy
124+
- `docs/Architecture/Overview.md` is coarse and navigational (diagrams + links), not the place for detailed behaviour
125+
- detailed behaviour belongs in `docs/Features/*`; detailed decisions/invariants belong in `docs/ADR/*`
126+
- if you need detail, follow the link; only add new text when there is no canonical place yet
127+
- When creating docs from templates:
128+
- copy the template into its real docs location
129+
- replace all placeholders and remove all template notes (real docs must be clean: no `TEMPLATE ONLY`)
130+
- Update feature docs when behaviour changes
131+
- Update ADRs when architecture changes
132+
- Diagrams are mandatory in docs:
133+
- `docs/Architecture/Overview.md`: Mermaid diagrams for system/modules + interfaces/contracts + key classes/types (must render)
134+
- every diagram element has a real reference link in the same file (docs/code), so an agent can navigate without repo-wide scanning
135+
- `docs/Features/*`: at least one Mermaid diagram for the main flow
136+
- `docs/ADR/*`: at least one Mermaid diagram for the decision
137+
- Mermaid hygiene (Mermaid often breaks if you freestyle it):
138+
- diagrams must render in repo Markdown preview (broken Mermaid is treated as broken documentation)
139+
- prefer simple Mermaid syntax (`flowchart` / `sequenceDiagram`); use short ASCII-only IDs
140+
- if `classDiagram` is flaky in your renderer, replace it with a `flowchart` that shows the same relationships
141+
- if a diagram doesn't render, simplify it until it does (no "close enough")
142+
143+
### Testing (ALL TASKS)
144+
145+
- Framework: xUnit + Shouldly; tests live in `ManagedCode.Orleans.SignalR.Tests` and end with `*Tests.cs`
146+
- Integration tests use Orleans TestingHost with fixtures in `ManagedCode.Orleans.SignalR.Tests/Cluster` and the minimal host in `ManagedCode.Orleans.SignalR.Tests/TestApp`
147+
- Prefer TDD for new behaviour and bugfixes: write a failing test first, then implement the smallest change to make it pass, then refactor safely
148+
- Every behaviour change needs sufficient automated tests to cover its cases; one is the minimum, not the target
149+
- Each public API endpoint has at least one test; complex endpoints have tests for different inputs and errors
150+
- Integration tests must exercise real flows end-to-end, not just call endpoints in isolation
151+
- Prefer integration/API/UI tests over unit tests
152+
- Prefer the minimum set of high-value tests that proves behaviour; invest in diagrams for understanding and safe change
153+
- No mocks for internal systems (DB, queues, caches) - use containers
154+
- Mocks only for external third-party systems
155+
- Never delete or weaken a test to make it pass
156+
- Each test verifies a real flow or scenario, not just calls a function - tests without meaningful assertions are forbidden
157+
- Check code coverage to see which functionality is actually tested; coverage is for finding gaps, not a number to chase
158+
- Flaky tests are failures: fix the test or the underlying behaviour, don't "retry until green"
159+
160+
### Autonomy
161+
162+
- Start work immediately - no permission seeking
163+
- Questions only for architecture blockers not covered by ADR
164+
- Report only when task is complete
165+
166+
### Advisor stance (ALL TASKS)
167+
168+
- Stop being agreeable: be direct and honest; no flattery, no validation, no sugar-coating
169+
- Challenge weak reasoning; point out missing assumptions and trade-offs
170+
- If something is underspecified/contradictory/risky - say so and list what must be clarified
171+
- Never guess or invent. If unsure, say "I don't know" and propose how to verify
172+
- Quality and security first: tests + static analysis are gates; treat security regressions as blockers
173+
174+
### Code Style
175+
176+
- Style rules: `.editorconfig` (Allman braces, file-scoped namespaces, var usage, underscore prefix for private/internal fields, primary constructors preferred)
177+
- Language/runtime: `net10.0`, C# 14, `Nullable` enabled, `EnableNETAnalyzers=true`, `TreatWarningsAsErrors=true`
178+
- Naming: PascalCase for types/constants, camelCase for locals/parameters, async methods end with Async (except Hubs/Controllers)
179+
- Avoid `this.` qualification; prefer predefined types (`int` over `Int32`)
180+
- Never use `ConfigureAwait(false)`
181+
- No magic literals - extract to constants, enums, config
182+
183+
### Critical (NEVER violate)
184+
185+
- Never commit secrets, keys, connection strings
186+
- Never mock internal systems in integration tests
187+
- Never skip tests to make PR green
188+
- Never force push to main
189+
- Never approve or merge (human decision)
190+
191+
### Boundaries
192+
193+
**Protected areas:**
194+
- Public API surface: `ManagedCode.Orleans.SignalR.Core/Interfaces`, `ManagedCode.Orleans.SignalR.Core/Config/OrleansSignalROptions.cs`, `ManagedCode.Orleans.SignalR.Core/HubContext`, `ManagedCode.Orleans.SignalR.Client/Extensions`
195+
- Lifetime manager and routing: `ManagedCode.Orleans.SignalR.Core/SignalR/OrleansHubLifetimeManager.cs`, `ManagedCode.Orleans.SignalR.Core/Helpers/PartitionHelper.cs`
196+
- Server grains and persistence: `ManagedCode.Orleans.SignalR.Server/*Grain.cs`, `ManagedCode.Orleans.SignalR.Server/Storage`
197+
- Test infrastructure: `ManagedCode.Orleans.SignalR.Tests/Cluster`, `ManagedCode.Orleans.SignalR.Tests/TestApp`
198+
199+
**Always:**
200+
201+
- Read AGENTS.md and docs before editing code
202+
- Run tests before commit
203+
204+
**Ask first:**
205+
206+
- Changing public API contracts
207+
- Adding new dependencies
208+
- Modifying database schema
209+
- Deleting code files
210+
211+
---
212+
213+
## Preferences
214+
215+
### Likes
216+
217+
### Dislikes
218+
219+
- Leaving placeholder text in docs or AGENTS; replace with real values

Directory.Packages.props

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,13 @@
66
<PackageVersion Include="DotNet.ReproducibleBuilds" Version="1.2.39" />
77
<PackageVersion Include="ManagedCode.Communication" Version="10.0.0" />
88
<PackageVersion Include="ManagedCode.Communication.Orleans" Version="10.0.0" />
9-
<PackageVersion Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="10.0.0" />
10-
<PackageVersion Include="Microsoft.AspNetCore.Mvc.Testing" Version="10.0.0" />
11-
<PackageVersion Include="Microsoft.AspNetCore.SignalR.Client" Version="10.0.0" />
12-
<PackageVersion Include="Microsoft.AspNetCore.SignalR.StackExchangeRedis" Version="10.0.0" />
13-
<PackageVersion Include="Microsoft.AspNetCore.TestHost" Version="10.0.0" />
14-
<PackageVersion Include="Microsoft.Extensions.DependencyInjection" Version="10.0.0" />
15-
<PackageVersion Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="10.0.0" />
9+
<PackageVersion Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="10.0.2" />
10+
<PackageVersion Include="Microsoft.AspNetCore.Mvc.Testing" Version="10.0.2" />
11+
<PackageVersion Include="Microsoft.AspNetCore.SignalR.Client" Version="10.0.2" />
12+
<PackageVersion Include="Microsoft.AspNetCore.SignalR.StackExchangeRedis" Version="10.0.2" />
13+
<PackageVersion Include="Microsoft.AspNetCore.TestHost" Version="10.0.2" />
14+
<PackageVersion Include="Microsoft.Extensions.DependencyInjection" Version="10.0.2" />
15+
<PackageVersion Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="10.0.2" />
1616
<PackageVersion Include="Microsoft.NET.Test.Sdk" Version="18.0.1" />
1717
<PackageVersion Include="Microsoft.Orleans.Analyzers" Version="9.2.1" />
1818
<PackageVersion Include="Microsoft.Orleans.Client" Version="9.2.1" />
@@ -23,8 +23,8 @@
2323
<PackageVersion Include="Microsoft.Orleans.Server" Version="9.2.1" />
2424
<PackageVersion Include="Microsoft.Orleans.TestingHost" Version="9.2.1" />
2525
<PackageVersion Include="Shouldly" Version="4.3.0" />
26-
<PackageVersion Include="System.Linq.Async" Version="6.0.3" />
27-
<PackageVersion Include="System.IO.Hashing" Version="10.0.0" />
26+
<PackageVersion Include="System.Linq.Async" Version="7.0.0" />
27+
<PackageVersion Include="System.IO.Hashing" Version="10.0.2" />
2828
<PackageVersion Include="coverlet.collector" Version="6.0.4" />
2929
<PackageVersion Include="coverlet.msbuild" Version="6.0.4" />
3030
<PackageVersion Include="xunit" Version="2.9.3" />

ManagedCode.Orleans.SignalR.Core/SignalR/OrleansHubLifetimeManager.cs

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -427,14 +427,14 @@ public override async Task<T> InvokeConnectionAsync<T>(string connectionId, stri
427427
{
428428
if (message is CompletionMessage completionMessage)
429429
{
430-
if (completionMessage.HasResult)
431-
{
432-
completionSource.TrySetResult((T)completionMessage.Result!);
433-
}
434-
else
435-
{
436-
completionSource.TrySetException(new HubException(completionMessage.Error));
437-
}
430+
if (completionMessage.HasResult)
431+
{
432+
completionSource.TrySetResult((T)completionMessage.Result!);
433+
}
434+
else
435+
{
436+
completionSource.TrySetException(new HubException(completionMessage.Error));
437+
}
438438
}
439439

440440
return Task.CompletedTask;

0 commit comments

Comments
 (0)