Rifqi Hafizuddin Claude Opus 5.5 commited on
Commit
1acca72
Β·
1 Parent(s): ac68af5

[NOTICKET] docs(plans): report reframe and prompt cleanup plan

Browse files

Question-anchored report with a scope section and an appendix ledger (Phase 1 is
generator-only), and the prompt P0/P1 items from the 2026-10-28 reviews. Open
decisions in section 6.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

docs/README.md CHANGED
@@ -59,6 +59,7 @@ Roll-up status: DEV_PLAN Β§0.8 Β· built state: REPO_STATUS Β§14 Β· eval harness:
59
  | [plans/PR2_EVALUATION.md](plans/PR2_EVALUATION.md) | πŸ”„ | **Read before PR-3.** Four layers, three of them free. Establishes that **14 of 14** tools have zero output-correctness coverage |
60
  | [plans/PR3_REPAIR_EDGE.md](plans/PR3_REPAIR_EDGE.md) | πŸ”„ | The feedback edge (trigger B, budget 1) **gated on measured hit-rate**, plus the determinism fixes that ship regardless |
61
  | [plans/PR23_PART2_PLANNER_EVAL.md](plans/PR23_PART2_PLANNER_EVAL.md) | πŸ”„ | **pr/23 part 2 (2026-09-23).** Planner, router and eval work re-checked against the code: measurement first, then router, retrieve-then-plan, planner structure. **A–E done 2026-09-23** (D4 reverted, F1 optional) |
 
62
  | [plans/UNSTRUCTURED_V2_PLAN.md](plans/UNSTRUCTURED_V2_PLAN.md) | πŸ”„ | **The demo track (2026-09-23).** Parsing v2 β†’ embeddings, private images via 1h signed URLs, analysis-scoped retrieval, the mixed structured+unstructured path **without a new intent**. Pre-empts the prompt-architecture work |
63
 
64
  ---
 
59
  | [plans/PR2_EVALUATION.md](plans/PR2_EVALUATION.md) | πŸ”„ | **Read before PR-3.** Four layers, three of them free. Establishes that **14 of 14** tools have zero output-correctness coverage |
60
  | [plans/PR3_REPAIR_EDGE.md](plans/PR3_REPAIR_EDGE.md) | πŸ”„ | The feedback edge (trigger B, budget 1) **gated on measured hit-rate**, plus the determinism fixes that ship regardless |
61
  | [plans/PR23_PART2_PLANNER_EVAL.md](plans/PR23_PART2_PLANNER_EVAL.md) | πŸ”„ | **pr/23 part 2 (2026-09-23).** Planner, router and eval work re-checked against the code: measurement first, then router, retrieve-then-plan, planner structure. **A–E done 2026-09-23** (D4 reverted, F1 optional) |
62
+ | [plans/REPORT_AND_PROMPT_PLAN.md](plans/REPORT_AND_PROMPT_PLAN.md) | πŸ’‘ | **2026-10-28.** Report reframe (question-anchored, scope section, appendix ledger; Phase 1 generator-only) + prompt cleanup (one home per fix, P0 token cuts). Open decisions in Β§6 |
63
  | [plans/UNSTRUCTURED_V2_PLAN.md](plans/UNSTRUCTURED_V2_PLAN.md) | πŸ”„ | **The demo track (2026-09-23).** Parsing v2 β†’ embeddings, private images via 1h signed URLs, analysis-scoped retrieval, the mixed structured+unstructured path **without a new intent**. Pre-empts the prompt-architecture work |
64
 
65
  ---
docs/plans/REPORT_AND_PROMPT_PLAN.md ADDED
@@ -0,0 +1,148 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Report reframe + prompt cleanup β€” plan
2
+
3
+ <!-- doc-status -->
4
+ > πŸ’‘ **PROPOSAL β€” agreed direction, not yet built (2026-10-28).** Report first (Phase 1),
5
+ > then the prompt P0 items. Items marked **DECISION** need Rifqi/team sign-off before work starts.
6
+
7
+ **Branch context:** `pr/25`. **Why now:** the SDJ / OB HAULER end-to-end test (2026-10-27,
8
+ live Space) produced a report whose defects all came from *accumulation* β€” every chat turn
9
+ copied in, including wrong and contradictory ones β€” and two independent reviews (2026-10-28)
10
+ reached the same diagnosis for the report and for the prompts. Defects of that test are logged
11
+ as #27–#32 in [AGENTIC_DRY_RUN_LOG.md](../testing/AGENTIC_DRY_RUN_LOG.md).
12
+
13
+ ---
14
+
15
+ ## 1. Diagnosis
16
+
17
+ **Report.** It reads as a transcript, not a report. The design guards one risk (the report-time
18
+ LLM inventing numbers) and that risk caused none of the SDJ defects. They entered upstream or in
19
+ selection, and the report certified them:
20
+
21
+ | Defect in the SDJ report | Enters at |
22
+ |---|---|
23
+ | Scope drift: no site filter, `week 1–6` as Jan–Jun, a follow-up dropped site and year | Planner IR (the report never sees filters) |
24
+ | Two contradictory answers to the same question both included (HDKM46049 vs HDKM46087; DRIVE SYSTEMS vs ENGINE) | Accumulation β€” no supersession or conflict check |
25
+ | "Most breakdowns" answered with the highest *average* over 7 rows | Metric/question fit β€” not checked |
26
+ | "Answered" on 5 periods, on the wrong metric, on leaky drivers | Status decided by the LLM alone |
27
+ | Target leakage as "drivers" (`mttr_usm` explains `mttr`) | `analyze_importance` guards train/test leakage only |
28
+ | Site-id lookup (`2005`) shown 6Γ—, raw model inputs as evidence | `_collect_evidence`: any table ≀ 8 columns qualifies |
29
+ | Garbled text, "chart displayed successfully" as findings | Copied verbatim (INV-4) |
30
+ | Data Sources lists all 16 tables / 315 columns | Lists the catalog, not what was queried |
31
+
32
+ INV-4 ("findings copied verbatim") keeps the report faithful to the chat, not to the data:
33
+ findings are Assembler prose. Real provenance is already persisted per tool output
34
+ (`meta.query`, `meta.table_name`, `meta.row_count`, `tools/data_access.py`).
35
+
36
+ **Prompts.** Sound design, but `planner.md` is growing one incident at a time again
37
+ (6,023 β†’ 7,142 tokens since 2026-09-22). Rules live in three places (prose + example +
38
+ validator). Tool descriptions contradict `planner.md` (`analyze_aggregate` "total per region",
39
+ `aggregation.py:83`). 11 of 27 examples open with `check_data`, against "smallest plan".
40
+ Incident-specific text in general prompts. Document context placed before the catalog breaks
41
+ prefix caching. A planner call is ~22–23.5k input tokens, ~15k of it instructions + examples.
42
+
43
+ ## 2. Target report shape
44
+
45
+ Question-anchored, two layers: a short main body (β‰ˆ 2 pages) + an appendix ledger. Records stay
46
+ the input (the locked decision holds through Phase 2).
47
+
48
+ | Β§ | Section | Built by |
49
+ |---|---|---|
50
+ | 1 | Thesis title (one line) + meta | LLM title (checked numbers only), code meta |
51
+ | 2 | Executive summary (3–5 sentences) | LLM, verified numbers only |
52
+ | 3 | **Scope & data**: period actually covered, filters, tables queried, rows, coverage gaps | **Code** (from stored queries) |
53
+ | 4 | **Answers by business question**: answer, status (code may only lower it, with a reason), metric named, one evidence table | LLM drafts, code caps + picks evidence |
54
+ | 5 | Conflicts (only when present) | Code detects, LLM one line |
55
+ | 6 | Limitations + "what this report does not claim" | Code-detected flags + fixed text |
56
+ | 7 | Next analyses to run (as chat prompts) | LLM |
57
+ | 8 | Charts (deduped) | Code |
58
+ | A | **Appendix: analysis ledger** β€” one row per turn: question, tables, filters, rows, tools, flags, superseded-by | **Code only** |
59
+
60
+ Not copied from Julius: the generic 30-day playbook, the 11-page length, hypotheses presented as
61
+ recommendations.
62
+
63
+ ## 3. Report work items
64
+
65
+ Type: Code = deterministic Β· Prompt Β· Handoff = outside this repo. Verify: free = local tests /
66
+ fixture; smoke = small paid subset.
67
+
68
+ ### Phase 1 β€” `src/agents/report/` only; no Go/FE/schema; no extra LLM calls
69
+
70
+ | ID | Item | Type | Verify | Status |
71
+ |---|---|---|---|---|
72
+ | R1 | Evidence filter: drop 1-row lookups and raw model inputs, dedupe identical tables, title in the report language | Code | free | ⬜ |
73
+ | R2 | Data Sources = tables actually queried + rows returned | Code | free | ⬜ |
74
+ | R3 | Scope fingerprint: read-only sqlglot parse of each stored `meta.query` β†’ tables / filters / group-by / limit | Code | free | ⬜ |
75
+ | R4 | Appendix A: analysis ledger | Code | free | ⬜ |
76
+ | R5 | Status caps (scope mismatch, small sample, conflict, leakage name-check), code-appended reason | Code | free | ⬜ |
77
+ | R6 | Number tracing against stored results; untraced β†’ "unverified" (snapshots keep 10 rows, so mark, don't delete). Reuse the `eval/faithfulness` matcher as a shared module | Code | free | ⬜ |
78
+ | R7 | Text sanity filter: unexpected scripts, tool-success narration | Code | free | ⬜ |
79
+ | R8 | Compact "Scope & limitations" + fixed non-claims footer. **DECISION: reverses the 2026-07-09 "compact report" drop** | Code | free | ⬜ |
80
+ | R9 | `report_summary.md`: feed scope + flags, name the metric per question, allow "inconclusive", thesis title. **First** build a free fixture check from the SDJ v2 records (no eval covers this prompt today) | Prompt | fixture + 1 smoke | ⬜ |
81
+
82
+ ### Phase 2 β€” Python, touches the Assembler and the stored record shape
83
+
84
+ | ID | Item | Type | Note |
85
+ |---|---|---|---|
86
+ | R10 | Tag each turn with the business question it answers, at turn time | Prompt + Code | |
87
+ | R11 | Supersession (a later, tighter analysis replaces an earlier one) + Conflicts section | Code | |
88
+ | R12 | Store all numbers a turn saw (fact sheet), not 10 rows | Code | Ask Harry whether it fits `report_inputs` jsonb |
89
+ | R13 | Findings as templates with cell references; code renders numbers | Prompt + Code | `assembler.md` β†’ chat_sim smoke + faithfulness eval |
90
+ | R14 | Per-question layout | Code | |
91
+ | H1 | FE: choose analyses before Generate (the `exclude_record_ids` API exists), show status reasons, collapsible appendix | Handoff | FE via Rifqi |
92
+
93
+ ### Phase 3 β€” opt-in "Deep report"
94
+
95
+ | ID | Item | Type | Note |
96
+ |---|---|---|---|
97
+ | R15 | Report-planning agent re-queries through the existing planner/IR pipeline (fair per-exposure comparisons, stability tests, uncertainty); ≀ 8 tasks, token cap, degrades to Phase 2 | Code + Prompt | **DECISION: reverses the locked "records-based" decision.** ~120–250k tokens per report |
98
+ | H2 | Background job + progress (the HF proxy times out long requests β€” cf. the ingest 502) | Handoff | Harry + FE |
99
+
100
+ ## 4. Prompt work items
101
+
102
+ ### P0 β€” cheap
103
+
104
+ | ID | Item | Type | Saves | Verify | Status |
105
+ |---|---|---|---|---|---|
106
+ | P1 | **One home per fix**: validator if checkable, example if a plan shape, prose only for judgment | Process | prevents growth | β€” | ⬜ |
107
+ | P2 | Strip HTML comments when prompts load (`help.md` sends a 719-token changelog every call) | Code | ~950 tok/call | free + 1 smoke per prompt | ⬜ |
108
+ | P3 | Move `# Document context` to just before `# Question` (`planner/prompt.py:208-229`) | Code | caching of ~10–12k tok | free + planner smoke | ⬜ |
109
+ | P4 | Remove the `check_data` opener from examples A–M | Prompt | ~700 tok/call | `--only` ~6 cases | ⬜ |
110
+ | H3 | Tool descriptions contradicting `planner.md` (`analyze_aggregate` "total per region"; "plot revenue by region") | Handoff | β€” | tools owner | ⬜ |
111
+
112
+ ### P1 β€” consolidation (one approved run)
113
+
114
+ | ID | Item | Verify |
115
+ |---|---|---|
116
+ | P5 | Drop prose for rules the validator already enforces (top-1 limit, typed ids, capped importance, args, aliases) | ~30-case run (~720k) β€” **DECISION: spend approval** |
117
+ | P6 | Merge the "can't answer" rule (restated ~8Γ—) | same run |
118
+ | P7 | Remove incident-specific text ("kalo di XYZ", "site ABC", hard-coded 10,000-row budget, EXHC36007 in `assembler.md`) | same run + chat smoke |
119
+ | P8 | Add ~6 "can't answer" eval cases first (2 of 68 today) | free to write |
120
+
121
+ Target after P0 + P1: `planner.md` ~7.1k β†’ ~5k tokens, 15–20% fewer tokens per planner call,
122
+ no known contradictions.
123
+
124
+ ### P2 β€” later
125
+
126
+ | ID | Item |
127
+ |---|---|
128
+ | P9 | Bug #30 (score direction) as catalog metadata ("lower is worse"), not another prose rule |
129
+ | P10 | Select examples by relevance instead of sending the whole group |
130
+
131
+ Keep: stable/dynamic split, group-scoped tools and examples, data fencing, retry-error placement,
132
+ paired feasible/infeasible examples, guard/guardrails/report prompts.
133
+
134
+ ## 5. Order of work
135
+
136
+ 1. Report Phase 1: R1 + R2 β†’ R3 + R4 β†’ R5 + R7 β†’ R6 β†’ R8 (after DECISION) β†’ R9.
137
+ 2. Prompt P2 + P3 (free/smoke), then P4.
138
+ 3. Handoffs H1–H3 sent by Rifqi.
139
+ 4. Phase 2 / P1 consolidation after Phase 1 is in use.
140
+
141
+ ## 6. Open decisions
142
+
143
+ | Decision | Owner |
144
+ |---|---|
145
+ | Bring back a compact limitations section (R8) | Rifqi / team |
146
+ | Deep report re-querying data (R15) | Rifqi / team / mentor |
147
+ | Spend for the P1 consolidation eval (~720k tokens) | Rifqi |
148
+ | Leakage guard inside `analyze_importance` | Tools owner, via Rifqi |