The datetime rule only matched a literal holding a call such as
datetime('now'). The query builder spells the same function as
eb.fn('datetime', [...]), where the literal is just the name, so that form
slipped through while strftime, json_extract and glob are caught bare. A
literal that is exactly datetime, julianday or unixepoch now counts as well,
the same way the glob rule treats a bare glob. The only such call lives in the
dialect layer, which is not scanned, so the baseline does not change.
ESLint keeps raw SQL out of the repositories, but nothing looked at the rest
of src/: the entities, the domain services, the src/db lifecycle files or a
migration added from now on. scripts/dialect-lint.mjs (npm run lint:dialect)
reads every string and template literal under src/, skipping comments, and
counts INSERT OR IGNORE/REPLACE, datetime(), strftime, json_extract, GLOB,
last_insert_rowid, AUTOINCREMENT, PRAGMA outside the lifecycle files, ||
concatenation in SQL and .insertId reads. scripts/dialect-baseline.json
holds today's thirteen hits; the counts may only go down, like lint:size.
The dialect layer is not scanned, and neither are the migrations that have
shipped.
The four seeders that still spelled INSERT OR IGNORE (addons, photo and
document providers, the schema_version marker) are Kysely inserts that do
nothing on conflict now, so a re-run still leaves an operator's rows alone.
They leave the SQL-string exemption list in eslint.config.mjs and their pins
in the selector test.