Rifqi Hafizuddin commited on
Commit Β·
e0384e1
1
Parent(s): 9bd8ec5
[NOTICKET] Add revision plan md file
Browse files- DEV_PLAN.md +119 -0
DEV_PLAN.md
ADDED
|
@@ -0,0 +1,119 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Data Eyond β Current Development Plan (post 2026-06-24 meeting)
|
| 2 |
+
|
| 3 |
+
**Purpose:** context file for Claude Code sessions working on the current sprint.
|
| 4 |
+
**Branch:** `pr/4` Β· **Snapshot:** 2026-06-25.
|
| 5 |
+
**Companion:** [REPO_STATUS.md](REPO_STATUS.md) describes the repo's *current built state*; this file
|
| 6 |
+
describes the *in-flight plan* that changes it.
|
| 7 |
+
|
| 8 |
+
---
|
| 9 |
+
|
| 10 |
+
## 1. The direction change (locked decisions from 2026-06-24)
|
| 11 |
+
|
| 12 |
+
1. **"Problem statement" is replaced by two user-entered fields: `objective` + `business_questions`.**
|
| 13 |
+
User fills them at onboarding; **both mandatory to submit; NO agent validation.**
|
| 14 |
+
2. The **gate (`problem_validated`) and the `problem_statement` skill/intent are removed** (comment out, don't delete).
|
| 15 |
+
3. **Report is records-based** (reads persisted `AnalysisRecord`s) β **decided and pushed** (KM-674).
|
| 16 |
+
It is formal markdown: title, date, "generated by {user}", objective, business questions,
|
| 17 |
+
findings, insights. **NOT gated** on whether business questions were answered.
|
| 18 |
+
4. **`owner_id` β `user_id`** everywhere (Harry mirrors in dedorch/Go).
|
| 19 |
+
5. **State writes go through a request to Go**, not direct Python DB writes.
|
| 20 |
+
6. **FE-callable surface = 4 endpoints:** `call_agent` (chat/stream), `list_skills` (`GET /tools`),
|
| 21 |
+
**skill: help**, **skill: report**. `problem_statement` removed; `check_data` not FE-facing from
|
| 22 |
+
Python (Go provides it); analysis CRUD not needed from FE (comment, don't delete).
|
| 23 |
+
7. Deliverables for Harry: (a) API endpoint doc (MD); (b) full Python project doc (MD β PDF/Word BRD).
|
| 24 |
+
8. Integration tested via Swagger `/docs` on the HF Python build (simulating FE manually). Target ~Wed.
|
| 25 |
+
|
| 26 |
+
## 2. What is already done (KM-674, pushed on `pr/4`)
|
| 27 |
+
|
| 28 |
+
Report layer adapted to the new goal shape:
|
| 29 |
+
- `report/schemas.py::ProblemStatement` β `objective: str` + `business_questions: list[str]`
|
| 30 |
+
(old `target_value`/`scope`/`metric_direction`/`target_metric` dropped). Class name kept for now
|
| 31 |
+
(rename to `ReportGoal` once the upstream AnalysisState rename lands).
|
| 32 |
+
- `report/generator.py` renders **Objective** + numbered **Business Questions** + a
|
| 33 |
+
**"generated by {user}"** line.
|
| 34 |
+
- `api/v1/report.py::_problem_statement_from` is **tolerant**: prefers new `objective` /
|
| 35 |
+
`business_questions` from state, falls back to legacy `problem_statement` β works before AND after
|
| 36 |
+
Harry's migration.
|
| 37 |
+
- `config/prompts/report_summary.md` updated to objective + business questions.
|
| 38 |
+
- Report stays **records-based**; the floor gate (`problem_validated`) was deliberately left for task #2.
|
| 39 |
+
|
| 40 |
+
**This tolerant-migration pattern (getattr fallback) is the model for tasks #2 and #4.**
|
| 41 |
+
|
| 42 |
+
## 3. Assessment β gaps & contradictions to resolve before building
|
| 43 |
+
|
| 44 |
+
These came out of reviewing the plan against the actual code. They are folded into the task table (Β§4) as tasks 15β19.
|
| 45 |
+
|
| 46 |
+
- **G1 (β task 15). Records-based reports need the slow path ON.** `AnalysisRecord`s persist only in
|
| 47 |
+
`chat_handler._run_slow_path`, which runs only when `ENABLE_SLOW_PATH=true`. Default is off β no
|
| 48 |
+
records β `POST /report` 409s. The Swagger demo can't show a non-empty report unless slow path is
|
| 49 |
+
flipped on and a `structured_flow` question is run first. `BusinessContext` is still a stub but the
|
| 50 |
+
slow path runs fine on it.
|
| 51 |
+
- **G2 (β task 16). `analysis_records` ownership is now required and collides with `SKIP_INIT_DB`.**
|
| 52 |
+
It's created today by Python `create_all` (`db/postgres/init_db.py`), is in no dedorch/Go migration,
|
| 53 |
+
and after the dedorch cutover (`SKIP_INIT_DB=true`) Python stops running `create_all` β the table
|
| 54 |
+
won't exist β reports break. Decide: dedorch migration (Harry) OR a Python carve-out that creates
|
| 55 |
+
just this one table even under `SKIP_INIT_DB`.
|
| 56 |
+
- **G3 (β task 17). `chat_history` in the report contract is vestigial.** Records-based generation
|
| 57 |
+
reads records by `analysis_id`; it never uses chat history. Drop `chat_history` from the report
|
| 58 |
+
skill contract, or mark it reserved/unused.
|
| 59 |
+
- **G4 (β task 4 note). Make #2/#4 tolerant of both state shapes.** If Harry drops
|
| 60 |
+
`problem_validated`/`owner_id` from dedorch before Python stops reading them, Python's gate +
|
| 61 |
+
state_store break. Use the same `getattr` tolerance KM-674 used. The `owner_id`β`user_id` rename
|
| 62 |
+
also touches `api/v1/analysis.py` (`_serialize_state`, `list_analyses`, `get_analysis`), not just
|
| 63 |
+
the model + state_store.
|
| 64 |
+
- **G5 (β task 18). "State writes via Go" is bigger than `report_id`.** Python still writes state in
|
| 65 |
+
`/analysis/create` (state + room + bindings, plus the data-first gate and soon the mandatory-field
|
| 66 |
+
check) and in `state_store.ensure` per turn. If creation moves to Go (consistent with commenting
|
| 67 |
+
analysis CRUD), then Go owns ALL state writes + both creation gates, and Python's `ensure` must
|
| 68 |
+
become a **read-only get** (Go must guarantee the row exists before any chat turn).
|
| 69 |
+
- **G6 (smaller).**
|
| 70 |
+
- Removing `problem_statement` (task 1) means neutering it in 4 places: the `Intent` literal
|
| 71 |
+
(`agents/orchestration.py`), the router prompt (`config/prompts/intent_router.md`), the handler,
|
| 72 |
+
and the gate's redirect *target*. Do it with task 2.
|
| 73 |
+
- "generated by {user}" currently prints the raw `user_id`; a formal report wants a name β source
|
| 74 |
+
from `users.fullname` or have Go pass a display name (task 19).
|
| 75 |
+
- The meeting's outline (background / EDA / insights) isn't fully in the renderer; map those
|
| 76 |
+
sections onto the record fields deliberately (task 5 follow-up).
|
| 77 |
+
- The full project doc (task 11) should reuse [REPO_STATUS.md](REPO_STATUS.md), not restart.
|
| 78 |
+
|
| 79 |
+
## 4. Task table
|
| 80 |
+
|
| 81 |
+
Status legend: β¬ not started Β· π in progress Β· β
done Β· β blocked Β· π verify.
|
| 82 |
+
|
| 83 |
+
| # | Task | Owner | Status | Note |
|
| 84 |
+
|---|---|---|---|---|
|
| 85 |
+
| 1 | Comment out `problem_statement` skill **+ `Intent` literal + router prompt + gate redirect target**; remove `/problem-statement` from `list_tools` | Rifqi | β¬ | Do with #2 β 4 places name it |
|
| 86 |
+
| 2 | Drop `problem_validated`: gate β identity/presence-check (or remove); `is_report_ready` β presence(`objective` + β₯1 `business_question`) + β₯1 analysis, no-LLM | Rifqi | β¬ | Merges Sofhia 2+3. Make reads tolerant (getattr) |
|
| 87 |
+
| 3 | dedorch `analysis` migration: drop `problem_statement`/`problem_validated`, add `objective` + `business_questions`, rename `owner_id`β`user_id` | Harry | β¬ | Blocks #4 |
|
| 88 |
+
| 4 | Update Python `analysis` model + `state_store` + `analysis.py` to match #3; `owner_id`β`user_id` | Rifqi/Sofhia | β after #3 | getattr-tolerant so deploy order isn't a hard blocker |
|
| 89 |
+
| 5 | Report generator β `objective`+`business_questions`, "generated by {user}", formal outline | Sofhia | π pushed (KM-674) | Goal-shape done. Open: author name source (#19); background/EDA/insights mapping |
|
| 90 |
+
| 6 | Report skill input contract: `analysis_id` + `user_id` (+ `chat_history`?) | Sofhia/Rifqi | β¬ | Records-based β chat_history unused β see #17 |
|
| 91 |
+
| 7 | `report_id` state update via request to Go, not direct DB | Sofhia + Harry | β¬ | Needs Go endpoint. See #18 for the rest of the writes |
|
| 92 |
+
| 8 | Expose/confirm 4 FE endpoints; comment `check_data` + analysis CRUD | Sofhia | β¬ | Confirm `help` via `call_agent` (recommended) vs own endpoint |
|
| 93 |
+
| 9 | Verify `analysis_id` in `call_agent` contract | Sofhia | π | Present as `room_id` (== `analysis_id`); document the equivalence |
|
| 94 |
+
| 10 | API endpoint doc (MD), 4 endpoints, for Go integration | Rifqi + Sofhia | β¬ | β |
|
| 95 |
+
| 11 | Full Python project doc (MD β PDF/Word BRD) | Rifqi | β¬ | Reuse REPO_STATUS.md as the base |
|
| 96 |
+
| 12 | Reconcile/open the `list_tools` PR cleanly (stacked commits) | Rifqi | β¬ | β |
|
| 97 |
+
| 13 | Merge HF Python build β test 4 endpoints via Swagger | Sofhia + Harry | β¬ | Not E2E. Blocked by #15 |
|
| 98 |
+
| 14 | `analysis_records` home | Rifqi + Sofhia + lead | β¬ β required | Records-based decided β no longer conditional; see #16 |
|
| 99 |
+
| 15 | Flip `ENABLE_SLOW_PATH=true` on HF + verify an `AnalysisRecord` persists from a `structured_flow` question | Rifqi | β¬ new | Precondition for any report demo (#13) |
|
| 100 |
+
| 16 | Decide `analysis_records` creation under `SKIP_INIT_DB`: dedorch migration (Harry) or Python carve-out | Rifqi + Harry | β¬ new | Table won't exist post-cutover otherwise |
|
| 101 |
+
| 17 | Reconcile report contract with records-based: remove/flag `chat_history` | Sofhia/Rifqi | β¬ new | Resolves #5 β #6 contradiction |
|
| 102 |
+
| 18 | Confirm Go owns ALL analysis-state writes + both creation gates; make Python `state_store.ensure` read-only | Rifqi + Harry | β¬ new | Extends #7 to the full decision #4 (G5) |
|
| 103 |
+
| 19 | Decide report author display-name source (`users.fullname` vs Go-passed name) | Sofhia | β¬ new | Raw `user_id` in a formal report looks unprofessional |
|
| 104 |
+
|
| 105 |
+
## 5. Critical path & sequencing
|
| 106 |
+
|
| 107 |
+
- **Critical path:** #3 β #4 (de-risked by getattr tolerance). #15 + #16 β #13.
|
| 108 |
+
- **Parallelizable now (no blockers):** #1+#2 (together), #8, #10, #11, #12.
|
| 109 |
+
- **Harry-blocked:** #3 (blocks #4), #7 (Go endpoint), #16/#18 (dedorch + Go ownership).
|
| 110 |
+
- **Demo gate for Wednesday (#13):** slow path on (#15) + records table exists (#16) + report contract
|
| 111 |
+
settled (#17). Without #15/#16 the report endpoint 409s in Swagger.
|
| 112 |
+
|
| 113 |
+
## 6. Decisions still open (need the team / Harry / lead)
|
| 114 |
+
|
| 115 |
+
- `analysis_records`: dedorch-owned vs Python-owned-with-carve-out (#16/#14).
|
| 116 |
+
- Whether `help` is its own endpoint or via `call_agent` (#8).
|
| 117 |
+
- Author display-name source for the report (#19).
|
| 118 |
+
- Confirm Go takes over analysis creation + both creation gates (data-first + mandatory fields) (#18).
|
| 119 |
+
- Keep vs drop `chat_history` in the report contract (#17).
|