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
30 changes: 14 additions & 16 deletions .coderabbit.yaml
Original file line number Diff line number Diff line change
@@ -1,15 +1,13 @@
# yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json
#
# CodeRabbit config for Axis. Purpose: make automated review cite this repo's
# canonical rules (CLAUDE.md + docs/playbooks) instead of generic advice, so
# every finding maps to a section a human (or agent) can act on — and so the
# review-findings ledger (docs/review-findings-ledger.md) can track which
# finding classes have been mechanized away vs. still need human review.
# canonical rules (CLAUDE.md + docs/playbooks) instead of generic advice.
# Every finding should map to a section a human or agent can act on. The
# enforcement taxonomy lives in docs/REVIEW_FINDINGS.md.
#
# Deterministic rules (no var, one-type-per-file, using-not-FQCN, forward
# CancellationToken) are enforced by analyzers in .editorconfig — they should
# fail the build, not wait for review. The instructions below are for the
# judgment-based classes that an analyzer cannot reliably catch.
# Deterministic rules like no-var locals and CancellationToken forwarding are
# enforced by analyzers/.editorconfig and should fail the build, not wait for
# review. The instructions below are for judgment-based classes or guidance.
language: en-US

reviews:
Expand All @@ -20,14 +18,14 @@ reviews:
path_instructions:
- path: "**/*.cs"
instructions: |
Project rules: CLAUDE.md (machine rules P0-P2) and .editorconfig are
authoritative. Style/naming (no `var` for locals, `using` not
fully-qualified names) and CancellationToken forwarding (CA2016, escalated
in .editorconfig + TreatWarningsAsErrors) are analyzer-enforced and fail
the build — only flag them if the build somehow did not. (One-public-type-
per-file is deliberately NOT enforced it conflicts with intentional
groupings like Result/Result<T>, ICommand/ICommand<T>, and polymorphic
value-object hierarchies; see review-findings-ledger.md. Do not flag it.)
Project rules: CLAUDE.md (machine rules P0-P2), .editorconfig, and
docs/REVIEW_FINDINGS.md are authoritative. No `var` for locals and
CancellationToken forwarding (CA2016) are analyzer-enforced and fail
the build; only flag them if the build somehow did not. Inline
fully-qualified type names are style guidance, not a hard gate.
One-public-type-per-file is deliberately NOT enforced because it
conflicts with intentional groupings; see docs/REVIEW_FINDINGS.md.
Do not flag it.
Focus review on:
- Result / Result<T> for business failures; exceptions only for
infrastructure faults (CLAUDE.md P1). Flag bespoke bool/tuple/throw
Expand Down
3 changes: 2 additions & 1 deletion .editorconfig
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
root = true

[*]
# Enforced by `python scripts/axis.py check text-encoding`.
charset = utf-8
end_of_line = lf
indent_style = space
Expand Down Expand Up @@ -345,7 +346,7 @@ dotnet_analyzer_diagnostic.category-Reliability.severity = suggestion

# ── Escalated to warning (→ build error via TreatWarningsAsErrors) ──
# Recurring review findings that are mechanical and deterministic: cheaper to
# fail the build than to re-flag in review. See docs/review-findings-ledger.md.
# fail the build than to re-flag in review. See docs/REVIEW_FINDINGS.md.
# CA2016: forward the CancellationToken parameter to methods that take one.
# Caught dropped tokens in schedulers/middleware/gRPC that review kept finding.
dotnet_diagnostic.CA2016.severity = warning
Expand Down
10 changes: 5 additions & 5 deletions .github/PULL_REQUEST_TEMPLATE.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,13 @@

## Requirements & rules followed

<!-- Most important first. Tick what applies; mark N/A with a short reason. Order matches the Gates in docs/playbooks/agent-checklist.md. -->
<!-- Most important first. Tick what applies; mark N/A with a short reason. Order matches the review/gate flow in docs/playbooks/agent-checklist.md. -->

- [ ] **Spec → code** — changes match use-case file ACs (or gaps documented in `> **Implementation status**` callouts; deferred items have `**Deferred (PR #N follow-up):**` lines)
- [ ] **Gate 0** — AC map complete; use-case/domain docs identified (when shipping code)
- [ ] **Ready review** — AC map complete; use-case/domain docs identified (when shipping behavior)
- [ ] **Path coverage matrix** — for each touched implementation surface, happy/validation/auth/isolation/dependency paths are tested or explicitly marked `N/A` (see `docs/playbooks/agent-checklist.md` § AC coverage)
- [ ] **Gate 1** — local fast gate (`python scripts/axis.py verify`: build + vulnerability scan + format + unit test projects + frontend checks + doc drift) ran green for paths touched; full `dotnet test Axis.sln` is enforced by CI/branch protection (N/A with reason)
- [ ] **Gate 2** — docs updated in same PR (use-case callout, domain README, `PROGRESS.md`, `TECH_STACK` / patterns as triggered); `python scripts/axis.py check doc-drift` ran green locally
- [ ] **Gate 3** — retrospective done; `patterns.md` / use-case file / `TECH_STACK.md` / `CLAUDE.md` updated if a new durable rule emerged
- [ ] **Verification gate** — local fast gate (`python scripts/axis.py verify`: build + vulnerability scan + format + unit test projects + frontend checks + policy tests + doc drift) ran green for paths touched; full `dotnet test Axis.sln` is enforced by CI/branch protection (N/A with reason)
- [ ] **Docs review** — owning docs updated when behavior/spec/status changed; pure refactor/style/test-only changes marked N/A
- [ ] **Retrospective review** — `REVIEW_FINDINGS.md` / patterns / use-case / `TECH_STACK.md` / `CLAUDE.md` updated if a durable rule or repeat finding emerged
- [ ] **Workarounds** — this PR neither introduces nor resolves a P0/P1 violation **OR** [`docs/WORKAROUNDS.md`](../docs/WORKAROUNDS.md) was updated in the same commit and the violation site has a `// WORKAROUND: see docs/WORKAROUNDS.md#<slug>` comment
- [ ] **No new `TODO` / `FIXME` / `NotImplementedException` / placeholder / stub** under `src/`, `tests/`, `frontend/src/`
21 changes: 4 additions & 17 deletions .github/workflows/build-and-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,6 @@ jobs:
outputs:
backend: ${{ steps.filter.outputs.backend }}
frontend: ${{ steps.filter.outputs.frontend }}
doc-drift-scope: ${{ steps.filter.outputs['doc-drift-scope'] }}
protobuf: ${{ steps.filter.outputs.protobuf }}
markdown: ${{ steps.filter.outputs.markdown }}
steps:
Expand Down Expand Up @@ -77,19 +76,6 @@ jobs:
# when no frontend/** file is touched in the same PR.
- 'openapi.json'
- '.github/workflows/build-and-test.yml'
doc-drift-scope:
- 'src/**'
- 'tests/**'
# The umbrella's full-tree checks (link targets, use-case
# structure, code-fence integrity) validate every doc, so any
# doc change must trigger them — not just use-cases.
- 'docs/**'
# Globbed, not enumerated: the umbrella invokes several checker
# scripts, and a new one must trigger the job without anyone
# remembering to add it here.
- 'scripts/**'
- 'buf.yaml'
- '.github/workflows/build-and-test.yml'
protobuf:
- '**/*.proto'
- 'buf.yaml'
Expand Down Expand Up @@ -138,7 +124,7 @@ jobs:
- name: Build
run: dotnet build --no-restore

# Format gate — see CLAUDE.md § Gate 1. Runs after build so analyzer
# Format gate — see CLAUDE.md § Verification gate. Runs after build so analyzer
# diagnostics are populated. Fails the job on any whitespace / charset
# / style violation the local `dotnet format` would also catch.
- name: Verify formatting (dotnet format)
Expand Down Expand Up @@ -210,8 +196,6 @@ jobs:

doc-drift:
name: Doc drift
needs: detect
if: needs.detect.outputs['doc-drift-scope'] == 'true'
runs-on: ubuntu-latest
timeout-minutes: 5
steps:
Expand All @@ -220,6 +204,9 @@ jobs:
fetch-depth: 0
persist-credentials: false

- name: Test policy gates
run: python scripts/axis.py check policy-tests

- name: Check doc drift
run: python scripts/axis.py check doc-drift
env:
Expand Down
2 changes: 1 addition & 1 deletion Axis.sln
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@


Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.0.31903.59
Expand Down
24 changes: 12 additions & 12 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -57,12 +57,12 @@ Stack, versions, and ADRs are owned by [`docs/TECH_STACK.md`](docs/TECH_STACK.md

- Tech stack immutable without explicit user approval.
- Spec → code only; never rewrite specs to match shortcuts.
- Never weaken tests, `.Skip()`, or mock away behavior under test.
- Never weaken tests, add test `Skip = ...`, or mock away behavior under test.
- Never bypass auth, skip an AC silently, or mark ✅ to avoid a hard gap.
- Domain: zero external dependencies.
- No implementation of a non-trivial change without completing the **Design Gate** ([design-gate.md](docs/playbooks/design-gate.md)); high-risk surfaces require user sign-off before code.
- Never commit with failing Gate 1; docs and requirements satisfied before merge (agent-checklist + PR template).
- When `src/`, `tests/`, or `docs/use-cases/` change: run `python scripts/axis.py check doc-drift` before push; CI **Doc drift** must be green. Tick **Gate 2** in the PR template — do not paste drift-script output.
- Never commit with a failing Verification gate; docs and requirements satisfied before merge (agent-checklist + PR template).
- Run `python scripts/axis.py check policy-tests` and `python scripts/axis.py check doc-drift` before push when touching docs, scripts, repo layout, handlers, endpoints, or generated-contract surfaces; CI **Doc drift** runs on every PR and must be green. Tick **Docs review** in the PR template when docs were reviewed — do not paste drift-script output.

**P1 — confirm with user before deviating:**

Expand All @@ -77,7 +77,7 @@ Stack, versions, and ADRs are owned by [`docs/TECH_STACK.md`](docs/TECH_STACK.md
**P2 — every commit:**

- Zero build warnings and zero test failures.
- Docs in the same PR as code (see [agent-checklist](docs/playbooks/agent-checklist.md)).
- Owning docs in the same PR when behavior/spec/status changes; pure refactor/style/test-only changes do not need a token docs edit (see [agent-checklist](docs/playbooks/agent-checklist.md)).
- No new TODO/FIXME/placeholder/stub code.
- For **wireframe** changes (`docs/wireframes/`, `docs/use-cases/**` screen `.excalidraw`/`.svg`): run [`docs/playbooks/visual-artifact-checklist.md`](docs/playbooks/visual-artifact-checklist.md) before commit. **Diagrams** are Mermaid in `docs/README.md` and use-case `README.md` — one theme in [`docs/diagrams/mermaid-theme.mjs`](docs/diagrams/mermaid-theme.mjs); run `node docs/scripts/sync-mermaid-theme.mjs` after editing `MERMAID_INIT` ([`docs/playbooks/mermaid.md`](docs/playbooks/mermaid.md)).

Expand Down Expand Up @@ -118,18 +118,18 @@ Response header for multi-file / new-layer tasks:

Skip for trivial single-file fixes and doc-only edits.

### Gates
### Reviews And Gates

**Gate 0/1 ownership:** detailed AC-map/path-coverage requirements and the authoritative Gate 1 command matrix are owned by
**Ready review / Verification gate ownership:** detailed AC-map/path-coverage requirements and the authoritative Verification gate command matrix are owned by
[agent-checklist.md](docs/playbooks/agent-checklist.md) (single source).
This file keeps policy-level requirements only:

- **Gate 0 policy:** no blank AC map rows for in-scope bullets; no happy-path-only completion claims.
- **Gate 1 policy:** follow [agent-checklist.md § Gate 1](docs/playbooks/agent-checklist.md#gate-1--verify-before-push-fast-local-gate), the single owner for local fast-gate commands and CI full-gate expectations. Never present a unit-only/local-fast run as a full-suite run.
- **Ready review policy:** no blank AC map rows for in-scope bullets; no happy-path-only completion claims.
- **Verification gate policy:** follow [agent-checklist.md § Verification Gate](docs/playbooks/agent-checklist.md#verification-gate--verify-before-push), the single owner for local fast-gate commands and CI full-gate expectations. Never present a unit-only/local-fast run as a full-suite run.

**Gate 2** — docs in same PR ([agent-checklist.md § Gate 2](docs/playbooks/agent-checklist.md)). **Doc drift** — run script before push when code/use-cases change; CI job must be green.
**Docs review** — docs walkthrough when behavior/spec/status changes ([agent-checklist.md](docs/playbooks/agent-checklist.md)). **Doc drift** — CI-enforced deterministic policy/doc checks; it does not require a token docs edit for every code diff.

**Gate 3** — retrospective ([agent-checklist.md § Gate 3](docs/playbooks/agent-checklist.md)); update docs on any "yes".
**Retrospective review** — update docs, tests, or [REVIEW_FINDINGS.md](docs/REVIEW_FINDINGS.md) when a durable rule or repeat finding emerges.

### Git

Expand Down Expand Up @@ -190,7 +190,7 @@ Add navigation back-links per [docs/README.md](docs/README.md) (playbooks, use-c

**Per layer / module:** all use-case callouts updated; domain README table; [`PROGRESS.md`](docs/PROGRESS.md) (layer summary only — not per-class detail).

**Per PR before merge:** PR description = Summary + Linked spec + Requirements only (no CI status, no commit list — Checks tab covers that). Run `python scripts/axis.py check doc-drift` before push when `src/`, `tests/`, or `docs/use-cases/` change — the command enforces use-case-docs same-PR, new-handler tests, the no-new `TODO`/`FIXME`/`stub` rule, script-standard enforcement, and new raw-SQL call review (cross-module guard).
**Per PR before merge:** PR description = Summary + Linked spec + Requirements only (no CI status, no commit list — Checks tab covers that). Run `python scripts/axis.py check policy-tests` and `python scripts/axis.py check doc-drift` before push when touching docs, scripts, repo layout, handlers, endpoints, generated-contract surfaces, or bulk file rewrites. The CI job runs on every PR and enforces deterministic policy/doc checks: text encoding (`UTF-8` without BOM + LF), changed-handler test files, no-new `TODO`/`FIXME`/`stub`, no new test `Skip = ...`, no `EnsureCreated`, script standards, layout checks, and docs integrity.

Diagrams/wireframes: regenerate `.svg` in same PR when source `.excalidraw` changes. Agents must pass [`docs/playbooks/visual-artifact-checklist.md`](docs/playbooks/visual-artifact-checklist.md) before commit.

Expand All @@ -212,7 +212,7 @@ Diagrams/wireframes: regenerate `.svg` in same PR when source `.excalidraw` chan
| [TECH_STACK.md](docs/TECH_STACK.md) | Libraries + ADRs |
| [PROGRESS.md](docs/PROGRESS.md) | Module layer status |
| [WORKAROUNDS.md](docs/WORKAROUNDS.md) | Intentional rule violations + cleanup triggers (**read when touching legacy or shipping a known shortcut**) |
| [REVIEW_FINDINGS.md](docs/REVIEW_FINDINGS.md) | Recurring review finding classes → the gate that prevents each (or why manual); wired to Gate 3 |
| [REVIEW_FINDINGS.md](docs/REVIEW_FINDINGS.md) | Recurring review finding classes → Enforced / Partial / Review-only / Guidance status; wired to Retrospective review |
| [docs/playbooks/visual-artifact-checklist.md](docs/playbooks/visual-artifact-checklist.md) | **Required when changing diagrams/wireframes/use-case visuals** |
| [Architecture tests README](tests/Architecture/Axis.Architecture.Tests/README.md) | What's mechanically enforced + how to add a new rule |
| [docs/use-cases/](docs/use-cases/README.md) | Features + ACs |
Expand Down
10 changes: 5 additions & 5 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,13 @@ Docs-first development: feature specs in `docs/use-cases/` are the contract; cod

## Before you push

Install the local hook once with `python scripts/axis.py bootstrap`, then use `python scripts/axis.py verify` for the fast pre-push gate. During implementation, prefer targeted checks for the surface you are editing; the hook is the local enforcement point before push. The authoritative Gate 1 policy and command matrix live in [agent-checklist.md § Gate 1](docs/playbooks/agent-checklist.md#gate-1--verify-before-push-fast-local-gate); unit-only feedback is available via `python scripts/axis.py test unit`. Script standards live in [scripts.md](docs/playbooks/scripts.md).
Install the local hook once with `python scripts/axis.py bootstrap`, then use `python scripts/axis.py verify` for the fast pre-push gate. During implementation, prefer targeted checks for the surface you are editing; the hook is the local enforcement point before push. The authoritative Verification gate policy and command matrix live in [agent-checklist.md § Verification Gate](docs/playbooks/agent-checklist.md#verification-gate--verify-before-push); unit-only feedback is available via `python scripts/axis.py test unit`. Script standards live in [scripts.md](docs/playbooks/scripts.md).

1. Walk **Gates 0-3** in [docs/playbooks/agent-checklist.md](docs/playbooks/agent-checklist.md) locally; tick the matching boxes in the PR body.
1. Walk Ready review, Verification gate, Docs review, and Retrospective review in [docs/playbooks/agent-checklist.md](docs/playbooks/agent-checklist.md) locally; tick the matching boxes in the PR body.
2. When you touch C# under `src/` or `tests/`, run `dotnet format Axis.sln` - style and naming rules live in [`.editorconfig`](.editorconfig) (CI runs `dotnet format --verify-no-changes`).
3. Run `python scripts/axis.py check doc-drift` when `src/`, `tests/`, or `docs/use-cases/` change. **New module, endpoint, Kafka event, or proto?** Follow [docs/playbooks/repo-layout-discovery.md](docs/playbooks/repo-layout-discovery.md) (checklists A-E - what CI auto-checks vs what you still edit by hand). Use-case layout: [USE_CASE_TEMPLATE.md](docs/use-cases/USE_CASE_TEMPLATE.md). If `docker-compose.yml` changes, update [local-dev.md](docs/playbooks/local-dev.md). CI job **Doc drift** must be green.
3. Run `python scripts/axis.py check policy-tests` and `python scripts/axis.py check doc-drift` when touching docs, scripts, repo layout, handlers, endpoints, or generated-contract surfaces. **New module, endpoint, Kafka event, or proto?** Follow [docs/playbooks/repo-layout-discovery.md](docs/playbooks/repo-layout-discovery.md) (checklists A-E - what CI auto-checks vs what you still edit by hand). Use-case layout: [USE_CASE_TEMPLATE.md](docs/use-cases/USE_CASE_TEMPLATE.md). If `docker-compose.yml` changes, update [local-dev.md](docs/playbooks/local-dev.md). CI job **Doc drift** runs on every PR and must be green.
4. PR description: **Summary + Linked spec + Requirements only** - no commit list, no CI status (the Checks tab covers that). GitHub auto-fills [.github/PULL_REQUEST_TEMPLATE.md](.github/PULL_REQUEST_TEMPLATE.md); CI job **PR body guard** enforces the required sections and checklist state.
5. When adding or changing `.proto` files: run `python scripts/axis.py generate buf-yaml` (updates [`buf.yaml`](buf.yaml) module paths), then `buf lint` - see [repo-layout-discovery.md section D](docs/playbooks/repo-layout-discovery.md). CI **Protobuf** job runs on proto/`buf.yaml` changes.
5. When adding or changing `.proto` files: run `python scripts/axis.py generate buf-yaml` (updates [`buf.yaml`](buf.yaml) module paths), then `buf lint` - see [repo-layout-discovery.md § Auto-discovered](docs/playbooks/repo-layout-discovery.md#auto-discovered-do-not-duplicate-lists-elsewhere). CI **Protobuf** job runs on proto/`buf.yaml` changes.

## Dependency updates (Dependabot)

Expand Down Expand Up @@ -54,7 +54,7 @@ When you change [`docker-compose.yml`](docker-compose.yml), update that playbook
| Doc | Purpose |
|-----|---------|
| [CLAUDE.md](CLAUDE.md) | Architecture rules, P0 stops, machine rules |
| [docs/playbooks/agent-checklist.md](docs/playbooks/agent-checklist.md) | Daily workflow + Gates 0-3 |
| [docs/playbooks/agent-checklist.md](docs/playbooks/agent-checklist.md) | Daily workflow, Verification gate, and review checks |
| [docs/playbooks/process.md](docs/playbooks/process.md) | Layer-by-layer implementation + deferred follow-ups |
| [docs/playbooks/patterns-index.md](docs/playbooks/patterns-index.md) | Jump table into patterns |
| [docs/README.md](docs/README.md) | Documentation hub + single source of truth per topic |
Loading
Loading