Equivalency pairings + rehabilitation engine: the s. 36 screening suite
Browse filescanlex_us_equivalency: 13 curated US->Canadian offence pairings with every
maximum penalty verified against the corpus text of the Criminal Code and
CDSA. Headlines: one US DUI = serious criminality via hybrid deeming (with
the Tran 2017 SCC 50 commission-date caveat for pre-2018-12-18 offences);
cannabis simple possession has NO Canadian equivalent post-legalization;
a single disorderly conduct equates to s. 175 (pure summary) and grounds
nothing; property offences split at the Canadian $5,000 line. Hill
methodology chunk included; honest no-pairing fallback.
canlex_rehabilitation: pure rule engine (canlex/rehab.py) for IRPA
s. 36(3)(c) + IRPR ss. 17/18/18.1, rules verified verbatim against the
corpus consolidation -- deemed rehabilitation (10 clean years single /
5 years two-plus-summary; never for serious criminality), individual
applications at 5 years, record-suspension route for in-Canada convictions,
the 18.1 two-summary exemption. 10 unit tests.
Together with canlex_us_disposition these form the three-step US-record
screening flow: conviction? -> equivalent offence? -> cured by time?
Reviewed by the user 2026-07-15.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- canlex/rehab.py +143 -0
- canlex/server.py +165 -0
- data/curated/us_equivalency.json +285 -0
- tests/test_rehab.py +71 -0
|
@@ -0,0 +1,143 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"""Criminal-rehabilitation assessment under IRPA s. 36(3)(c) and IRPR ss. 17-18.1.
|
| 2 |
+
|
| 3 |
+
Pure rule logic, verified against the corpus text of IRPR ss. 17, 18 and 18.1
|
| 4 |
+
(SOR-2002-227, current consolidation) and IRPA s. 36(3). The rules:
|
| 5 |
+
|
| 6 |
+
Deemed rehabilitation (IRPR s. 18(2)) -- automatic, no application:
|
| 7 |
+
(a) ONE foreign conviction, indictable-equivalent, punishable in Canada by
|
| 8 |
+
a maximum of LESS THAN 10 years: 10 years after sentence completion,
|
| 9 |
+
with the cleanliness conditions (i)-(vii).
|
| 10 |
+
(b) TWO OR MORE foreign convictions that would all be summary offences:
|
| 11 |
+
5 years after the sentences were completed, with conditions.
|
| 12 |
+
(c) ONE committed act (s. 36(1)(c)/(2)(c)), <10-year maximum: 10 years
|
| 13 |
+
after the commission, with conditions.
|
| 14 |
+
Serious criminality (>=10-year maximum equivalent) can NEVER be deemed
|
| 15 |
+
rehabilitated -- only an individual application.
|
| 16 |
+
|
| 17 |
+
Individual rehabilitation (IRPA s. 36(3)(c), period per IRPR s. 17):
|
| 18 |
+
eligible to APPLY 5 years after sentence completion (conviction branches)
|
| 19 |
+
or 5 years after commission (act branches). Available for serious
|
| 20 |
+
criminality too.
|
| 21 |
+
|
| 22 |
+
In-Canada convictions are outside the rehabilitation scheme entirely --
|
| 23 |
+
the cure is a record suspension (IRPA s. 36(3)(b)) -- EXCEPT the IRPR
|
| 24 |
+
s. 18.1 prescribed class: inadmissible SOLELY for two or more in-Canada
|
| 25 |
+
summary-only convictions, exempt from s. 36(2)(a) five years after the
|
| 26 |
+
sentences were completed.
|
| 27 |
+
"""
|
| 28 |
+
|
| 29 |
+
BASES = ("foreign-conviction", "foreign-act", "canada-conviction")
|
| 30 |
+
COUNTS = ("one", "two-plus-summary-only", "multiple")
|
| 31 |
+
|
| 32 |
+
|
| 33 |
+
def assess(basis, max_penalty_lt_10, count, years_elapsed, clean_record):
|
| 34 |
+
"""Assess rehabilitation status. Returns a dict:
|
| 35 |
+
{status, provision, explanation, caveats}.
|
| 36 |
+
|
| 37 |
+
basis: how the inadmissibility arises (BASES).
|
| 38 |
+
max_penalty_lt_10: True if the equivalent Canadian offence's maximum term
|
| 39 |
+
is under 10 years (False = serious criminality territory).
|
| 40 |
+
count: 'one' | 'two-plus-summary-only' | 'multiple' (COUNTS).
|
| 41 |
+
years_elapsed: full years since sentence completion (conviction bases)
|
| 42 |
+
or since commission (act basis).
|
| 43 |
+
clean_record: True if there are no other convictions or committed acts
|
| 44 |
+
(the s. 18(2) (i)-(vii) conditions, simplified -- see caveats).
|
| 45 |
+
"""
|
| 46 |
+
caveats = [
|
| 47 |
+
"The 'clean record' answer stands in for the detailed conditions in "
|
| 48 |
+
"IRPR s. 18(2)(i)-(vii) (no Canadian indictable conviction ever; no "
|
| 49 |
+
"recent summary convictions; at most one older summary conviction; no "
|
| 50 |
+
"other committed acts) -- confirm each condition against the full "
|
| 51 |
+
"record before relying on deemed rehabilitation.",
|
| 52 |
+
"A temporary resident permit (IRPA s. 24) remains available at any "
|
| 53 |
+
"time regardless of rehabilitation status.",
|
| 54 |
+
"Time runs from the day AFTER completion of the ENTIRE sentence -- "
|
| 55 |
+
"including probation, fines and driving prohibitions -- not from the "
|
| 56 |
+
"conviction date.",
|
| 57 |
+
]
|
| 58 |
+
|
| 59 |
+
if basis == "canada-conviction":
|
| 60 |
+
if count == "two-plus-summary-only":
|
| 61 |
+
if years_elapsed >= 5:
|
| 62 |
+
return _r("exempt", "IRPR s. 18.1",
|
| 63 |
+
"Inadmissible solely for two or more in-Canada "
|
| 64 |
+
"summary-only convictions, and at least five years "
|
| 65 |
+
"have passed since the sentences were completed: "
|
| 66 |
+
"the person is in the prescribed class exempt from "
|
| 67 |
+
"IRPA s. 36(2)(a).", caveats)
|
| 68 |
+
return _r("not-yet", "IRPR s. 18.1",
|
| 69 |
+
"The in-Canada two-summary-only exemption requires five "
|
| 70 |
+
"years since the sentences were completed "
|
| 71 |
+
f"({years_elapsed} elapsed).", caveats)
|
| 72 |
+
return _r("record-suspension-route", "IRPA s. 36(3)(b)",
|
| 73 |
+
"Rehabilitation does not apply to in-Canada convictions. "
|
| 74 |
+
"The cure is a record suspension under the Criminal Records "
|
| 75 |
+
"Act (IRPA s. 36(3)(b)); once ordered and not revoked, the "
|
| 76 |
+
"conviction cannot ground inadmissibility.", caveats)
|
| 77 |
+
|
| 78 |
+
since = ("sentence completion" if basis == "foreign-conviction"
|
| 79 |
+
else "the commission of the act")
|
| 80 |
+
|
| 81 |
+
if not max_penalty_lt_10:
|
| 82 |
+
# Serious criminality: deemed rehabilitation is never available.
|
| 83 |
+
if years_elapsed >= 5:
|
| 84 |
+
return _r("eligible-to-apply", "IRPA s. 36(3)(c); IRPR s. 17",
|
| 85 |
+
"The equivalent Canadian offence carries a maximum of "
|
| 86 |
+
"10 years or more (serious criminality), so deemed "
|
| 87 |
+
"rehabilitation is NOT available -- but at least five "
|
| 88 |
+
f"years have passed since {since}, so the person is "
|
| 89 |
+
"eligible to APPLY for individual rehabilitation.",
|
| 90 |
+
caveats)
|
| 91 |
+
return _r("not-yet", "IRPR s. 17",
|
| 92 |
+
"Serious criminality: deemed rehabilitation is not "
|
| 93 |
+
"available, and the five-year eligibility period to apply "
|
| 94 |
+
f"for individual rehabilitation has not yet run "
|
| 95 |
+
f"({years_elapsed} of 5 years since {since}).", caveats)
|
| 96 |
+
|
| 97 |
+
if count == "multiple":
|
| 98 |
+
if years_elapsed >= 5:
|
| 99 |
+
return _r("eligible-to-apply", "IRPA s. 36(3)(c); IRPR s. 17",
|
| 100 |
+
"More than one indictable-equivalent conviction/act: "
|
| 101 |
+
"deemed rehabilitation is not available (IRPR s. 18(2) "
|
| 102 |
+
"covers only a single such conviction or act), but the "
|
| 103 |
+
"five-year period to apply for individual "
|
| 104 |
+
"rehabilitation has run.", caveats)
|
| 105 |
+
return _r("not-yet", "IRPR s. 17",
|
| 106 |
+
"Multiple indictable-equivalent matters: only individual "
|
| 107 |
+
"rehabilitation is possible, and its five-year eligibility "
|
| 108 |
+
f"period has not run ({years_elapsed} of 5 years).", caveats)
|
| 109 |
+
|
| 110 |
+
if count == "two-plus-summary-only":
|
| 111 |
+
para = "IRPR s. 18(2)(b)"
|
| 112 |
+
need = 5
|
| 113 |
+
elif basis == "foreign-act":
|
| 114 |
+
para = "IRPR s. 18(2)(c)"
|
| 115 |
+
need = 10
|
| 116 |
+
else:
|
| 117 |
+
para = "IRPR s. 18(2)(a)"
|
| 118 |
+
need = 10
|
| 119 |
+
|
| 120 |
+
if years_elapsed >= need and clean_record:
|
| 121 |
+
return _r("deemed-rehabilitated", para,
|
| 122 |
+
f"All {para} requirements appear met: {years_elapsed} years "
|
| 123 |
+
f"since {since} (needs {need}), a qualifying single/summary "
|
| 124 |
+
"profile, and a clean record. The person is deemed "
|
| 125 |
+
"rehabilitated -- the matter cannot ground inadmissibility "
|
| 126 |
+
"under IRPA s. 36(3)(c).", caveats)
|
| 127 |
+
if years_elapsed >= 5:
|
| 128 |
+
why = (f"only {years_elapsed} of {need} years have run"
|
| 129 |
+
if years_elapsed < need else
|
| 130 |
+
"the record is not clean, which defeats deemed rehabilitation")
|
| 131 |
+
return _r("eligible-to-apply", f"{para}; IRPR s. 17",
|
| 132 |
+
f"Deemed rehabilitation is not (yet) made out ({why}), but "
|
| 133 |
+
"five years have passed, so the person is eligible to APPLY "
|
| 134 |
+
"for individual rehabilitation.", caveats)
|
| 135 |
+
return _r("not-yet", f"{para}; IRPR s. 17",
|
| 136 |
+
f"Neither deemed rehabilitation ({years_elapsed} of {need} "
|
| 137 |
+
"years) nor application eligibility (five years) has been "
|
| 138 |
+
"reached.", caveats)
|
| 139 |
+
|
| 140 |
+
|
| 141 |
+
def _r(status, provision, explanation, caveats):
|
| 142 |
+
return {"status": status, "provision": provision,
|
| 143 |
+
"explanation": explanation, "caveats": caveats}
|
|
@@ -480,6 +480,171 @@ def _match_dispositions(data, disposition, state):
|
|
| 480 |
return [e for _, e in scored[:2]]
|
| 481 |
|
| 482 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 483 |
@mcp.tool(name="canlex_us_disposition",
|
| 484 |
annotations={"title": "US Disposition vs IRPA 'Conviction'", **_READONLY})
|
| 485 |
def canlex_us_disposition(params: DispositionInput) -> str:
|
|
|
|
| 480 |
return [e for _, e in scored[:2]]
|
| 481 |
|
| 482 |
|
| 483 |
+
class EquivalencyInput(BaseModel):
|
| 484 |
+
"""Input for canlex_us_equivalency."""
|
| 485 |
+
model_config = ConfigDict(str_strip_whitespace=True, extra="forbid")
|
| 486 |
+
|
| 487 |
+
offense: str = Field(
|
| 488 |
+
...,
|
| 489 |
+
description="The US offence as charged or described, e.g. 'DUI', "
|
| 490 |
+
"'petty theft', 'aggravated assault', 'possession of a controlled "
|
| 491 |
+
"substance', 'disorderly conduct'.",
|
| 492 |
+
min_length=2, max_length=200,
|
| 493 |
+
)
|
| 494 |
+
|
| 495 |
+
|
| 496 |
+
def _load_equivalency():
|
| 497 |
+
from canlex.config import DATA_DIR
|
| 498 |
+
path = DATA_DIR / "curated" / "us_equivalency.json"
|
| 499 |
+
if not path.exists():
|
| 500 |
+
return None
|
| 501 |
+
return json.loads(path.read_text(encoding="utf-8"))
|
| 502 |
+
|
| 503 |
+
|
| 504 |
+
@mcp.tool(name="canlex_us_equivalency",
|
| 505 |
+
annotations={"title": "US Offence Equivalency", **_READONLY})
|
| 506 |
+
def canlex_us_equivalency(params: EquivalencyInput) -> str:
|
| 507 |
+
"""Map a common US offence to its Canadian equivalent and the resulting
|
| 508 |
+
IRPA s. 36 inadmissibility branch (serious criminality vs criminality vs
|
| 509 |
+
none), from CanLex's curated pairing table with corpus-verified maximum
|
| 510 |
+
penalties.
|
| 511 |
+
|
| 512 |
+
This is step 2 of a s. 36 analysis (step 1: is the disposition a
|
| 513 |
+
conviction -- canlex_us_disposition; step 3: rehabilitation --
|
| 514 |
+
canlex_rehabilitation, which takes this tool's max-penalty answer as
|
| 515 |
+
input). Covers the COMMON pairings (DUI, theft, assault, fraud, drugs,
|
| 516 |
+
cannabis, disorderly conduct...); anything unusual gets the Hill
|
| 517 |
+
methodology and an honest no-entry statement.
|
| 518 |
+
|
| 519 |
+
Returns:
|
| 520 |
+
str: Markdown -- the pairing with penalty, branch, caveats and
|
| 521 |
+
authorities, or the Hill framework when nothing matches.
|
| 522 |
+
"""
|
| 523 |
+
from canlex.commentary import BANNER
|
| 524 |
+
data = _load_equivalency()
|
| 525 |
+
if data is None:
|
| 526 |
+
return ("The equivalency dataset is not present in this deployment. "
|
| 527 |
+
"Apply Hill v Canada (MEI) (1987), 73 NR 315 (FCA): compare "
|
| 528 |
+
"essential elements, or the evidence of what was done, or "
|
| 529 |
+
"both; remember IRPA s. 36(3)(a) hybrid deeming.")
|
| 530 |
+
q = set(re.findall(r"[a-z0-9]+", params.offense.lower()))
|
| 531 |
+
scored = []
|
| 532 |
+
for p in data.get("pairings", []):
|
| 533 |
+
best = 0.0
|
| 534 |
+
for t in p["us_terms"]:
|
| 535 |
+
toks = set(re.findall(r"[a-z0-9]+", t.lower()))
|
| 536 |
+
if toks:
|
| 537 |
+
best = max(best, len(q & toks) / len(toks))
|
| 538 |
+
if best > 0.4:
|
| 539 |
+
scored.append((best, p))
|
| 540 |
+
scored.sort(key=lambda x: -x[0])
|
| 541 |
+
parts = [BANNER]
|
| 542 |
+
if scored:
|
| 543 |
+
for _, p in scored[:2]:
|
| 544 |
+
lines = [f"US offence: {'; '.join(p['us_terms'][:5])}",
|
| 545 |
+
f"Canadian equivalent: {p['canadian_offence']}",
|
| 546 |
+
f"Maximum penalty (verified): {p['penalty']}",
|
| 547 |
+
f"Inadmissibility branch: {p['branch']}", "",
|
| 548 |
+
p["analysis"]]
|
| 549 |
+
if p.get("caveats"):
|
| 550 |
+
lines.append("")
|
| 551 |
+
lines += [f"- CAVEAT: {c}" for c in p["caveats"]]
|
| 552 |
+
if p.get("authorities"):
|
| 553 |
+
lines += ["", "Authorities:"]
|
| 554 |
+
lines += [f"- {a['cite']} ({a['court']}): {a['holding']}"
|
| 555 |
+
for a in p["authorities"]]
|
| 556 |
+
parts.append("\n".join(lines))
|
| 557 |
+
else:
|
| 558 |
+
parts.append(
|
| 559 |
+
f"No curated pairing matches '{params.offense}'. Apply the Hill "
|
| 560 |
+
"framework (below) to the actual foreign statute -- compare "
|
| 561 |
+
"essential elements, or the evidence of what was done, or both.")
|
| 562 |
+
for m in data.get("methodology", []):
|
| 563 |
+
if m["id"] == "equivalency-framework":
|
| 564 |
+
parts.append("---\n\nGoverning framework:\n\n" + m["text"])
|
| 565 |
+
break
|
| 566 |
+
parts.append("Retrieve the Canadian provisions with canlex_get_section "
|
| 567 |
+
"to verify elements and penalties; feed the max-penalty "
|
| 568 |
+
"answer into canlex_rehabilitation for step 3.")
|
| 569 |
+
return "\n\n".join(parts)
|
| 570 |
+
|
| 571 |
+
|
| 572 |
+
class RehabInput(BaseModel):
|
| 573 |
+
"""Input for canlex_rehabilitation."""
|
| 574 |
+
model_config = ConfigDict(str_strip_whitespace=True, extra="forbid")
|
| 575 |
+
|
| 576 |
+
basis: str = Field(
|
| 577 |
+
...,
|
| 578 |
+
description="How the inadmissibility arises: 'foreign-conviction' "
|
| 579 |
+
"(IRPA s. 36(1)(b)/(2)(b)), 'foreign-act' (s. 36(1)(c)/(2)(c)), or "
|
| 580 |
+
"'canada-conviction' (s. 36(1)(a)/(2)(a)).",
|
| 581 |
+
pattern="^(foreign-conviction|foreign-act|canada-conviction)$",
|
| 582 |
+
)
|
| 583 |
+
max_penalty_lt_10: bool = Field(
|
| 584 |
+
...,
|
| 585 |
+
description="True if the equivalent Canadian offence's maximum term "
|
| 586 |
+
"of imprisonment is LESS THAN 10 years (remember IRPA s. 36(3)(a): "
|
| 587 |
+
"hybrid offences count as indictable at their indictable maximum).",
|
| 588 |
+
)
|
| 589 |
+
count: str = Field(
|
| 590 |
+
...,
|
| 591 |
+
description="'one' (a single conviction or act), "
|
| 592 |
+
"'two-plus-summary-only' (two or more, all summary-equivalent), or "
|
| 593 |
+
"'multiple' (more than one indictable-equivalent matter).",
|
| 594 |
+
pattern="^(one|two-plus-summary-only|multiple)$",
|
| 595 |
+
)
|
| 596 |
+
years_elapsed: int = Field(
|
| 597 |
+
..., ge=0, le=100,
|
| 598 |
+
description="Full years since the day after completion of the ENTIRE "
|
| 599 |
+
"imposed sentence (conviction bases) or since the act was committed "
|
| 600 |
+
"(act basis).",
|
| 601 |
+
)
|
| 602 |
+
clean_record: bool = Field(
|
| 603 |
+
...,
|
| 604 |
+
description="True if the person has no other convictions or "
|
| 605 |
+
"committed acts anywhere (the IRPR s. 18(2)(i)-(vii) conditions, "
|
| 606 |
+
"simplified -- the answer carries a caveat to confirm in detail).",
|
| 607 |
+
)
|
| 608 |
+
|
| 609 |
+
|
| 610 |
+
@mcp.tool(name="canlex_rehabilitation",
|
| 611 |
+
annotations={"title": "Criminal Rehabilitation Assessment", **_READONLY})
|
| 612 |
+
def canlex_rehabilitation(params: RehabInput) -> str:
|
| 613 |
+
"""Assess whether a person is deemed rehabilitated, eligible to apply for
|
| 614 |
+
individual rehabilitation, or neither, under IRPA s. 36(3)(c) and IRPR
|
| 615 |
+
ss. 17-18.1 -- the time-based cures for criminal inadmissibility.
|
| 616 |
+
|
| 617 |
+
Rules verified against the current IRPR consolidation: deemed
|
| 618 |
+
rehabilitation (automatic) for a single <10-year-maximum foreign
|
| 619 |
+
conviction after 10 clean years, two-plus summary-only convictions after
|
| 620 |
+
5 years, or a single committed act after 10 years; individual
|
| 621 |
+
rehabilitation applications after 5 years (available even for serious
|
| 622 |
+
criminality, which can never be deemed); record suspensions for in-Canada
|
| 623 |
+
convictions. This is step 3 of a s. 36 screening: step 1 is whether the
|
| 624 |
+
disposition is a conviction (canlex_us_disposition), step 2 is offence
|
| 625 |
+
equivalency (which also supplies the max-penalty input here).
|
| 626 |
+
|
| 627 |
+
Returns:
|
| 628 |
+
str: The assessment with the governing provision, explanation and
|
| 629 |
+
mandatory caveats. Curated logic -- verify against the cited
|
| 630 |
+
provisions via canlex_get_section.
|
| 631 |
+
"""
|
| 632 |
+
from canlex.rehab import assess
|
| 633 |
+
from canlex.commentary import BANNER
|
| 634 |
+
r = assess(params.basis, params.max_penalty_lt_10, params.count,
|
| 635 |
+
params.years_elapsed, params.clean_record)
|
| 636 |
+
lines = [BANNER, "",
|
| 637 |
+
f"REHABILITATION STATUS: {r['status'].upper().replace('-', ' ')}",
|
| 638 |
+
f"Governing provision(s): {r['provision']}", "",
|
| 639 |
+
r["explanation"], "", "Caveats:"]
|
| 640 |
+
lines += [f"- {c}" for c in r["caveats"]]
|
| 641 |
+
lines.append("")
|
| 642 |
+
lines.append("Retrieve the provisions with canlex_get_section (act "
|
| 643 |
+
"'IRPR', sections '17'/'18'/'18.1'; act 'IRPA', section "
|
| 644 |
+
"'36').")
|
| 645 |
+
return "\n".join(lines)
|
| 646 |
+
|
| 647 |
+
|
| 648 |
@mcp.tool(name="canlex_us_disposition",
|
| 649 |
annotations={"title": "US Disposition vs IRPA 'Conviction'", **_READONLY})
|
| 650 |
def canlex_us_disposition(params: DispositionInput) -> str:
|
|
@@ -0,0 +1,285 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"reviewed": "2026-07-15",
|
| 3 |
+
"_provenance": "Authored 2026-07-12. Every Canadian maximum penalty verified against the corpus text of the Criminal Code (C-46) and CDSA (C-38.8), current consolidations; branch classifications apply IRPA s. 36(3)(a) (hybrid offences deemed indictable). Tran v Canada, 2017 SCC 50 (in-corpus) supplies the commission-date rule for assessing maximum penalties. Equivalency methodology per Hill v Canada (MEI) (1987), 73 NR 315 (FCA), as set out in IRB Legal Services, Sponsorship Appeals Ch. 2 (Criminal Refusals). These are the COMMON pairings only -- an unusual offence needs the full Hill analysis against the actual foreign statute.",
|
| 4 |
+
"methodology": [
|
| 5 |
+
{
|
| 6 |
+
"id": "equivalency-framework",
|
| 7 |
+
"title": "How offence equivalency works (step 2 of the s. 36 analysis)",
|
| 8 |
+
"text": "Equivalency asks whether the foreign offence, if committed in Canada, would constitute a federal offence of the required seriousness. The governing test is Hill v Canada (MEI) (1987), 73 NR 315 (FCA): equivalency can be established (1) by comparing the precise wording and essential elements of the two provisions; (2) by examining the evidence of what the person actually did, to see whether it would satisfy the essential elements of the Canadian offence; or (3) by a combination of both. Key rules: (a) HYBRID DEEMING -- IRPA s. 36(3)(a): an offence prosecutable either way in Canada is deemed indictable, at its indictable maximum, even if it would likely proceed summarily; (b) TIMING -- Tran v Canada, 2017 SCC 50: the maximum penalty is assessed as of the DATE OF COMMISSION, so a later increase in the Canadian maximum does not retroactively convert criminality into serious criminality; (c) THRESHOLDS -- Canadian property offences split at $5,000 (theft, fraud, mischief), so the value in the foreign record often decides the branch; (d) the comparison is with the CANADIAN offence's elements -- a foreign offence broader than its Canadian counterpart requires the evidence branch of Hill to see what was actually done; (e) purely SUMMARY Canadian equivalents (e.g. causing a disturbance, s. 175) cannot ground s. 36(2)(b) inadmissibility on a single conviction -- only the two-or-more-convictions branch reaches them."
|
| 9 |
+
}
|
| 10 |
+
],
|
| 11 |
+
"pairings": [
|
| 12 |
+
{
|
| 13 |
+
"id": "dui",
|
| 14 |
+
"us_terms": [
|
| 15 |
+
"DUI",
|
| 16 |
+
"DWI",
|
| 17 |
+
"OWI",
|
| 18 |
+
"OUI",
|
| 19 |
+
"driving under the influence",
|
| 20 |
+
"driving while intoxicated",
|
| 21 |
+
"operating under the influence",
|
| 22 |
+
"drunk driving",
|
| 23 |
+
"impaired driving"
|
| 24 |
+
],
|
| 25 |
+
"canadian_offence": "Criminal Code s. 320.14 (operation while impaired / over the legal limit); punishment s. 320.19",
|
| 26 |
+
"penalty": "Hybrid; indictable maximum 10 years (s. 320.19(1)(a): 'liable to imprisonment for a term of not more than 10 years')",
|
| 27 |
+
"branch": "SERIOUS CRIMINALITY -- IRPA s. 36(1)(b): via s. 36(3)(a) hybrid deeming, a single ordinary US DUI conviction equates to an offence punishable by 10 years",
|
| 28 |
+
"status": "judicially-considered",
|
| 29 |
+
"analysis": "The single most consequential everyday pairing: one US misdemeanor DUI grounds serious criminality, because Canada's impaired-driving offence is hybrid with a 10-year indictable maximum since December 18, 2018. Deemed rehabilitation is therefore unavailable (10-year-or-more maximum); only individual rehabilitation or a TRP cures it.",
|
| 30 |
+
"caveats": [
|
| 31 |
+
"TIMING (Tran, 2017 SCC 50): for offences COMMITTED before December 18, 2018, the equivalent was the former s. 253 (maximum 5 years) -- criminality under s. 36(2)(b) only, not serious criminality, and deemed rehabilitation remains available.",
|
| 32 |
+
"Zero-tolerance administrative per-se findings are not convictions (see the DUI entry in the dispositions helper); this pairing addresses criminal DUI convictions.",
|
| 33 |
+
"A US 'wet reckless' plea-down maps to careless/dangerous driving analysis, not s. 320.14 -- check what was actually convicted."
|
| 34 |
+
],
|
| 35 |
+
"authorities": [
|
| 36 |
+
{
|
| 37 |
+
"cite": "Tran v Canada (Public Safety), 2017 SCC 50",
|
| 38 |
+
"court": "Supreme Court of Canada",
|
| 39 |
+
"holding": "The maximum term for equivalency/seriousness purposes is assessed as of the date of commission; subsequent increases do not apply retrospectively."
|
| 40 |
+
}
|
| 41 |
+
]
|
| 42 |
+
},
|
| 43 |
+
{
|
| 44 |
+
"id": "theft-under",
|
| 45 |
+
"us_terms": [
|
| 46 |
+
"petty theft",
|
| 47 |
+
"petit larceny",
|
| 48 |
+
"shoplifting",
|
| 49 |
+
"misdemeanor theft",
|
| 50 |
+
"theft under"
|
| 51 |
+
],
|
| 52 |
+
"canadian_offence": "Criminal Code s. 334(b) (theft not exceeding $5,000)",
|
| 53 |
+
"penalty": "Hybrid; indictable maximum 2 years (s. 334(b)(i))",
|
| 54 |
+
"branch": "CRIMINALITY -- IRPA s. 36(2)(b) (foreign national); a permanent resident is NOT inadmissible on this alone",
|
| 55 |
+
"status": "guidance-only",
|
| 56 |
+
"analysis": "Ordinary shoplifting equates to theft under $5,000: hybrid, deemed indictable, 2-year maximum. One conviction makes a foreign national inadmissible for criminality; two convictions not arising from a single occurrence also engage s. 36(2)(b). Deemed rehabilitation after 10 years (single) per IRPR s. 18(2)(a).",
|
| 57 |
+
"caveats": [
|
| 58 |
+
"Convert the stolen value at the offence date: a US 'felony grand theft' at a low state threshold (some states: $500+) may still be theft UNDER $5,000 in Canadian terms -- the CANADIAN threshold controls the branch.",
|
| 59 |
+
"Value over $5,000 -> s. 334(a), 10-year maximum -> serious criminality (see theft-over)."
|
| 60 |
+
],
|
| 61 |
+
"authorities": []
|
| 62 |
+
},
|
| 63 |
+
{
|
| 64 |
+
"id": "theft-over",
|
| 65 |
+
"us_terms": [
|
| 66 |
+
"grand theft",
|
| 67 |
+
"grand larceny",
|
| 68 |
+
"felony theft",
|
| 69 |
+
"auto theft",
|
| 70 |
+
"grand theft auto"
|
| 71 |
+
],
|
| 72 |
+
"canadian_offence": "Criminal Code s. 334(a) (theft exceeding $5,000); motor vehicle theft s. 333.1",
|
| 73 |
+
"penalty": "Indictable maximum 10 years (s. 334(a): 'not more than 10 years'); motor vehicle theft (s. 333.1) hybrid, 10 years",
|
| 74 |
+
"branch": "SERIOUS CRIMINALITY -- IRPA s. 36(1)(b), where the value genuinely exceeds $5,000 (or the subject is a motor vehicle under s. 333.1)",
|
| 75 |
+
"status": "guidance-only",
|
| 76 |
+
"analysis": "Theft of property over $5,000 (Canadian dollars, at the offence date) is a 10-year offence: serious criminality; no deemed rehabilitation.",
|
| 77 |
+
"caveats": [
|
| 78 |
+
"The US felony label does not control -- verify the actual value against the Canadian $5,000 line; borderline values with exchange-rate movement deserve the evidence branch of Hill."
|
| 79 |
+
],
|
| 80 |
+
"authorities": []
|
| 81 |
+
},
|
| 82 |
+
{
|
| 83 |
+
"id": "assault-simple",
|
| 84 |
+
"us_terms": [
|
| 85 |
+
"simple assault",
|
| 86 |
+
"misdemeanor assault",
|
| 87 |
+
"battery",
|
| 88 |
+
"simple battery",
|
| 89 |
+
"assault in the fourth degree"
|
| 90 |
+
],
|
| 91 |
+
"canadian_offence": "Criminal Code s. 266 (assault)",
|
| 92 |
+
"penalty": "Hybrid; indictable maximum 5 years (s. 266(a): 'not exceeding five years')",
|
| 93 |
+
"branch": "CRIMINALITY -- IRPA s. 36(2)(b)",
|
| 94 |
+
"status": "guidance-only",
|
| 95 |
+
"analysis": "US simple assault/battery generally equates to s. 266: hybrid, 5-year maximum -- criminality, not serious criminality. Deemed rehabilitation available after 10 years (single conviction).",
|
| 96 |
+
"caveats": [
|
| 97 |
+
"Bodily injury, a weapon, or choking moves the equivalent to s. 267 (10 years) -> serious criminality (see assault-aggravated).",
|
| 98 |
+
"Domestic-violence variants equate to the same assault provisions; the DV character matters to sentencing and to some US dispositions, not to the Canadian equivalency.",
|
| 99 |
+
"Some US assault statutes cover mere threats -- threat-only conduct maps to s. 264.1 (uttering threats, 5 years), same branch."
|
| 100 |
+
],
|
| 101 |
+
"authorities": []
|
| 102 |
+
},
|
| 103 |
+
{
|
| 104 |
+
"id": "assault-aggravated",
|
| 105 |
+
"us_terms": [
|
| 106 |
+
"aggravated assault",
|
| 107 |
+
"assault with a deadly weapon",
|
| 108 |
+
"ADW",
|
| 109 |
+
"felony assault",
|
| 110 |
+
"assault causing injury",
|
| 111 |
+
"domestic battery with injury"
|
| 112 |
+
],
|
| 113 |
+
"canadian_offence": "Criminal Code s. 267 (assault with a weapon / causing bodily harm / choking); s. 268 (aggravated assault)",
|
| 114 |
+
"penalty": "s. 267: hybrid, indictable maximum 10 years; s. 268: indictable, maximum 14 years",
|
| 115 |
+
"branch": "SERIOUS CRIMINALITY -- IRPA s. 36(1)(b)",
|
| 116 |
+
"status": "guidance-only",
|
| 117 |
+
"analysis": "Weapon involvement or bodily harm lifts the Canadian equivalent to s. 267 (10 years) or s. 268 (wounding/maiming, 14 years): serious criminality either way; no deemed rehabilitation.",
|
| 118 |
+
"caveats": [
|
| 119 |
+
"US 'aggravated' labels sometimes rest only on the victim's status (e.g. assault on an officer) -- if no weapon/injury, the closer equivalent may be s. 270 (assaulting an officer, hybrid 5 years) -> criminality only. Use the evidence branch."
|
| 120 |
+
],
|
| 121 |
+
"authorities": []
|
| 122 |
+
},
|
| 123 |
+
{
|
| 124 |
+
"id": "fraud",
|
| 125 |
+
"us_terms": [
|
| 126 |
+
"fraud",
|
| 127 |
+
"bad checks",
|
| 128 |
+
"check fraud",
|
| 129 |
+
"insufficient funds",
|
| 130 |
+
"credit card fraud",
|
| 131 |
+
"identity theft",
|
| 132 |
+
"wire fraud"
|
| 133 |
+
],
|
| 134 |
+
"canadian_offence": "Criminal Code s. 380 (fraud); s. 342 (credit card offences); s. 402.2 (identity theft)",
|
| 135 |
+
"penalty": "s. 380(1)(a): indictable maximum 14 years where value exceeds $5,000; s. 380(1)(b): hybrid, 2 years where value $5,000 or less",
|
| 136 |
+
"branch": "SERIOUS CRIMINALITY over $5,000 (36(1)(b)); CRIMINALITY at or under $5,000 (36(2)(b))",
|
| 137 |
+
"status": "guidance-only",
|
| 138 |
+
"analysis": "Fraud splits on the $5,000 line exactly like theft. Bad-check convictions are usually small-value: hybrid 2-year equivalents -> criminality. Larger frauds (14 years) are serious criminality.",
|
| 139 |
+
"caveats": [
|
| 140 |
+
"Many US bad-check statutes criminalize mere non-payment without dishonesty elements -- where intent to defraud is not an element, the Canadian equivalent may fail on essential elements; use the Hill evidence branch."
|
| 141 |
+
],
|
| 142 |
+
"authorities": []
|
| 143 |
+
},
|
| 144 |
+
{
|
| 145 |
+
"id": "drug-possession",
|
| 146 |
+
"us_terms": [
|
| 147 |
+
"drug possession",
|
| 148 |
+
"possession of a controlled substance",
|
| 149 |
+
"simple possession",
|
| 150 |
+
"cocaine possession",
|
| 151 |
+
"meth possession",
|
| 152 |
+
"narcotics possession"
|
| 153 |
+
],
|
| 154 |
+
"canadian_offence": "CDSA s. 4(1) (possession); punishment s. 4(3)-(6) by schedule",
|
| 155 |
+
"penalty": "Schedule I (cocaine, heroin, meth, fentanyl): hybrid, indictable maximum 7 years (s. 4(3)(a): 'not exceeding seven years'); Schedule III: hybrid, 3 years",
|
| 156 |
+
"branch": "CRIMINALITY -- IRPA s. 36(2)(b) (7-year maximum is below the 10-year serious-criminality line)",
|
| 157 |
+
"status": "guidance-only",
|
| 158 |
+
"analysis": "Simple possession of hard drugs equates to CDSA s. 4(1): hybrid, 7-year maximum for Schedule I -- criminality, NOT serious criminality. Deemed rehabilitation available after 10 clean years for a single conviction.",
|
| 159 |
+
"caveats": [
|
| 160 |
+
"CANNABIS IS DIFFERENT: see the cannabis entry -- simple possession within legal limits is no longer an offence in Canada at all.",
|
| 161 |
+
"Possession WITH INTENT to distribute equates to trafficking (see drug-trafficking): a completely different branch."
|
| 162 |
+
],
|
| 163 |
+
"authorities": []
|
| 164 |
+
},
|
| 165 |
+
{
|
| 166 |
+
"id": "cannabis-possession",
|
| 167 |
+
"us_terms": [
|
| 168 |
+
"marijuana possession",
|
| 169 |
+
"cannabis possession",
|
| 170 |
+
"possession of marijuana",
|
| 171 |
+
"weed possession"
|
| 172 |
+
],
|
| 173 |
+
"canadian_offence": "None for simple possession within legal limits -- the Cannabis Act legalized adult possession of up to 30 g of dried cannabis (public)",
|
| 174 |
+
"penalty": "Not an offence in Canada (within limits); over-limit possession: Cannabis Act s. 8, hybrid, maximum 5 years less a day",
|
| 175 |
+
"branch": "NO INADMISSIBILITY for simple possession equivalents: with no equivalent Canadian offence, neither s. 36(1)(b) nor s. 36(2)(b) can be made out",
|
| 176 |
+
"status": "guidance-only",
|
| 177 |
+
"analysis": "A US conviction for simple marijuana possession (an amount lawful in Canada) has no Canadian equivalent offence since October 17, 2018 -- there is nothing to equate, so the conviction cannot ground criminal inadmissibility. This is the clearest 'NO' in the pairing table.",
|
| 178 |
+
"caveats": [
|
| 179 |
+
"Quantities beyond Canadian legal limits, distribution, sale, cultivation beyond limits, and import/export DO have Cannabis Act equivalents (ss. 8-14; import/export max 14 years -> serious criminality).",
|
| 180 |
+
"The equivalency is assessed against Canadian law at the ADMISSIBILITY DECISION date for the would-it-be-an-offence question -- post-legalization assessments of old possession convictions find no equivalent offence.",
|
| 181 |
+
"US felony marijuana TRAFFICKING remains serious criminality (Cannabis Act s. 9/10 or CDSA analysis)."
|
| 182 |
+
],
|
| 183 |
+
"authorities": []
|
| 184 |
+
},
|
| 185 |
+
{
|
| 186 |
+
"id": "drug-trafficking",
|
| 187 |
+
"us_terms": [
|
| 188 |
+
"drug trafficking",
|
| 189 |
+
"possession with intent to distribute",
|
| 190 |
+
"PWID",
|
| 191 |
+
"drug distribution",
|
| 192 |
+
"sale of a controlled substance",
|
| 193 |
+
"drug dealing"
|
| 194 |
+
],
|
| 195 |
+
"canadian_offence": "CDSA s. 5 (trafficking / possession for the purpose)",
|
| 196 |
+
"penalty": "Schedule I or II: indictable, maximum LIFE (s. 5(3)(a): 'liable to imprisonment for life'); Schedule III/V: hybrid, 10 years",
|
| 197 |
+
"branch": "SERIOUS CRIMINALITY -- IRPA s. 36(1)(b) for any schedule (all branches reach at least 10 years)",
|
| 198 |
+
"status": "guidance-only",
|
| 199 |
+
"analysis": "Any trafficking or possession-with-intent conviction equates to CDSA s. 5: serious criminality at every schedule level. No deemed rehabilitation; individual rehabilitation after 5 years or TRP only.",
|
| 200 |
+
"caveats": [
|
| 201 |
+
"Also engages potential organized-criminality analysis (s. 37) where a criminal organization is involved."
|
| 202 |
+
],
|
| 203 |
+
"authorities": []
|
| 204 |
+
},
|
| 205 |
+
{
|
| 206 |
+
"id": "disorderly-conduct",
|
| 207 |
+
"us_terms": [
|
| 208 |
+
"disorderly conduct",
|
| 209 |
+
"disturbing the peace",
|
| 210 |
+
"public disturbance",
|
| 211 |
+
"breach of the peace",
|
| 212 |
+
"public intoxication"
|
| 213 |
+
],
|
| 214 |
+
"canadian_offence": "Criminal Code s. 175 (causing a disturbance)",
|
| 215 |
+
"penalty": "SUMMARY ONLY -- s. 175 is a pure summary conviction offence",
|
| 216 |
+
"branch": "A SINGLE conviction grounds NO inadmissibility: s. 36(2)(b) requires an indictable-equivalent, and s. 175 is not one. TWO OR MORE convictions (not from a single occurrence) engage s. 36(2)(b)'s second branch",
|
| 217 |
+
"status": "guidance-only",
|
| 218 |
+
"analysis": "The most common harmless record: one US disorderly conduct/disturbing-the-peace conviction, equated to s. 175 (summary only), makes NOBODY inadmissible -- not even a foreign national. The two-or-more branch changes that, and IRPR s. 18(2)(b) then offers deemed rehabilitation five years after the sentences.",
|
| 219 |
+
"caveats": [
|
| 220 |
+
"Check what the conviction actually covers: some US disorderly statutes bundle assaultive or threatening conduct that would equate to hybrid offences -- the evidence branch of Hill controls where the statute is broader than s. 175.",
|
| 221 |
+
"Public intoxication alone typically has no federal Canadian equivalent at all (provincial regulatory matter) -- even cleaner than s. 175."
|
| 222 |
+
],
|
| 223 |
+
"authorities": []
|
| 224 |
+
},
|
| 225 |
+
{
|
| 226 |
+
"id": "resisting-arrest",
|
| 227 |
+
"us_terms": [
|
| 228 |
+
"resisting arrest",
|
| 229 |
+
"obstruction",
|
| 230 |
+
"obstructing an officer",
|
| 231 |
+
"evading arrest",
|
| 232 |
+
"failure to comply with police"
|
| 233 |
+
],
|
| 234 |
+
"canadian_offence": "Criminal Code s. 129 (resisting or obstructing a peace officer)",
|
| 235 |
+
"penalty": "Hybrid; indictable maximum 2 years (s. 129(d): 'not exceeding two years')",
|
| 236 |
+
"branch": "CRIMINALITY -- IRPA s. 36(2)(b)",
|
| 237 |
+
"status": "guidance-only",
|
| 238 |
+
"analysis": "Non-violent resisting/obstruction equates to s. 129: hybrid, 2-year maximum -- criminality only.",
|
| 239 |
+
"caveats": [
|
| 240 |
+
"Vehicle flight equates to s. 320.17 (flight from police: hybrid, 10 years) -> SERIOUS criminality -- distinguish on-foot obstruction from vehicular flight.",
|
| 241 |
+
"Assaulting the officer moves it to s. 270 or s. 267 territory."
|
| 242 |
+
],
|
| 243 |
+
"authorities": []
|
| 244 |
+
},
|
| 245 |
+
{
|
| 246 |
+
"id": "threats",
|
| 247 |
+
"us_terms": [
|
| 248 |
+
"criminal threatening",
|
| 249 |
+
"terroristic threats",
|
| 250 |
+
"menacing",
|
| 251 |
+
"harassment threats",
|
| 252 |
+
"intimidation"
|
| 253 |
+
],
|
| 254 |
+
"canadian_offence": "Criminal Code s. 264.1 (uttering threats)",
|
| 255 |
+
"penalty": "Hybrid; indictable maximum 5 years for threats to cause death or bodily harm (s. 264.1(2)(a))",
|
| 256 |
+
"branch": "CRIMINALITY -- IRPA s. 36(2)(b)",
|
| 257 |
+
"status": "guidance-only",
|
| 258 |
+
"analysis": "Threat offences equate to s. 264.1: hybrid, 5-year maximum -- criminality. Criminal harassment courses of conduct equate to s. 264 (10 years) -> serious criminality instead.",
|
| 259 |
+
"caveats": [
|
| 260 |
+
"'Terroristic threats' is a state-law label with no terrorism content -- do not confuse with IRPA s. 34 security grounds absent actual terrorism facts.",
|
| 261 |
+
"Repeated/stalking conduct: s. 264 criminal harassment (10 years) -> serious criminality."
|
| 262 |
+
],
|
| 263 |
+
"authorities": []
|
| 264 |
+
},
|
| 265 |
+
{
|
| 266 |
+
"id": "mischief-vandalism",
|
| 267 |
+
"us_terms": [
|
| 268 |
+
"vandalism",
|
| 269 |
+
"criminal mischief",
|
| 270 |
+
"malicious mischief",
|
| 271 |
+
"property damage",
|
| 272 |
+
"graffiti"
|
| 273 |
+
],
|
| 274 |
+
"canadian_offence": "Criminal Code s. 430 (mischief)",
|
| 275 |
+
"penalty": "Value over $5,000: hybrid, indictable maximum 10 years (s. 430(3)); $5,000 or under: hybrid, 2 years (s. 430(4))",
|
| 276 |
+
"branch": "CRIMINALITY at or under $5,000 (36(2)(b)); SERIOUS CRIMINALITY over $5,000 (36(1)(b))",
|
| 277 |
+
"status": "guidance-only",
|
| 278 |
+
"analysis": "Vandalism splits on the $5,000 damage value like the other property offences. Ordinary graffiti/vandalism records are 2-year equivalents -> criminality.",
|
| 279 |
+
"caveats": [
|
| 280 |
+
"The damage figure in the US record (restitution ordered is a good proxy) decides the branch -- convert to CAD at the offence date."
|
| 281 |
+
],
|
| 282 |
+
"authorities": []
|
| 283 |
+
}
|
| 284 |
+
]
|
| 285 |
+
}
|
|
@@ -0,0 +1,71 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"""Unit tests for the rehabilitation rule engine (canlex/rehab.py).
|
| 2 |
+
|
| 3 |
+
Offline; the rule table mirrors IRPR ss. 17, 18(2)(a)-(c) and 18.1.
|
| 4 |
+
|
| 5 |
+
python -m unittest discover -s tests
|
| 6 |
+
"""
|
| 7 |
+
import unittest
|
| 8 |
+
|
| 9 |
+
from canlex.rehab import assess
|
| 10 |
+
|
| 11 |
+
|
| 12 |
+
class DeemedRehabTests(unittest.TestCase):
|
| 13 |
+
def test_single_foreign_conviction_deemed_after_10_clean_years(self):
|
| 14 |
+
r = assess("foreign-conviction", True, "one", 10, True)
|
| 15 |
+
self.assertEqual(r["status"], "deemed-rehabilitated")
|
| 16 |
+
self.assertIn("18(2)(a)", r["provision"])
|
| 17 |
+
|
| 18 |
+
def test_not_deemed_at_9_years_but_eligible_to_apply(self):
|
| 19 |
+
r = assess("foreign-conviction", True, "one", 9, True)
|
| 20 |
+
self.assertEqual(r["status"], "eligible-to-apply")
|
| 21 |
+
|
| 22 |
+
def test_dirty_record_defeats_deemed(self):
|
| 23 |
+
r = assess("foreign-conviction", True, "one", 12, False)
|
| 24 |
+
self.assertEqual(r["status"], "eligible-to-apply")
|
| 25 |
+
|
| 26 |
+
def test_two_summary_convictions_deemed_after_5_years(self):
|
| 27 |
+
r = assess("foreign-conviction", True, "two-plus-summary-only", 5, True)
|
| 28 |
+
self.assertEqual(r["status"], "deemed-rehabilitated")
|
| 29 |
+
self.assertIn("18(2)(b)", r["provision"])
|
| 30 |
+
|
| 31 |
+
def test_committed_act_deemed_after_10_years(self):
|
| 32 |
+
r = assess("foreign-act", True, "one", 10, True)
|
| 33 |
+
self.assertEqual(r["status"], "deemed-rehabilitated")
|
| 34 |
+
self.assertIn("18(2)(c)", r["provision"])
|
| 35 |
+
|
| 36 |
+
|
| 37 |
+
class SeriousCriminalityTests(unittest.TestCase):
|
| 38 |
+
def test_never_deemed_even_after_decades(self):
|
| 39 |
+
r = assess("foreign-conviction", False, "one", 30, True)
|
| 40 |
+
self.assertEqual(r["status"], "eligible-to-apply")
|
| 41 |
+
self.assertIn("17", r["provision"])
|
| 42 |
+
|
| 43 |
+
def test_under_5_years_nothing_available(self):
|
| 44 |
+
r = assess("foreign-conviction", False, "one", 3, True)
|
| 45 |
+
self.assertEqual(r["status"], "not-yet")
|
| 46 |
+
|
| 47 |
+
|
| 48 |
+
class InCanadaTests(unittest.TestCase):
|
| 49 |
+
def test_record_suspension_route(self):
|
| 50 |
+
r = assess("canada-conviction", True, "one", 20, True)
|
| 51 |
+
self.assertEqual(r["status"], "record-suspension-route")
|
| 52 |
+
self.assertIn("36(3)(b)", r["provision"])
|
| 53 |
+
|
| 54 |
+
def test_two_summary_class_exempt_after_5_years(self):
|
| 55 |
+
r = assess("canada-conviction", True, "two-plus-summary-only", 5, True)
|
| 56 |
+
self.assertEqual(r["status"], "exempt")
|
| 57 |
+
self.assertIn("18.1", r["provision"])
|
| 58 |
+
|
| 59 |
+
def test_two_summary_class_not_yet_at_4_years(self):
|
| 60 |
+
r = assess("canada-conviction", True, "two-plus-summary-only", 4, True)
|
| 61 |
+
self.assertEqual(r["status"], "not-yet")
|
| 62 |
+
|
| 63 |
+
|
| 64 |
+
class MultipleIndictableTests(unittest.TestCase):
|
| 65 |
+
def test_never_deemed_apply_only(self):
|
| 66 |
+
r = assess("foreign-conviction", True, "multiple", 15, True)
|
| 67 |
+
self.assertEqual(r["status"], "eligible-to-apply")
|
| 68 |
+
|
| 69 |
+
|
| 70 |
+
if __name__ == "__main__":
|
| 71 |
+
unittest.main()
|