Packets
A packet is a read-only bundle of reference files attached to a mission. Use it when you want agents to be able to read documentation, knowledge bases, examples, prompt libraries, or any other text-only material that should never change during the run.
Packets are the read-only counterpart to memory and scratchpad slots. Memory slots are writable workspaces with Squadron-managed paths; packets point at user-controlled directories and are immutable to agents.
| Capability | Packet | Memory / Scratchpad |
|---|---|---|
| Agents can read files | yes | yes |
| Agents can write/delete | no | yes |
| Path | user-supplied | Squadron-derived |
| Allowed file types | UTF-8 text only | any |
| HCL parsed inside the path | no (excluded) | n/a |
| Tool slot name | packet.<name> | <name> / "memory" / "scratchpad" |
Declaring a packet
Declare packets at the top level of your HCL, alongside memory blocks:
packet "knowledge_base" {
path = "./reference/kb"
description = "Internal product documentation"
}
packet "examples" {
path = "./reference/examples"
description = "Worked examples agents can imitate"
}| Attribute | Type | Description |
|---|---|---|
path | string (required) | Directory path. Resolved by the project-wide rule (see below). Must already exist — packets are reference data, so Squadron never creates the folder for you. |
description | string | Human-readable description shown to agents in the system prompt. |
Path resolution
The same rule applies to every path attribute in Squadron config (currently packet.path, plugin.source local sources, and the load() function):
| Form | Resolves to |
|---|---|
./foo, ../foo, bare foo | The directory of the HCL file declaring the attribute |
@/foo | The project root — the directory you pass to squadron -c <dir> |
/foo, absolute | Rejected (absolute paths are not allowed) |
After resolution, the path must remain inside the project root AND must not be the project root itself. Three failure modes are rejected at parse time:
| Bad input | Error |
|---|---|
path = "/etc" | absolute paths are not allowed — use a path relative to the HCL file or prefix with "@/" for the project root |
path = "../../escaped" | escapes the project root "<project>" |
path = "@/" | resolves to the project root "<project>" itself — config path attributes must point at a specific file or subdirectory, not the whole project |
This means path = "reference/kb" works the same regardless of where you cd’d to before running squadron — there’s no CWD dependence anywhere in the resolution. The same rule is shared with plugin.source and load().
Why no
path = "@/"? The whole point of a packet is to bundle a specific subset of the project — and the HCL-exclusion filter drops any.hclfiles inside the packet path. Ifpath = "@/"were allowed, every.hclfile in your project would be filtered out and squadron would silently load with zero missions. The explicit error tells you exactly what went wrong.
Names must not collide with the reserved memory / scratchpad slot names and follow the same character rules as memory names (no path separators, no leading dot).
Attaching packets to a mission
A mission opts in by listing the packets it cares about. The same namespace works at the task level when a particular task wants to declare its own packet dependencies:
mission "answer_questions" {
commander { model = models.anthropic.claude_sonnet_4 }
agents = [agents.researcher]
# Mission-wide packet — available to every task
packets = [packets.knowledge_base]
task "draft" {
objective = "Draft an answer using the KB."
# Task-level packet — declared per task
packets = [packets.examples]
}
}Both mission-level and task-level references are validated at load time; an unknown packet name fails the parse.
Task-level declarations are not runtime access boundaries. Every task in a mission shares the same mission-wide slot store, so a packet referenced by any task is accessible to every task in that mission. Use task-level
packets = [...]to document intent, not for isolation.
Reading from a packet
Once a packet is attached, agents access it through the same file tools as memory slots. The slot parameter takes the prefixed name packet.<name> so packets cannot be confused with writable slots:
{
"slot": "packet.knowledge_base",
"path": "billing/refunds.md"
}The six file tools apply the following policy for packet slots:
| Tool | Behavior in a packet slot |
|---|---|
file_list | Lists files normally |
file_read | Returns text content. Rejects files that look binary (NUL byte in the first 8 KB) |
file_search | Filename regex search, recursive |
file_grep | Content regex search; binary files are silently skipped |
file_create | Always returns Error: slot is read-only (packet bundles are immutable) |
file_delete | Always returns the same read-only error |
File types
Packets are designed for UTF-8 text: Markdown, source code, JSON/YAML, prose, transcripts, anything an LLM can read directly. Binary payloads (images, audio, video, archives, compiled binaries) and non-UTF-8 encodings (e.g. UTF-16) are not supported — file_read rejects them up front so agents don’t get a wall of garbled bytes.
If you need to expose mixed-type material, split it: keep the text in a packet and put any binaries in a writable memory slot that a pre-processor can stage on demand.
HCL exclusion
A packet folder is treated as opaque reference data, not as part of the squadron config. Any .hcl files that happen to live inside a packet path are ignored at config load time — Squadron will not parse them, will not surface their syntax errors, and will not pick up model/agent/mission/etc. blocks from them.
This lets you point a packet at a folder that contains arbitrary user files without worrying about accidental collisions with the HCL loader.
Full example
# Two equivalent forms: "./..." anchors to this HCL file's directory,
# "@/..." anchors to the project root (the `-c` argument). For a flat
# project layout where the HCL lives at the root, the two are
# interchangeable; for a layered config (sub-HCL files in subdirectories)
# "@/" is the clearer choice for paths that should mean "from the top."
packet "playbooks" {
path = "@/reference/playbooks"
description = "Customer-support playbooks (read-only)"
}
packet "tone_guide" {
path = "./reference/voice"
description = "Brand voice and tone guidance"
}
mission "support_reply" {
commander { model = models.anthropic.claude_sonnet_4 }
agents = [agents.support_writer]
packets = [packets.playbooks, packets.tone_guide]
scratchpad = true
task "draft" {
objective = "Read the relevant playbook from packet.playbooks and draft a reply in the scratchpad."
}
task "polish" {
depends_on = [tasks.draft]
objective = "Refine the draft against packet.tone_guide and save the final reply to the scratchpad."
packets = [packets.tone_guide]
}
}