The direction of deference, with the source to back it up.
A rule-based Japanese linter says nothing about 「お持ちします」. As a string it is fine. But if the reader is the one carrying something, that form does not raise them — it raises whoever the act is directed to, which here is the writer.
Deference decides from whose action it is, who it is directed to, and whether the message goes inside or outside your company, then cites the page of the Council for Cultural Affairs’ Keigo no Shishin (敬語の指針, 2007) the judgement rests on.
This page is a static Space, so the model does not run in your browser. Everything below is genuine output from the published model, recorded in advance. To check your own text, see Run it yourself.
needs context surface form variation — not reported
On error types that cannot be decided without context, textlint and a surface-rule set both score 0.0%. On types that are visible in the surface pattern, the rule set also reaches 100% — and no advantage is claimed there.
Painting every divided usage red destroys trust in a checker. The guidelines say as much themselves:
男女の違いや世代の違いなどによって画一的に考える態度は避けるべきである。
(One should avoid treating usage uniformly by gender or
generation.) — Ch.1 Sec.2-2, p.8
53 such cases are held apart and reported as none of them by default: doubled honorifics the report calls established by custom (お伺いする), forms it calls equally usable (ご利用いただく ↔ ご利用くださる), and usages whose tolerance it says varies by individual (させていただく).
Output stays informational — how the guidelines organise the matter, not a verdict. Tests enforce this in both languages, checking that phrases like “is wrong” or 「誤用」 never reach the user. Every run closes with:
Honorifics are chosen as a form of self-expression (Keigo no Shishin, Ch.1 Sec.1-3). What is shown here is how the guidelines organise the matter; it is not a judgement on the writer’s Japanese.
pip install git+https://github.com/NagaYu/deference
deference check mail.txt --audience external
deference check mail.txt --audience internal # the judgement changes
from deference import Deference, MailContext, Audience
result = Deference().check(open("mail.txt").read(), MailContext(audience=Audience.EXTERNAL))
for f in result.reportable: print(f.span.text, f.message, f.citation.render("en"))
The model is 277.5M parameters and runs on CPU in about 26 ms per message after int8 quantisation. It works without the trained checkpoint too, falling back to the rule engine.