Cannabis Freedom Index

Changelog 88140a0tree, with Claude Opus 5.5

Research growth chart: leave estimated entries out, as the History page does

The chart counted every "- id:" line in changes.yaml, so it included the 56 estimated first restrictions (estimate: true) that the History page and its progress box leave out: 3,417 entries and 98% checked against 3,361 and 100%. It now counts each commit's entries without the estimates, so both pages agree. The cached counts are recounted once.

1 file of code, design or docs +8 −4 lines

Code, design and documents 1 file

src/lib/progress.js +8 −4
@@ -3,5 +3,7 @@
 // pages cited by the profiles, the history, the articles and the atlas. For the chart on
 // /research/. Counted straight from each commit's files without parsing them (a history entry is a
-// line "- id:", a cited page a `url:` field), so it stays quick; a commit never changes, so each is
+// block starting "- id:", a cited page a `url:` field), so it stays quick. Estimated entries
+// (`estimate: true`, a first restriction assumed where no law is known) are left out, as on the
+// History page: they are not researched history and can never be checked; a commit never changes, so each is
 // counted once and kept in .cache/progress. Without git, or in a shallow copy, the chart shows the
 // commits there are.
@@ -12,5 +14,5 @@ import path from "node:path";
 const ROOT = process.cwd();
 const CACHE = path.join(ROOT, ".cache", "progress");
-const VERSION = "1"; // raise to count every commit again after changing what is counted
+const VERSION = "2"; // raise to count every commit again after changing what is counted
 const git = (...args) => {
   try { return execFileSync("git", args, { cwd: ROOT, maxBuffer: 1 << 29, stdio: ["ignore", "pipe", "ignore"] }).toString(); } catch { return ""; }
@@ -22,6 +24,8 @@ function countAt(hash) {
   const file = path.join(CACHE, `${VERSION}-${hash}.json`);
   if (existsSync(file)) return JSON.parse(readFileSync(file, "utf8"));
-  const entries = +git("grep", "-h", "-c", "^- id:", hash, "--", "changes.yaml").trim() || 0;
-  const checked = +git("grep", "-h", "-c", "^  checked: true", hash, "--", "changes.yaml").trim() || 0;
+  // each history entry is a block from its "- id:" line to the next; estimates are not counted
+  const blocks = git("show", `${hash}:changes.yaml`).split(/^(?=- id:)/m).filter((b) => b.startsWith("- id:") && !/^  estimate: true\s*$/m.test(b));
+  const entries = blocks.length;
+  const checked = blocks.filter((b) => /^  checked: true\s*$/m.test(b)).length;
   const md = (dir) => lines(git("ls-tree", "-r", "--name-only", hash, "--", dir)).filter((f) => f.endsWith(".md")).length;
   // a `url:` field holds its address on the same line, or on the next when folded (url: >-)

    ↑↓ to move, ↵ to open.