diff --git a/AGENTS.md b/AGENTS.md index 589cc14..2b029b8 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -121,7 +121,7 @@ In [docs/decisions.md](docs/decisions.md): - Goal 5.1's `{…}` covers `{{`, `}}` and a lone `}`, so the goal names no escape - Goal 7.2 holds while a first template can be written with no escape; a literal brace still takes `{{` or `}}` - The locales are Ethnologue 2026's ten most-spoken languages, each in the country with the most speakers of it, the Nordic countries and Germany -- A country with no open national address register ships its places and postal codes without streets +- A country with no open address register covering it whole ships its places and postal codes without streets # Scoring run diff --git a/README.md b/README.md index c30c268..232bf34 100644 --- a/README.md +++ b/README.md @@ -960,10 +960,9 @@ Where the project is heading; the sections before Audience document what ships t it where developers read. 2. **Enough data ships built in to fill a real test database: the CLI carries all of it, a library imports what it needs, and nothing is fetched at run time.** - 1. It covers the ten most-spoken languages and the Nordic countries. - 2. Each locale covers the common categories: names, addresses, phone numbers, ids, + 1. Each locale covers the common categories: names, addresses, phone numbers, ids, companies and dates. - 3. The shipped data comes in Go packages, and a program links only the packages it + 2. The shipped data comes in Go packages, and a program links only the packages it imports. 3. **The code is easy to understand.** 1. You can go from a bug to the code behind it without asking anyone. diff --git a/docs/decisions.md b/docs/decisions.md index 05aac8a..330a75d 100644 --- a/docs/decisions.md +++ b/docs/decisions.md @@ -138,7 +138,7 @@ A directory a machine happens to have would make `--seed 42` machine-dependent; ## The shipped data is Go packages a library imports by choice, and the CLI carries every one, from 0.1.0 -2026-10-04, Lilleman auf Larv; revised 2026-10-09 to put the packages in the core's Go module. Serves goals 2.3, 6.2, 7.3, 9 and 10.1. Carried out by `todo.md` items 181, 184, 185, 186 and 196. The CLI binary may grow to hundreds of MB. +2026-10-04, Lilleman auf Larv; revised 2026-10-09 to put the packages in the core's Go module. Serves goals 2.2, 6.2, 7.3, 9 and 10.1. Carried out by `todo.md` items 181, 184, 185, 186 and 196. The CLI binary may grow to hundreds of MB. - One Go package per locale, one per country's `geo` tree, and one for `misc`, all in the core's Go module. A package registers nothing when imported. - A bare `New()` loads no data and fails, naming the option to add. `WithoutShippedData` goes. @@ -936,24 +936,24 @@ while `{{` and `}}` are the template syntax's only escape. ## The locales are Ethnologue 2026's ten most-spoken languages, each in the country with the most speakers of it, the Nordic countries and Germany -2026-10-11, Lilleman auf Larv. Serves goal 2.1. [The Ethnologue +2026-10-11, Lilleman auf Larv. Serves goal 2. [The Ethnologue 200](https://www.ethnologue.com/insights/ethnologue200/) for 2026 ranks languages by first- and second-language speakers together: English, Mandarin Chinese, Hindi, Spanish, Standard Arabic, French, Bengali, Portuguese, Indonesian and Urdu. Each ships in the country with the most speakers of it: `en_US`, `zh_CN`, `hi_IN`, `es_MX`, `ar_EG`, `fr_FR`, `bn_BD`, `pt_BR`, `id_ID` and `ur_PK`. The Nordic countries are `sv_SE`, `nb_NO`, `da_DK`, `fi_FI` and -`is_IS`. The maintainer added `de_DE` on 2026-10-11, and moved every locale outside the -Nordic countries, France and Germany to 0.2.0. Each locale carries goal 2.2's categories, -and its `address` reads its country's `geo/` tree by reference. Egypt and Pakistan are not -yet confirmed: `todo.md` item 209 and `todo.md` item 214 check each against Ethnologue's -country pages before it ships, and record the result here. Valid until Ethnologue's ranking -changes its ten. +`is_IS`, and the maintainer adds Germany, `de_DE`. Each locale carries goal 2.1's +categories, and its `address` reads its country's `geo/` tree by reference. Egypt and +Pakistan are not yet confirmed: `todo.md` item 209 and `todo.md` item 214 check each against +Ethnologue's country pages before it ships, and record the result here. Valid until +Ethnologue's ranking changes its ten. -## A country with no open national address register ships its places and postal codes without streets +## A country with no open address register covering it whole ships its places and postal codes without streets -2026-10-11, Lilleman auf Larv. Serves goal 2. Where no register publishes a country's -streets under an open licence, the only source is OpenStreetMap, and its ODbL binds a -derived database to share-alike and attribution, which every program linking that country's -geo package would carry. Its `address` prints no street, and the README's Data section says -why beside that country. It holds today for China, India, Egypt, Bangladesh, Indonesia and -Pakistan. Valid until the maintainer accepts ODbL data, or the country opens a register. +2026-10-11, Lilleman auf Larv. Serves goal 2.2. Where no open register covers a country's +streets, the only source is OpenStreetMap. ODbL binds a database derived from it to +share-alike and attribution, and every program linking that country's geo package would +inherit both terms. So that country's `address` prints no street, and the README's Data +section says why beside each such country. This works against goal 2.1 until +`todo.md` item 218 gives those countries streets. Valid until the maintainer accepts ODbL +data, or the country opens a register. diff --git a/todo.md b/todo.md index 05b6f90..15f7ed3 100644 --- a/todo.md +++ b/todo.md @@ -6,7 +6,7 @@ `Bar = 9` -`Next ID = 218` +`Next ID = 219` | Goal | W | |---|---| @@ -15,7 +15,6 @@ | 2 | 0.95 | | 2.1 | 0.95 | | 2.2 | 0.95 | -| 2.3 | 0.95 | | 3 | 0.90 | | 3.1 | 0.90 | | 3.2 | 0.90 | @@ -66,19 +65,19 @@ | ID | Release | Exempt | Item | R | S | A | G | Goals | Score | |---|---|---|---|---|---|---|---|---|---| -| 185 | 0.1.0 | decision | **Seat a panel of the README's audience personas to pull data in through the module API and build a custom CLI, and fix what it names.** | 1 | 3 | 7 | 8 | 2.3, 1 | 28.2 | -| 16 | 0.1.0 | | **Add locale categories: company, phone, finance, vehicle, words.** | 3 | 8 | 8 | 9 | 2.2, 15 | 28.1 | +| 185 | 0.1.0 | decision | **Seat a panel of the README's audience personas to pull data in through the module API and build a custom CLI, and fix what it names.** | 1 | 3 | 7 | 8 | 2.2, 1 | 28.2 | +| 16 | 0.1.0 | | **Add locale categories: company, phone, finance, vehicle, words.** | 3 | 8 | 8 | 9 | 2.1, 15 | 28.1 | | 192 | 0.1.0 | decision | **Fail the gate when the shipped data passes 100 MiB, naming item 193.** | 1 | 2 | 6 | 8 | 2, 1.1 | 26.5 | -| 210 | 0.1.0 | | **Add `fr_FR` with its `geo/FR` tree.** | 3 | 8 | 8 | 8 | 2.1 | 26.2 | +| 210 | 0.1.0 | | **Add `fr_FR` with its `geo/FR` tree.** | 3 | 8 | 8 | 8 | 2 | 26.2 | | 15 | 0.1.0 | | **Add `misc` tables and templates, one row of its detail's table per chunk.** | 3 | 9 | 8 | 8 | 2, 15, 14 | 25.9 | | 184 | 0.1.0 | decision | **Make the CLI the library call `cli.Main(modules ...fs.FS) int`, with `fejkdata`'s own `main` one line over `data.Modules()`.** | 4 | 5 | 7 | 9 | 9.6, 2 | 25.8 | | 201 | 0.1.0 | | **Place each Swedish street in the postort whose area holds it, so a big postort such as Stockholm carries its own streets.** | 4 | 6 | 8 | 8 | 2, 16 | 25.7 | | 129 | 0.1.0 | decision | **Take a template wherever the library renders, so `fake:"{/sv_SE.person.first}"` and `Fake("{/sv_SE.person}")` render, and text with no `{…}` prints as written, as the CLI already does.** | 5 | 8 | 8 | 10 | 5.9, 7 | 25.0 | | 163 | 0.1.0 | | **Lift the CLI's `--repeat` cap, since the CLI streams each render, and give the builtins' count and decimal caps a technical reason in the README.** | 2 | 2 | 7 | 7 | 2, 5.7 | 24.8 | -| 202 | 0.1.0 | | **Add `nb_NO` with its `geo/NO` tree.** | 3 | 7 | 7 | 8 | 2.1 | 24.4 | -| 203 | 0.1.0 | | **Add `da_DK` with its `geo/DK` tree.** | 3 | 7 | 7 | 8 | 2.1 | 24.4 | -| 204 | 0.1.0 | | **Add `fi_FI` with its `geo/FI` tree.** | 3 | 7 | 7 | 8 | 2.1 | 24.4 | -| 205 | 0.1.0 | | **Add `is_IS` with its `geo/IS` tree.** | 3 | 6 | 6 | 8 | 2.1 | 22.7 | +| 202 | 0.1.0 | | **Add `nb_NO` with its `geo/NO` tree.** | 3 | 7 | 7 | 8 | 2 | 24.4 | +| 203 | 0.1.0 | | **Add `da_DK` with its `geo/DK` tree.** | 3 | 7 | 7 | 8 | 2 | 24.4 | +| 204 | 0.1.0 | | **Add `fi_FI` with its `geo/FI` tree.** | 3 | 7 | 7 | 8 | 2 | 24.4 | +| 205 | 0.1.0 | | **Add `is_IS` with its `geo/IS` tree.** | 3 | 6 | 6 | 8 | 2 | 22.7 | | 57 | 0.1.0 | | **Rewrite `CHANGELOG.md`'s `[Unreleased]` as what v0.1.0 holds.** | 1 | 2 | 6 | 6 | 1.1 | 22.5 | | 217 | 0.1.0 | | **Add `de_DE` with its `geo/DE` tree.** | 3 | 7 | 7 | 6 | 2 | 20.6 | | 196 | 0.1.0 | decision | **Name, in the error for a reference nothing loaded provides, the module the reader's manifest reads by default that would provide it, or say none does.** | 3 | 4 | 6 | 8 | 6.2, 9.2 | 20.0 | @@ -96,19 +95,20 @@ | 216 | 0.1.0 | | **Share between countries what `geo-se.py` and `data_test.go` hard-code for SE, in the first locale chunk that needs each.** | 2 | 2 | 2 | 6 | 3.2 | 12.3 | | 191 | 0.1.0 | defect | **Read an existing tag through `git/ref/tags/{tag}` in `publish_release.py`, so its guard against a tag at another commit fires.** | 1 | 1 | 3 | 6 | 10 | 11.4 | | 58 | 0.2.0 | | **Ship prebuilt binaries, a container image, and packages for Homebrew, Scoop and the biggest Linux package managers, so the CLI needs no Go.** | 3 | 7 | 8 | 9 | 1.1, 7 | 29.2 | -| 206 | 0.2.0 | | **Add `zh_CN` with its `geo/CN` tree.** | 4 | 8 | 8 | 8 | 2.1 | 25.2 | -| 208 | 0.2.0 | | **Add `es_MX` with its `geo/MX` tree.** | 4 | 8 | 8 | 8 | 2.1 | 25.2 | -| 212 | 0.2.0 | | **Add `pt_BR` with its `geo/BR` tree.** | 4 | 8 | 8 | 8 | 2.1 | 25.2 | +| 206 | 0.2.0 | | **Add `zh_CN` with its `geo/CN` tree.** | 4 | 8 | 8 | 8 | 2 | 25.2 | +| 208 | 0.2.0 | | **Add `es_MX` with its `geo/MX` tree.** | 4 | 8 | 8 | 8 | 2 | 25.2 | +| 212 | 0.2.0 | | **Add `pt_BR` with its `geo/BR` tree.** | 4 | 8 | 8 | 8 | 2 | 25.2 | | 113 | 0.2.0 | defect | **Draw `{iban(CC)}` with its country's national check digits, and SE's with a real bank's id, so a validator checking more than mod 97 accepts it.** | 3 | 5 | 7 | 9 | 4 | 25.0 | -| 207 | 0.2.0 | | **Add `hi_IN` with its `geo/IN` tree.** | 4 | 8 | 7 | 8 | 2.1 | 23.2 | -| 209 | 0.2.0 | decision | **Add `ar_EG` with its `geo/EG` tree.** | 4 | 8 | 7 | 8 | 2.1 | 23.2 | -| 211 | 0.2.0 | | **Add `bn_BD` with its `geo/BD` tree.** | 4 | 8 | 7 | 8 | 2.1 | 23.2 | -| 213 | 0.2.0 | | **Add `id_ID` with its `geo/ID` tree.** | 4 | 8 | 7 | 8 | 2.1 | 23.2 | -| 214 | 0.2.0 | decision | **Add `ur_PK` with its `geo/PK` tree.** | 4 | 8 | 7 | 8 | 2.1 | 23.2 | -| 154 | 0.2.0 | | **Add `en_US.routing`, an ABA routing number over the Fed's prefix ranges with its check digit drawn by `{aba()}`.** | 2 | 2 | 6 | 7 | 2.2, 15 | 22.8 | +| 207 | 0.2.0 | | **Add `hi_IN` with its `geo/IN` tree.** | 4 | 8 | 7 | 8 | 2 | 23.2 | +| 209 | 0.2.0 | decision | **Add `ar_EG` with its `geo/EG` tree.** | 4 | 8 | 7 | 8 | 2 | 23.2 | +| 211 | 0.2.0 | | **Add `bn_BD` with its `geo/BD` tree.** | 4 | 8 | 7 | 8 | 2 | 23.2 | +| 213 | 0.2.0 | | **Add `id_ID` with its `geo/ID` tree.** | 4 | 8 | 7 | 8 | 2 | 23.2 | +| 214 | 0.2.0 | decision | **Add `ur_PK` with its `geo/PK` tree.** | 4 | 8 | 7 | 8 | 2 | 23.2 | +| 154 | 0.2.0 | | **Add `en_US.routing`, an ABA routing number over the Fed's prefix ranges with its check digit drawn by `{aba()}`.** | 2 | 2 | 6 | 7 | 2.1, 15 | 22.8 | | 155 | 0.2.0 | | **Add `misc.isin` and `misc.cusip`, built by their structure rules with their check digits drawn by `{isin()}` and `{cusip()}`.** | 2 | 2 | 6 | 7 | 2, 15 | 22.8 | | 26 | 0.2.0 | defect | **Spell `sv_SE.personnummer` with the `+` Skatteverket uses from the year the holder turns 100, judged by a date the caller gives.** | 4 | 6 | 7 | 8 | 4 | 22.1 | | 34 | 0.2.0 | | **Add `{isin()}`, `{cusip()}`, `{aba()}` and `{vin()}`.** | 2 | 4 | 6 | 7 | 4 | 20.9 | +| 218 | 0.2.0 | decision | **Give every country shipped without streets its streets, once the maintainer accepts ODbL data or the country opens a register.** | 3 | 6 | 6 | 7 | 2.1 | 20.8 | | 81 | 0.2.0 | decision | **Refuse at load every `calc` operand not proven numeric and every divisor not proven nonzero, in a string column too.** | 4 | 4 | 6 | 8 | 6.1, 4 | 20.6 | | 177 | 0.2.0 | decision | **Run the nine-seat comprehension panel and the scoring run again once item 107 has moved the engine, and file what the panel names.** | 1 | 3 | 3 | 9 | 3 | 20.4 | | 91 | 0.2.0 | | **Accept a path through a name as a `calc` operand, so `{/misc.coordinate as c}{c}: {calc(c.lat * 60)}` computes from the coordinate `{c}` prints.** | 3 | 4 | 6 | 7 | 4.1, 5.3 | 19.9 | @@ -120,7 +120,7 @@ | 28 | 0.2.0 | decision | **Accept a middle name, and draw a `personnummer` whose sex matches a sex selected through a named pick.** | 4 | 4 | 6 | 7 | 4.1 | 18.9 | | 24 | 0.2.0 | defect | **Stop `misc.territory[EH].tld` rendering `.eh`, the one shipped TLD `misc.tld` does not hold.** | 1 | 1 | 4 | 7 | 4 | 18.6 | | 178 | 0.2.0 | | **Plan with the systems architect which `internal/` packages the engine splits into, by area, and how each type stops being written by more than one stage, then file the moves as items.** | 1 | 3 | 2 | 9 | 3, 3.2 | 18.4 | -| 193 | 0.2.0 | decision | **Move the largest shipped packages into nested Go modules that keep their import paths, once item 192's gate fails.** | 6 | 6 | 6 | 7 | 2.3, 2 | 17.8 | +| 193 | 0.2.0 | decision | **Move the largest shipped packages into nested Go modules that keep their import paths, once item 192's gate fails.** | 6 | 6 | 6 | 7 | 2.2, 2 | 17.8 | | 92 | 0.2.0 | | **Name the hyphenated field in a `calc`'s refusal, and say to rename it: today `{calc(postal-code * 2)}` reports `no field "postal"`.** | 1 | 2 | 5 | 6 | 6 | 17.5 | | 194 | 0.2.0 | decision | **Let a data author write and check their own `.fejkdata.json` index with the library or the CLI, and fail a load whose index leaves out a category file.** | 2 | 4 | 5 | 7 | 6.3, 9.1 | 17.5 | | 53 | 0.2.0 | | **Let a table column carry a `datatype`, so `--format json` writes `"safe": true` and `--format sql` a boolean.** | 4 | 5 | 6 | 6 | 4 | 16.9 | @@ -314,7 +314,7 @@ Nothing has shipped, so "no longer paths", "where it used to fail" and "where it ### 217. Add `de_DE` with its `geo/DE` tree. -The maintainer added Germany on 2026-10-11, as the decision "The locales are Ethnologue 2026's ten most-spoken languages, each in the country with the most speakers of it, the Nordic countries and Germany" records. GeoNames publishes Germany's postal codes. Find an open national address register for its streets first; without one, it ships without streets, as the decision "A country with no open national address register ships its places and postal codes without streets" says. +GeoNames publishes Germany's postal codes. Its address data is published by each Land; where open registers cover every Land, they are its street source, else it ships without streets (decision: no open address register covering it whole). ### 196. Name, in the error for a reference nothing loaded provides, the module the reader's manifest reads by default that would provide it, or say none does. @@ -378,7 +378,7 @@ GoReleaser attaches the binaries to the release the tag workflow publishes, and ### 206. Add `zh_CN` with its `geo/CN` tree. -Written in simplified characters. `rows.Pins` holds eight pins inline, enough for a five-deep geo tree. If CN's tree runs deeper, raise that number to keep a render off the heap. It ships without streets, as the decision "A country with no open national address register ships its places and postal codes without streets" says. +Written in simplified characters. `rows.Pins` holds eight pins inline, enough for a five-deep geo tree. If CN's tree runs deeper, raise that number to keep a render off the heap. It ships without streets (decision: no open address register covering it whole). ### 208. Add `es_MX` with its `geo/MX` tree. @@ -394,23 +394,23 @@ Brazil holds the most Portuguese speakers. IBGE's CNEFE lists every address with ### 207. Add `hi_IN` with its `geo/IN` tree. -Hindi is written in Devanagari. India's PIN code directory is open data on data.gov.in. It ships without streets, as the decision "A country with no open national address register ships its places and postal codes without streets" says. +Hindi is written in Devanagari. India's PIN code directory is open data on data.gov.in. It ships without streets (decision: no open address register covering it whole). ### 209. Add `ar_EG` with its `geo/EG` tree. -Standard Arabic has no native speakers. Confirm from Ethnologue's country pages that Egypt holds the most second-language speakers, and record the answer in the decision. It ships without streets, as the decision "A country with no open national address register ships its places and postal codes without streets" says. +Standard Arabic has no native speakers. Confirm from Ethnologue's country pages that Egypt holds the most second-language speakers, and record the answer in the decision. It ships without streets (decision: no open address register covering it whole). ### 211. Add `bn_BD` with its `geo/BD` tree. -Bangladesh holds the most Bengali speakers. It ships without streets, as the decision "A country with no open national address register ships its places and postal codes without streets" says. +Bangladesh holds the most Bengali speakers. It ships without streets (decision: no open address register covering it whole). ### 213. Add `id_ID` with its `geo/ID` tree. -Indonesian is spoken almost only in Indonesia. It ships without streets, as the decision "A country with no open national address register ships its places and postal codes without streets" says. +Indonesian is spoken almost only in Indonesia. It ships without streets (decision: no open address register covering it whole). ### 214. Add `ur_PK` with its `geo/PK` tree. -Urdu is Pakistan's national language, yet India has more native speakers: 50.8M by its 2011 census against Pakistan's 22.3M by its 2023 one. Confirm from Ethnologue's country pages that Pakistan holds the most speakers in all, else the locale is ur_IN, and record the answer in the decision. It ships without streets, as the decision "A country with no open national address register ships its places and postal codes without streets" says. +Urdu is Pakistan's national language, yet India has more native speakers: 50.8M by its 2011 census against Pakistan's 22.3M by its 2023 one. Confirm from Ethnologue's country pages that Pakistan holds the most speakers in all, else the locale is ur_IN, and record the answer in the decision. It ships without streets (decision: no open address register covering it whole). ### 154. Add `en_US.routing`, an ABA routing number over the Fed's prefix ranges with its check digit drawn by `{aba()}`. @@ -434,6 +434,10 @@ The format hard-codes `-`, and its earliest birthdate, 1930-01-01, makes the old `isin`: Luhn over letters expanded to digits. `aba`: 3-7-1 weights. `vin`: position 9 over the whole; a sample taking the WMI, since the check sits mid-string. +### 218. Give every country shipped without streets its streets, once the maintainer accepts ODbL data or the country opens a register. + +Ends the decision "A country with no open address register covering it whole ships its places and postal codes without streets". + ### 81. Refuse at load every `calc` operand not proven numeric and every divisor not proven nonzero, in a string column too. The decision "A constant zero divisor is a load error; in a string column a divisor that is not constant prints `Inf`" lets `{calc(a/(b*c))}` with `b` fixed at `"0"` write `Inf` into every row. An operand that is sometimes not a number prints `NaN`. Both work against goals 6.1 and 4. `valueproof.go` already proves a typed column's divisor nonzero. Once every operand is proven, `neverNumeric` and `constantValue` in `calc.go` go, and with them their reading of `NaN` and `Inf` as numbers, which `proven.Literal` refuses: calc reads text as a number one way.