Originally created by: pyy3
Resolves the =EPM() client-drift half of [#28], split out of [#34] so it can be reviewed/merged on its own (it's the one change that couldn't be runtime-tested here).
The Office.js add-in (taskpane.js) budget-refresh path had drifted from the konsol.api.epm_batch contract:
{queries: [...]} instead of a bare JSON arrayfiscal_year doctype key instead of the API's yeardata.message as an array instead of data.message.valuesAll three are corrected. OpenEPM.bas (VBA) was already correct.
docs/reference/epm-formula-protocol.md — single source of truth for the =EPM() wire contract both clients implement.tests/test_epm_client_parity.py — pins the contract for both clients (7 tests, pass) so they can't silently drift again.This is runtime-untested — there's no Excel/Office.js runtime in the build environment. The change is strictly closer to the API contract than the broken original, but please smoke-test the add-in's budget refresh in Excel before merging.
Companion to [#34] (security + design), which keeps the rest of [#23]–#31. This PR is independent — branched off
main, no overlap with [#34]'s files.
🤖 Generated with Claude Code
Closes [#28].
Ticket changed by: grynn-in