Imported from SheepReaper/IHeartFiction (
AGENTS.md). Install upstream withnpx skills add SheepReaper/IHeartFiction. Copyright stays with the author.
Agent Command Guardrails
Repository Context (Mandatory)
Before changing code:
- Preserve unrelated working-tree changes.
- Read the target files, their tests, and one nearby complete analogue.
- For vertical feature work, follow
.agents/skills/ihfiction-feature-workflow/SKILL.mdand load only the references relevant to the task. - Read
.agents/WORKAROUNDS.mdbefore changing workaround-looking code or build/deployment plumbing.
The solution uses vertical slices and CQRS-lite. PostgreSQL/EF Core owns relational metadata, MongoDB driver collections own document bodies where existing slices use them, Redis/WolverineFx owns distributed messaging, and SharedWeb consumes the API contract generated from FictionApi. Do not introduce a second source of truth or hand-edit generated client output.
EF Core Migration Creation (Mandatory)
For this repository, the migration creation command is fixed.
Use exactly:
dotnet ef migrations add <MigrationName> --project src/lib/IHFiction.Data/IHFiction.Data.csproj --context FictionDbContext
Do not use any variant for standard migration creation, including:
- Any
--projectpath other than./src/lib/IHFiction.Data/IHFiction.Data.csproj
If the wrong command is run, rerun immediately with the exact command above and report the correction.
Migration Application And Schema Mismatch Guardrail (Mandatory)
Local EF migrations are applied by src/aspire/IHFiction.MigrationService/.
If any of these appear after model or migration changes:
relation ... does not exist- missing table, column, index, or constraint errors
- runtime failures that start immediately after schema changes
Do this first:
- Start or verify the AppHost.
- Start or verify the migration resource/container.
- Wait for the migration service to finish.
- Only then debug API, EF, LINQ, serialization, or frontend symptoms.
Stateful Credential Drift Guardrail (Mandatory)
For persistent PostgreSQL, MongoDB, Redis, or Keycloak containers, treat credentials as cluster state, not just environment configuration.
When a resource is mounted to an existing data volume:
- A changed Aspire secret or container env value does not automatically rewrite existing in-database password hashes.
- A correct volume mount and healthy process startup do not prove credential alignment.
If authentication fails (28P01, SCRAM storedKey mismatch, or equivalent):
- Verify mount/source first with
docker inspectand service logs before changing secrets. - Confirm actual runtime credential behavior with an explicit auth probe against the running container.
- Prefer in-place credential realignment on the persisted data over destructive volume replacement.
- Re-check
aspire describeand service logs after repair before debugging higher layers.
Do not assume auth failures are caused by wrong volume, migration defects, or feature code until this guardrail is exhausted.
WolverineFx Guidance (Mandatory For New Work)
For new features in this repository, WolverineFx is the primary mechanism when asynchronous, queued, or cross-domain messaging behavior is needed.
Use WolverineFx when:
- API requests should return immediately while work is processed asynchronously.
- Work crosses service/domain boundaries and should be modeled as messages/events.
- Queued work should be processed in parallel by multiple instances.
Do not refactor existing features solely to adopt WolverineFx unless explicitly requested.
Logging Guidance (Preferred Pattern)
When adding or updating structured logs in C# code, prefer source-generated logging via LoggerMessage attributes.
Use this pattern by default:
- Mark the containing class as
partial. - Define
private partial voidlogging methods with[LoggerMessage(...)]attributes. - Do not use cached delegate fields from
LoggerMessage.Define(...)unless explicitly required.
This aligns with analyzer expectations and keeps logging style consistent across the repository.
Head Metadata Composition Guardrail (Mandatory)
For Blazor head metadata in this repository, treat HeadContent as a single-owner primitive.
Rules:
HeadContentmust appear only once in the effective render tree for SEO metadata composition.- Exception:
src/lib/IHFiction.SharedWeb/Components/MarkdownEditor/Editor.razormay continue usingHeadContentfor editor assets. - The metadata owner component is
src/lib/IHFiction.SharedWeb/Components/SocialPreviewMetadata.razor. - Do not add additional page/component
HeadContentblocks for SEO/social/JSON-LD metadata.
Why this is mandatory:
- Multiple
HeadContentinstances overwriteHeadOutletoutput instead of appending. - This causes silent metadata loss (OG, Twitter, canonical, JSON-LD) depending on render order.
Append strategy:
- Prefer
SectionContent+SectionOutletfor append-style metadata composition. SectionContentalso overwrites when the same named/keyed section is emitted more than once in the same render tree branch.- Therefore use unique section names per concern (or guarantee single writer per section name).
InteractiveServer considerations (must check when changing metadata plumbing):
SectionOutletand correspondingSectionContentmust participate in compatible rendering flow.- If metadata appears in detail pages but not list/home pages, suspect render-tree placement/layout path differences.
- Validate with browser DOM inspection, not assumptions.
Required verification for metadata changes:
- Confirm expected tags exist in
document.headon/,/stories,/authors, one story detail, one chapter page, and one author detail page. - Confirm JSON-LD script count/types per route match expectations.
- Confirm OG/Twitter/canonical tags remain present after structured-data additions.
Cloud Agent Preflight (Mandatory for agent/cloud runners)
This preflight is intended for cloud-agent or automated runner environments. It is not required for a normal local editor session when you are already working in the repo and the required commands are present.
If you are running locally in VS Code or a developer shell, use the bootstrap only when intentionally validating the cloud-agent setup. If dotnet tool list --local already shows the necessary commands (aspire and dotnet-ef) and the project is otherwise healthy, ignore partial tool-restore noise and continue without blocking the local session.
Before running dotnet build --no-restore, dotnet test --no-restore, or git push/fetch commands that assume origin, run:
./tools/agent-bootstrap.sh
On Windows PowerShell, run:
./tools/agent-bootstrap.ps1
Preflight guarantees:
originremote is validated and configured when it can be inferred.- Repository-local tools from
.config/dotnet-tools.jsonare restored at their pinned versions. dotnet restorehas completed soproject.assets.jsonis present.- The current .NET SDK version is printed for diagnostics.
- A matching
.artifacts/packages/IHFiction.SourceGenerators*.nupkgis reused without repacking, regardless of its version/suffix.
After changing IHFiction.SourceGenerators, explicitly refresh its local package:
./tools/agent-bootstrap.sh --force-source-generator-package
./tools/agent-bootstrap.ps1 -ForceSourceGeneratorPackage
The Bash publication path requires python3 so package comparison can ignore nondeterministic NuGet metadata without degrading to bytewise comparison.
On Windows, a Git Bash dotnet: command not found error is an environment limitation, not evidence that the Bash script is defective. Use PowerShell for the normal Windows preflight and Ubuntu WSL for Bash behavior. If WSL has no Linux .NET SDK, Windows dotnet.exe may be used for verification only through a wrapper that converts /mnt/... and Linux temporary paths with wslpath -w; do not pass WSL paths directly to MSBuild.
If preflight cannot infer a remote, do not guess. Use the explicit command:
git remote add origin https://github.com/SheepReaper/IHeartFiction.git
When validating behavior changes after code edits, ensure the running resources are rebuilt/restarted from fresh binaries. On Windows, stale locked assemblies can make runtime responses lag behind source changes even after a successful build.
Temporary Workaround Registry (Mandatory)
Before removing unusual build targets, suppressions, or workaround-looking code, check:
.agents/WORKAROUNDS.md
If you add a new temporary workaround, document the symptom, cause, removal criteria, and verification command there.