This file is the canonical coding contract for AI-assisted changes in turbo-cloud.
Tool-specific instruction files should reference this file instead of duplicating rules.
This repository targets the following core stack. When coding, prefer patterns compatible with these versions:
- .NET SDK
9.0.310(fromglobal.json) - C# / BCL
net9.0 - Orleans
9.2.1 - EF Core
9.0.8 - Pomelo MySQL provider
9.0.0 - SuperSocket
2.0.2
Activate the relevant skill checklist before editing code in that domain:
handler-development- Trigger: editing files under
Turbo.PacketHandlers/**or message-to-composer orchestration logic. - Enforce: orchestration-only handlers, no DB queries, canonical grain access, no silent catches.
- Trigger: editing files under
grain-development- Trigger: editing files under
Turbo.*\\Grains\\**orTurbo.Primitives/**/Grains/*.cs. - Enforce: keep ownership boundaries, lifecycle rules, and snapshot/state coherence.
- Trigger: editing files under
session-presence-routing- Trigger: touching session gateway, presence flow, room routing, outbound composer fan-out.
- Enforce: player outbound via
PlayerPresenceGrain.SendComposerAsync; no direct handler socket sends.
message-contracts- Trigger: editing
Turbo.Primitives/Messages/Incoming/**or outgoing composer payload mappings. - Enforce: explicit mandatory fields, no placeholder payloads when source data exists.
- Trigger: editing
revision-protocol(cross-repo)- Trigger: changes referencing
Revision<id>packet mappings. - Enforce: edit plugin revision tree in
../turbo-sample-plugin/TurboSamplePlugin/Revision/**.
- Trigger: changes referencing
- Build and quality checks in repo files (
Directory.Build.props,Directory.Build.targets,.editorconfig) CONTEXT.mdarchitecture and placement boundaries- Existing neighboring code conventions in the target folder
- Tool-specific adapters (for example
.github/copilot-instructions.md)
Use this request shape with any AI tool:
- Goal:
- Target files:
- Required context files:
- Invariants to preserve:
- Forbidden changes:
- Validation commands:
- Output format:
Default output format:
- concise rationale
- file-by-file diff summary
- risks/assumptions
- exact validation command results
- Target framework/tooling:
.NET 9pinned viaglobal.json. - Keep C# formatting compatible with repo quality gates (
dotnet csharpier check,dotnet format). - Follow
.editorconfignaming/style preferences. - Keep diffs focused and minimal; avoid unrelated refactors.
- Avoid introducing new dependencies unless required by the task.
- Match local conventions in the files you touch.
- Prefer deterministic handlers/services with clear guard clauses.
- Preserve cancellation and async flow where it already exists.
- Handle failure paths explicitly; do not ship happy-path-only changes.
- Avoid dead code, unused allocations, and broad catch blocks that hide errors.
- For revision compatibility work, prefer restoring/adding missing incoming message contracts in
Turbo.Primitives/Messages/Incoming/**before mutating serializer/composer payload behavior. - Do not alter serializer/composer behavior by replacing real payload writes with placeholder constants (for example, unconditional
WriteInteger(0)) unless explicitly requested. - If work references
Revision<id>parsers/serializers, edit the plugin repo path:../turbo-sample-plugin/TurboSamplePlugin/Revision/**- Do not hallucinate those trees into
turbo-cloud.
- Keep packet handlers orchestration-only:
- validate input
- call grains through canonical grain-factory access patterns
- map snapshot data to outgoing composers
- Do not query database contexts or repositories directly from packet handlers.
- Keep persistence access in grains/services/providers that own domain state.
- Do not use ad-hoc grain key strings in handlers when extension-based access exists.
- Do not add silent
catchblocks in handlers. - When snapshot fields are available, map them into composer payloads instead of TODO placeholders.
- For incoming message records in
Turbo.Primitives/Messages/Incoming/**, keep mandatory fields explicit (userequiredwhere appropriate) instead of default-fallback contracts.
- Connection/session lifecycle starts in gateway flow; do not duplicate session registration in handlers.
- Post-SSO session attachment goes through
PlayerPresenceGrain(one active presence grain per player id). - Player-targeted outbound flow must be:
- resolve player presence grain
- call
SendComposerAsync - rely on presence fan-out to subscribed sessions
- Do not send directly to raw sockets/session transports from packet handlers.
- Active-room membership/discovery belongs to
RoomDirectoryGrain; do not bypass it with ad-hoc room tracking. - Grain lifetime remains Orleans-managed by default; use
[KeepAlive]only for explicitly justified directory/manager grains.
When adding packet mappings in Turbo.Revisions/Revision20260112:
- Update
Turbo.Revisions/Revision20260112/Headers.cs:- add/update incoming
MessageEventid constants - add/update outgoing
MessageComposerid constants
- add/update incoming
- Add parser class under:
Turbo.Revisions/Revision20260112/Parsers/<Domain>/*MessageParser.cs
- Add serializer class under:
Turbo.Revisions/Revision20260112/Serializers/<Domain>/*MessageComposerSerializer.cs
- Register mappings in:
Turbo.Revisions/Revision20260112/Revision20260112.cs- incoming:
Parsersdictionary withMessageEventkey - outgoing:
Serializersdictionary with composer type +MessageComposerid
- Ensure the required
usingdirectives are present inRevision20260112.csfor new parser/serializer namespaces.
- Required context files:
AGENTS.mdCONTEXT.mdTurbo.Primitives/Orleans/GrainFactoryExtensions.cs
- Required references:
- one handler in same domain under
Turbo.PacketHandlers/<Domain>/ - related incoming message type under
Turbo.Primitives/Messages/Incoming/**
- one handler in same domain under
- Forbidden changes:
- no direct DB access in handler
- no direct session/socket sends
- no ad-hoc grain key literals when extension methods exist
- Validation:
dotnet build Turbo.Main/Turbo.Main.csproj -t:TurboCloudFastCheckdotnet build Turbo.Main/Turbo.Main.csproj -t:TurboCloudQualityGate
- Required context files:
AGENTS.mdCONTEXT.md- target grain interface in
Turbo.Primitives/**/Grains/*.cs
- Required references:
- existing grain in same module
- related snapshot/state types in
Turbo.Primitives/Orleans/Snapshots/**orStates/**
- Forbidden changes:
- no handler-layer fallback logic that bypasses grain ownership
- no lifecycle changes that abuse
[KeepAlive]without infrastructure justification
- Validation:
dotnet build Turbo.Main/Turbo.Main.csproj -t:TurboCloudFastCheckdotnet build Turbo.Main/Turbo.Main.csproj -t:TurboCloudQualityGate
- Required context files:
AGENTS.mdCONTEXT.md- neighboring message/composer classes
- Required references:
- incoming message under
Turbo.Primitives/Messages/Incoming/** - outgoing composer under
Turbo.Primitives/Messages/Outgoing/** - handler using same message family
- incoming message under
- Forbidden changes:
- no placeholder payload collections when source snapshot data exists
- no implicit default-fallback contracts for mandatory incoming fields
- Validation:
dotnet build Turbo.Main/Turbo.Main.csproj -t:TurboCloudFastCheckdotnet build Turbo.Main/Turbo.Main.csproj -t:TurboCloudQualityGate
- Required context files:
AGENTS.mdCONTEXT.md- current lookup owner grain/service
- Required references:
- existing set/invalidate methods
- all reverse-lookup call sites
- Forbidden changes:
- no one-way cache updates; forward/reverse mappings must stay coherent
- no loss of case-insensitive semantics for username lookups
- Validation:
dotnet build Turbo.Main/Turbo.Main.csproj -t:TurboCloudFastCheckdotnet build Turbo.Main/Turbo.Main.csproj -t:TurboCloudQualityGate
dotnet build Turbo.Main/Turbo.Main.csproj -t:TurboCloudFastCheck
dotnet build Turbo.Main/Turbo.Main.csproj -t:TurboCloudQualityGate- All modified files match nearby patterns and contract rules.
- Quality gates pass with no new warnings introduced by the change.
- Architecture invariants for touched areas are explicitly confirmed in PR.
- Edge/failure behavior is addressed for logic changes.
- Any context-rule updates needed by the change are included in the same PR.
- Disclose AI usage and major generated sections.
- Be able to explain complex generated logic in your own words.
- Include verification of at least one edge/failure scenario when behavior changes.