A semantic domain is a complete bounded language over One's fixed structural source format. It owns its vocabulary, rules, defaults, compatibility, normalization, and contributions to downstream owners. One-owned and organization-owned domains use the same contracts and lifecycle.
Foundation, inheritance, and composition
Every domain has exactly one compatibility lineage rooted at
one.semantic@1. extends inherits one complete language; use composes any
number of additional packages without making them compatibility parents.
one 1
semantic acme.process.language
domain one.semantic.domain@1
domain Process@1
extends one.semantic@1
use one.identity@1 only Principal, TenantId
use one.data@1 only Key, Scope
use acme.audit.Audited@1
kind Entity
exposes StableIdentity
kind Transition
exposes StateChange
Use extends one.product@1 when the domain intentionally inherits the full
product language. Extend one.semantic@1 and import narrow packages when it
does not. There is no multiple inheritance or source-order conflict winner.
one.standard@1 is an optional explicit aggregation package, not an ambient
prelude. A domain export preserves the original owner of every imported type,
trait, unit, capability, and declaration kind.
Define a trait
Trait packages use the one.trait@1 meta-domain. A trait definition owns:
- its owner-qualified identity and compatibility lane;
- the broad application-site category it may refine;
- typed arguments, defaults, bounds, conflicts, and repetition rules;
- semantic laws, normalization, and compatibility effects;
- required capabilities or prerequisite traits;
- possible owner contribution contracts; and
- documentation, diagnostics, formatting, and conformance obligations.
A broad category is only an upper bound. Declaring Key as a field trait does
not make it applicable to every field.
Implement applicability coherently
Inside a domain definition, impl associates an already defined trait with an
exact bounded subject pattern:
impl Key
for Entity@1.field<T>
where T implements StableKeyValue
normalize_with: ProcessTraitNormalizer
This is distinct from a top-level executable impl: the leading for marks a
semantic trait implementation, while an executable claim uses realizes and
using.
A package may publish a globally coherent implementation only when it owns the trait or the target nominal type/declaration kind. A package owning neither side publishes an explicit directional mapping that remains inert until one root selects it. Overlapping implementations fail unless their subject sets are provably disjoint; import order and “most specific” guesses never choose a winner.
Apply traits after the subject exists
Postfix traits refine a completed type, field, member, declaration, operation, environment, or evidence subject:
type UserName@1 = Text @Length(1..=128)
type Percentage@1 = Decimal @Value(0..=100)
record Upload@1
tenant: TenantId @Scope
id: Text @Length(1..=64) @Key
chunks: List<Bytes> @Cardinality(1..=10_000)
total_size: DataSize @Value(1B..=5GiB)
@Invariant(total_size == sum(chunks[*].length))
A field trait follows the field type. A declaration-wide invariant appears after every member it references. Trait applications form a canonical set, not an order-sensitive decorator pipeline.
Use precise traits: numeric value, text length, and collection cardinality are
different meanings. @Value, @Length, and @Cardinality are not aliases for
one generic range annotation.
Every bare @Key field contributes to one logical primary key. Multiple key
fields form a canonical composite identity without choosing physical index
order. @Unique(name) represents an independent candidate key. @Scope
identifies logical subject scope; it does not create a partition or grant.
Resolution and normalization
Strict checking:
- resolves the trait through the primary domain or prior import;
- constructs the exact completed subject descriptor;
- finds matching implementations in the selected package closure;
- rejects zero matches or non-identical multiple matches;
- validates arguments, prerequisites, conflicts, and repetition;
- runs the exact declarative rule or capability-empty normalizer;
- asks every destination owner to validate proposed contributions; and
- retains a receipt naming every definition, implementation, input, proof, contribution, and revision.
A custom normalizer receives only the bounded subject, arguments, exact package dependencies, and deterministic budget. It has no filesystem, network, clock, entropy, credentials, source-write access, provider selection, or authority, and it cannot mint trusted IR.
Unknown traits, unsupported subjects, ambiguity, invalid arguments, normalizer failure, and rejected owner contributions are semantic errors. Tooling retains and explains the source; it never discards a trait as metadata.
Publish and consume a domain
The domain follows the ordinary lifecycle: check its schema and closure, build or select its normalizer, run domain and trait conformance, publish the exact package and evidence, lock it in a consumer, then select it as that semantic item's primary domain.
Publishing proves no application behavior and activates no consumer. The lock selects exact package, export, trait implementation, normalizer, definition, and compatibility revisions.
Next: author a product or follow define a semantic domain.