73 lines
4.0 KiB
Markdown
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.
|