@@ -5,6 +5,72 @@ follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/) and
55the project uses [ CalVer] ( https://calver.org/ ) (YY.MM.PP) per the
66Firefly Framework convention (memory: ` firefly_uses_calver ` ).
77
8+ ## [ 26.5.12] - 2026-05-28
9+
10+ ### Fixed — Re-upload pipeline correctness + LLM rename detection
11+
12+ Four cooperating bug fixes uncovered during multi-version re-upload
13+ testing of the same workbook. No public API or response-shape change:
14+ the PUT endpoint URL, multipart contract and ` ReuploadResponse `
15+ DTO are byte-equivalent to ` 26.5.11 ` , so the Python and Java SDKs
16+ keep working without regeneration.
17+
18+ 1 . ** ` PUT /api/v1/datasets/{ds}/tables/{tbl}:upload ` no longer
19+ corrupts the targeted snapshot of a multi-section workbook.**
20+ ` IngestService.ingest_reupload ` now looks up the existing table's
21+ ` sheet_or_json_path ` and sanitised ` name ` (single PK lookup) and
22+ threads them into Stage 2. ` run_parse ` filters the proposed-table
23+ list down to the matching section, with fallback by sanitised name
24+ so a row insertion that shifts the section range
25+ (` section[1:697] ` → ` section[1:698] ` ) still resolves correctly.
26+ Before the fix, the parser kept whatever section came first in the
27+ workbook (usually Sheet1), silently overwriting the targeted
28+ table's snapshot with unrelated data.
29+
30+ 2 . ** LLM rename-detection agent is actually invoked.** Both call
31+ sites of ` run_reconcile ` (` IngestService.ingest ` sync path and
32+ ` IngestWorker ` async path) now forward ` settings=self._settings ` .
33+ Without this, ` _invoke_rename_agent ` short-circuited on
34+ ` if settings is None: return None ` , so the Haiku-backed rename
35+ resolver never ran and every ambiguous removed-column landed as a
36+ ` RENAMED_CANDIDATE ` for human review instead of being auto-confirmed.
37+
38+ 3 . ** ` flyquery_schema_changes.llm_rationale ` is persisted.**
39+ ` _invoke_rename_agent ` now returns the full ranked list
40+ (` [{name, confidence, rationale}, ...] ` ) instead of just the top
41+ ` (confidence, name) ` tuple. ` _detect_renames ` returns a third
42+ ` confirmed_rationales ` map keyed by old column name.
43+ ` _write_schema_changes ` writes the rationale into ` RENAMED ` rows
44+ (LLM rationale or "Auto-confirmed by 1-to-1 type signature match"
45+ for the unambiguous branch) and into ` RENAMED_CANDIDATE ` rows
46+ (rationale of the top proposal hoisted for fast audit).
47+
48+ 4 . ** ` RENAMED_CANDIDATE.after_json.candidates ` carries the LLM's
49+ ranking.** When the top proposal misses the 0.8 auto-confirm
50+ threshold, the system now stores the ranked
51+ ` [{name, confidence, rationale}] ` list from the agent. The old
52+ behaviour stored the raw type-group of added columns with no
53+ discrimination — every ` RENAMED_CANDIDATE ` for the same type
54+ showed the same flat list. Operators reviewing pending renames
55+ now see "best guess first" with the confidence and rationale per
56+ alternative.
57+
58+ ### Changed — Internal-only
59+
60+ - ` run_parse ` accepts two new keyword params: ` target_sheet_or_json_path `
61+ and ` target_name ` . Both default to ` None ` , so call sites that didn't
62+ ask for targeted-section selection are unaffected. The OpenAPI
63+ surface is unchanged.
64+ - ` _detect_renames ` signature changed from
65+ ` tuple[dict, list] ` to ` tuple[dict, dict, list] ` . Internal helper;
66+ not exported. Callers updated in the same change.
67+
68+ ### Fixed — CI
69+
70+ - ` ruff format ` on ` stages/parse.py ` and ` stages/reconcile.py `
71+ (line-length wrapping). Caught by the ` task lint ` step on the
72+ ` 26.5.11 ` PR; rewrapped without behavior change.
73+
874## [ 26.5.11] - 2026-05-24
975
1076### Added — Webhook callbacks for every async ingest job
0 commit comments