docs/DATA-MAINTENANCE.md +11 −0
@@ -670,4 +670,15 @@ node scripts/data-status.cjs chain de # one country's full timeline
## Rules learned the hard way
+- **Date a law by when it took effect, not when it was signed.** Assent, promulgation and
+ publication are not commencement. Botswana's Cannabis Act was scored on its assent (17 October
+ 2025) although the parts that allow anything commenced on 22 December. Look for the
+ commencement notice or statutory instrument; if the law took effect in stages, date the scored
+ entry by the stage that changes what people may do, and mention the earlier dates in its
+ description.
+- **Never state a whole region's law in one country's profile.** "The model is prohibited
+ throughout the European Union" sat in 13 profiles, copied from a 2018–2019 study, and was
+ false once Malta and Germany licensed associations. Say what the country's own law does; date
+ any comparison. `scripts/profile-claims.test.mjs` keeps a list of such sentences that must not
+ come back.
- **Never trust a search summary for a fact you will mark as checked.** One summary attributed
Bosnia's December 2025 medical approval to Kosovo; others invented sentence lengths or dates.
package.json +1 −1
@@ -13,5 +13,5 @@
"books:test": "node --test scripts/books-status.test.cjs",
"history:test": "node --test scripts/history-scope.test.cjs",
- "answers:test": "node --test scripts/answers.test.mjs",
+ "answers:test": "node --test scripts/answers.test.mjs scripts/profile-claims.test.mjs",
"articles:backlog": "node scripts/article-backlog.cjs",
"scores:triage": "node scripts/score-triage.cjs",
scripts/profile-claims.test.mjs +32 −0
@@ -0,0 +1,32 @@
+// Sentences found to be false in the profiles and the history, which must not come back: copied
+// from an old source, or left behind when the law changed. Each names where it was reported.
+// Add one whenever a factual error turns out to be a phrase that was repeated across files.
+// node --test scripts/profile-claims.test.mjs
+import { test } from "node:test";
+import assert from "node:assert/strict";
+import fs from "node:fs";
+import path from "node:path";
+import { fileURLToPath } from "node:url";
+
+const root = path.join(path.dirname(fileURLToPath(import.meta.url)), "..");
+const walk = (dir) => fs.readdirSync(dir, { withFileTypes: true }).flatMap((e) =>
+ e.isDirectory() ? walk(path.join(dir, e.name)) : /\.(ya?ml|md)$/.test(e.name) ? [path.join(dir, e.name)] : []);
+const files = [...walk(path.join(root, "countries")), ...walk(path.join(root, "articles")), path.join(root, "changes.yaml")];
+// folded YAML breaks sentences across lines, so compare with the whitespace flattened
+const texts = files.map((file) => [path.relative(root, file), fs.readFileSync(file, "utf8").replace(/\s+/g, " ")]);
+
+const CLAIMS = [
+ // Malta (2021) and Germany (2024) license non-profit associations: issue #127
+ { claim: /prohibited throughout the European Union/i, why: "clubs are not prohibited EU-wide: Malta and Germany license associations (#127)" },
+ // Italy's 2024 drug-driving reform as read by the Constitutional Court, Judgment 10/2026: issue #124
+ { claim: /positive test is enough, without proof of impairment/i, why: "since Judgment 10/2026 a positive test alone is not enough in Italy (#124)" },
+ // New Zealand allows notified low-THC hemp growing since 28 May 2026: issue #125
+ { claim: /Growing any cannabis plant is a criminal offence/i, only: "countries/nz.yaml", why: "New Zealand allows notified hemp growing since May 2026 (#125)" },
+];
+
+test("no profile, article or history entry repeats a sentence known to be false", () => {
+ const found = CLAIMS.flatMap(({ claim, only, why }) => texts
+ .filter(([file, text]) => (!only || file === only) && claim.test(text))
+ .map(([file]) => `${file}: ${why}`));
+ assert.deepEqual(found, []);
+});