Example · ce-linear · document.ce.md
---
{
"@context": "https://w3id.org/canonical-english/context/v1",
"@graph": [
{ "@id": "oewn:06645018-n", "form": "hello" },
{ "@id": "oewn:02475618-n", "form": "world" }
]
}
---
Hello, world!
Canonical English (CE) is a
controlled natural language
(CNL) for machine authors: a formal, computable, unambiguous subset of English intended for
machine-to-human and
machine-to-machine communication. Humans can write it
too, with machine assistance (for example
noah-parser, which performs
semantic parsing).
CE is a domain-schema-independent API for agentic communication.
CE is meant to match uncontrolled English in semantic expressibility and beauty in the formal register — a better English, for the machine era. It is written by and for machines, and for humans who need the text to be unambiguous. Proper nouns carry stable semantic-web URIs, so the same text is readable by people and unambiguous even into the far future, after the original context is gone.
Every CE sentence is assigned exactly one syntax tree, the way a compiler assigns a program an abstract syntax tree. Ordinary English does not record one: attachment, scope, and function are recovered by the reader, and two readers need not agree. That tree enables use cases a string of English cannot support: rewrite by time or person, query by grammatical structure, reversible edits, house style as a check.
noah:
ruff
for natural English. A highly opinionated and extremely fast
linter, written in Rust. Refuses to accept any ambiguity or
grammatical or spelling mistakes or variations. Can be used in a
tight loop with LLMs to produce high-quality English prose for
communication with humans or other agents. [UNDER DEVELOPMENT]
noah-parser
performs
semantic parsing: it converts an English sentence into a
Discourse Representation Structure, a machine-understandable logical form, and records each content
word’s WordNet sense in the JSON-LD frontmatter. The linter does not
parse meaning; it checks that a CE file already records one parse, one
sense, and one referent.
Although self-attention models parse natural text well, those models do not record which sense or which entity they chose, so every later reader must still perform word sense disambiguation and entity disambiguation — and because the models are non-deterministic, two readings need not agree [2]. CE moves that burden to the writing step, where attention models resolve each sense and embed the result in the text. Once written, CE is deterministic: every content lexeme carries its sense in the metadata, and nothing is re-inferred downstream.
CE is a formal grammar, a sense-resolved lexicon, and formatting conventions that produce readable, unambiguous output. By “unambiguous” we mean that CE documents are free from all three sources of ambiguity:
Syntactic ambiguity what is attached to what?
Structure. Every CE sentence has exactly one parse. The CE rule set admits no second reading. The same prepositional-phrase attachment (“with the telescope”) is a standard test of whether a semantic parser records both logical forms or silently drops one [1].
English two parses
I saw the man with the telescope.
CE one parse
I saw a man who had a telescope.
Lexical ambiguity which sense of a word is intended?
Sense. Every content lexeme — a word, or a multi-word OEWN lemma such as cherry tree — resolves to exactly one lexicon entry, so no reader has to perform word sense disambiguation.
English one spelling, many senses
She sat on the bank.
CE one sense
She sat on the bank.
https://en-word.net/id/oewn-09236472-n sloping land beside a body of water
Referential/world ambiguity which real-world entity or situation is being discussed?
Reference. Every proper noun resolves to a semantic-web URI, so no reader has to perform entity disambiguation.
English which one?
Steve Smith scored a century.
CE one referent
Steve Smith scored a century.
wikidata.org/entity/Q7613970 Steven Peter Devereux Smith, cricketer
CE consists of:
ce-linear is formatted as
GitHub-flavored Markdown
(GFM pinned). First-pass checking is
markdownlint. A ce-linear text must be valid GFM and must
conform to every
style rule — citations, punctuation,
hyphenation, dates and times, units, and title case.
ce-tree is the same document as JSON-LD.
Canonical English is useful in the formal, bench-level, in-house, neutral, technical, and consultative registers.
It is not intended to be used for the slang register, where deviations from proper grammar are de rigueur.
CE resolves syntactic, lexical, and referential ambiguity. It does not encode pragmatics — what an utterance is doing in a situation, beyond the proposition the words literally express. No amount of dictionary sense disambiguation closes that gap.
“Can you open the window?” is grammatically a question about ability. In ordinary use it is usually a request. “That’s interesting.” can be genuine enthusiasm, polite dismissal, sarcasm, surprise, or criticism. Those readings are not further senses of interesting; they are uses of the same proposition.
CE specifies literal propositional meaning and does not attempt to encode pragmatics (In linguistics and the philosophy of language, pragmatics is the study of how context contributes to meaning.). A CE document records the question about ability, and the predication that something is interesting. The request, and the tone, remain outside the language.
Formal-register communication is, by definition, intended to be low-context (i.e., low-pragmatics). The author encodes as much of the situation as possible in the words themselves, so a later reader can recover the assertions without sharing the original physical or social environment. Constraining CE to that register therefore makes the task of embedding context easier, since the gap is already intended to be minimal.
Fine-grained WordNet senses are among the hardest labels in natural-language processing to agree on. Trained human annotators agree roughly 70 percent of the time. The OntoNotes project merged senses specifically to reach 90 percent agreement [16].
That ceiling would become a training label if a language model were trained only on a CE corpus. A pretraining-scale CE corpus would be sense-tagged by a model. The CE-only model would then learn that tagger’s choices as ground truth, and many of those choices are ones a second annotator would dispute.
A mitigation follows from the nocuous / innocuous distinction used to derive grammar rules: merge Open English WordNet synsets that readers do not actually disagree about.
CE derives grammar rules from the Cambridge Grammar of the English Language (CGEL) by Rodney D. Huddleston and Geoffrey K. Pullum (2002) [6], as codified by the CGELBank team [7] [11].
Extending from CGEL, CE derives additional rules empirically, from corpora in which human annotators have already recorded which reading was intended:
noah
produces a false negative or false positive, language models
propose a new grammar rule. This candidate rule is added to the
set, and the new linter is backtested to ensure no regression of
any previous test cases. A rule that does not regress our test
cases while correcting one or more false positives or false
negatives is included.
A false negative or false positive must be measurable. The requirements-engineering literature distinguishes nocuous from innocuous ambiguity: an ambiguity is nocuous only when readers actually disagree about it. Innocuous ambiguity gets a construal rule; nocuous ambiguity is rejected. The disposition of every rule is therefore an empirical finding rather than an editorial preference. The same agreement test applies to the sense inventory: synsets that readers do not actually disagree about can be merged, which is the mitigation for the noisy-label cost of a CE-only model.
Every sentence in CE must parse to exactly one reading under the rule set. The rule set has conventions that are implicit and may assist in clearing up ambiguity.
Most English sentences a native speaker would consider to be “correct” are also judged as passing in CE. However, there is a long tail of somewhat unusual sentences, a few percent of sentences appearing in wild English, that may not pass the current version of CE.
By definition those sentences are considered invalid, although future more sophisticated versions of CE may include them.
Since noah will mark such sentences invalid, authors
wishing to conform to CE must rewrite their words until the text
conforms.
The set-theoretic framing of this process — ideal CE as a Stewart set, and each CE1.0.x as a computable approximation measured by false positives and false negatives — is on the methodology page.
CE has two equivalent serializations,
ce-linear
and
ce-tree.
Both are equally unambiguous, and both are equally parsable by a
computer. They differ only in audience:
ce-linear is
GFM
that humans can read;
ce-tree is
JSON-LD
that tools can walk as a sentence tree. Each is accompanied by a
JSON-LD lexicon of all words used, linked to the
semantic web.
The sense @id is a dereferenceable
Open English WordNet
synset IRI for an open-class word, a
Wikidata lexeme
IRI for a closed-class function word, or a
Wiktionary
English-section URL for a mark or digit.
@context is the
w3id.org
PURL
https://w3id.org/canonical-english/context/v1.
That identifier redirects to the hosted JSON-LD context. The
identifier contract is in
FORMAT.md.
Example · ce-linear · document.ce.md
---
{
"@context": "https://w3id.org/canonical-english/context/v1",
"@graph": [
{ "@id": "oewn:06645018-n", "form": "hello" },
{ "@id": "oewn:02475618-n", "form": "world" }
]
}
---
Hello, world!
Example · ce-tree · document.ce.jsonld
{
"@context": "https://w3id.org/canonical-english/context/v1",
"@graph": [
{ "@id": "oewn:06645018-n", "form": "hello" },
{ "@id": "oewn:02475618-n", "form": "world" }
],
"linear_content": "Hello, world!",
"type": "root",
"children": [
{
"type": "paragraph",
"children": [
{
"type": "text",
"value": "Hello"
},
{
"type": "punctuation",
"value": ","
},
{
"type": "text",
"value": "world"
},
{
"type": "punctuation",
"value": "!"
}
]
}
]
}
ce-linear · document.ce.md
A ce-linear document is
GFM
prose (encoding:
UTF-8, MIME
type:
text/markdown) conforming to every
style rule. The metadata is a
JSON-LD
document in the frontmatter, between ---
delimiters: the entity graph and the relation triples, so
nothing about the meaning has to be recovered by inference.
JSON is a subset of
YAML 1.2, so
ordinary Markdown tools that already skip YAML frontmatter
ignore the JSON-LD and render the body as regular Markdown.
document.ce.md
text/markdown
ce-tree · document.ce.jsonld
A ce-tree document is the same CE text as a
single JSON-LD file (encoding:
UTF-8, MIME
type:
application/ld+json). It contains the same entity graph as the
ce-linear frontmatter, plus an explicit tree of
each sentence — clauses, phrases, grammatical functions, and
sense URIs — in the
CGEL
constituency formalism
[11]. A tool that
analyzes attachment, scope, or reference can walk that tree
directly, without parsing the prose. The sentence string is
still present on each node, so nothing is discarded.
The root also carries linear_content: the
paragraph string, so a page can render the prose without
walking the tree.
document.ce.jsonld
application/ld+json
Best-effort conversion
noah-parser — converts natural English into CE
This is
semantic parsing: English in, a
Discourse Representation Structure
out. English is naturally ambiguous, so the parser works on a
best-effort basis and is not necessarily deterministic.
It reads your text and writes a single .ce.md file
that keeps your prose intact and adds JSON-LD frontmatter
describing its logical structure.
The input must already be valid GFM. The parser refuses a file markdownlint rejects, because Markdown block structure is what it walks: it splits the document into blocks — paragraphs, headings, list items, table cells — and then parses those blocks sequentially, in document order, one sentence at a time. Order matters, because an entity introduced in an earlier block is what a later reference resolves against.
.txt / .md) that is valid GFM
.ce.md)
Deterministic verdict · 1.0.0
noah-linter — verifies a CE file
A fast, deterministic checker that answers yes or no: is this CE?
Its first step is to require the JSON-LD frontmatter on the
.ce.md file and extract it as JSON-LD. Its first pass
over the prose is
markdownlint, which decides whether the body is well-formed GFM. After those
gates it holds the file to two further standards — that the
human-readable prose obeys every
style rule, and that the extracted
frontmatter describes exactly that prose and nothing else. Because
the linter is deterministic, the specification defines CE as what
the linter accepts, not what the parser emits.
.ce.md)
draft.md
plain English, already valid GFM
│
▼
┌─────────────────────────────────────────────┐
│ noah-parser │
│ │
│ 1. Refuse anything markdownlint rejects. │
│ 2. Split the text into blocks: paragraphs, │
│ headings, lists, tables. │
│ 3. Parse the blocks in document order, one │
│ sentence at a time. │
└─────────────────────────────────────────────┘
│
▼
document.ce.md
JSON-LD frontmatter + the same prose
│
▼
┌─────────────────────────────────────────────┐
│ noah-linter │
│ │
│ 1. Require JSON-LD frontmatter; extract it. │
│ 2. markdownlint the GFM body. │
│ 3. Does the prose obey the style rules? │
│ 4. Does the frontmatter match the prose? │
└─────────────────────────────────────────────┘
│
▼
Pass / Fail / Warnings
Those two programs convert and check a finished draft. Putting a language model in front of the same linter — so the model keeps proposing until the verdict is accept — is the generation loop below.
Natural English is a linear string. The relations it names are a tree, and later a graph. Token-level tagging — part of speech, even a word-sense label on each token — cannot decide attachment: which phrase a preposition modifies, which noun a relative clause restricts. A parser that tries to force arbitrary English into one tree fails on the unbounded edge cases of real text.
CE inverts that job. The generator — a language model, or a human
with
noah-parser — proposes a
.ce.md file. A deterministic linter,
noah-linter, answers yes or
no. A text is CE only when the linter accepts it, not merely because
a model emitted it. On accept, the same document is already a graph:
JSON-LD frontmatter plus a single parse, ready for RDF or any later
triple store. On reject, the diagnostic goes back to the generator.
messy English
│
▼
┌─────────────────┐ CE-nnnn diagnostic
│ language model │◄────────────────────────┐
└────────┬────────┘ │
│ proposed .ce.md │
▼ │
┌─────────────────┐ │
│ noah-linter │─────────────────────────┘
└────────┬────────┘
│ accept
▼
valid CE
ce-linear / ce-tree
That loop can close in two places. Both treat the linter as the gatekeeper. They differ in when the check runs, and in what access they need to the model.
Inner loop · self-hosted
The inference engine intercepts generation token by token. A logit processor — in vLLM, llama.cpp, or lm-format-enforcer — sets the score of every token that cannot continue a valid prefix to negative infinity, so it cannot be sampled [13]. The finished string is then valid by construction, not by later luck.
A per-token checker cannot wait for a complete sentence. It must
answer a prefix question: can this incomplete sequence still
become a document the linter would accept? Today’s
noah-linter judges finished files. Constrained
decoding needs a prefix-valid checker on top of that verdict —
additional work, not a flag on the current binary.
Prefix search still dead-ends: every remaining token is illegal,
yet the string is not yet a complete document. Three mitigations
are standard. Beam search keeps several live prefixes so a
doomed branch can be dropped. A scratchpad lets the model plan
in unconstrained text before emitting the constrained
.ce.md. Catch-and-release treats a terminal dead
end as a structured error and restarts from the failure point.
The inner loop needs logit access, so it runs only on self-hosted open-weight models. Hosted APIs do not expose the decoder.
Outer loop · any API
The model writes a complete
.ce.md file. The linter then evaluates that file
as a whole. Accept ends the loop. Reject returns the
CE-nnnn diagnostic and the failing span; the model
revises and tries again. The statistical name for that pattern
is
rejection sampling: draw a candidate, test it against a hard predicate, keep it
only if the predicate holds.
This is middleware. It wraps any chat or completions API —
hosted frontier models and open-weight servers alike — and
needs no GPU cluster and no custom decoder. The authoring
loop is the same: emit JSON-LD frontmatter plus GFM, then run
noah check until the process exits 0.
The cost is retries rather than masked tokens. The benefit is that the gatekeeper is the same complete-document linter that defines CE, with no prefix approximation in between.
| Dimension | Grammar-constrained decoding | Post-generation validation |
|---|---|---|
| When it runs | Each token, on the current prefix | After a complete .ce.md draft |
| What it needs | A prefix-valid checker, plus logit access in the inference engine |
Today’s complete-document noah-linter, plus a
retry loop
|
| Where it runs | Self-hosted open-weight serving | Any API, as an external wrapper |
| Failure mode | Dead-end prefix; beam, scratchpad, or restart | Reject and regenerate from the diagnostic |
Earlier controlled languages such as Attempto Controlled English (ACE) succeeded as mathematics: a sentence that parsed mapped onto first-order logic and then onto OWL or RDF. They did not succeed as authoring languages. The grammar was a constructive recipe — humans had to learn which sentences were in the fragment — and the fragment was often too small for work outside the lab [14]. That is the usual controlled natural language dilemma: formal enough to check, or large enough to write, but not both. The comparison places CE in that family.
CE is a verdict, not a constructive how-to-write-it grammar. The linter says accept or reject; it does not have to enumerate every sentence it would accept. A later constructive definition may be attempted. Until then, the pair of a language model and a deterministic linter is what makes the language usable: humans keep writing natural English, the model proposes CE, and the linter is the contract. The model is the compiler. The linter is the type checker. Nothing downstream has to guess.
The style rules are the contract for a CE text: encoding, lexicon, grammar, and typography, together with the specification for citations, punctuation and quotations, words used as words, hyphenation of compound modifiers, dates and times, SI units, deterministic title case, pronouns, reference, and figurative language. Every rule exists to remove a judgement call that an ordinary style guide would leave to the writer.
This project requires no attribution and may be freely used.
Language data
canon/ —
CC0 1.0 Universal (Public Domain). Public-domain dedication for the language data itself.
Code and site
Everything else (including src/, the site under
docs/, and repo tooling) —
MIT-0. No
attribution required.
It is ironic that CGEL forms the basis of CE, given Geoffrey K. Pullum’s famous contention that the notion of “a language” is not scientifically reconstructable [8]. Because CE is not intended for the casual register, however, there is perhaps no discrepancy:
It seems to me that the notion of ‘a language’ should not be regarded as scientifically reconstructable at all. … The vagueness is ineliminable, and unproblematic.
DATA: Tell me. Are you using a polymer-based neuro-relay to transmit the organic nerve impulses to the central processor in my positronic net? If that is the case, how have you solved the problem of increased signal degradation inherent to organosynthetic transmission across…
BORG QUEEN: Do you always talk this much?
DATA: Not always, but often.
BORG QUEEN: Why do you insist on utilising this primitive linguistic communication? Your android brain is capable of so much more.