diff --git a/.github/workflows/squad-ci.yml b/.github/workflows/squad-ci.yml index 42a433b..7684856 100644 --- a/.github/workflows/squad-ci.yml +++ b/.github/workflows/squad-ci.yml @@ -19,10 +19,6 @@ jobs: - name: Build and test run: | - # TODO: Add your dotnet build/test commands here - # Go: go test ./... - # Python: pip install -r requirements.txt && pytest - # .NET: dotnet test - # Java (Maven): mvn test - # Java (Gradle): ./gradlew test - echo "No build commands configured — update squad-ci.yml" + dotnet restore + dotnet build --no-restore --configuration Release + dotnet test --no-build --configuration Release diff --git a/.github/workflows/squad-main-guard.yml b/.github/workflows/squad-main-guard.yml index 7ea0dbe..aafb668 100644 --- a/.github/workflows/squad-main-guard.yml +++ b/.github/workflows/squad-main-guard.yml @@ -69,36 +69,36 @@ jobs: } // Check each file against forbidden path rules - // Allow removals ΓÇö deleting forbidden files from protected branches is fine + // Allow removals - deleting forbidden files from protected branches is fine const forbidden = files .filter(f => f.status !== 'removed') .map(f => f.filename) .filter(f => { - // .ai-team/** and .squad/** ΓÇö ALL team state files, zero exceptions + // .ai-team/** and .squad/** - ALL team state files, zero exceptions if (f === '.ai-team' || f.startsWith('.ai-team/') || f === '.squad' || f.startsWith('.squad/')) return true; - // .ai-team-templates/** ΓÇö Squad's own templates, stay on dev + // .ai-team-templates/** - Squad's own templates, stay on dev if (f === '.ai-team-templates' || f.startsWith('.ai-team-templates/')) return true; - // team-docs/** ΓÇö ALL internal team docs, zero exceptions + // team-docs/** - ALL internal team docs, zero exceptions if (f.startsWith('team-docs/')) return true; - // docs/proposals/** ΓÇö internal design proposals, stay on dev + // docs/proposals/** - internal design proposals, stay on dev if (f.startsWith('docs/proposals/')) return true; return false; }); if (forbidden.length === 0) { - core.info('Γ£à No forbidden paths found in PR ΓÇö all clear.'); + core.info('[OK] No forbidden paths found in PR - all clear.'); return; } // Build a clear, actionable error message const lines = [ - '## ≡ƒÜ½ Forbidden files detected in PR to main', + '## [WARNING] Forbidden files detected in PR to main', '', 'The following files must NOT be merged into `main`.', - '`.ai-team/` and `.squad/` are runtime team state ΓÇö they belong on dev branches only.', - '`.ai-team-templates/` is Squad\'s internal planning ΓÇö it belongs on dev branches only.', - '`team-docs/` is internal team content ΓÇö it belongs on dev branches only.', - '`docs/proposals/` is internal design proposals ΓÇö it belongs on dev branches only.', + '`.ai-team/` and `.squad/` are runtime team state - they belong on dev branches only.', + '`.ai-team-templates/` is Squad\'s internal planning - it belongs on dev branches only.', + '`team-docs/` is internal team content - it belongs on dev branches only.', + '`docs/proposals/` is internal design proposals - it belongs on dev branches only.', '', '### Forbidden files found:', '', @@ -121,7 +121,7 @@ jobs: 'git push', '```', '', - '> ΓÜá∩╕Å `.ai-team/` and `.squad/` are committed on `dev` and feature branches by design.', + '> [NOTE] `.ai-team/` and `.squad/` are committed on `dev` and feature branches by design.', '> The guard workflow is the enforcement mechanism that keeps these files off `main` and `preview`.', '> `git rm --cached` untracks them from this PR without deleting your local copies.', ]; diff --git a/.squad/decisions/inbox/aragorn-crud-alignment-review.md b/.squad/decisions/inbox/aragorn-crud-alignment-review.md new file mode 100644 index 0000000..6e1c2e9 --- /dev/null +++ b/.squad/decisions/inbox/aragorn-crud-alignment-review.md @@ -0,0 +1,278 @@ +# CRUD API Alignment Review + +**Reviewer:** Aragorn (Backend) +**Date:** 2026-02-20 +**Status:** ✅ ALIGNED - Ready for Sprint 1 implementation + +--- + +## Executive Summary + +The current domain model (`Issue.cs`), CRUD API specification (Gandalf's design doc), and handler implementations are **well-aligned**. The recent revert by Gimli restored a clean, minimal model that matches the design intent. No model changes are required. Handlers are correctly implemented and follow the CQRS pattern as specified. + +--- + +## Detailed Analysis + +### 1. Domain Model vs. CRUD Spec + +#### Issue Model (Current State) +```csharp +public record Issue( + string Id, + string Title, + string? Description, + IssueStatus Status, + DateTime CreatedAt, + DateTime UpdatedAt, + IReadOnlyCollection