RuleStack

Configs

Stacks

Compare

Diff

RuleStack

Configs

Stacks

Compare

Diff

Read API

RuleStack

Configs

Stacks

Compare

Diff

Read API

Diff/jleist-clemson-acheron-cursor-rules-api-routes ↔ jleist-clemson-acheron-agents

Comparison

A · Cursor rules · jleist-clemson/acheronB · AGENTS.md · jleist-clemson/acheron
What each file covers, counted
DimensionSharedOnly in AOnly in BOverlap
Sections0260%
Commands000—
Section tags11514%

What each file covers

Sections

0 shared · 2 only in A · 6 only in B
  • − API Route Conventions
  • − Error → status mapping (be consistent)
  • + Acheron — AI agent & contributor guide
  • + What this is
  • + Layering (keep these boundaries)
  • + Store roles (do not blur)
  • + Conventions in brief (see the scoped rules for detail)
  • + Docs are a first-class deliverable

Commands

neither file has any

Section tags

1 shared · 1 only in A · 5 only in B
  • − api
  • + test
  • + lint-format
  • + do-not
  • + agent-behaviour
  • + docs
  •   code-style

Line diff

+41 added−31 removed7 unchanged14.6% identical
jleist-clemson/acheron · .cursor/rules/api-routes.mdc
@@ −1 @@
1---
2description: FastAPI route conventions for the events API
3globs: app/api/**/*.py
4alwaysApply: false
5---
6 
7# API Route Conventions
 
 
 
 
 
8 
9- Routes are thin: validate input, call a service/store, shape the response.
10 No persistence, aggregation, or business logic in a handler.
11- Pull dependencies off `app.state` via the `Depends(_helper)` pattern (e.g.
12 `_mongo`, `_es`, `_cache`, `_ingestion`); don't reach into globals.
13- The events routes declare a Pydantic `response_model` from
14 `app/api/schemas.py`; `/health` (a status-code-driven `JSONResponse`) and
15 `/metrics` (a loose ops snapshot) are intentionally exempt. Nullable fields are
16 **always present** in the response (return explicit `null`, e.g. `total`,
17 `bucket`, `computed_at`) for a stable shape.
18 
19# Error → status mapping (be consistent)
 
 
 
 
20 
21Stores raise native exceptions; the route catches and maps them. Log at the
22boundary with the exception type, then raise `HTTPException`.
23 
24| Condition | Status |
25|---|---|
26| Mongo (source of truth) unavailable | `503` |
27| Elasticsearch (derived) unavailable | `502` |
28| Queue full (backpressure) | `429` |
29| Service shutting down | `503` |
30 
31```python
32try:
33 events, has_more, total = await mongo.find_events(...)
34except PyMongoError as exc:
35 logger.error("Mongo query failed (%s): %s", type(exc).__name__, exc)
36 raise HTTPException(status_code=503, detail="Event store temporarily unavailable")
37```
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
38 
jleist-clemson/acheron · AGENTS.md
@@ +1 @@
1# Acheron — AI agent & contributor guide
 
 
 
 
2 
3Vendor-neutral project context, shared across AI coding tools. Cursor reads this
4file natively; Claude Code reads it via the `@AGENTS.md` import in `CLAUDE.md`.
5Tool-specific rules live in `.cursor/rules/` (Cursor, glob-scoped via `globs:`)
6and `.claude/rules/` (Claude Code, imported from `CLAUDE.md` so they load every
7session) — keep those mirrors in sync with each other and with this file.
8`ARCHITECTURE.md` is the authoritative design document.
9 
10## What this is
 
 
 
 
 
 
 
 
11 
12`acheron` is a Distributed Event Processing Platform. Write path:
13`POST /events` → bounded in-process `asyncio.Queue` → async worker →
14**MongoDB (source of truth)**. Elasticsearch is a **derived mirror**, populated
15strictly downstream from a Mongo outbox (`es_indexed` marker) by the `EsIndexer`.
16Redis caches the realtime stats summary.
17 
18## Layering (keep these boundaries)
 
19 
20- `app/api/` — HTTP only: translate request ↔ domain, map errors to status codes.
21- `app/ingestion/`, `app/worker/` — pipeline logic (enqueue, consume, index, rollup).
22- `app/storage/`, `app/cache/`, `app/queue/` — one backend per module.
 
 
 
23 
24Business logic lives in services/stores, never in route handlers.
25 
26## Store roles (do not blur)
27 
28- **Mongo is authoritative.** If Mongo and ES disagree, Mongo wins.
29- **ES is best-effort and rebuildable** — never fail an authoritative write on it.
30- **Redis is a cache** — a Redis outage must degrade, never lose data.
31- The queue is **in-process and non-durable**; that constraint drives most
32 failure-mode and scaling reasoning. Don't design as if it were durable.
33 
34## Conventions in brief (see the scoped rules for detail)
35 
36- `from __future__ import annotations` atop every module; Google-style docstrings
37 (ruff `D`, pydocstyle google). Tunables live in `Settings`, not magic numbers.
38- Routes are thin; the events routes declare a Pydantic `response_model`
39 (`/health` and `/metrics` are intentionally exempt). Errors map to status
40 codes (Mongo→503, ES→502, queue full→429, shutdown→503).
41- Tests: pytest with `asyncio_mode=auto`; unit tests are hermetic, Docker-backed
42 tests are marked `integration` and deselected by default.
43 
44## Docs are a first-class deliverable
45 
46When you change behavior, update `ARCHITECTURE.md` and `README.md` in the same
47change. Code and docs must not drift — the architecture doc is graded.
48 
@@ −1 +1 @@
1−---
2−description: FastAPI route conventions for the events API
3−globs: app/api/**/*.py
4−alwaysApply: false
5−---
1+# Acheron — AI agent & contributor guide
62  
7−# API Route Conventions
3+Vendor-neutral project context, shared across AI coding tools. Cursor reads this
4+file natively; Claude Code reads it via the `@AGENTS.md` import in `CLAUDE.md`.
5+Tool-specific rules live in `.cursor/rules/` (Cursor, glob-scoped via `globs:`)
6+and `.claude/rules/` (Claude Code, imported from `CLAUDE.md` so they load every
7+session) — keep those mirrors in sync with each other and with this file.
8+`ARCHITECTURE.md` is the authoritative design document.
89  
9−- Routes are thin: validate input, call a service/store, shape the response.
10− No persistence, aggregation, or business logic in a handler.
11−- Pull dependencies off `app.state` via the `Depends(_helper)` pattern (e.g.
12− `_mongo`, `_es`, `_cache`, `_ingestion`); don't reach into globals.
13−- The events routes declare a Pydantic `response_model` from
14− `app/api/schemas.py`; `/health` (a status-code-driven `JSONResponse`) and
15− `/metrics` (a loose ops snapshot) are intentionally exempt. Nullable fields are
16− **always present** in the response (return explicit `null`, e.g. `total`,
17− `bucket`, `computed_at`) for a stable shape.
10+## What this is
1811  
19−# Error → status mapping (be consistent)
12+`acheron` is a Distributed Event Processing Platform. Write path:
13+`POST /events` → bounded in-process `asyncio.Queue` → async worker →
14+**MongoDB (source of truth)**. Elasticsearch is a **derived mirror**, populated
15+strictly downstream from a Mongo outbox (`es_indexed` marker) by the `EsIndexer`.
16+Redis caches the realtime stats summary.
2017  
21−Stores raise native exceptions; the route catches and maps them. Log at the
22−boundary with the exception type, then raise `HTTPException`.
18+## Layering (keep these boundaries)
2319  
24−| Condition | Status |
25−|---|---|
26−| Mongo (source of truth) unavailable | `503` |
27−| Elasticsearch (derived) unavailable | `502` |
28−| Queue full (backpressure) | `429` |
29−| Service shutting down | `503` |
20+- `app/api/` — HTTP only: translate request ↔ domain, map errors to status codes.
21+- `app/ingestion/`, `app/worker/` — pipeline logic (enqueue, consume, index, rollup).
22+- `app/storage/`, `app/cache/`, `app/queue/` — one backend per module.
3023  
31−```python
32−try:
33− events, has_more, total = await mongo.find_events(...)
34−except PyMongoError as exc:
35− logger.error("Mongo query failed (%s): %s", type(exc).__name__, exc)
36− raise HTTPException(status_code=503, detail="Event store temporarily unavailable")
37−```
24+Business logic lives in services/stores, never in route handlers.
25+ 
26+## Store roles (do not blur)
27+ 
28+- **Mongo is authoritative.** If Mongo and ES disagree, Mongo wins.
29+- **ES is best-effort and rebuildable** — never fail an authoritative write on it.
30+- **Redis is a cache** — a Redis outage must degrade, never lose data.
31+- The queue is **in-process and non-durable**; that constraint drives most
32+ failure-mode and scaling reasoning. Don't design as if it were durable.
33+ 
34+## Conventions in brief (see the scoped rules for detail)
35+ 
36+- `from __future__ import annotations` atop every module; Google-style docstrings
37+ (ruff `D`, pydocstyle google). Tunables live in `Settings`, not magic numbers.
38+- Routes are thin; the events routes declare a Pydantic `response_model`
39+ (`/health` and `/metrics` are intentionally exempt). Errors map to status
40+ codes (Mongo→503, ES→502, queue full→429, shutdown→503).
41+- Tests: pytest with `asyncio_mode=auto`; unit tests are hermetic, Docker-backed
42+ tests are marked `integration` and deselected by default.
43+ 
44+## Docs are a first-class deliverable
45+ 
46+When you change behavior, update `ARCHITECTURE.md` and `README.md` in the same
47+change. Code and docs must not drift — the architecture doc is graded.
3848  
RuleStack

Built by

Kynth Studio

Directory

Configs
Stacks
Compare formats
Diff two configs
Best AGENTS.md examples

Formats

AGENTS.md
CLAUDE.md
Cursor rules
Copilot instructions

Reference

Read API
Corpus health
Privacy Policy
Terms

RuleStack

RuleStack

Built by

Kynth Studio

Directory

Configs
Stacks
Compare formats
Diff two configs
Best AGENTS.md examples

Formats

AGENTS.md
CLAUDE.md
Cursor rules
Copilot instructions

Reference

Read API
Corpus health
Privacy Policy
Terms

RuleStack

RuleStack

Built by

Kynth Studio

Directory

Configs
Stacks
Compare formats
Diff two configs
Best AGENTS.md examples

Formats

AGENTS.md
CLAUDE.md
Cursor rules
Copilot instructions

Reference

Read API
Corpus health
Privacy Policy
Terms

RuleStack