Code, design and documents 8 files
docs/DATA-MAINTENANCE.md +8 −2
@@ -1579,6 +1579,12 @@ penalty from a context heading alone: it may discuss an abolished or excluded pe
For medical access, date a score increase to an operating route for obtaining the relevant
cannabis product, rather than enactment, production licences or a patient-registry proposal.
-CBD-only sales do not establish access to psychoactive cannabis. A framework still being
-implemented can retain `medical: limited` with access zero. Greece’s finished prescription
+CBD-only sales do not establish access to psychoactive cannabis. An enacted patient treatment
+framework still being implemented can retain `medical: limited` with access zero. A specific
+individual medical-use/import authorisation can also qualify, as in Tuvalu; verify its legal
+basis separately from issued licences and medicine availability. Research registration or
+export-production licensing alone does not qualify. Use `medical: none` (displayed as “None
+verified”) when no patient route has been verified, and retain research/production permissions
+in context. This records an evidence gap, not a categorical finding that every exceptional
+treatment is illegal. Keep quick answers and metadata equally precise. Greece’s finished prescription
products reached patients in February 2024; Panama’s 2021 framework and 2026 CBD listings
alone do not establish a working THC medicine route.
docs/research/issue-corrections-205-215-218-2026-10-27.md +9 −0
@@ -0,0 +1,9 @@
+# Issue corrections #205 and #215–218
+
+Reviewed 27 October 2026. Corrections to standing-law descriptions; no index score changes.
+
+## #205 — Patient routes and research/export licensing
+
+Changed fm, ls, al, sl, zw and so to medical none, displayed as “None verified”. The same explicit production-only mismatch in the existing gh, lb and np profiles is corrected. All access scores remain zero. Reviewed the named profiles' cited access/medical material; no new blanket prohibition is inferred. FSM Title 11 §§1119, 1133 and 1138 distinguishes Schedule I research from dispensing; Yap §1005 bars prescriptions for its listed hallucinogens. Pohnpei's 2012 text and later state amendments retain their existing currency caveats. Sierra Leone's Pharmacy Board 2024 guidelines describe licensed export cultivation/processing, not patient dispensing. Zimbabwe MCAZ 2022 report, printed pp. 54–55 (existing local primary PDF/text), describes export production, local R&D and CBD applications; none verifies a psychoactive-cannabis patient supply route.
+
+Tuvalu stays limited: read Act 9/2025 §14A and Form G, which explicitly permit individual medical use and import licences. Issued patient licences and working supply remain unverified. Replaced its absolute no-source quick answer with the licensing qualification. Updated shared label/help, map lede/legend, SEO and maintenance/schema guidance. Research/export permissions remain in profile context. This correction does not purport to complete a global audit of every exceptional treatment route. Albania's agency-hosted 2023 law PDF and Somalia archive were unavailable on this recheck; their existing qualified source reviews are retained, rather than claimed as newly read primary texts.
scripts/profile-claims.test.mjs +15 −0
@@ -575,2 +575,17 @@ test('Montana combines product equivalents and preserves strict civil boundaries
assert.doesNotMatch(mt.segments.enforcement,/felony above 2 oz/);
});
+
+// Issue #205
+test('Medical labels require a patient route, not research or export licensing (#205)',()=>{
+ for(const id of ['fm','ls','al','sl','zw','so','gh','lb','np']) {
+ const x=country(id);assert.equal(x.medical,'none',id);assert.equal(x.scores.access,0,id);
+ assert.match(x.answers.buy.text,/route verified/);
+ }
+ const tv=country('tv');assert.equal(tv.medical,'limited');assert.equal(tv.scores.access,0);
+ assert.match(tv.context.medical.text,/Section 14A.*medical use and import/s);
+ assert.match(tv.answers.buy.text,/ministerial licence.*not verified/);
+ const labels=fs.readFileSync(path.join(root,'src/lib/countries.js'),'utf8');
+ assert.match(labels,/no: "None verified"/);assert.doesNotMatch(labels,/production-only/);
+ const seo=fs.readFileSync(path.join(root,'src/lib/seo.js'),'utf8');
+ assert.match(seo,/No patient cannabis treatment route verified/);
+});
src/components/HomePage.astro +2 −2
@@ -141,6 +141,6 @@ const LAW_SECTIONS = {
med: { name: "Medical status", complete: true, statuses: Object.fromEntries(MED_ORDER.map((k) => [k, { label: MED_LABEL[k], help: MED_HELP[k] }])),
tiers: { yes: 5, limited: 3, no: 0 },
- sub: "Green means a medical cannabis programme is legal, yellow that access is limited, red that there is none.",
- note: "Whether patients can get cannabis legally. Medical programmes are not part of the score." },
+ sub: "Green means an established patient route, yellow a restricted or unimplemented patient route, red that no patient route is verified.",
+ note: "Documented patient treatment routes. Research/export licences alone do not qualify. Medical status is not part of the score." },
};
const MAP_SECTIONS = { ...LAW_SECTIONS, ...STATUS_SECTIONS };
src/content.config.ts +3 −3
@@ -38,7 +38,7 @@ const status = {
recreational: z.enum(["legal", "partial", "decriminalised", "illegal", "death"]),
// "legal": an established patient route for cannabis or cannabis-based medicine.
- // "limited": case-specific or pharmaceutical-only access, or legal authority limited to a pilot,
- // one region, research/production, or a framework that is not yet operational.
- // "none": no legal medical use; a proposal, CBD/hemp alone, or a future programme does not qualify.
+ // "limited": a specific patient treatment route, including individual authorisation, approved
+ // medicines, regional/pilot schemes or an enacted patient framework not yet operational.
+ // "none": no patient route verified; research/export licences, proposals or CBD/hemp alone do not qualify.
medical: z.enum(["legal", "limited", "none"]),
};
src/lib/countries.js +3 −3
@@ -20,9 +20,9 @@ export const REC_HELP = {
death: "A crime, and the law allows the death penalty for cannabis offences, in practice trafficking",
};
-export const MED_LABEL = { yes: "Legal", limited: "Limited", no: "None" };
+export const MED_LABEL = { yes: "Legal", limited: "Limited", no: "None verified" };
export const MED_HELP = {
yes: "Patients have an established legal route to cannabis or cannabis-based medicine",
- limited: "Access is case-specific, pharmaceutical-only, regional, a pilot, production-only or not yet operational",
- no: "No legal medical use; proposals and CBD or industrial hemp alone do not qualify",
+ limited: "A patient treatment route is case-specific, pharmaceutical-only, regional, a pilot or not yet operational",
+ no: "No patient treatment route verified; research/export licences and CBD or industrial hemp alone do not establish one",
};
// Explanations that exist for each country but are not part of the score.
src/lib/map-views.js +1 −1
@@ -29,5 +29,5 @@ export const MAP_VIEWS = [
lede: "The legal status of cannabis for adults in every country: legal, tolerated, decriminalised, illegal, or punishable by death." },
{ slug: "medical", metric: "status:med", title: "Where medical cannabis is legal",
- lede: "Whether patients can get cannabis legally in each country: a full programme, limited access, or none." },
+ lede: "Documented patient treatment routes: established, restricted or not yet operational, or none verified. Research and export licences alone do not qualify." },
// the outside datasets (datasets.js), one view each
...MAPPED.map((ds) => ({ slug: ds.map.slug, metric: `data:${ds.id}`, title: ds.map.title, lede: ds.map.lede })),
src/lib/seo.js +1 −1
@@ -40,5 +40,5 @@ const REC_SENTENCE = {
death: "is illegal, with the death penalty for trafficking",
};
-const MED_SENTENCE = { yes: "Medical cannabis: legal.", limited: "Medical cannabis: limited.", no: "No medical cannabis." };
+const MED_SENTENCE = { yes: "Medical cannabis: legal.", limited: "Medical cannabis: limited.", no: "No patient cannabis treatment route verified." };
const monthYear = (iso) => new Date(iso).toLocaleString("en-GB", { month: "long", year: "numeric", timeZone: "UTC" });
const lower = (s) => s[0].toLowerCase() + s.slice(1);