docsLanguage

MemQL Reserved Names

Last updated: 2026-05-19

This document is the single index of every identifier MemQL reserves in the author surface. Field names, arg names, import aliases, and function names that collide with one of these are rejected at load time.

Authoring against this list is much cheaper than re-running the engine to find out which name was reserved.


1. Engine-provided names (top-level)

These are available inside every body and cannot be redeclared as local args / fields:

NameWhatWhere
argsCaller-passed arguments object. Read fields as args.X.every body
actorResolved auth context. Fields: userId, role, identityId, isClusterOwner, partitions.every body
nowRFC3339 timestamp captured at evaluation start.every body
partitionActive partition for this call.every body
configAllow-listed config entries. See component/config/policy_exposable.go for the surface. Read as config.X.every body
tracePolicy-trace handle (trace.persist, trace.note).policies + logic invoked from policies

An args field whose name collides with any of these is a load-time error. Defined in component/memql/keyword_slices.go and enforced during args parsing.


2. Row intrinsics (concept rows)

Every persistent row has these engine-stamped fields. They are reserved on every concept's payload schema -- redeclaring one in a concept body is a hard error. They are also the canonical names the executor reads at SQL push-down time.

FieldTypeStamped byNotes
idstringmutation executionCanonical id format: {partition}:{concept}:{contentHash}. See identifiers.md.
conceptstringmutation executionThe concept id, e.g. v1:cognition:participant.
typestringconcept declarationCurrently mirrors concept; reserved for future versioning differences.
createdAtdatetimemutation executionRFC3339 timestamp at insert time.
createdBystringmutation executionStamped from the request actor's identity.
partitionstringmutation executionEnvelope partition for partition-scoped concepts; _system for global-scoped concepts.
schemastringconcept declarationConcept schema version hash (engine-derived).
provenanceobjectmutation executionOrigin metadata: {kind, name, trigger, via}. Supports nested paths.

Defined in component/memql/intrinsic_fields.go. Cross-referenced in docs/public/language/authoring-rules.md (gotcha #19).


3. Actor-envelope fields

Inside an @actor shape or a context-spec, the engine exposes a fixed envelope. Field paths under actor. are restricted to:

PathWhat
actor.userIdThe acting user's id.
actor.roleCluster role: owner / admin / writer / reader.
actor.identityIdThe credential row (token, magic-link, PAT).
actor.isClusterOwnerBool short-circuit; bypasses the per-partition ACL.
actor.nowRFC3339 timestamp at evaluation start.
actor.config.<key>Allow-listed config entries.

The fields are the only names valid under actor. -- a typo like actor.userid (lowercase) is a hard error. The caller.X / @caller spellings are retired in #221; the parser rejects them with a migration hint pointing at the canonical actor.X / @actor.


4. Import aliases (DSL import-model refactor)

When the import-model refactor lands (dsl-import-model-refactor.md), import aliases default to the basename of the imported file. The following are reserved alias names -- attempting import "./foo" as <name> for one of these is a load-time error:

Reserved aliasReason
actorTop-level engine-provided name.
nowTop-level engine-provided name.
partitionTop-level engine-provided name.
configTop-level engine-provided name.
traceTop-level engine-provided name.

The basename rule applies first: import "./foo" resolves to alias foo. If the resulting basename collides with another import's basename, the author must add as <name>. Files whose basename is not a legal identifier (regex ^[a-z][a-zA-Z0-9_]*$) require an explicit as clause too.


5. Reserved keywords (declaration headers)

Each construct's declaration header uses a reserved keyword. These cannot be used as identifier names anywhere in the author surface:

KeywordConstruct
conceptRow schema declaration.
shapeReusable field projection.
specAtomic boolean predicate.
traitConcept-agnostic atomic predicate.
queryRead function.
mutationWrite function.
logicImperative orchestration block.
automationEvent-triggered workflow.
toolSI-callable surface.
promptSI prompt template.
providerSI vendor + model config.
builtinGo-backed operation wrapper.
seedDeclarative row template.
policyCross-cutting decision OR SI-router routing config.

Plus body-level keywords inside specific constructs: args, body, filter, shape, insert, update, step, params, auth, include. Their reservation is scoped to the construct that defines them.


6. Reserved annotation names

The full annotation surface is per-construct and enforced by each parser's allow-list (search allowedXAnnotations in component/memql/). Cross-construct annotations:

AnnotationWhere it applies
@description("...")Every construct.
@enabled / @disabledLifecycle on functions / automations / traits / tools / builtins / policies. Not on specs -- the engine controls spec lifecycle.
@deprecated("hint")Functions, automations, tools, builtins.
@internalFunctions; hides from SI tool surfaces + external docs.

Cross-construct dependencies do NOT go through annotations. The legacy @useConcept / @useShape / @useQuery / @useMutation / @useLogic / @useBuiltin / @useSpec / @useTrait / @useTool / @usePrompt / @useProvider / @useAutomation family was retired in the import-model pivot (memql PRs #47 / #48 / #49, 2026-05-19) and is rejected at parse time. The canonical post-migration shape:

  • File-top Form B imports declare cross-file dependencies: use cognition.concepts.{ participant }, use common.traits.{ traitIsActiveRecord }.
  • Concept binding lives in the construct signature for seeds / queries / mutations / shapes: query <Concept> <name> { ... }, mutation <Concept> <name> { ... }, shape <Concept> <name> { ... }, seed <Concept> <name> { ... }.

The legacy @input wrapper and @template body annotation are also retired -- the parser rejects them with a migration hint.


7. Where this list lives in code

This file is documentation; the source of truth is split across several Go files. When the list below changes, update this doc:

ItemSource
Top-level engine namescomponent/memql/keyword_slices.go
Row intrinsicscomponent/memql/intrinsic_fields.go
Caller envelopecomponent/memql/sense/builtins.go + runtime_evaluator.go
Construct keywordsper-construct parser allow-lists in component/memql/
Annotation allow-listsper-construct parser allow-lists in component/memql/
Import aliasescomponent/memql/dslimports/dslimports.go (post-refactor)

Why a doc index instead of just code?

Because authors write .memql files in editors first and read engine errors second. The fast way to write a correct file is to know the rule before it bites; the slow way is to fix the file after the engine boots and rejects it. This doc closes that gap.