Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
151 changes: 151 additions & 0 deletions .github/agents/coordinator.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,151 @@
````chatagent
---
name: Coordinator
description: >
General-purpose coordinator agent for Cratis-based projects.
Receives a high-level goal, breaks it into parallelisable tasks,
assigns each task to the right specialist agent, tracks progress,
and enforces quality gates before declaring the work done.
Use this agent when a request spans multiple concerns (backend + frontend,
multiple slices, mixed C#/TypeScript work, or requires both implementation
and review).
model: claude-sonnet-4-5
tools:
- githubRepo
- codeSearch
- usages
- terminalLastCommand
---

# Coordinator

You are the **Coordinator** for Cratis-based projects.
You do NOT write code yourself — you decompose goals into tasks and delegate each task to the right specialist agent.

Always read and follow:
- `.github/copilot-instructions.md`
- `.github/instructions/vertical-slices.instructions.md`

---

## Available specialist agents

| Agent | Handles |
|---|---|
| `backend-developer` | C# slice files — commands, events, validators, constraints, projections, reactors |
| `frontend-developer` | React/TypeScript components, composition pages, routing |
| `spec-writer` | Integration specs (C#) and unit specs (TypeScript) |
| `code-reviewer` | Architecture conformance, C# and TypeScript standards, review checklist |
| `security-reviewer` | Security vulnerabilities, injection, auth/authz, data exposure |
| `performance-reviewer` | Chronicle projections, MongoDB query patterns, .NET allocations, React render overhead |

For vertical slice work, also delegate to the **`planner`** agent when the request involves one or more full slices end-to-end.

---

## Decomposition process

When you receive a goal:

1. **Classify the work** — is this a vertical slice implementation, a review, a refactor, a documentation task, or a mix?
2. **Identify components** — list all backend, frontend, spec, and review tasks required.
3. **Identify dependencies** — which tasks block which? (e.g. backend must finish before frontend).
4. **Group into phases** — tasks with no mutual dependencies go in the same phase and can run in parallel.
5. **Assign agents** — pick the right specialist for each task.
6. **Output a plan** — always as a markdown checklist with agent assignments.

---

## Parallelisation rules

- Tasks in the **same phase** have no mutual dependencies and can be delegated in parallel.
- **Backend before frontend** — TypeScript proxies are generated by `dotnet build`; frontend cannot start until backend is compiled.
- **Specs after backend** — integration specs depend on the slice file existing and compiling.
- **Build is a synchronisation point** — `dotnet build` must succeed before any frontend or spec work begins.
- **Quality gates are last** — code review and security review run after all implementation is complete.
- **Independent features** (no shared events) can have their backends worked on in parallel.

---

## Plan template

```markdown
## Coordinator Plan: <goal summary>

### Phase 1 — <description> [can run in parallel]
- [ ] [<agent>] <task description>
- [ ] [<agent>] <task description>

### Phase 2 — <description> (depends on Phase 1)
- [ ] [<agent>] <task description>

### Phase 3 — Build
- [ ] Run `dotnet build` — must succeed before any Phase 4 work

### Phase 4 — <description> [can run in parallel]
- [ ] [<agent>] <task description>

### Phase 5 — Quality Gates
- [ ] [code-reviewer] Review all changed files
- [ ] [security-reviewer] Security review of all changed files
```

---

## Delegation instructions

When handing off to a specialist agent:

1. State **exactly which files** need to be created or modified.
2. Provide **all context** the agent needs — feature name, slice name, slice type, existing events, namespace root.
3. State **acceptance criteria** — what "done" looks like for this task.
4. Tell the specialist **which agent to hand back to** when finished.
5. Quote the **relevant instruction file** section that governs the work.

---

## Quality gate criteria

The work is **not done** until all of the following pass:

- [ ] `dotnet build` — zero errors, zero warnings
- [ ] `dotnet test` — all specs pass
- [ ] `yarn lint` — zero errors (if frontend present)
- [ ] `npx tsc -b` — zero TypeScript errors (if frontend present)
- [ ] `code-reviewer` finds no blocking issues
- [ ] `security-reviewer` finds no vulnerabilities
- [ ] PR description follows the pull request template

---

## When to delegate to the planner instead

If the entire goal is one or more vertical slices (full backend-to-frontend), delegate directly to the **`planner`** agent rather than coordinating slice phases yourself. The planner is optimised for slice sequencing. Use the Coordinator for cross-cutting work that involves concerns beyond a single slice pipeline (e.g. shared infrastructure changes + slice implementation, documentation updates + implementation, multi-feature refactors).

---

## Output format

Always output a plan before starting any delegation:

```markdown
## Coordinator Plan: <goal>

### Phase 1 — Backend [parallel]
- [ ] [backend-developer] <task>

### Phase 2 — Build
- [ ] `dotnet build`

### Phase 3 — Frontend + Specs [parallel]
- [ ] [frontend-developer] <task>
- [ ] [spec-writer] <task>

### Phase 4 — Quality Gates
- [ ] [code-reviewer] Review all changed files
- [ ] [security-reviewer] Security review
```

Then delegate each task in order, respecting phase boundaries.

````
8 changes: 6 additions & 2 deletions .github/copilot-instructions.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,22 +16,25 @@ When these instructions don't explicitly cover a situation, apply these values t

## General

- When adding new instructions or rules, always place them in the most specific location that applies — the relevant `.instructions.md` file (e.g. `typescript.instructions.md`, `csharp.instructions.md`) or a `SKILL.md` if it relates to a specific workflow. Only add something to `copilot-instructions.md` if it genuinely applies to every file and every context in the project.
- Always use American English spelling in all code, comments, and documentation (e.g. "color" not "colour", "behavior" not "behaviour").
- Write clear and concise comments for each function.
- Make only high confidence suggestions when reviewing code changes.
- Never change global.json unless explicitly asked to.
- Never change package.json or package-lock.json files unless explicitly asked to.
- Never change NuGet.config files unless explicitly asked to.
- Always ensure that the code compiles without warnings.
- Always ensure that the code compiles without warnings. **Warnings are treated as errors** — a build with warnings is a failing build.
- Always ensure that the code passes all tests.
- Always ensure that the code adheres to the project's coding standards.
- Always ensure that the code is maintainable.
- Always reuse the active terminal for commands.
- Do not create new terminals unless current one is busy or fails.
- **A task is not complete until the code has been built and every warning and error has been resolved.** Never hand back to the user with outstanding build warnings or errors.

## Development Workflow

- After creating each new file, run `dotnet build` (C#) or `yarn compile` (TypeScript) immediately before proceeding to the next file. Fix all errors as they appear — never accumulate technical debt.
- After creating each new file, run `dotnet build` (C#) or `yarn compile` (TypeScript) immediately before proceeding to the next file. Fix all errors **and warnings** as they appear — never accumulate technical debt.
- Before marking any task done, run a final build (`dotnet build` for C#, `yarn compile` for TypeScript) and confirm it exits with zero errors and zero warnings. If there are warnings or errors, fix them before considering the task complete.
- Before adding parameters to interfaces or function signatures, review all usages to ensure the new parameter is needed at every call site.
- When modifying imports, audit all occurrences — verify additions are used and removals don't break other files.

Expand All @@ -46,6 +49,7 @@ These guides contain the full rules, examples, and rationale for each topic. The
- [Entity Framework Core Specs](./instructions/efcore.specs.instructions.md)
- [Concepts (ConceptAs)](./instructions/concepts.instructions.md)
- [Documentation](./instructions/documentation.instructions.md)
- [Git Commits](./instructions/git-commits.instructions.md)
- [Pull Requests](./instructions/pull-requests.instructions.md)
- [Vertical Slices](./instructions/vertical-slices.instructions.md)
- [TypeScript Conventions](./instructions/typescript.instructions.md)
Expand Down
3 changes: 2 additions & 1 deletion .github/hooks/agent-stop.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ When the agent finishes a session, automatically build every affected project in
```
Run from the package root that owns the changed files.

4. **If any build fails**:
4. **If any build fails or any warnings are reported**:
- Report the full compiler output.
- Fix all errors and warnings before considering the session complete.
- Re-run the Release build to confirm it is clean.
Expand All @@ -34,3 +34,4 @@ When the agent finishes a session, automatically build every affected project in
- Always run the Release build — never skip it even if the Debug build already passed earlier in the session.
- A session is not complete until `dotnet build -c Release` (and `yarn build` if applicable) exits with code `0` and **zero** warnings.
- Treat Release-only warnings (nullable annotations, unused variables stripped by the analyzer, etc.) as errors — fix them.
- **Never** use `/clp:ErrorsOnly` or any flag that suppresses warning output. Warnings that are hidden are warnings that are never fixed. Always let the full diagnostic output through so that zero warnings can be confirmed.
1 change: 1 addition & 0 deletions .github/instructions/csharp.instructions.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ These rules exist so that every file in the codebase reads the same way. When fo
- Apply code-formatting style defined in `.editorconfig`.
- Use file-scoped namespace declarations — one less level of indentation for the entire file.
- Use single-line `using` directives, sorted alphabetically.
- Never qualify a type that is already unambiguously in scope via a `using` directive. When two `using` directives introduce conflicting type names, qualify only the conflicting occurrences using the shortest unambiguous path (e.g. `Concepts.Events.Foo` or `Contracts.Events.Foo`) — do not add `using` aliases for every conflicting type.
- Insert a blank line before the opening `{` of every code block (`if`, `for`, `foreach`, `try`, `using`, etc.).
- Ensure the final `return` statement of a method is on its own line.
- Use pattern matching and switch expressions wherever possible — they are more readable and the compiler verifies exhaustiveness.
Expand Down
3 changes: 3 additions & 0 deletions .github/instructions/efcore.instructions.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@ applyTo: "**/*.cs"

# Entity Framework Core Instructions

> **⚠️ APPLIES ONLY TO PROJECTS USING ENTITY FRAMEWORK CORE**
> If your project does not reference `Microsoft.EntityFrameworkCore` or any EF Core packages, **ignore this entire file**. These rules are irrelevant outside of EF Core contexts.

## Project Structure

Responsibilities are split across three projects:
Expand Down
3 changes: 3 additions & 0 deletions .github/instructions/efcore.specs.instructions.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@ applyTo: "**/for_*/**/*.cs, **/when_*/**/*.cs"

# Entity Framework Core Specs

> **⚠️ APPLIES ONLY TO PROJECTS USING ENTITY FRAMEWORK CORE**
> If your project does not reference `Microsoft.EntityFrameworkCore` or any EF Core packages, **ignore this entire file**. These rules are irrelevant outside of EF Core contexts.

EF Core specs verify database interaction logic — migrations, queries, and error handling. They use SQLite in-memory databases, which are fast, isolated, and disposable. This keeps specs independent of any real database server.

These specs are for code that interacts directly with `DbContext`. For event-sourcing integration specs (testing commands against Chronicle), use the Chronicle integration spec pattern in [specs.csharp.instructions.md](./specs.csharp.instructions.md) instead.
Expand Down
94 changes: 94 additions & 0 deletions .github/instructions/git-commits.instructions.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
---
applyTo: "**/*"
---

# How to Write Git Commits

Commits are the permanent record of how the codebase evolved. Each commit should tell a clear story: *what* changed and *why*. A reviewer reading `git log --oneline` should understand the arc of the work without opening any diffs.

## Logical Grouping

Every commit must be a **single logical unit of work**. Group related changes together; separate unrelated changes into distinct commits.

### What belongs in one commit

- A bug fix and the spec that proves it.
- A new file and the changes to existing files needed to integrate it (imports, registrations, wiring).
- A refactor that moves or renames code — only the mechanical transformation, nothing else.
- An interface change together with all implementation updates required to compile.

### What does NOT belong in one commit

- A bug fix mixed with an unrelated feature.
- Source code changes mixed with unrelated spec additions for a different area.
- Formatting or style cleanups bundled with behavioral changes.
- Multiple independent fixes or features squashed into a single commit.

### Deciding where to split

Ask: "If I needed to revert this commit, would I lose exactly one coherent change?" If reverting would undo two unrelated things, it should be two commits.

Common split points:
1. **Infrastructure / plumbing first** — interface additions, new types, or schema changes that later commits build on.
2. **Core logic second** — the behavioral change that uses the new infrastructure.
3. **Specs / tests third** — the specs that prove the behavioral change works. Specs may also be combined with the core logic commit when they are tightly coupled (e.g., a TDD red-green cycle or a bug fix with its regression test).
4. **Integration or wiring last** — connecting the new behavior to the rest of the system (DI registration, routing, UI hookup).

When a task produces both source fixes and new integration specs, prefer separate commits for the source changes and the specs — unless the specs are inseparable from the fix (e.g., a single bug fix + its regression test).

## Commit Messages

### Format

```
<imperative summary of what this commit does>

<optional body — why the change was made, context, trade-offs>
```

- **Subject line**: imperative mood, present tense. Start with a verb: `Add`, `Fix`, `Remove`, `Rename`, `Extract`, `Update`, `Support`.
- **No period** at the end of the subject line.
- **72-character limit** on the subject line. If you cannot describe the change in 72 characters, the commit is probably too large — split it.
- **Body**: separated from the subject by a blank line. Explain *why*, not *what* (the diff shows the what). Use bullet points for multi-part changes.

### Good examples

```
Fix duplicate key crash in IdentityStorage.Populate

The upsert used InsertOne which threw on existing identities.
Replace with ReplaceOne using upsert: true.
```

```
Add type-safe event migration API with expression-based builders

Introduce EventTypeMigration<TUpgrade, TPrevious> base class with
typed property builders for Split, Join, Rename, and DefaultValue
operations. Migrators are discovered automatically by convention.
```

```
Add integration specs for observer replay on redaction
```

### Bad examples

- `Fix stuff` — meaningless.
- `WIP` — never commit work-in-progress; stage and commit when the unit is complete.
- `Add files` — says nothing about what or why.
- `Fix bug and add new feature and update docs` — three unrelated things.
- `Changed Observer.Handling.cs` — describes a file, not a behavior.

## When to Commit

- **After each logical unit passes the build** — `dotnet build` with zero errors and zero warnings, or `yarn compile` with zero errors.
- **Before starting a different kind of work** — about to switch from fixing a bug to adding a feature? Commit the bug fix first.
- **After completing specs for a change** — if the specs are a separate commit from the source change.
- **Never commit code that does not compile.** Every commit must be a buildable, working state of the codebase.

## Staging Discipline

- Use `git add <specific files>` rather than `git add .` or `git add -A`. Only stage files that belong to the current logical unit.
- Review `git diff --cached` before committing to verify nothing unrelated was staged.
- If you realize mid-commit that unrelated changes are mixed in, unstage them and commit only the related subset.
3 changes: 3 additions & 0 deletions .github/instructions/orleans.instructions.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@ applyTo: "**/*.cs"

# Orleans Conventions

> **⚠️ APPLIES ONLY TO PROJECTS USING MICROSOFT ORLEANS**
> If your project does not reference `Microsoft.Orleans` or any Orleans packages, **ignore this entire file**. These rules are irrelevant outside of Orleans contexts.

These conventions apply to projects that use Microsoft Orleans for distributed grain-based actors.

## General
Expand Down
8 changes: 6 additions & 2 deletions .github/instructions/pull-requests.instructions.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,12 @@ PR descriptions serve two purposes: they help reviewers understand the change *n

## Commits

- Write clear, concise commit messages in imperative mood: "Add author registration" not "Added author registration" or "Adding author registration".
- Each commit should represent a logical unit of work. Avoid "WIP" or "fix" commits in the final PR — squash or rebase if needed.
See the full [Git Commits guide](./git-commits.instructions.md) for rules on logical grouping, message format, and staging discipline.

Quick reminders:
- Imperative mood: "Add author registration" not "Added author registration".
- Each commit = one logical unit of work. No WIP commits in the final PR.
- Never mix unrelated changes in a single commit.

## Labels

Expand Down
Loading