File system
File system
A tenant workspace is a plain Vite project. Authors place one declaration in each recognized filesystem role under src/ ; Bolt derives all assembly and generated types from there. This page is the map — the rest of the Authoring section details each role.
Canonical layout
src/
├── +agents.md # required — the workspace prompt
├── +env.ts # optional — declare env vars; private keys are server-only
├── access/
│ ├── +teams.ts # which policies each named team holds
│ ├── +anonymous_limits.ts # pre-sign-in address limits only
│ └── policies/+<name>.ts # grants, approvals, capabilities, and limits
├── capabilities/
│ ├── tools/+<name>.ts # optional workspace tool
│ ├── mcp/+<name>.ts # optional remote MCP server
│ └── skills/<name>/+skill.md # optional workspace Agent Skill
├── collections/
│ ├── +relationship.ts
│ └── <lower_snake_case>/
│ ├── +model.ts
│ ├── +hooks.ts # optional
│ ├── +pipelines.ts # optional
│ ├── +integrations.ts # optional
│ └── +representation.svelte # optional create/display/edit override
├── datatypes/<name>/
│ ├── +definition.ts
│ └── +renderer.svelte # required
├── apps/
│ ├── +<app>.svelte
│ └── <group>/
│ ├── +group.ts
│ └── +<app>.svelte
├── automations/+<name>.ts
├── envoys/+<name>.ts
├── functions/+<name>.ts
├── i18n/
│ ├── messages.en.json # required — English copy
│ └── messages.zh.json # required — Chinese copy, exact same keys
└── lib/** # optional, free-form helper code — no role, no + prefix Required roles are src/collections/+relationship.ts , at least one collection +model.ts , and at least one app src/apps/**/+<lower_snake_case>.svelte . App, automation, function, and envoy IDs come from their filenames. Misplaced, duplicated, nested, and unknown role files fail structural compilation. The workspace prompt in src/+agents.md and the bilingual catalogs in src/i18n/ are required.
Generated state
.norbital/
├── diagnosis/ # ignored
├── dist/ # ignored
├── generated/ # ignored
├── migrations/ # committed
├── types/ # ignored
└── tsconfig.json # ignored The authored root tsconfig.json extends .norbital/tsconfig.json . Bolt owns that single generated config and all compiler paths; it does not use baseUrl . Only .norbital/migrations/ is committed.
Commands
bolt sync
bolt migrate bolt syncruns the filesystem compiler: it validates roles, generates registry modules, local$types, and the generated TypeScript config.bolt migratediffs the authored models against the migration lineage and writes the next entry under.norbital/migrations/.
Authoring boundaries
- Apps import typed client access from
$bolt/client. - Server roles use their adjacent generated
./$types.js. - Do not hand-author registries, assembly modules, generated declarations, or bundling scripts.
- Do not add SvelteKit routes,
svelte.config.*,$app/*, or#lib.
Every role at a glance
Each role is one file in one place, default-exports one declaration, and owns its identity by filename. Unknown, duplicate, misplaced, or legacy role files are compiler errors — not silently ignored files.
| Role | Location | Exports | Docs |
|---|---|---|---|
| Collection model | collections/<name>/+model.ts | defineModel | Collections |
| Relationship registry | collections/+relationship.ts | relationship builder | Collections |
| Hooks | collections/<name>/+hooks.ts | hooks declaration | Hooks |
| Pipelines | collections/<name>/+pipelines.ts | pipelines declaration | Pipelines |
| Integrations | collections/<name>/+integrations.ts | integrations declaration | Integrations |
| Form override | collections/<name>/+representation.svelte | create/display/edit component | UI components |
| Custom type | datatypes/<name>/+definition.ts | defineCustomType | UI components |
| Custom type renderer | datatypes/<name>/+renderer.svelte | display/edit component | UI components |
| App | apps/**/+<name>.svelte | app component | Apps |
| App group | apps/<group>/+group.ts | group | Apps |
| Automation | automations/+<name>.ts | defineAutomation | Automations |
| Agent tool | capabilities/tools/+<name>.ts anywhere under src/ | defineAgentTool | Custom tools |
| Envoy | envoys/+<name>.ts | envoy declaration | Envoys |
| Agent instructions | +agents.md | workspace prompt | Agents |
| Agent skill | capabilities/skills/<name>/+skill.md | skill document | Agents |
| Policy | access/policies/+<name>.ts | policy declaration | Policies |
| Remote | functions/+<name>.ts | defineQueryHandler / defineCommandHandler | Functions |
| Environment | +env.ts | defineEnvironment | Workspace Studio |
| Seed | +seed.ts | tenant fixture behavior | — |
Reserved names and identifiers
Several names are owned by the platform. Using them is a compile error, not an override:
- System collections —
user,team,approval_request,session, and the rest of the platform baseline can be queried but never redefined ( System collections ) - Platform columns —
id,created_at,updated_at,row_version,sys_period, andapproval_idare added to every row automatically - Built-in agent tools —
describe_workspace,read_collection,write_collection,list_skills,read_skill,spawn_subagentcannot be redefined as workspace agent tools - Shipped skills —
norbital-platformandauthoring-tenant-workspacewin their names; a workspace skill that shadows one is refused - Layout primitives —
Stack,Inline,Cluster,Split,Grid,Columns,Column,Cover,Center,Frame,Bound,Scrollown their geometry props — see Layout - Compiler-private modules —
virtual:bolt/*is compiler-private; tenant source must use$bolt/client
Forbidden anywhere in tenant source:
-
schema.ts,workspace.ts, collection barrels,*.schema.ts, appApp.svelte, SvelteKit routes, a custom bundler,defineTable,defineSchema,QueryRow,NorbitalAuthoring,$tenant,#lib - Legacy APIs the compiler rejects outright — the former Page/Pane/Region, layout metadata, split-client, legacy enum, record-rep,
+create.svelte, and call-site create APIs. There is no compatibility path.