Appendix B · section 20 of 32
ask/schedule.ts
From Once Found, Look It Up.
import type { Law } from "./corpus.js";
// The court's fine schedule: what a driver actually pays, whether it can be
// paid without going to court, and the points. The code says what a driver
// must do and, at most, the range a fine may fall in; the figure a learner
// pays for not showing a license is $50 in the District Court's schedule and
// in no section of the Transportation Article.
export interface PenaltyRow {
id: string;
state: string;
/** The section the row joins to: the key the code's rows carry too. */
section: string;
/** The schedule's own reference, "16-112(c)", which the id is made from. */
code: string;
/** The offence in the schedule's own wording. */
offence: string;
fine_text: string;
fine_min_cents: number | null;
fine_max_cents: number | null;
points: number | null;
appear: "payable" | "must-appear" | "court-sets";
source_url: string;
source_title: string;
as_of: string;
/** The schedule's own line, verbatim: what the figure is grounded on. */
quote: string;
}
const SOURCE = {
state: "MD",
source_url: "https://www.mdcourts.gov/sites/default/files/court-forms/dccr090.pdf",
source_title: "District Court of Maryland, DC-CR-090 (Rev. 10/2026)",
as_of: "2026-10-11",
} as const;
export const ROWS: PenaltyRow[] = [
{
...SOURCE,
id: "MD-P-16-112-b",
section: "Md. Code, Transp. § 16-112",
code: "16-112(b)",
offence: "Failure of individual driving on hwy. to have lic. with them",
fine_text: "$50.00",
fine_min_cents: 5000,
fine_max_cents: 5000,
points: 0,
appear: "payable",
quote: "16 112 b Failure of individual driving on hwy. to have lic. with them $ 50.00 00",
},
{
...SOURCE,
id: "MD-P-16-112-c",
section: "Md. Code, Transp. § 16-112",
code: "16-112(c)",
offence: "Failure of individual driving on hwy. to display lic. to uniformed police on demand",
fine_text: "$50.00",
fine_min_cents: 5000,
fine_max_cents: 5000,
points: 0,
appear: "payable",
quote: "16 112 c Failure of individual driving on hwy. to display lic. to uniformed police on demand $ 50.00 00",
},
{
...SOURCE,
id: "MD-P-21-604-d",
section: "Md. Code, Transp. § 21-604",
code: "21-604(d)",
offence: "Driver failing to give turn signal continuously during last 100 ft. of travel before turning",
fine_text: "$90.00",
fine_min_cents: 9000,
fine_max_cents: 9000,
points: 1,
appear: "payable",
quote: "21 604 d Driver failing to give turn signal continuously during last 100 ft. of travel before turning $ 90.00 01",
},
{
...SOURCE,
id: "MD-P-21-801-1",
section: "Md. Code, Transp. § 21-801.1",
code: "21-801.1",
offence: "Driving veh. on hwy. at speed exceeding limit Exceeding posted speed limit by: 1 to 9 mph",
fine_text: "$80.00",
fine_min_cents: 8000,
fine_max_cents: 8000,
points: 1,
appear: "payable",
quote: "21 801.1 Driving veh. on hwy. at speed exceeding limit Exceeding posted speed limit by: 1 to 9 mph $ 80.00 01",
},
];
/** Cents as a learner reads a price: "$50", "$25.50", "$1,000". */
export function dollars(cents: number): string {
const whole = Math.floor(cents / 100);
const rest = cents % 100;
return `$${whole.toLocaleString("en-US")}${rest === 0 ? "" : `.${String(rest).padStart(2, "0")}`}`;
}
function pointsPhrase(points: number | null): string {
if (points === null) return "";
return points === 0 ? ", no points" : `, ${points} point${points === 1 ? "" : "s"}`;
}
// The law a schedule row is given to the model as: one sentence a learner can
// read. A row the court sets names the range and says so, never the low
// figure alone: "$25" for an offence a court may fine $200 is a promise the
// schedule does not make. Points only where the row has them: "no points"
// from a source that does not list points would be invented.
export function penaltySentence(row: PenaltyRow): string {
const points = pointsPhrase(row.points);
const { fine_min_cents: min, fine_max_cents: max } = row;
if (row.appear === "must-appear") {
return `${row.offence}: you must go to court, and the court sets the fine${points}.`;
}
if (row.appear === "court-sets") {
const range =
min !== null && max !== null
? `within ${dollars(min)} to ${dollars(max)}`
: max !== null
? `of up to ${dollars(max)}`
: min !== null
? `of at least ${dollars(min)}`
: "in an amount the law leaves to it";
return `${row.offence}: a fine set by the court ${range}${points}.`;
}
const fine = min === null ? row.fine_text : max === null || max === min ? dollars(min) : `${dollars(min)} to ${dollars(max)}`;
return `${row.offence}: ${fine}, can be paid without going to court${points}.`;
}
/** A schedule row as a law the model is given and the checker grounds, cited to the schedule's own line. */
export function penaltyLaw(row: PenaltyRow): Law {
return {
id: row.id,
law: penaltySentence(row),
question: "",
concept: row.offence,
citation: `${row.source_title} — '${row.quote}'`,
kind: "penalty",
asOf: row.as_of,
};
}