Skip to main content

What's new

What changed in TDC that you can see — a new command or flag, a new check, something that now works differently — newest first, each with a link to where the docs explain it now. Changes inside the engine that alter nothing you write or read are left out; every change is in the changelog.

25 October 2026 — version 0.3.6​

  • <line each="Pool"> prints a pool record by record. One line per record, every field read as ${{Pool.field}}, so a lookup table comes out of the same config as the rows that point at it. The positions Pool._first, Pool._last and Pool._item count the lines actually printed, which is what puts a comma between JSON objects and not after the last one. → A whole pool, record by record
  • <group> keeps several lines together. <group each="Depts"> prints its lines once per department, and a group inside it prints that department's doctors — a nested JSON document from one config. Without each, its if= keeps or drops all its lines at once. → Several lines per element
  • The json filter. ${{Name | json}} writes a JSON string with the escaping done, or null for an empty value; ${{Tags | json:;}} writes a list as a JSON array. A list printed without its separator gets a warning, TDC312. → json
  • plus= reads the distance from a column. <gen type="date" of="Start" plus="Length m"> ends each appointment its own length after it starts. → A distance read from another column
  • The if= of an each line decides element by element. <line each="Orders" if="Orders > 5000"> prints the large orders only; it used to keep or drop the whole line. → What's visible inside an each line
  • Fixture lines are checked, and their if= is read. A misspelled ${{Name}} in <before> is an error in check instead of reaching the file as written. → Fixtures
  • Health identifiers with real check digits: the US NPI, Germany's KVNR and LANR, France's RPPS and FINESS, Brazil's CNS. → National tax and document numbers
  • US and Canadian phone numbers use every area code in service, with 555-0100 to 555-0199, the line numbers reserved for fiction. Every US number used to start +1 202 555. → Phone numbers
  • The pack registry holds 294 bundles. Traditional Chinese, Uzbek, Montenegrin, Breton, Sindhi, four more languages and 46 countries can be downloaded now, and tdcv2 pack list names countries as names: United States, not "Usa". → pack list
  • Rust and C#: a pack whose <valid> check rejects a value now redraws it the way the other three do. Eleven shipped packs, the ISO 6346 container code and Slovenian postal codes among them, gave different values there. → <valid>
  • AI agents. Claude Code, Codex, Cursor, VS Code and Gemini CLI can write and run TDC configs for you, through a skill and an MCP server. → AI Agents

17 October 2026 — version 0.3.5​

  • check says which engine will run the config, and why. A second line after "is valid", such as runs on engine 1 (in memory): uniq="true" on "Code" — that is where the run's memory goes. --brief leaves it out. → tdcv2 check
  • --engine 3 says when engine 1 runs the config instead. On a running total, a statistic or a uniq="true" column it always handed the run to the in-memory engine; it now prints a note, so a memory reading is not quietly one of engine 1. → Which engine runs your config
  • Fixed: a lookup or a formula reading a <uniq> member saw the value from before the group was settled — the day printed and the day looked up disagreed on almost every row. → <uniq> — across separate sequences
  • Fixed: <assert> and if= read a field two or more pools deep, such as D.room.dept.dep_id. → How deep can it go
  • Fixed: a filter inside a pool reads the fields beside it. filter="dept_no == want", with want a field of the same pool, was refused as a filter that can never match. → What a name means inside filter
  • Fixed: every element of a repeat= is its own draw. A repeated e-mail address no longer repeats one domain, and a distribution whose parameter names another column reads each row's own value. → Multiple values in a cell
  • Fixed: February 29 stays February 29. In the npm package a date bounded by or measured from 2024-02-29 came out as March 1. → A random date in a range
  • Python, Rust, Java and C#: a <switch> on a field of a pool record, a date measured from one, and repeat= inside a <switch> branch or a <mix> case work as they do in the npm package. → Two names, one dot

16 October 2026 — version 0.3.4​

  • init can leave the examples out. tdcv2 init --yes --no-examples writes the config and the pack folder and nothing else — for a script or an AI agent that sets up a project on someone's behalf. → --no-examples

  • check warns about three mistakes that used to pass in silence. Each one ran without a word and gave the wrong data:

    • no seed= on <env>: every run draws a different file → seed
    • mm in a date format is minutes, so YYYY-mm-DD printed month 00; the month is MM → Formatting the output
    • &quot; or another XML entity in <data> is printed as written → <data> — raw text

    They are warnings: check still exits with 0. A run given --seed has nothing to warn about, and a run without one prints the seed it drew instead. → tdcv2 check, codes TDC309–TDC311 in the diagnostics reference

  • A date measured from another date has its format checked. format="YYY" on a date with of=/plus= printed 25Y on every row; check now refuses it, as it does for any other date. → A date measured from another date

  • npm package: init --locale with no value is refused. It used to write an en config without a word; the other four implementations already refused it. → --locale