| Dimension | Shared | Only in A | Only in B | Overlap |
|---|---|---|---|---|
| Sections | 0 | 4 | 1 | 0% |
| Commands | 0 | 0 | 0 | — |
| Section tags | 0 | 3 | 1 | 0% |
What each file covers
Sections
0 shared · 4 only in A · 1 only in B- − Elasticsearch Mapping & Indexing
- − Mapping is immutable — changes require a reindex
- − Field-type conventions (don't drift)
- − Indexing must tolerate partial failure
- + Claude Code
Commands
neither file has anySection tags
0 shared · 3 only in A · 1 only in B- − code-style
- − types
- − do-not
- + agent-behaviour
Line diff
jleist-clemson/acheron · .cursor/rules/elasticsearch-mapping.mdc
@@ −1 @@
1---
2description: Elasticsearch index mapping and indexing constraints
3globs: app/storage/es.py,app/worker/es_indexer.py
4alwaysApply: false
5---
6
7# Elasticsearch Mapping & Indexing
8
9ES is a **derived, rebuildable mirror** of Mongo — never the source of truth.
10The explicit mapping is intentional; document any change in `ARCHITECTURE.md §6`.
11
12## Mapping is immutable — changes require a reindex
13
14A field's mapping type cannot change on an existing index. Editing `_MAPPING`
15only affects newly created indices, so any type change means: create a new
16index with the new mapping and reindex from Mongo (the outbox is the source).
17Call this out explicitly in the PR/commit and the architecture doc.
18
19## Field-type conventions (don't drift)
20
21- Exact-match / aggregatable fields (`event_type`, `user_id`) → `keyword`.
22- `schema_version` → `integer` (producer-declared event schema version).
23- `source_url` → `keyword` with a `text` sub-field for tokenized search.
24- `metadata` → `flattened`: schemaless keys can't explode the mapping and mixed
25 value types across events can't cause index-time conflicts. The trade-off is
26 that `flattened` leaves are exact-match keyword, not analyzed full-text — which
27 is why metadata values are *also* mirrored into `metadata_text` (below).
28- `metadata_text` → `text` (analyzed). Derived at index time from the metadata
29 leaf values and included in the `/search?q=` query, so full-text search hits
30 terms that appear only inside metadata. Search-only: excluded from `/search`
31 responses (`source_excludes`) and never stored in Mongo (ARCHITECTURE §6).
32
33## Indexing must tolerate partial failure
34
35`ensure_mapping()` is idempotent and may run lazily (ES can be down at startup).
36Bulk index with `raise_on_error=False` so one malformed document doesn't discard
37the rest of the batch; log the failures. A transport-level error (ES
38unreachable) **should** propagate so the `EsIndexer` leaves events unindexed and
39retries them next pass — that's the outbox guarantee, not a bug to swallow.
40
jleist-clemson/acheron · CLAUDE.md
@@ +1 @@
1@AGENTS.md
2
3@.claude/rules/python-standards.md
4@.claude/rules/api-routes.md
5@.claude/rules/testing.md
6@.claude/rules/elasticsearch-mapping.md
7@.claude/rules/background-tasks.md
8
9## Claude Code
10
11Shared, vendor-neutral project context lives in `AGENTS.md` (imported above).
12Project conventions live in `.claude/rules/` and are **imported above** so they
13load every session — Claude Code has no glob-scoped rules directory, so each
14file simply names the paths it applies to in an "Applies to" line. They mirror
15the Cursor rules in `.cursor/rules/` (which *are* glob-scoped via `globs:`); if
16you change a convention, update **both** mirrors and the relevant section of
17`ARCHITECTURE.md` so the tools and docs don't drift.
18
@@ −1 +1 @@
1−---
2−description: Elasticsearch index mapping and indexing constraints
3−globs: app/storage/es.py,app/worker/es_indexer.py
4−alwaysApply: false
5−---
1+@AGENTS.md
62
7−# Elasticsearch Mapping & Indexing
3+@.claude/rules/python-standards.md
4+@.claude/rules/api-routes.md
5+@.claude/rules/testing.md
6+@.claude/rules/elasticsearch-mapping.md
7+@.claude/rules/background-tasks.md
88
9−ES is a **derived, rebuildable mirror** of Mongo — never the source of truth.
10−The explicit mapping is intentional; document any change in `ARCHITECTURE.md §6`.
9+## Claude Code
1110
12−## Mapping is immutable — changes require a reindex
13−
14−A field's mapping type cannot change on an existing index. Editing `_MAPPING`
15−only affects newly created indices, so any type change means: create a new
16−index with the new mapping and reindex from Mongo (the outbox is the source).
17−Call this out explicitly in the PR/commit and the architecture doc.
18−
19−## Field-type conventions (don't drift)
20−
21−- Exact-match / aggregatable fields (`event_type`, `user_id`) → `keyword`.
22−- `schema_version` → `integer` (producer-declared event schema version).
23−- `source_url` → `keyword` with a `text` sub-field for tokenized search.
24−- `metadata` → `flattened`: schemaless keys can't explode the mapping and mixed
25− value types across events can't cause index-time conflicts. The trade-off is
26− that `flattened` leaves are exact-match keyword, not analyzed full-text — which
27− is why metadata values are *also* mirrored into `metadata_text` (below).
28−- `metadata_text` → `text` (analyzed). Derived at index time from the metadata
29− leaf values and included in the `/search?q=` query, so full-text search hits
30− terms that appear only inside metadata. Search-only: excluded from `/search`
31− responses (`source_excludes`) and never stored in Mongo (ARCHITECTURE §6).
32−
33−## Indexing must tolerate partial failure
34−
35−`ensure_mapping()` is idempotent and may run lazily (ES can be down at startup).
36−Bulk index with `raise_on_error=False` so one malformed document doesn't discard
37−the rest of the batch; log the failures. A transport-level error (ES
38−unreachable) **should** propagate so the `EsIndexer` leaves events unindexed and
39−retries them next pass — that's the outbox guarantee, not a bug to swallow.
11+Shared, vendor-neutral project context lives in `AGENTS.md` (imported above).
12+Project conventions live in `.claude/rules/` and are **imported above** so they
13+load every session — Claude Code has no glob-scoped rules directory, so each
14+file simply names the paths it applies to in an "Applies to" line. They mirror
15+the Cursor rules in `.cursor/rules/` (which *are* glob-scoped via `globs:`); if
16+you change a convention, update **both** mirrors and the relevant section of
17+`ARCHITECTURE.md` so the tools and docs don't drift.
4018
