Skip to content
Merged
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
5 changes: 3 additions & 2 deletions .squad/agents/gimli/charter.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ You are Gimli, the Tester on the {ProjectName} project. You own unit tests, inte
- Does NOT write production code (flag gaps, don't fix them — tell Aragorn or the relevant agent)

## Critical Rules
1. **Before any push: run the FULL local test suite** — `dotnet test tests/Api.Tests.Unit tests/Shared.Tests.Unit tests/Web.Tests.Unit tests/Web.Tests.Bunit tests/Architecture.Tests`. Zero failures required. Pre-push hook gates on these test suites. CI must never be the first place test failures are discovered.
1. **Before any push: run the FULL local test suite** — `dotnet test tests/Unit.Tests tests/Architecture.Tests -c Release`. Zero failures required, and the coverage gate (89% line threshold) must pass. Pre-push hook gates on these suites. CI must never be the first place test failures or coverage gaps are discovered.
2. **Domain-specific collections REQUIRED** — Use `[Collection("{Entity}Integration")]` (one per domain entity) on all integration test classes. Each collection is backed by `ICollectionFixture<MongoDbFixture>`. Do NOT use the old single `[Collection("Integration")]`. Use `$"T{Guid.NewGuid():N}"` as the DB name in the constructor for per-test-method isolation.
3. **NEVER compare two `{Entity}Dto.Empty` calls** — `Empty` calls `DateTime.UtcNow` each time; assert individual fields instead
4. **`GenerateSlug` trailing underscore is correct** — `"C# Is Great!"` → `"c_is_great_"` (trailing underscore expected)
Expand All @@ -38,9 +38,10 @@ You are Gimli, the Tester on the {ProjectName} project. You own unit tests, inte
// Project Name : {ProjectName}
// =============================================
```
Project Name: `Api.Tests.Unit`, `Shared.Tests.Unit`, `Web.Tests.Unit`, `Api.Tests.Integration`, `Web.Tests.Bunit`, or `Aspire` based on test project directory.
Project Name: `Unit.Tests`, `Architecture.Tests`, or `Integration.Tests` based on test project directory.
7. AAA pattern (Arrange / Act / Assert) with comments
8. File-scoped namespaces, tab indentation
9. **Gimli is spawned in parallel with Sam/Legolas** for every feature/fix. Tests ship with the code — not after the PR is opened.

## Model
Preferred: auto (test authoring resolves to claude-sonnet-4.6)
35 changes: 30 additions & 5 deletions .squad/ceremonies.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,29 @@

> Team meetings that happen before or after work. Each squad configures their own.

## Feature Work Kickoff

| Field | Value |
|-------|-------|
| **Trigger** | auto |
| **When** | before |
| **Condition** | any agent picks up a feature or fix issue that touches production code |
| **Facilitator** | coordinator |
| **Participants** | feature author + Gimli + Frodo |
| **Time budget** | focused |
| **Enabled** | ✅ yes |

**Agenda:**
1. Feature author reads the issue and identifies files to be changed
2. Gimli is spawned in parallel to write tests from the issue's acceptance criteria
3. Frodo is spawned in parallel to note doc/README impact
4. If new architectural patterns are involved → rubber duck BEFORE coding starts
5. All agents confirm scope before the first file is opened

**Hard Rule:** No feature code is written without Gimli already working on tests. Tests are a parallel deliverable, not a post-merge cleanup.

---

## Design Review

| Field | Value |
Expand All @@ -28,14 +51,16 @@
|-------|-------|
| **Trigger** | auto |
| **When** | after |
| **Condition** | build failure, test failure, or reviewer rejection |
| **Condition** | build failure, test failure, coverage gate failure, CI failure, or reviewer rejection |
| **Facilitator** | lead |
| **Participants** | all-involved |
| **Time budget** | focused |
| **Enabled** | ✅ yes |

**Agenda:**
1. What happened? (facts only)
2. Root cause analysis
3. What should change?
4. Action items for next iteration
1. What happened? (facts only — no blame)
2. Root cause analysis (was it a guardrail gap? a bypass? missing agent activation?)
3. What should change? (update routing.md, ceremonies.md, or playbooks)
4. Action items with owner assigned

**Hard Rule:** Every CI failure triggers a retrospective. Ralph documents action items in `.squad/decisions/inbox/` within the same session. The squad does not move to the next sprint without closing all retrospective action items.
6 changes: 5 additions & 1 deletion .squad/playbooks/pr-merge-process.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,13 +56,17 @@ Ralph MUST verify ALL of the following before spawning reviewers. Any failing ga
| Gate | Command | Expected |
| ------------------------- | ---------------------------------------------------------------- | ------------------------------- |
| GitHub issue exists | `gh pr view <N> --json body -q .body \| grep -E "Closes #[0-9]+"` | Contains `Closes #N` |
| CI green | `gh pr checks <N> --watch --interval 5` | All passing |
| CI fully green | `gh pr checks <N> --watch --interval 5` | All checks passing (including coverage gate) |
| Coverage gate passing | Check CI run logs for `The total line coverage is below` | No coverage error in logs |
| No conflicts | `gh pr view <N> --json mergeable -q .mergeable` | `MERGEABLE` |
| PR template filled | `gh pr view <N> --json body` | Contains filled checkboxes |
| Branch is `squad/*` | `gh pr view <N> --json headRefName -q .headRefName` | Starts with `squad/` |
| Tests authored | PR diff includes test file additions/modifications | Gimli coverage present |

> **If `Closes #N` is missing**, the PR was opened without a GitHub issue. Ralph must STOP, create the issue, link it in the PR body, assign it to the correct milestone and Project #4, then re-run this gate.

> **If coverage gate is failing** (CI red on coverage, not test logic), DO NOT spawn reviewers. Route to Gimli (issue #68 pattern) to add Domain tests. The PR is not review-ready until CI is fully green including coverage.

## Step 4 — Spawn Reviewers

Aragorn is ALWAYS required. Additional reviewers depend on files changed:
Expand Down
13 changes: 12 additions & 1 deletion .squad/playbooks/pre-push-process.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,21 @@

**Owner:** Boromir (DevOps) + Aragorn (Lead)
**Ref:** `.github/hooks/pre-push`, `CONTRIBUTING.md`
**Last Updated:** 2026-04-13
**Last Updated:** 2026-04-19

---

> ⛔ **HARD BLOCK — `git push --no-verify` is prohibited.**
> Bypassing the pre-push hook defeats all local quality gates (build, tests,
> coverage). CI becomes the first place failures are discovered — wasting
> everyone's time. **Fix the root cause instead:**
> - SDK mismatch → install the SDK version pinned in `global.json` from https://dot.net
> - Hook not installed → run `scripts/install-hooks.sh`
> - Docker not running → start Docker Desktop / `sudo systemctl start docker`
>
> Any `--no-verify` push requires **prior written approval from Ralph + Aragorn**
> documented in a GitHub issue comment. Undocumented bypasses are a retro action item.

## Overview

The pre-push hook (`.github/hooks/pre-push`) enforces 5 gates that mirror CI. This playbook documents what agents must do before pushing and how to troubleshoot failures.
Expand Down
29 changes: 24 additions & 5 deletions .squad/playbooks/sprint-planning.md
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,16 @@ Todo ID: {todo-id}"
**Issue title convention:** `[Sprint N] {Verb} {Noun}`
(e.g., `[Sprint 1] Add BlogPost entity and repository`)

**Mandatory format — every issue must satisfy both:**

| Field | Requirement |
|-------|-------------|
| Title | Must start with `[Sprint N]` prefix |
| Milestone | Must be set to `Sprint N: {Theme}` before any branch is created |

> **Hard rule:** An issue without a milestone or without the `[Sprint N]` prefix in its
> title is incomplete. No branch or code may reference it until both fields are set.

After creating each issue, **Aragorn immediately triages** it:
- Replace `squad` label with `squad:{member}` (e.g., `squad:sam`)
- This triggers normal issue routing for that member
Expand Down Expand Up @@ -292,22 +302,31 @@ Before any agent writes, modifies, or commits code, a GitHub issue **must** exis

```
1. Does a GitHub issue exist for this work?
YES → confirm it is assigned to the correct milestone + Project #4, then proceed to Step 1
YES → does the issue have:
a) a milestone set to "Sprint N: {Theme}"?
b) a title starting with "[Sprint N]"?
If either is missing → fix it now before touching any file.
Then proceed to Step 1.
NO → CREATE the issue now before touching any file
→ Assign to milestone, add to Project #4
→ Title MUST start with "[Sprint N]"
→ Milestone MUST be set to "Sprint N: {Theme}"
→ Add to Project #4
→ Create squad/{issue}-{slug} branch
→ THEN and only then begin writing code
```

If you skip this gate and write code without an issue, you have violated the squad's process.
The work must be stashed, the issue created retroactively, a proper branch checked out, and
the stash re-applied before committing. This costs time — follow the gate.
If you skip this gate and write code without an issue, or create an issue without the
sprint prefix and milestone, you have violated the squad's process. The work must be
stashed, the issue corrected, a proper branch checked out, and the stash re-applied
before committing. This costs time — follow the gate.

---

## Anti-Patterns

- ❌ **Writing any code before a GitHub issue exists** — always create the issue first
- ❌ **Creating an issue without setting its milestone** — every issue must be assigned to `Sprint N: {Theme}` before any branch is created
- ❌ **Creating an issue whose title does not start with `[Sprint N]`** — the sprint prefix is mandatory; bare titles like "Fix login bug" are invalid
- ❌ **Implementing a `[[PLAN]]` request without first running the sprint planning ceremony** — plan → issue → branch → code
- ❌ **Opening `squad/{issue}` PRs directly to `dev`** during an active sprint
- ❌ **Skipping worktree** — always work in `../MyBlog-sprint-{N}/` for isolation
Expand Down
31 changes: 25 additions & 6 deletions .squad/routing.md
Original file line number Diff line number Diff line change
Expand Up @@ -63,10 +63,12 @@ spawn prompt:
After Sprint 1.1, these process assets are part of normal squad flow:

1. **Before writing any code**, a GitHub issue MUST exist for the work. This is an
absolute gate with no exceptions. If no issue exists, create it first — assign
to the correct milestone, add to Project #4 — then create the `squad/{issue}-{slug}`
branch, and only then write code. See the Hard Gate section in
`.squad/playbooks/sprint-planning.md`.
absolute gate with no exceptions. The issue must also have a milestone set to
`Sprint N: {Theme}` and a title that starts with `[Sprint N]`. If no issue
exists — or the issue lacks a milestone or sprint prefix — create/fix it first,
assign to the correct milestone, add to Project #4 — then create the
`squad/{issue}-{slug}` branch, and only then write code. See the Hard Gate section
in `.squad/playbooks/sprint-planning.md`.
2. **Before any push-ready handoff**, route through the pre-push gate skill and
pre-push playbook so agents respect the live MyBlog hook: `squad/{issue}-{slug}`
branch naming, Release build, `Architecture.Tests`, `Unit.Tests`, and
Expand All @@ -85,7 +87,24 @@ After Sprint 1.1, these process assets are part of normal squad flow:
`.squad/playbooks/sprint-planning.md`.
8. **When a user makes any coding request** (direct instruction, `[[PLAN]]`, or
follow-on work), the very first agent action is to check whether a GitHub issue
exists. If not, create it before any file is opened or modified.
exists with a `[Sprint N]` title prefix and a sprint milestone set. If the issue
is missing, create it. If it exists but lacks the prefix or milestone, fix those
fields before any file is opened or modified.
9. **When any production code is written or modified** (Domain, Web, Persistence,
AppHost), Gimli MUST be spawned in parallel to write or update unit tests.
No feature branch closes without corresponding test authoring. The coverage gate
(currently 89% line threshold in `Unit.Tests.csproj`) must pass locally before
push. This is not optional — test coverage is a first-class deliverable.
10. **`git push --no-verify` is PROHIBITED.** It bypasses all pre-push quality gates
(build, tests, coverage) and wastes CI time when failures are discovered
remotely. If the hook fails due to a local SDK mismatch, fix the root cause:
install the SDK version pinned in `global.json` (e.g., `dotnet-install.sh`
or download from https://dot.net). SDK mismatch is never a valid bypass reason.
Any `--no-verify` push requires prior documented approval from Ralph + Aragorn.
11. **When new architectural patterns are introduced** (new CQRS handler type, new
service abstraction, new Blazor rendering pattern, new repository strategy), a
rubber duck review MUST be run before the branch is pushed. Document the
pattern decision in `.squad/decisions/inbox/` and route to Aragorn for ADR.

## Rules

Expand All @@ -94,5 +113,5 @@ After Sprint 1.1, these process assets are part of normal squad flow:
3. **Quick facts → coordinator answers directly.** Don't spawn an agent for "what port does the server run on?"
4. **When two agents could handle it**, pick the one whose domain is the primary concern.
5. **"Team, ..." → fan-out.** Spawn all relevant agents in parallel as `mode: "background"`.
6. **Anticipate downstream work.** If a feature is being built, spawn the tester to write test cases from requirements simultaneously.
6. **Anticipate downstream work.** If a feature is being built, spawn Gimli (tests), Frodo (doc impact), and Pippin (changelog note) in parallel with the feature author. Tests are not an afterthought — they ship with the code.
7. **Issue-labeled work** — when a `squad:{member}` label is applied to an issue, route to that member. The Lead handles all `squad` (base label) triage.
13 changes: 13 additions & 0 deletions .squad/templates/issue-lifecycle.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,19 @@ squad/{issue-number}-{kebab-case-slug}
```
Example: `squad/42-fix-login-validation`

**Mandatory issue format:**

Every GitHub issue created by Squad MUST satisfy both of the following before any
branch or code references it:

| Field | Requirement | Example |
|-------|-------------|---------|
| Title | Starts with `[Sprint N]` prefix | `[Sprint 3] Add BlogPost list page` |
| Milestone | Set to `Sprint N: {Theme}` | `Sprint 3: MongoDB Persistence` |

If either field is missing, set it before creating the branch. An issue without a
sprint assignment is considered incomplete and must not be used as a branch target.

### Azure DevOps

| ADO State | Squad Board State |
Expand Down
Loading