reconify.yaml file: sources (where files live and how to parse them), pairs (which two sources to compare and under what rules), and optional index settings for large files. Get it right once and every later run is a single command.
Three ways to get a configuration file
Infer it
reconify.engine.config-proposal.v1 document with candidate date, amount, and reference mappings, and writes reconify.yaml only when it is confident in all three. If it isn’t, the command returns needs_input, names the column it couldn’t resolve, and (with --out set) exits 2 without writing anything.
The usual fix is to open the YAML it half-wrote and name the ambiguous column yourself, then run config validate to confirm.
See Run it with an agent for the exact confidence gates.
The minimum shape is two sources and one pair:
bank stores amounts in major units (123.45), so multiplier: 100 converts 123.45 into 12345 minor units. ledger already stores minor units (12345), so its multiplier is 1. Getting this backwards puts every amount off by a factor of 100 and turns most rows into amount_diff.
If your right-side file can exceed a few hundred MB, add an index block so Reconify spills to disk instead of running out of memory:
Use the wizard
.csv to csv, .json/.ndjson to json, .xlsx/.xlsm to xlsx), and CSV sources get extra prompts for decimal and thousands separators. Cancelling at any prompt prints Config init cancelled. and exits cleanly.
--agent refuses this command outright: it’s interactive by design, and an agent that ran it would hang on the first prompt. Use config infer or a hand-written file instead.
Map the columns
Every parser needstype, date_col, date_layout, and amount_col.
auto infers from .csv, .json, .ndjson, .xlsx, .xlsm. Legacy .xls files aren’t supported: save them as .xlsx or .csv first.
date_layout uses Go’s reference time, not YYYY-MM-DD placeholders. The reference date is 2006-01-02 15:04:05 MST:
Set
tz when your dates have no offset and aren’t UTC; it defaults to UTC. decimal and thousands control amount parsing (defaults . and none). Parenthetical negatives like (1,234.56) are handled automatically. For xlsx, set sheet if the data isn’t on the first sheet; if omitted, Reconify reads the first sheet, and the first row on that sheet must be headers, not a title row.
ref_col, name_col, and currency_col are optional but change what Reconify can do. Omit ref_col and every row gets an empty reference, which disables reference matching entirely. Omit name_col and name-token matching has nothing to compare.
Prove the mapping against real rows
Order matters here: each step only makes sense once the previous one passes.1
Validate the config’s structure
multiplier: 0, which is not a valid conversion factor.- A
date_layoutwritten asYYYY-MM-DDinstead of Go’s2006-01-02. - A pair naming a source that doesn’t exist in
sources.
2
Check the source against a real file
parser block actually exists in the file’s headers, then parses 25 data rows to catch date-layout and amount-format errors before a full run. Use --rows 0 for a headers-only check. Column lookup is case-insensitive and trims whitespace, so Date and date both match.If date_col or amount_col isn’t found, fix the config or the export headers. If an optional column (currency_col, name_col, ref_col) isn’t found, either correct the name or drop the field: Reconify parses without it.3
Parse and read the normalized rows
150000 for 1,500.00, not 1500.00), the reference column is populated, and the name field has useful text if name_mode: tokens is on.When rows still look wrong
Ifcheck-source passes but the parsed rows are wrong, the problem is almost never the column name; the header lookup already succeeded. Look at date_layout, multiplier, or decimal/thousands instead. A date_layout mismatch shifts every date by a fixed offset. A wrong multiplier puts every amount off by exactly a factor of 100.
If references come through empty, reference matching is silently disabled for every row in that source: Reconify won’t error, it reports everything as unmatched instead.
Check ref_col against the file’s actual header name before touching anything in the matching config.