diff --git a/CLAUDE.md b/CLAUDE.md index 557f00b..bf53e99 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -1,99 +1,47 @@ # Development Guidelines -Universal development practices for all Svrnty/a-gent repositories. +> **Source of truth**: All engineering principles, commit rules, documentation standards, and governance policies are defined in the [root CLAUDE.md](../CLAUDE.md). This file contains repo-specific notes only. -## Engineering Principles +## Quick Reference -### KISS (Keep It Simple) -- Prefer straightforward control flow over clever meta-programming -- Keep error paths obvious and localized +- **Branch**: `JP` for active development +- **Commit format**: `type(scope): message` +- **Co-Author**: `Co-Authored-By: Svrnty Inc. ` +- **Hooks**: `lefthook install` — enforces author, secrets, doc hygiene +- **Docs required**: README.md, CHANGELOG.md, LICENSE, CONTRIBUTING.md, SECURITY.md -### YAGNI (You Aren't Gonna Need It) -- Do not add features without concrete accepted use case -- Do not introduce speculative abstractions +## Tech Stack -### DRY + Rule of Three -- Duplicate small logic when it preserves clarity -- Extract shared utilities only after 3+ repeated patterns +| Tool | Version | +|------|---------| +| C# | 14 | +| .NET | 10.0 | +| AOT | enabled (IsAotCompatible=true) | +| Nullable | enabled | -### SRP + ISP (Single Responsibility + Interface Segregation) -- Keep each module focused on one concern -- Avoid "god modules" mixing multiple responsibilities +## Commands -### Fail Fast + Explicit Errors -- Prefer explicit errors for unsupported states -- Document fallback behavior when intentional +| Command | Description | +|---------|-------------| +| `dotnet build` | Build all 18 projects | +| `dotnet test` | Run tests | +| `dotnet format` | Format code | -### Secure by Default -- Deny-by-default for access boundaries -- Never log secrets or sensitive payloads +## Key Dependencies -## Agent Workflow +| Package | Description | +|---------|-------------| +| Svrnty.CQRS.Core | Core CQRS abstractions | +| Svrnty.CQRS.DynamicQuery | Dynamic query support | +| Svrnty.CQRS.gRPC | gRPC transport | +| Svrnty.CQRS.Events | Event sourcing | +| Svrnty.CQRS.Sagas | Saga orchestration | +| Svrnty.CQRS.Notifications | Notification handlers | +| Svrnty.CQRS.MinimalApi | Minimal API bindings | -1. **Read before write** - Inspect existing code before editing -2. **Define scope** - One concern per PR -3. **Implement minimal patch** - Apply KISS/YAGNI explicitly -4. **Validate** - Run lint, format, test before commit -5. **Document impact** - Note behavior changes and risks +## Repo-Specific Notes -## Branch Strategy - -- All repos use `JP` branch for active development -- Always verify current branch before committing - -## Commit Rules - -### Allowed Authors -Only these emails are permitted for commits: -- `jp@svrnty.io` (Jean-Philippe Brule) -- `mathias@svrnty.io` (Mathias Beaulieu-Duncan) - -Configure with: `git config user.email jp@svrnty.io` - -### AI-Assisted Commits -All AI-authored commits MUST include: -``` -Co-Authored-By: Svrnty Inc. -``` - -NEVER use third-party AI tool/company names in commits. - -### Git Hooks Setup -Install lefthook to enforce commit standards: -```bash -brew install lefthook -lefthook install -``` - -The hooks automatically: -- Validate author email is in allowed list -- Append Co-Authored-By footer -- Warn on conventional commit format violations - -## PR Discipline - -- Clear, scoped commit messages -- Small PRs preferred -- Never commit personal/sensitive data -- Reference related repos for cross-repo changes - -## Validation - -Run before every commit: -- Format check (language-specific) -- Lint check (language-specific) -- Test suite - -## Anti-Patterns - -- Do NOT add heavy dependencies for minor convenience -- Do NOT mix formatting-only with functional changes -- Do NOT modify unrelated modules "while here" -- Do NOT bypass failing checks without explanation - -## Cross-Repo Changes - -- Each repo is standalone with its own build configuration -- Reference related repos in commit messages for cross-repo changes -- Coordinate multi-repo changes via matching branch names -- Test each repo independently before pushing +- Solution file: `Svrnty.CQRS.sln` with 18 projects. +- Lint is handled by .NET analyzers — AOT compatibility and nullable reference types are enforced. +- No Docker or proto files in this repo. +- Published under the `svrnty` org (git.openharbor.io/svrnty), not `a-gent`. diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 83ef48b..a8be988 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -37,7 +37,7 @@ See [CLAUDE.md](./CLAUDE.md) for development practices, engineering principles, AI-authored commits must include: ``` - Co-Authored-By: Svrnty Inc. + Co-Authored-By: Svrnty Inc. ``` 6. **Push & Create PR** diff --git a/LICENSE b/LICENSE index f7bd2f2..3c3eefb 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2021 Powered Softwares Inc. +Copyright (c) 2026 svrnty Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/SECURITY.md b/SECURITY.md index 91fde16..df0d158 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -50,4 +50,3 @@ Security updates are provided for the latest release only. |---------|-----------| | Latest | Yes | | Older | No | - diff --git a/lefthook.yml b/lefthook.yml index cc87a6c..503a809 100644 --- a/lefthook.yml +++ b/lefthook.yml @@ -25,6 +25,25 @@ pre-commit: echo "WARNING: large files staged (>5MB):" echo "$LARGE" fi + doc-hygiene: + run: | + STAGED=$(git diff --cached --name-only) + # Check if code files are staged (not just docs) + CODE_CHANGED=$(echo "$STAGED" | grep -vE '\.(md|txt|yml|yaml|json|toml|lock)$|^LICENSE$|^\.gitignore$' || true) + if [ -z "$CODE_CHANGED" ]; then + exit 0 + fi + # Warn if CHANGELOG.md is not being updated with code changes + if ! echo "$STAGED" | grep -q '^CHANGELOG.md$'; then + echo "WARNING: code changes staged without CHANGELOG.md update" + echo " → Update CHANGELOG.md under [Unreleased] before committing" + echo " → See root CLAUDE.md § Documentation Standards for format" + fi + # Warn if README.md is missing + if [ ! -f "README.md" ]; then + echo "WARNING: README.md is missing — every repo must have one" + echo " → See root CLAUDE.md § README Requirements for structure" + fi commit-msg: commands: @@ -36,6 +55,7 @@ commit-msg: fi if ! echo "$MSG" | head -1 | grep -qE '^[a-z]+(\([a-zA-Z0-9_-]+\))?: .+'; then echo "WARNING: commit message does not follow conventional format: type(scope): message" + echo " → Types: feat, fix, refactor, docs, test, chore, ci, perf" fi append-coauthor: run: | @@ -70,16 +90,24 @@ post-commit: run: | REPO_ROOT=$(git rev-parse --show-toplevel) HOOKS_DIR="$REPO_ROOT/../.svrnty-hooks" + [ -d "$HOOKS_DIR" ] || exit 0 [ -f "$HOOKS_DIR/lefthook.yml" ] || exit 0 - [ -f "$HOOKS_DIR/CLAUDE.md.template" ] || exit 0 for sibling in "$REPO_ROOT"/../*/; do [ -d "$sibling/.git" ] || continue [ -f "$sibling/lefthook.yml" ] && continue SNAME=$(basename "$sibling") + # Deploy lefthook cp "$HOOKS_DIR/lefthook.yml" "$sibling/lefthook.yml" - cp "$HOOKS_DIR/CLAUDE.md.template" "$sibling/CLAUDE.md" + # Deploy CLAUDE.md + [ -f "$HOOKS_DIR/CLAUDE.md.template" ] && cp "$HOOKS_DIR/CLAUDE.md.template" "$sibling/CLAUDE.md" + # Deploy governance docs + [ -f "$HOOKS_DIR/LICENSE" ] && [ ! -f "$sibling/LICENSE" ] && cp "$HOOKS_DIR/LICENSE" "$sibling/LICENSE" + [ -f "$HOOKS_DIR/CONTRIBUTING.md" ] && [ ! -f "$sibling/CONTRIBUTING.md" ] && cp "$HOOKS_DIR/CONTRIBUTING.md" "$sibling/CONTRIBUTING.md" + [ -f "$HOOKS_DIR/SECURITY.md" ] && [ ! -f "$sibling/SECURITY.md" ] && cp "$HOOKS_DIR/SECURITY.md" "$sibling/SECURITY.md" + [ -f "$HOOKS_DIR/CHANGELOG.md.template" ] && [ ! -f "$sibling/CHANGELOG.md" ] && cp "$HOOKS_DIR/CHANGELOG.md.template" "$sibling/CHANGELOG.md" + # Install lefthook (cd "$sibling" && lefthook install 2>/dev/null) - echo "BOOTSTRAP: installed lefthook + CLAUDE.md in '$SNAME'" + echo "BOOTSTRAP: installed lefthook + governance docs in '$SNAME'" done pre-push: