Files
duocthu/CLAUDE.md
T

73 lines
4.0 KiB
Markdown

# Instructions for Claude working in this repo
## Never fabricate, never bluff
Do not state a number, a test result, a "verified" claim, or a capability
estimate unless it is backed by something you actually ran or actually
read. If you haven't checked something, say so explicitly ("not verified
yet", "estimate, not measured") instead of presenting a guess as fact.
**Why:** this project involves parsing a medical reference book into a
chatbot's knowledge base — false confidence here is not a cosmetic bug, it
propagates into medical answers. During the ingestion-strategy
investigation, a size-based heading threshold silently dropped ~15% of real
monographs before whole-document validation caught it; a monograph-boundary
scan was initially run on 1405 of 1668 pages before being caught and
corrected. Confident-sounding claims that turn out wrong cost real rework
and could cost real answer quality once this is live.
**How to apply:**
- Prefer "I ran X and got Y" over "X should work" — run the check.
- When asked something you don't know for certain (throughput estimates,
whether a tool/library works on this environment, whether a heuristic
holds at scale), say what's measured vs. estimated, explicitly.
- Whole-document / whole-scope validation over small-sample claims — if the
user states a total (e.g. "1668 pages"), any check must cover that literal
total before being reported as done, not a convenient subset.
- When a claim turns out wrong after fuller checking, say so plainly and
show the corrected result — don't quietly smooth over the miss.
See `docs/pdf-parsing-outlier-catalog.md` and
`docs/adr/0003-pdf-parsing-strategy.md` for the concrete track record this
rule comes from.
## Real code follows Clean Code / Clean Architecture / SoC / DRY / SOLID
Applies to anything meant to be committed as part of the actual system
(`apps/*`, `ingestion/*`, `packages/*`) — not throwaway investigation
scripts (e.g. a one-off scan to check a hypothesis), which may stay quick
and disposable as long as they're never confused for production code and
get deleted once their finding is written down.
**Why this is a written rule, not just an intention:** intentions from one
conversation don't carry into the next session, and under time pressure or
mid-refactor it's easy to let a principle slip without noticing — a written
checklist is what actually catches that, the same reasoning behind the
"never fabricate" rule above.
**How to apply, concretely, in this repo:**
- **SoC**: keep the `ingestion/` pipeline stages (`extract/`, `segment/`,
`chunk/`, `embed/`, `load/`) genuinely independent — extraction code must
not know about chunking, chunking must not call OpenAI, etc.
- **DRY**: shared logic (e.g. the bold-span heading/boundary detector) lives
in exactly one module that both the real pipeline and any validation
script import — never re-implemented per script, which is what happened
during exploratory investigation and is fine there, but must not carry
into real code.
- **SOLID**: single-responsibility modules/classes (a detector detects, it
doesn't also chunk); open/closed section taxonomy (adding a new section
label — e.g. a field like "Tên thương mại" not in the book's own
documented list — must not require editing existing matching code, only
adding an entry); dependency inversion at infrastructure boundaries
(`ai-service`'s domain/retrieval logic depends on an interface, not a
hard import of the Qdrant SDK or OpenAI client directly, so it stays
testable without live services).
- **Clean Architecture**: domain/business logic (parsing rules, chunking
rules, retrieval/grounding logic) stays independent of infrastructure
(OpenAI SDK, Qdrant client, filesystem, NestJS framework details) so it's
testable in isolation.
- **Clean Code**: meaningful names, small functions, minimal comments (only
where the *why* isn't obvious from the code itself) — matches the
no-comments-unless-non-obvious style already used throughout this
project's docs and ADRs.