Fix migration workflow: upload as artifact instead of scp to practice EC2

This commit is contained in:
2026-08-13 11:14:25 +07:00
parent 7ebbe1f309
commit a4819b8653
51 changed files with 6830 additions and 8 deletions
+120
View File
@@ -0,0 +1,120 @@
# 28 — Roadmap from code
**Not a product roadmap.** This is only what the code itself says is unfinished:
explicit `TODO`s, `NotImplementedError`s, placeholder files, empty directories,
unwired implementations, and code comments naming a known gap. The team's actual
priorities may differ.
## Explicit `TODO` markers
Every `TODO` in the repository is in the ArgoCD manifests — three per
environment, identical across `dev`, `staging`, `prod`:
| File | Line | TODO |
|---|---|---|
| `infra/argocd/applications/{env}/app.yaml` | 7 | confirm the team's ArgoCD project/RBAC scope |
| same | 9 | confirm the repo URL once the repo is created |
| same | 17 | point `destination.server` at the team's target cluster |
There are **no** `TODO`/`FIXME` comments in any Python or TypeScript source
file.
## Explicit `NotImplementedError`
| Command | File | Declared purpose |
|---|---|---|
| `ingestion.cli visual-diff` | `ingestion/ingestion/cli.py:435` | Render a page with detected boundaries overlaid |
| `ingestion.cli scaffold-golden` | same | Draft golden-set entries for human review |
Both raise deliberately rather than silently no-op-ing, and both are covered by
`tests/test_cli.py`.
## Placeholder services (README + package.json, no source)
| Path | README describes |
|---|---|
| `apps/api-gateway` | Public entry point, routing, JWT validation, rate limiting |
| `apps/auth-service` | Signup/login, password hashing, JWT issue/refresh |
| `apps/user-service` | Profiles, preferences, account settings |
| `apps/chat-service` | Session lifecycle, message-history persistence |
| `apps/mobile` | README + `.gitkeep` only |
## Empty scaffolding directories
| Path | Contents |
|---|---|
| `infra/k8s/base/{ai-service,api-gateway,auth-service,chat-service,postgres,qdrant,redis,user-service,web}` | `.gitkeep` |
| `infra/k8s/overlays/{dev,staging,prod}` | `.gitkeep` |
| `infra/terraform/envs/{dev,staging,prod}` | `.gitkeep` |
| `infra/terraform/modules/{k8s-cluster,managed-postgres,networking,object-storage,secrets}` | `.gitkeep` |
| `docs/runbooks/` | `.gitkeep` |
| `packages/config/eslint-preset/` | `.gitkeep` |
| `packages/shared-types/src/events/` | `.gitkeep` — implies an event-driven design that does not exist |
| `ingestion/data/{interim,qa}/` | `.gitkeep` |
| `ingestion/notebooks/` | `.gitkeep` |
## Promised-but-absent CI workflows
`infra/ci/github-actions/README.md` names five workflows as "not yet functional
— filled in during Phase 6". None exists:
`ai-service-ci.yml`, `node-services-ci.yml`, `web-ci.yml`, `ingestion-ci.yml`,
`bump-image-tag.yml`.
`bump-image-tag.yml` is the linchpin of the GitOps flow the same README
describes, so that flow cannot run.
## Implemented but never called
Found by import-graph analysis, not by comment:
| Code | Capability it would add | Status |
|---|---|---|
| `rag/fusion.py::reciprocal_rank_fusion` | Hybrid dense+lexical retrieval | Tested, no caller |
| `rag/expansion.py::expand_siblings` | Bounded adjacent-chunk expansion | Tested, no caller |
| `rag/calculators.py::body_surface_area_m2` | BSA-based dosing without reading a quarantined table — the docstring says that is exactly why it was written | Tested, no caller |
| `rag/condition_evaluation.py::summarize_condition_outcomes` | The full condition→drug metric suite | Tested, no runner |
| `rag/evaluation.py::summarize` | Retrieval metrics | Only `run_eval.py`, which uses in-memory stores |
| `rag/routing.py::QueryRoutingService.retrieve` | Legacy text-resolution path | Reached only when `ANSWER_PROVIDER=disabled` |
| `adapters/bedrock_claude.py` | Anthropic Messages generation path | Selectable via `ANSWER_PROVIDER=bedrock-claude`; not the configured provider |
| `ingestion/embed/{bedrock_titan,local_bge_m3,benchmark_local,probe}.py` | Alternative embedding providers + a local benchmark | Tested; `cohere-v4` is what the corpus was built with |
| `Golden Dataset/*.csv` | 209 labelled evaluation rows | Read by no code |
| `duocthu_loop_*`, `duocthu_followup_inherited_total` | Metrics for the retired ADR 0007 loop | Registered, never incremented |
| `atc_codes` payload index | ATC-scoped filtering | Indexed, never queried |
| `parent_id` / `ParentStore` hydration | Parent-document retrieval | No chunk sets `parent_id` |
| `infra/docker/docker-compose.yml` `redis` service | Cache / rate-limit counters / job queue | No client imported anywhere |
## Gaps the code names about itself
Each is a written comment, not an inference:
| Gap | Source |
|---|---|
| "a real pool, with startup-time lifecycle, is a further improvement not made here" | `adapters/postgres.py` (F-09) |
| Conversation history durability — `_last_frame`/`_clarify_streak` still in-process | `rag/agent.py`, ADR 0008 |
| The budget "cannot cancel a call already in flight; a hard per-call cancellation would need cooperative cancellation support" | `rag/budget.py` |
| Rate limiting "needs to move to Redis … or to the gateway" once `web` scales | `apps/web/middleware.ts` |
| `/metrics` "stops being safe the moment the service is exposed through an Ingress, which the Helm chart now makes possible" | `apps/ai-service/main.py` |
| "the real fix (streaming verified claims as they land)" for the long wait | `apps/web/app/_components/ChatPanel.tsx` |
| `rag/agent.py` "should consolidate onto this module once the new orchestrator is wired", re. the duplicate non-human keyword list | `rag/policy.py` |
| Header rows kept out of retrieval "until a reviewed logical-table artifact can prove which row is a header" | `ingestion/chunk/chunker.py` |
| Not proven by the gates: content accuracy vs the source, table row/column reconstruction, borderless-table and bar-less-formula recall | `ingestion/cli.py::_cmd_chunk_ready` output |
| Temporary timing instrumentation added 2026-08-07 for a specific bug | `rag/agent.py::handle` |
## What a code-derived backlog looks like
Ordered by what the repository itself makes cheapest and most consequential —
cross-referenced to [27-technical-debt.md](27-technical-debt.md):
1. Run the existing 555 tests in CI before deploying (D-01).
2. Commit `.env.example` and a `conftest.py` so the suite runs out of the box
(D-05, D-06).
3. Wire one of the existing eval sets to one of the existing metric summarisers
(D-10).
4. Persist `_last_frame`/`_clarify_streak`, or state the single-replica
constraint (D-04).
5. Decide the fate of `calculators.py`, `fusion.py`, `expansion.py` and the four
dead metrics (D-12, D-13).
6. Backups (D-03) and a real credential (D-02).
Items 13 are wiring existing, tested code. None of them is new design.