Project Layout
The agent/ directory convention — every slot, how it maps to the manifest, and the rules Zett validates.
A Zett agent is a directory of well-known slots. Zett discovers the slots
(static analysis, for arcie dev / arcie build) and loads them into an
agent manifest — the object the runtime executes.
agent/
├── agent.ts # required-ish — the agent config (model + Cencori)
├── instructions.md # the system prompt
├── tools/ # defineTool — what the agent can do
├── skills/ # defineSkill — what the agent knows
├── hooks/ # defineHook — lifecycle callbacks
├── channels/ # defineChannel — HTTP / Slack / custom ingress
├── schedules/ # defineSchedule — cron jobs
├── subagents/ # nested specialist agents (directories)
├── sessions/ # config.ts — durable-execution config
├── policies/ # index.ts — security + budget guardrails
├── connections/ # outbound service connections (discovered)
└── lib/ # shared helpers (discovered)Slot reference
| Slot | Holds | Helper | Loaded into manifest |
|---|---|---|---|
agent.ts | Agent config | defineAgent | Yes — config |
instructions.md | System prompt (text) | — | Yes — instructions |
tools/*.ts | Callable tools | defineTool | Yes — tools |
skills/*.ts | Loadable knowledge/procedures | defineSkill | Yes — skills |
hooks/*.ts | Lifecycle callbacks | defineHook | Yes — hooks |
channels/*.ts | Message ingress | defineChannel | Yes — channels |
schedules/*.ts | Cron jobs | defineSchedule | Yes — schedules |
subagents/<id>/ | Nested specialist agents | defineAgent | Yes — subagents |
sessions/config.ts | Session behavior | — (plain object) | Yes — session |
policies/index.ts | Guards + budgets | — (plain object) | Yes — policy |
connections/*.ts | Outbound connections | — | Discovered only |
lib/*.ts | Shared helpers | — | Discovered only |
Each file in a slot directory default-exports its config; the file name (without extension) becomes the slot's name. Subagents are the exception — they're directories, each a small agent of its own (see Subagents).
skills/ vs knowledge/. The loader and validator read skills from
skills/. The current starter template scaffolds a knowledge/ directory, and
the getSkill() helper reads markdown from knowledge/. If your skills live in
knowledge/, rename the directory to skills/ so they load into the manifest.
This naming drift is being reconciled upstream.
Defaults
- Missing
agent.ts→ the agent falls back to{ model: "gpt-4o" }. - Missing
instructions.md→ defaults to"You are a helpful AI agent." - Empty slot directory → simply contributes nothing.
Naming rules
Slot names are validated against slug patterns. A bad name is a warning
(INVALID_SLOT_NAME), not a hard failure.
| Slots | Pattern |
|---|---|
tools, skills, schedules, hooks, subagents, lib | [a-zA-Z][a-zA-Z0-9_-]{0,63} |
channels, connections | [a-z][a-z0-9-]{0,63} (lowercase) |
Recognized module extensions: .ts, .mts, .cts, .js, .mjs, .cjs.
Files named .gitkeep are ignored.
Diagnostics
arcie dev and arcie build run discovery first and report diagnostics. Any
error-severity diagnostic stops the command (exit code 1); warnings are printed
and execution continues.
| Code | Severity | Meaning |
|---|---|---|
AGENT_DIR_NOT_FOUND | error | The agent directory doesn't exist. |
MODULE_SLOT_COLLISION | error | Multiple agent.* files for one slot. |
SUBAGENT_MISSING_CONFIG | error | A subagents/<id>/ has no agent.ts. |
DIRECTORY_READ_ERROR | error | A slot directory couldn't be read. |
INVALID_SLOT_NAME | warning | A file/dir name fails the slug pattern. |
DEPRECATED_SYSTEM_SLOT | warning | system.md found — rename to instructions.md. |
The manifest
loadAgent(agentDir) resolves every slot into an AgentManifest:
interface AgentManifest {
config: AgentConfig;
instructions: string;
tools: Record<string, ToolConfig>;
skills: Record<string, SkillConfig>;
hooks: Record<string, HookConfig>;
channels: Record<string, ChannelConfig>;
schedules: Record<string, ScheduleConfig>;
subagents: Record<string, SubagentManifest>;
session?: SessionConfig;
policy?: PolicyConfig;
}arcie build serializes a summary of this to .arcie/manifest.json. See the
CLI reference.