Entity schema and type names must be mechanically predictable. Every exported Zod schema is named with a Schema suffix. The exported TypeScript type inferred from that schema is named by replacing only the final Schema suffix with Type. For example, RepositorySchema is the Zod schema and RepositoryType is z.infer<typeof RepositorySchema>. RepositoryListPayloadSchema becomes RepositoryListPayloadType, and RepositoryPlatformRepositorySchema becomes RepositoryPlatformRepositoryType.

Entity remote method argument and result schema selection is owned by <Entity>Contract.ts. Schema modules own the named Zod shapes themselves. Contracts bind methods to those shapes; they must select an existing canonical schema whenever one already describes the method argument or result. They must not invent method-specific result names when a method returns an existing domain shape. For example, a Mission method that returns the complete Mission Entity uses MissionSchema as its result rather than introducing MissionReadResponseSchema, MissionReadResultSchema, MissionCreateResultSchema, or MissionResultSchema. A method whose only argument is the target Entity identity uses EntityIdSchema directly; it must not introduce <Entity>ReadInputSchema, <Entity>LocatorSchema, or another method-specific object solely to repeat the target id. Schema modules must not export parallel remote schema maps such as query-input, command-input, query-result, or command-result lookup objects because they duplicate contract metadata and drift from the canonical method contract.

This convention is non-negotiable for Entity schemas on both daemon/core and Open Mission/client sides. If a shape is validated by Zod, the schema export owns the name. If a TypeScript type represents that validated shape, it must be inferred from the schema with z.infer; it must not be hand-written beside the schema, widened by an interface, or renamed into a domain-specific synonym. The schema name carries the domain role. The inferred type name is a mechanical consequence of the schema name.

Schema and type aliasing is forbidden. Code must not re-export, import-rename, or assign an existing schema under a second schema name, such as RepositoryDataSchema = RepositorySchema, RepositoryProjectionSchema = RepositorySchema, or import { RepositorySchema as RepositoryReadSchema } from "...". Code must not define aliases such as RepositoryOtherType = RepositoryType, and imports must not rename canonical schemas or types, such as import { RepositoryType as RepositorySnapshot } from "...". If Mission needs a distinct domain shape, it must receive its own explicitly named Zod schema and inferred Type pair in the owning schema module, with a distinct field set or validation role. A different name means a different schema-backed concept, not an alias for an existing one. The general clean-sheet rule for aliases, fallbacks, and backward compatibility is recorded in ADR-0000.01.

Test file names follow the exact same mechanical rule as the code file they verify: the test file uses the same basename plus .test.ts. For example, MissionSchema.ts is tested by MissionSchema.test.ts, Repository.ts by Repository.test.ts, and SurrealDatabase.ts by SurrealDatabase.test.ts. Test files must not introduce technology, adapter, or projection suffixes such as MissionSurrealSchema.test.ts, RepositoryReadModel.test.ts, or TaskStorageProjection.test.ts when the code under test already has a canonical file name.

Partial composition schemas are forbidden when they do not name an independent domain concept. Schema modules must not export vague field-bundle names such as <Entity>PrimaryDataSchema, <Entity>BaseDataSchema, <Entity>CoreDataSchema, <Entity>CommonSchema, <Entity>SharedSchema, <Entity>MetadataSchema, or <Entity>DetailsSchema merely to share a subset of fields between storage, hydrated Entity data, adapter construction, tests, or documentation. That pattern is a duplication breach even when the field set is not byte-for-byte identical to another schema, because it creates a second named authority for fields whose real owner is <Entity>StorageSchema, <Entity>Schema, a method input/result schema, an event schema, or a daemon-private implementation type. A narrower exported schema is allowed only when its name describes a distinct domain value object or boundary payload that callers can use directly and that cannot be expressed by an existing canonical schema.

Schema-construction helper functions are also forbidden when they do not name an independent domain concept. <Entity>Schema.ts must not introduce local factories such as describedText(...), storedText(...), describedOptionalUrl(...), createThingSchema(...), or similar wrappers that merely restate z.string(), .optional(), .meta(...), .register(...), or object assembly behind a generic helper name. Those helpers make field definitions harder to read because the reader must decode a local mini-DSL before seeing the actual schema. If a field needs validation and description, declare that field directly where it is used. Reuse is allowed only when the reused schema already names a real domain concept, such as EntityIdSchema, RepositoryIconSchema, or another canonical schema export whose name explains the value it validates.

EntityStorageSchema is the parent schema for canonical persisted Entity storage records. Any schema that represents a physically stored Entity record, such as MissionStorageSchema, TaskStorageSchema, StageStorageSchema, or ArtifactStorageSchema, extends EntityStorageSchema instead of redeclaring the id field locally. Entity identity is therefore inherited from the Entity boundary and not copied into each storage schema as parallel structure.

EntitySchema is the parent schema for canonical hydrated Entity objects exposed by the domain boundary. It extends EntityStorageSchema and adds shared hydrated Entity material such as commands. Any thick Entity schema, such as MissionSchema, extends EntitySchema and may specialize the shared hydrated fields only when it is composing child Entity schemas. Hydrated Entity fields are not storage fields and must not be accepted by <Entity>StorageSchema.

The abstract Entity<TData> base stores data: TData, where TData is the concrete Entity’s canonical serialized instance shape. For ordinary thick Entities, TData is <Entity>Type, inferred from <Entity>Schema. TData is not <Entity>StorageType unless the Entity class intentionally models a storage-row Entity whose full instance data is the storage row. Concrete Entity constructors must pass the matching data schema into the base constructor, and inherited updateFromData(...) must validate with that same schema.

For thick Entities, <Entity>InputSchema names the daemon-validated input required to create or register a new Entity. <Entity>StorageSchema names the daemon-owned persisted/runtime record physically stored on disk or in the daemon state store. <Entity>Schema names the canonical complete hydrated Entity instance exposed by the domain boundary, including persisted fields, derived fields, related Entity data, workflow read material, and commands. The inferred <Entity>Type belongs to <Entity>Schema; narrower enum or classifier schemas must use their own mechanical names, such as MissionEntityTypeSchema and MissionEntityTypeType, rather than occupying MissionType.

Method-specific input schemas are distinct from <Entity>InputSchema. They use explicit names such as TaskStartInputSchema, MissionWriteDocumentInputSchema, or RepositoryStartMissionFromBriefSchema, and they are bound to remote methods by <Entity>Contract.ts. They must not be treated as the Entity creation input schema.

SnapshotSchema and SnapshotType names are subject to the same rule. They are valid only when the schema validates a distinct point-in-time read model, such as a terminal snapshot or state-store snapshot. They must not wrap, rename, or re-export an Entity’s canonical schema. When an Entity event carries a transitional child Entity data shape, the schema and payload may use DataChanged, data, and data.changed, and the data field validates that child Entity data schema. When an Entity event carries the complete hydrated Entity, the schema field uses the Entity name and validates <Entity>Schema; for example, MissionChangedEventSchema emits mission.changed with a mission field validated by MissionSchema.

Workflow-engine schemas and types use workflow vocabulary. They must not use Mission* as a product prefix for workflow-owned concepts; for example, use WorkflowRuntimeStateSchema, WorkflowRequest, WorkflowEvent, and WorkflowConfigurationSnapshot rather than MissionWorkflowRuntimeStateSchema, MissionWorkflowRequest, MissionWorkflowEvent, or MissionWorkflowConfigurationSnapshot. References to the Mission Entity from the workflow engine remain explicit Mission Entity imports rather than aliases.

Entity files keep strict ownership. <Entity>Schema.ts owns all Entity-based Zod schemas and their exported inferred TypeScript types. <Entity>Contract.ts owns Entity contract metadata only: remote method argument schemas, result schemas, execution mode, events, and UI presentation metadata. <Entity>.ts owns the Entity class implementation, including behavior, invariants, identity handling, instance-state lifecycle, and remote method targets. Concrete Entity classes extend the abstract Entity base class.

Every schema and every field declared in <Entity>Schema.ts must be generated with a Zod .meta({ description: "..." }) description. This applies to exported Entity schemas, storage schemas, hydrated read schemas, creation/input schemas, method input schemas, method result schemas, event payload schemas, acknowledgement schemas, descriptor schemas, subschemas, enum schemas, discriminated-union members, object fields, array fields, nested object fields, optional fields, nullable fields, literal fields, and relation/reference fields. Descriptions explain domain role, ownership, and boundary meaning; they must not merely repeat the schema or property name.

When a storage schema participates in SurrealDB provisioning, the canonical storage schema, persisted fields, relation/reference fields, relation tables, indexes, and generated model definitions must also carry @flying-pillow/zod-surreal metadata with an equivalent description. The Zod .meta({ description }) text is the schema/documentation source in <Entity>Schema.ts; zod-surreal description metadata is the storage-facing DDL/provisioning source.

Repository and its platform-backed repository-ref shapes are the first naming cleanup targets for this decision. Their daemon/core classes and Open Mission/client usage must converge on the same canonical schema/type names rather than preserving mixed names such as snapshot-style aliases, GitHubRepository holdovers, or domain-specific inferred type names that do not directly mirror a schema export.

This decision deepens the Entity schema interface by making validation, TypeScript inference, remote contracts, persistence mapping, and client imports point at one canonical name pair. It also keeps future refactors local: changing the shape of an Entity payload means changing the owning schema and its inferred type, not chasing aliases or renamed imports across daemon and Open Mission modules.