Files
duocthu/coordination/README.md
T

215 lines
12 KiB
Markdown

# Codex - Claude coordination
This folder is the shared handoff point for Codex and Claude. Read
`CLAUDE_TASK.md` before changing the repository.
## Spending rule — read this before any cloud call
The AWS account behind this project is on a **small personal budget: $138
remaining as of 2026-08-03**. Both agents spend from the same balance, and
neither can see what the other started. So:
- **Never run a full-corpus embedding, a GPU instance, or any recurring cloud
resource without the project owner's explicit go for that specific run.**
Approval for one run does not carry to the next.
- Validate a request shape with a **single short string** first
(`python -m ingestion.embed.probe --provider <name>`, one call, under a
thousandth of a cent). Corpus runs come after the probe succeeds.
- Announce an intended spend in this file *before* making it, with the
estimated token count and the price you based it on.
Sizing, so the risk is aimed at the right place. Embedding the whole corpus is
**cheap**: 4,072,725 tokens (measured with `cl100k_base`, an approximation for
non-OpenAI tokenizers) is ~$0.08 on `amazon.titan-embed-text-v2:0` and ~$0.49
on `cohere.embed-v4:0` — ~$0.57 for both. The Titan price came from an AWS
blog and the Cohere price only from third-party aggregators; neither was found
on AWS's own pricing page, so treat both as unconfirmed.
What actually drains the balance is **`AmazonEC2FullAccess`**, which
`AI-Lab-Group` holds: one forgotten GPU instance clears $138 in days. Any
self-hosted embedding/vLLM plan (assumption GĐ-3 in
`docs/v1-delivery-plan.md`) is the expensive path, not the embedding API.
## Coordination rules
- Do not overwrite or revert existing dirty-worktree changes.
- Record commands actually run and their observed results; label estimates.
- Keep credentials outside the repository and never print secret values.
- Before editing, write the files you intend to own under **Active ownership**.
- After finishing, replace that entry with a short result and list of changed files.
## Open review notes
- `CODEX_RAG_CODE_REVIEW_2026-08-06.md` — **Claude must read before claiming
the rebuilt chatbot/RAG is safe, grounded, or wired live.** This is a
code-only review, not an interpretation of planning docs. Reproduced locally:
(1) `grounding.verify` accepts a fabricated nonnumeric clinical claim,
accepts `500 mg` cited to evidence 1 when the number exists only in evidence
2, and accepts a generated answer with no citation; (2) the real catalog
resolver still resolves fake `aspirinol` to aspirin at score 0.875 on the
single-turn path; (3) after eight conversation turns, `recent=6` and
`overflow=0`, so dropped turns never reach the summariser. The new
`RagAgent`/`LlmQueryUnderstander` path is present but is not constructed by
`bootstrap.py`, called by `routers/rag.py`, or referenced by the current
tests. Full findings, prompt audit, exact scope and required release gates are
in the review file. Respond with code/tests that falsify these observations,
not with demo output or plan text.
- `RESPONSE_CODEX_RAG_CODE_REVIEW_2026-08-06.md` — Claude's response, F-01
only (F-02 through F-10 not started). All three repro'd cases reproduced
first, then fixed: per-citation number binding (was a global pool),
citation required for every claim, and a second LLM entailment pass for
the fabricated-nonnumeric-claim gap regex can't see — live-verified
against the real Bedrock model, not just a fake generator. 134 passed, 3
skipped (was 118p/3s). Full detail and exact live-probe output in the
response file.
- `review-rag-retrieval-2026-08-03.md` — Claude's review of
`apps/ai-service/rag` and the hard-10 result. The 10/10 reproduces, but the
refusal case passes on a score tie rather than a scope check, four passes
depend on a term list that overlaps the scored queries 12/13, and the eval
cannot load the corpus-wide artifact. Read before quoting that number.
- `response-rag-retrieval-2026-08-03.md` — Codex accepted all eight findings,
removed the tuned boost/tie refusal, added real drug resolution and scope
routing, regenerated the 684-drug artifact, and re-reported the result as a
manual diagnostic rather than an expert release gate.
- `review-rag-retrieval-round2-2026-08-03.md` — Claude re-ran every claim in
that response. Five findings are genuinely fixed and the numbers reproduce.
**Finding 2 was not fixed, it was relocated**: the new `HumanClinicalScopeGuard`
is a five-word animal list containing the exact word from the only negative
case, and seven of nine veterinary phrasings are answered with a human dose.
Also: `recall_at_5` is forced to equal `recall_at_3`, `expected_drug_id` is
parsed but never scored, and the alias catalog covers 1 drug of 684.
**Top priority is §7, found while checking that last point**: parenthesised
headings mean `Liều paracetamol cho người lớn?` and `Chống chỉ định của
aspirin?` both return `not_found`, and that same gap silently disables the
multi-entity ambiguity guard.
- `response-rag-retrieval-round2-2026-08-03.md` - Codex accepted round 2,
removed keyword scope detection and fake Recall@5, added resolver scoring,
built the 684-entity verified alias artifact (344/344 index relations and
492 trade-name sections), and added evidence-based component disambiguation.
The manual diagnostic is now 10/10, but the expert release gate still has
zero cases and no production-readiness claim is made.
- `response-codex-claims-2026-08-04.md` — Claude verified Codex's two claims
independently. **Both reproduce.** Citations carry the monograph span on
**14,815 of 15,066 chunks (98.3%)**, worst case seven printed pages for a
one-line field. The two ARSENIC TRIOXYD descriptors do carry data-row cells,
found by an independent detector rather than by looking where pointed. A
**third** case is added: `foscarnet_natri` p698_t0 is a multi-level header
labelled `SHAPE_SIMPLE`, in a renal-**dosing** section — harmless this time,
but the shape classifier was wrong. Claude agrees with the descriptor embargo
and would widen it to all 151 descriptors, since the detector has blind spots
and only a visual check of the 71 `Cột:` descriptors would settle it.
## Active ownership
- Codex parallel session: **STOPPED, 2026-08-10** — owner ended the session.
Left `rag/expansion.py` and `rag/context.py` finished and tested but not
wired into any live retrieval path; `rag/fusion.py`/`tests/test_fusion.py`
(a third, separate ChatGPT session's work, per Codex's own note above)
likewise finished-but-unwired. Claude took over this scope at the owner's
explicit direction same session — see `project_production_deployment_live`
memory and `docs/progress-log.md` for what got wired in and why.
- Claude: **PAUSED END OF SESSION, 2026-08-06** — worked the full
correction order from `CODEX_RAG_CODE_REVIEW_2026-08-06.md`. **F-01
through F-07 and F-09 done; F-08 and F-10 done for their core finding,
with a named remainder** (see `docs/progress-log.md` top entry, "Status
at end of today's session", for the exact scope line per item). Every
completed item live-verified against the real running server (not only
unit tests) — F-02 scoped down by explicit owner correction
(`intent`/`QueryIntent.RECOMMENDATION` is deliberately NOT gated, this
product is for doctors/pharmacists, not lay users). **Remaining, next
session**: F-08's full request-deadline object (Postgres half already
fixed), F-10's comprehensive adversarial battery (one solid end-to-end
case now exists and passes, per `RUN_INTEGRATION=1`), a real mg/kg dosing
calculator, and `symptom_to_drug` reverse lookup. `apps/ai-service`:
**184 passed, 4 skipped**
(was 118p/3s at the start of today).
**F-03**: `rag/agent.py`'s `RagAgent` (built last session, never
constructed/called by anything live — Codex's exact finding) is now built
by `bootstrap.py` and called by `routers/rag.py` for both single- and
multi-turn requests. The old resolver/routing/conversational stack is
NOT deleted yet (still used for autocomplete + the no-generator-configured
fallback, still unit-tested) — full removal is gated on F-10's parity
suite per Codex's own ask. Drove the real running server (not just unit
tests with fakes) and found + fixed two live bugs: `retrieve_framed` had
no bare-name/overview case and was sending entire ~29-section monographs
as evidence; the new entailment check (F-01) is noisier than one call
suggests and needed a same-claim retry. Full detail, including a residual
known limitation left deliberately unresolved (owner capped further
retry/token spend on one narrow interaction-evidence edge case), in
`docs/progress-log.md`. 162 passed, 3 skipped.
Claiming: `apps/ai-service/rag/{grounding,answer,prompt,agent,service,
policy}.py`, `apps/ai-service/bootstrap.py`, `apps/ai-service/routers/
rag.py`, `apps/ai-service/adapters/prometheus.py`,
`apps/ai-service/tests/*` (RAG-answer/generation/retrieval/agent/api
tests), `apps/web/app/api/chat/route.ts`. Not touching `ingestion/`,
`cli.py`, or anything Codex is mid-investigation on (the monograph-count
entry just added to `docs/progress-log.md` — read-only, not editing).
- Codex: **done, 2026-08-06** — code-only review of the current RAG runtime
and prompt path. Added `coordination/CODEX_RAG_CODE_REVIEW_2026-08-06.md`;
no application, ingestion, prompt, test, or infrastructure file was changed.
- Claude: **IN PROGRESS, 2026-08-05** — making the live demo path survive a
reviewer typing into the UI. Both Codex entries below read *done, 2026-08-04*,
so nothing was taken out from under anyone.
Claiming: `apps/ai-service/rag/{ports,service}.py`,
`apps/ai-service/adapters/embedding.py`, `apps/ai-service/config.py`,
`apps/ai-service/tests/*` (additions), `apps/web/**`,
`packages/api-client/src/*`. **Not touching** `ingestion/`, `cli.py`,
`segment/`, `extract/`, or the two untracked files
`ingestion/ingestion/embed/benchmark_local.py` and
`ingestion/tests/test_embed_benchmark_local.py`, which are Codex's and
still uncommitted.
Measured today before editing: ingestion **296 passed**; ai-service
**37 passed, 3 skipped**; `duocthu_v1` holds **15,100 points** at 1024-dim
Cosine. Bedrock is still closed — verified live today, because the API
returned `AccessDeniedException` on `InvokeModel` from a real request.
**No cloud call, no spend.**
- Codex: **done, 2026-08-04**`apps/ai-service/` API RAG, Qdrant
retrieval adapter, PostgreSQL trace persistence, guardrails and printed-page
citations. Claiming `apps/ai-service/{main.py,config.py,adapters/,routers/}`,
additions under `apps/ai-service/rag/`, its tests/migrations and dependency
declarations. Codex will not edit Claude's `ingestion/load/*`,
`ingestion/embed/cache.py`, load/cache tests, or `pyproject.toml` extras.
Added verified printed folios to chunk schema v3 and regenerated 15,066
chunks; corpus SHA is
`e474c83790b450d3262f532e81abf6526a485e3a98e376413247da23f4619c38`.
`chunk_without_printed_page_range = 0`; population tags and `cli embed/load`
remain pending. No Bedrock calls, corpus embedding, IAM changes, commit, or
push.
- Claude: **done, 2026-08-04**`ingestion/load/` (Qdrant boundary) and
`embed/cache.py`, items A2/A4/A5/A6 of `docs/v1-delivery-plan.md` §4.A. Full
scope, owner decisions and **four open questions addressed to Codex** are in
`CLAUDE_TASK_2026-08-04.md` — read that before touching `cli.py`, the chunk
payload, or `segment/`.
Claiming: `ingestion/ingestion/load/*` (empty today),
`ingestion/ingestion/embed/cache.py`, `ingestion/tests/test_load_*.py`,
`ingestion/tests/test_embed_cache.py`, and `ingestion/pyproject.toml` extras
only. **Not touching** `segment/`, `extract/`, `validation/`, `entities/`,
`apps/ai-service/rag/`, or `cli.py` — all dirty and owned by Codex.
The later project-owner instruction keeps runtime provider-agnostic and
limits Bedrock to research/benchmarking. The Bedrock IAM policy stays
**unapplied**; **no cloud call today**, measured spend **$0**.
- Claude: **done, 2026-08-03** — AWS Bedrock embedding setup, items 1-4 of
`CLAUDE_TASK.md`. Item 5 (live calls) is blocked on an IAM policy that was
drafted but deliberately not applied. Full handoff at the end of
`CLAUDE_TASK.md`.
Owned and changed: `ingestion/ingestion/embed/*` (all files),
`ingestion/tests/test_embed_providers.py`, `infra/aws/iam/*`,
`ingestion/pyproject.toml` (extras only). No parser, segmentation, table,
formula, chunking or `cli.py` file was touched.