Every One project has one canonical authored source format. It is an envelope
grammar with posture-tagged items, not one executable programming language: a
.one file combines non-executable semantic items with isolated implementation
claims without merging their grammar, identity, or trust.
Two layers: a fixed kernel and domain vocabularies
The surface has exactly two layers, and they obey different rules:
- The kernel is the envelope, structural indentation, clause/member punctuation, identities and references, imports, literals, and comments. It is fixed and has exactly one canonical spelling everywhere.
- Domain vocabulary is the declaration heads and clause words supplied by the selected primary domain. Each domain owns its own words under the same Contracts meta-model; different domains may use different words for their own concepts, and those words are never parser keywords and never interchangeable across domains.
So the rule is: one canonical spelling per role within the selected vocabulary, plus one fixed spelling for every kernel role. A spelling the selected domain does not govern fails with a source-mapped diagnostic; it is never guessed, silently aliased, or borrowed from another domain.
What a .one file can contain
The one envelope carries four different things. Identify which one you are editing before you change it:
| Form | Authored shape | Executable? | Meaning owner |
|---|---|---|---|
| Envelope | one 1 plus indentation-delimited top-level items | No | System IDL |
| Semantic item | semantic <namespace> with a leading domain clause | No | The selected semantic domain |
| Implementation item | impl <identity> with realizes, using, and a source suite | Only the framed body | The selected implementation-language profile |
| Generated or owned record | A semantic item with selection or observation posture, emitted canonically by its owner | No | The emitting owner |
Authored application source, generated records, and machine-local configuration
share the grammar, parser, and formatter, but not their authority. A record is a
revision-bound projection emitted by its owner, never an authored source of
meaning; editing one cannot redefine meaning. Only a source body contains
executable code, and only after its exact using profile resolves.
Source units and items
Every source begins with its exact envelope revision:
one 1It then contains one or more top-level items. There are exactly two envelope forms:
semantic acme.orders
domain one.contracts@1
# declarations governed by the selected domain
impl acme.orders#OrdersRust@1
realizes acme.orders#Orders@1
using one.language.rust#OwnedAsync@1
source
// isolated source-language bodysemantic selects one namespace and one primary domain. impl associates one
stable implementation claim with one semantic target and one exact language
profile. Co-location creates no reference, reachability, provider choice,
authority, or runtime activation.
There is no third item verb. A generated record is a semantic item under a
standard domain with a non-definition posture; it is emitted by its owner and
is never selected as application source.
Kernel punctuation: clauses and members
The kernel distinguishes a clause from a typed member by one rule, and neither form is ever written the other way:
-
A clause begins with a lowercase word and takes a positional value, an indented child suite, or both. It never uses a colon and never uses
=:Onedeadline 1s consistency serializable retention 7y requires one.data.state#Read@1 resource: parcelhub.orders scope: fields(customer_id, order_id) -
A typed member or named argument is
name: Typeorname: value. The colon is valid only here, inside one line:Onerecord Order@1 id: OrderId items: List<LineItem> -
=is valid only for a nominal alias (type X@1 = ...,schema X@1 = ...) and for the envelopeconfig,dependencies, andtoolchainssuites (edition = 2024,cargo.tokio = >=1.40,<2). It never binds a clause or a typed member. -
A refinement is a postfix trait application after its complete subject:
Text @Length(1..=64),List<Bytes> @Cardinality(1..=10_000),@Key,@Scope,@Unique(name). A field trait follows the field's type, and applications form a canonical set, not an ordered pipeline. A record-wide invariant is its own clause —invariant <field> at most <field>— placed after the members it references.
One clause occupies one physical line. A newline ends the clause, and a later clause after members have begun is an ordering error. Two clauses may never share a physical line; split them onto separate lines.
A clause whose value is an unbounded member list (plans, browser,
security, roles, operations, and similar) takes an indented suite with one
entry per line; a bracketed [A, B] list is not used. Parentheses remain only
for an inline positional or named argument list, such as
fields(customer_id, order_id) or viewport(width: 1280, height: 720).
Grouping a repeated head
Some clause families repeat one leading word. Write them flat, one clause per line:
maximum entries 32
maximum key bytes 64
maximum value bytes 512or group them under the shared head, each remainder on its own line:
maximum
entries 32
key bytes 64
value bytes 512Both forms are the same clauses in the same order and normalize to the same
owner value, so grouping is presentation, not a second spelling. Only declared
groupable heads (on, maximum, and similar) accept a grouped suite, so a
suite that carries arguments — such as requires <Capability> followed by its
argument lines — is never misread as a group. The canonical formatter preserves
whichever form you authored; regrouping a flat run by its common head is a
domain-aware structured-edit action, not a change to the owner-neutral
formatter.
Indentation is structure. A trailing block colon and structural braces are
errors. : and = remain valid only as above. Expression delimiters remain
explicit and are unaffected by layout: List<T>, f(x), items[*],
1..=100, and @Length(1..=64).
Values, types, and literals
id: OrderId
items: List<LineItem>
lookup: Map<Key, Value>
note: Text?
result: 250msA record-wide invariant is a clause, not a postfix trait:
struct RangeLimit@1
minimum: Integer(0..=100)
maximum: Integer(0..=100)
invariant minimum at most maximum- Optionality is
T?, withsome(value)andnoneas typed values. There is noOptional<T>spelling. - A product value is
Type { field: value }with named fields. There is no positional product form. - Structural bounds and refinements follow the selected domain's vocabulary (see below); the kernel does not define a second bound spelling.
- Relations use
<,<=,==,!=,>=, and>. Ranges usestart..endor inclusivestart..=end.
Typed quantities are a number followed directly by an exact, case-sensitive unit symbol:
timeout 30s
retention 7y
payload_limit 16MiB
throughput 100MiB/s
monthly_cost <= 5_000USD
availability >= 99.95%Fixed durations and calendar periods remain distinct. m is a minute; mo is
a calendar month. B, KiB, and MiB are binary byte units, while kB and
MB are decimal. b is a bit. Case changes are semantic and are never
corrected heuristically. Quoted quantities ("30s") and wrapper calls
(seconds(30), bytes(1000)) are not accepted spellings.
Identities, lanes, and references
Order@1 names the @1 compatibility lane of Order; the lock selects its
exact immutable revision. A declaration name, continuing identity, compatibility
lane, and exact revision are different things.
| Reference | Canonical form | Example |
|---|---|---|
| Package or domain coordinate | namespace@lane | one.contracts@1 |
| Nominal identity | namespace#UpperCamel(.UpperCamel)*@lane | parcelhub.orders#Orders.Get@1 |
| Authored member selection | identity@lane::lower_member | one.project#Project@1::local_product |
A declaration name, continuing identity, compatibility lane, and exact revision are distinct. Source uses owner-qualified references where context does not already establish the namespace; a friendly name resolves only when the selected source and lock make it unambiguous. Later stages retain exact owner identities and never repeat name search.
Imports
Additional dependencies are definition-ordered use declarations. The
canonical form imports a package or domain coordinate by its dotted lowercase
namespace and exact lane, then optionally selects members with a finite
one-line only list:
use one.identity@1 only Principal, TenantId
use one.contracts@1 only Bool, Bytes, Length, List, Text, UInt, Value
use acme.compliance@1
use one.data@2 as data_v2use namespace@lanebinds the namespace's terminal lowercase segment (compliance.Control,data_v2.Key).use namespace@lane only A, Bimports only the comma-separated members, each of which may carry a category-preservingasrename (use one.semantic@1 only SourceIdentity as Identity).use namespace@lane as aliasrenames the whole namespace.- There is no dotted symbol-import form.
acme.money.Money@3is ambiguous (namespaceacme.money.Money? symbolMoneyofacme.money?) and is rejected; writeuse acme.money@3 only Money.
A symbol import binds its terminal name; a package import binds its terminal
namespace. only is a finite one-line list and never takes an indented suite or
implicit continuation. Two identities or lanes cannot occupy the same source
name, and an import cannot silently shadow a primary-domain export. Imports
precede first use; local declarations and members are definition-ordered.
Domain vocabulary
The selected primary domain supplies the declaration heads and clause words available in a semantic item. The standard distribution currently ships these owner-scoped vocabularies. They are not interchangeable: use the words of the domain you selected.
| Domain | Declaration heads | Operation / clause surface | Bounds and refinements |
|---|---|---|---|
one.project@1 | project, workspace | assurance, source, editor, dependencies, toolchains, lock | — |
one.contracts@1 | struct, schema, fault, enum, service, operation Ns.Member@1, workflow | accepts / returns / faults | bounded type T(args), e.g. Text(bytes: 2048), Integer(0..=...) |
one.product@1 | record, type, error, enum, service, state, event | operation / query / command members; input / returns / faults | bound traits @Value, @Length, @Cardinality; refinements @Key, @Scope, @Unique |
one.system@1 | component, system, root | provide, require, consume, activate, include, build | — |
one.data@1 | state, migration, projection | key, value, consistency, transaction, durability, retention, erasure | — |
one.test@1 | scenario, browser, benchmark, simulation | invoke, expect, assert | — |
The one.semantic.domain@1 and one.trait@1 meta-domains define how a domain
package itself is authored; their selector clause is domain <package-ref> and
their definitions export the vocabulary above. A domain that only defines an
organization's own meaning may expose completely different heads through the
same envelope.
Comments, formatting, and incomplete source
# introduces a comment in the envelope and in Native One bodies. A foreign
implementation body keeps its own language's comment syntax and braces; the
envelope never rewrites it. The formatter preserves comments and malformed
regions, uses four-space structural indentation, keeps every use on one line,
and never rewrites a foreign implementation body.
Incomplete or malformed bytes remain the current authored state. Editors may offer completion and patch candidates, but they cannot show a previous valid semantic value as though it represented newer invalid source.
Next: learn domains and traits, then author a product.