Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
59 commits
Select commit Hold shift + click to select a range
8571bf3
refactor(apphost): extract WithClearDatabaseCommand into MongoDbResou…
mpaulosky May 8, 2026
976ec57
fix(ci): use GH_PROJECT_TOKEN for Projects V2 access in squad-mark-re…
mpaulosky May 8, 2026
924edfc
feat(AppHost): add WithSeedDataCommand for local dev seeding (#263)
mpaulosky May 8, 2026
002b5bb
feat(AppHost): add WithShowStatsCommand for local dev stats (#264)
mpaulosky May 8, 2026
d1d7e79
refactor: rename _clearMutex to _dbMutex in MongoDbResourceBuilderExt…
mpaulosky May 8, 2026
3c309d2
fix(ci): Blog → README Sync — push to dev instead of main (#270)
mpaulosky May 8, 2026
c272feb
fix(ci): add pre-flight token validation and fix permissions block in…
mpaulosky May 8, 2026
c074b8f
test: harden AppHost.Tests flaky timing
mpaulosky May 8, 2026
3547113
docs(squad): merge 4 inbox decisions into decisions.md
mpaulosky May 8, 2026
5b1828f
docs(squad): merge Sprint 18 decisions and Ralph board sweep log (#275)
mpaulosky May 8, 2026
7c1fea2
fix(profile): fall back to authenticated email claims on /profile (#279)
mpaulosky May 10, 2026
80a2ef1
fix(build): clear remaining Release analyzer warnings (#283)
mpaulosky May 10, 2026
f680a57
fix(headers): preserve original year when normalizing headers (#285)
mpaulosky May 10, 2026
7541e68
ci(hooks): add dotnet format gate before Release build (#290)
mpaulosky May 11, 2026
158815e
feat(theme): centralise table, form, and alert CSS into input.css (#277)
mpaulosky May 11, 2026
3215029
chore(deps): bump actions/github-script from 7 to 9 in the all-action…
dependabot[bot] May 11, 2026
4a9b754
Bump MongoDB.Driver from 3.6.0 to 3.8.0 (#282)
dependabot[bot] May 11, 2026
97a3221
ci: add markdown and YAML lint workflows (#288)
mpaulosky May 11, 2026
2ba0886
fix(ui): correct dark-mode colours, add PageHeadingComponent, style b…
mpaulosky May 11, 2026
4b5d0d2
feat(app): add L1+L2 caching to UserManagement Auth0 API calls (#297)
mpaulosky May 11, 2026
3c4ed03
feat(domain): introduce PostAuthor value object for blog post authors…
mpaulosky May 11, 2026
628110f
fix(process): add AppHost.Tests to pre-push Gate 5, align docs (#301)
mpaulosky May 11, 2026
292fd26
feat(ui): restrict blog post editing to post author or Admin (#302)
mpaulosky May 11, 2026
7e15cdd
feat(app): restrict blog post editing to post author or Admin (#300) …
mpaulosky May 11, 2026
9fcf7dc
Merge dev: resolve project board automation option IDs conflict (#305)
mpaulosky May 11, 2026
5e176dc
fix(ui): clear loading state when Edit page gets null post result (#3…
mpaulosky May 11, 2026
a1ad0c9
fix(ui): refresh Edit page loading state on post-ID changes (#310)
mpaulosky May 12, 2026
dc34ce9
fix(ui): refresh edit page state on route changes
mpaulosky May 12, 2026
8aef7ee
fix(blogposts): align author claims, publish checkbox, and seed schem…
mpaulosky May 12, 2026
8fa725d
feat(314): add RTBlazorfied rich text editor + HtmlSanitizer backend …
mpaulosky May 12, 2026
d517f20
chore: upgrade from .NET 9 to .NET 10 (#317)
mpaulosky May 12, 2026
8aadab2
docs(squad): Sprint 19 execution rails for markdown migration (#322)
May 13, 2026
97129fa
docs(squad): update Aragorn history with #322 execution rails learnings
May 13, 2026
12f32f1
fix(docs): resolve markdownlint MD022/MD012/MD051 failures in assessm…
May 13, 2026
fe0634d
fix(docs): resolve markdownlint failures in execution-log.md and scen…
May 13, 2026
377162c
fix(docs): resolve all remaining markdownlint failures across upgrade…
May 13, 2026
6d9ffd0
[Sprint 19] Milestone/worktree execution rails for markdown migration…
mpaulosky May 13, 2026
a269e2a
[Sprint 19] Restore markdown editor compile path (#329)
mpaulosky May 13, 2026
cbc3aaa
feat(ui): replace InputTextArea with TextEditor markdown editor in Cr…
May 13, 2026
2a75eb4
feat(web): Edit flow markdown authoring slice (#325) (#331)
mpaulosky May 13, 2026
a5a1000
feat(ui): UX parity hardening for Create/Edit markdown editor (#326)
May 13, 2026
036aac2
test(bunit): add Sprint 19 markdown editor lifecycle and interop vali…
May 13, 2026
21a173a
test(bunit): Sprint 19 markdown editor lifecycle and interop validati…
mpaulosky May 13, 2026
171b6c5
docs(sprint-20): Sprint 19 markdown editor completion - Aragorn histo…
mpaulosky May 13, 2026
abd7e4b
chore(318): add markdownlint gate to pre-push hook and align docs (#319)
mpaulosky May 13, 2026
6d30cde
chore(deps): upgrade Aspire and markdown packages (#336)
mpaulosky May 14, 2026
be27b50
chore(squad): archive self-authored PR gate skill (#337) (#338)
mpaulosky May 15, 2026
ec92657
feat(categories): Categories CRUD UI + blog post category assignment …
mpaulosky May 15, 2026
b3cb66a
[Sprint 19] Polish category UX, test naming, and documentation (#342)
mpaulosky May 15, 2026
0474891
chore(deps): bump dotnet-sdk from 10.0.203 to 10.0.300 in the all-act…
dependabot[bot] May 17, 2026
30da76c
Bump the all-actions group with 6 updates (#344)
dependabot[bot] May 17, 2026
c0a44c7
fix(apphost): pin MongoDB to mongo:7 with mongo-data-v7 volume (#346)
mpaulosky May 17, 2026
883137f
docs(squad): correct Sam MongoDB guidance (#347)
mpaulosky May 17, 2026
b079c0d
fix(infra): resolve remaining database runtime issues (#348) (#349)
mpaulosky May 18, 2026
41c20a7
fix(#350): repair Aspire startup on fresh-machine clone (#351)
mpaulosky May 23, 2026
30fe262
chore(release): merge PR #352 conflict fix into dev (#354)
mpaulosky May 23, 2026
bf8919a
chore(release): merge main into dev to unblock PR #352 (#356)
mpaulosky May 23, 2026
3b1f1dc
Merge origin/main into dev for release PR #352 ancestry
mpaulosky May 23, 2026
e0a46c6
Merge pull request #358 from mpaulosky/squad/355-merge-main-into-dev-…
mpaulosky May 23, 2026
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
2 changes: 1 addition & 1 deletion .copilot/mcp-config.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
"command": "npx",
"args": [
"-y",
"@anthropic/github-mcp-server"
"@modelcontextprotocol/server-github"
],
"env": {
"GITHUB_TOKEN": "${GITHUB_TOKEN}"
Expand Down
9 changes: 8 additions & 1 deletion .editorconfig
Original file line number Diff line number Diff line change
Expand Up @@ -401,4 +401,11 @@ dotnet_naming_style.camelcase.capitalization = camel_case
dotnet_naming_style.s_camelcase.required_prefix = s_
dotnet_naming_style.s_camelcase.required_suffix =
dotnet_naming_style.s_camelcase.word_separator =
dotnet_naming_style.s_camelcase.capitalization = camel_case
dotnet_naming_style.s_camelcase.capitalization = camel_case

[tests/**/*.cs]
# Tests intentionally use xUnit-style method names with underscores.
dotnet_diagnostic.CA1707.severity = none
# Test code deliberately exercises sync validators and uses xUnit-created fixtures.
dotnet_diagnostic.CA1849.severity = none
dotnet_diagnostic.CA1515.severity = none
6 changes: 6 additions & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,9 @@
.squad/agents/*/history.md merge=union
.squad/log/** merge=union
.squad/orchestration-log/** merge=union

# Line ending normalization — keep LF everywhere to match dotnet format expectations
* text=auto eol=lf
*.sh text eol=lf
.github/hooks/* text eol=lf
*.cs text eol=lf
84 changes: 63 additions & 21 deletions .github/copilot-instructions.md
Original file line number Diff line number Diff line change
@@ -1,52 +1,94 @@
# Copilot Coding Agent — Squad Instructions
# Copilot Coding Agent Instructions

You are working on a project that uses **Squad**, an AI team framework. When picking up issues autonomously, follow these guidelines.
This repository uses **Squad** for orchestration and follows project-level .NET conventions.

## Team Context
## Squad Workflow (Required)

Before starting work on any issue:

1. Read `.squad/team.md` for the team roster, member roles, and your capability profile.
2. Read `.squad/routing.md` for work routing rules.
3. If the issue has a `squad:{member}` label, read that member's charter at `.squad/agents/{member}/charter.md` to understand their domain expertise and coding style — work in their voice.
1. Read `.squad/team.md` for the roster, roles, and capability profile.
2. Read `.squad/routing.md` for routing rules.
3. If the issue has a `squad:{member}` label, read `.squad/agents/{member}/charter.md` and work in that role's style.

## Capability Self-Check
### Capability Self-Check

Before starting work, check your capability profile in `.squad/team.md` under the **Coding Agent → Capabilities** section.
Check `.squad/team.md` under **Coding Agent → Capabilities**:

- **🟢 Good fit** — proceed autonomously.
- **🟡 Needs review** — proceed, but note in the PR description that a squad member should review.
- **🔴 Not suitable** — do NOT start work. Instead, comment on the issue:
- **🟡 Needs review** — proceed, and add reviewer guidance in the PR body.
- **🔴 Not suitable** — do not implement; comment on the issue:

```
🤖 This issue doesn't match my capability profile (reason: {why}). Suggesting reassignment to a squad member.
```

## Branch Naming
### Branch Naming

Use the squad branch convention:
Use:

```
squad/{issue-number}-{kebab-case-slug}
```

Example: `squad/42-fix-login-validation`

## PR Guidelines

When opening a PR:
### Pull Request Requirements

- Reference the issue: `Closes #{issue-number}`
- If the issue had a `squad:{member}` label, mention the member: `Working as {member} ({role})`
- If this is a 🟡 needs-review task, add to the PR description: `⚠️ This task was flagged as "needs review" — please have a squad member review before merging.`
- Follow any project conventions in `.squad/decisions.md`
- If labeled `squad:{member}`, include: `Working as {member} ({role})`
- For 🟡 tasks, include: `⚠️ This task was flagged as "needs review" — please have a squad member review before merging.`
- Follow decisions in `.squad/decisions.md`

## Decisions
### Team Decision Drop Box

If you make a decision that affects other team members, write it to:
If your work introduces a team-relevant decision, write it to:

```
.squad/decisions/inbox/copilot-{brief-slug}.md
```

The Scribe will merge it into the shared decisions file.
Scribe will merge inbox entries into `.squad/decisions.md`.

## Project Engineering Conventions

### Platform

- Target .NET 10 (`net10.0`) and latest stable patch SDK/runtime
- Use C# 14 language features where they improve clarity

### C# and Solution Style

- Respect `.editorconfig` and existing repository formatting
- Use explicit types when helpful; use `var` when type is obvious
- Prefer null checks with `is null` / `is not null`
- Use file-scoped namespaces, nullable reference types, and pattern matching
- Keep naming conventions consistent (`I*` interfaces, `Async` suffix, `_privateField`)

### Architecture

- Keep dependency injection and strongly typed options/configuration
- Prefer async/await end-to-end in app code and tests
- Maintain vertical-slice/CQRS patterns where they already exist
- Keep package versions centralized in `Directory.Packages.props`

### Security and Middleware

- Keep HTTPS, authentication, authorization, antiforgery, and secure headers enabled
- Preserve global exception handling and request logging patterns

### Blazor and Web UI

- Maintain existing component lifecycle/state-management patterns
- Keep interactive rendering strategy and shared component conventions
- Preserve error boundary patterns and existing UI composition style

### Data and Testing

- Keep MongoDB + EF Core integration patterns used in this repo
- Prefer async data access
- Keep unit, integration, architecture, and UI tests current with behavior changes

### Documentation

- Keep README/CONTRIBUTING and inline documentation aligned with behavioral changes
- Use OpenAPI + Scalar conventions for HTTP API documentation where applicable
2 changes: 1 addition & 1 deletion .github/dependabot.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

version: 2
updates:

# Maintain dependencies for GitHub Actions
- package-ecosystem: "github-actions"
directory: "/"
Expand Down
65 changes: 61 additions & 4 deletions .github/hooks/pre-push
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
#!/usr/bin/env bash
# Pre-push gate: mirrors CI checks to catch failures before they reach GitHub
# Runs: branch protection → untracked-file check → Release build → unit/architecture tests → integration tests
# Runs: branch protection → untracked-file check → markdownlint → dotnet format → Release build → unit/architecture tests → integration tests
# NOTE: git provides refspecs on stdin; interactive prompts must use /dev/tty.
# ⚠️ BYPASS POLICY: git push --no-verify is PROHIBITED without prior written
# approval from Ralph + Aragorn documented in a GitHub issue comment.
set -uo pipefail

ROOT="$(git rev-parse --show-toplevel)"
Expand Down Expand Up @@ -49,7 +51,61 @@ if [[ -n "$UNTRACKED_SRC" ]]; then
fi
fi

# ── Gate 2: Release build (mirrors CI exactly) ─────────────────────────────
# ── Gate 2: markdownlint check ─────────────────────────────────────────────
echo -e "\n${CYAN}📝 Checking Markdown lint (markdownlint-cli2)...${RESET}"
if [[ -x "$ROOT/node_modules/.bin/markdownlint-cli2" ]]; then
"$ROOT/node_modules/.bin/markdownlint-cli2" "**/*.md" \
"!**/node_modules/**" \
"!**/bin/**" \
"!**/obj/**" \
"!.squad/**" \
"!.copilot/**" \
"!.github/agents/**" \
"!.github/skills/**" \
"!.github/copilot-instructions.md" \
--config "$ROOT/.markdownlint.json"
MD_EXIT=$?
else
echo -e "${YELLOW}⚠️ markdownlint-cli2 not found at node_modules/.bin — run 'npm install'.${RESET}"
exit 1
fi

if [[ $MD_EXIT -ne 0 ]]; then
echo -e "${RED}❌ Markdownlint violations detected.${RESET}"
echo -e "${YELLOW} Fix: npx markdownlint-cli2 \"**/*.md\"${RESET}"
echo -e "${YELLOW} Then: git add -u && git commit (or --amend), then re-push.${RESET}"
exit 1
fi
echo -e "${GREEN}✅ Markdown lint OK.${RESET}"

# ── Gate 3: dotnet format check ────────────────────────────────────────────
echo -e "\n${CYAN}🎨 Checking code formatting (dotnet format --verify-no-changes)...${RESET}"
dotnet format MyBlog.slnx --verify-no-changes 2>&1
FORMAT_EXIT=$?

if [[ $FORMAT_EXIT -ne 0 ]]; then
echo -e "${RED}❌ Formatting issues detected — one or more files require formatting changes.${RESET}"
echo -e "${YELLOW} Fix: dotnet format MyBlog.slnx${RESET}"
echo -e "${YELLOW} Then: git add -u && git commit (or --amend), then re-push.${RESET}"
echo ""
printf "Auto-fix formatting now? Modified files must be staged and committed before re-pushing. [y/N] " >/dev/tty
read -r FORMAT_FIX </dev/tty
if [[ "$FORMAT_FIX" == "y" || "$FORMAT_FIX" == "Y" ]]; then
echo -e "${CYAN} 🔧 Running dotnet format MyBlog.slnx...${RESET}"
dotnet format MyBlog.slnx
if [[ $? -ne 0 ]]; then
echo -e "${RED}❌ dotnet format encountered errors. Fix manually and re-push.${RESET}"
exit 1
fi
echo -e "${YELLOW} ⚠️ Formatting applied to working tree. Stage changes: git add -u${RESET}"
echo -e "${YELLOW} Then commit and re-push.${RESET}"
fi
echo -e "${RED}Push blocked: commit the formatting changes and re-push.${RESET}"
exit 1
fi
echo -e "${GREEN}✅ Formatting OK.${RESET}"

# ── Gate 4: Release build (mirrors CI exactly) ─────────────────────────────
MAX_ATTEMPTS=3
BUILD_ATTEMPT=0
BUILD_OK=false
Expand Down Expand Up @@ -85,7 +141,7 @@ if [[ "$BUILD_OK" != true ]]; then
exit 1
fi

# ── Gate 3: Unit + Architecture tests ──────────────────────────────────────
# ── Gate 5: Unit + Architecture tests ──────────────────────────────────────
TEST_PROJECTS=(
"tests/Architecture.Tests/Architecture.Tests.csproj"
"tests/Domain.Tests/Domain.Tests.csproj"
Expand Down Expand Up @@ -121,10 +177,11 @@ if [[ "$TESTS_OK" != true ]]; then
exit 1
fi

# ── Gate 4: Docker-backed integration tests ────────────────────────────────
# ── Gate 6: Docker-backed integration tests ────────────────────────────────
# Requires Docker daemon for Testcontainers-backed dependencies.
INTEGRATION_PROJECTS=(
"tests/Web.Tests.Integration/Web.Tests.Integration.csproj"
"tests/AppHost.Tests/AppHost.Tests.csproj"
)

echo -e "\n${CYAN}🐋 Checking Docker availability for integration tests...${RESET}"
Expand Down
12 changes: 6 additions & 6 deletions .github/prompts/copyright-header-update-prompt.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ README files you write are appealing, informative, and easy to read.

## Plan

This plan details how to review and update copyright headers in C# files, supporting both single-file and solution-wide operations. It ensures every file has the correct header, updating or inserting as needed.
This plan details how to review and update copyright headers in C# files, supporting both single-file and solution-wide operations. It ensures every file has the correct header, preserves the original/earliest existing copyright year when normalizing an existing header, and collapses duplicate header blocks into one canonical header.

**Header Example (as required):**

Expand All @@ -31,14 +31,14 @@ This plan details how to review and update copyright headers in C# files, suppor
**Steps:**

1. Identify all target `.cs` files, excluding those in `bin/` and `obj/` folders.
2. For each file, check for an existing header at the very first line.
3. If a header exists, update it with the correct format and metadata, ensuring every line starts with `//`.
4. If no header exists, insert the new header at the very first line of the file, with every line C# line commented (start with `//`).
5. Validate that the header is present, correctly formatted, and at the top of each file after editing.
2. For each file, check for one or more existing header-like comment blocks at the very first line.
3. If one or more header blocks exist, treat the entire leading header region as a single unit: preserve the original/earliest copyright year already present, normalize the metadata to the canonical format, and replace the region with exactly one header block.
4. If no header exists, insert the new header at the very first line of the file, with every line C# line commented (start with `//`). When there is no existing year to preserve, use the file's creation year.
5. Validate that exactly one canonical header is present, correctly formatted, and at the top of each file after editing.
6. Output a summary of the files reviewed and the files changed.

**Open Questions:**

1. Should the header update logic support additional file types, or strictly `.cs` files?
2. Is there a preferred way to determine the file's creation year if metadata is unavailable?
2. If metadata is unavailable and no existing header year is present, is there a preferred fallback year source?
3. Should the solution/project name be parsed from the `.sln`/`.csproj` files or hardcoded?
Loading
Loading