Arete documentation
Project Dependencies
For the complete documentation index optimized for AI agents, see llms.txt or llms-full.txt. A markdown version of this page is available by appending.mdto the URL or sendingAccept: text/markdown.
For AI agents: the documentation index is at llms.txt (full corpus: llms-full.txt). A markdown source for this page is /building-stacks/configuration.md.
An Arete project keeps three records of its dependencies:
arete.tomlsays what you want. You or your agent write it.arete.locksays exactly what that resolved to, and stays put until you ask for a change.- Provenance inside the generated SDK says which locked input produced each output.
Use a4 install, a4 update, and a4 remove to keep all three in step. If
you have used package.json with a lockfile, or Cargo.toml with Cargo.lock,
the arrangement will feel familiar.
Initialize
Section titled “Initialize”a4 init -yInitialization creates a minimal manifest if there isn’t one yet and configures the project’s agents. It never adds registry dependencies on its own.
manifest_version = 1
[project]name = "my-project"private = trueAdd dependencies through the CLI
Section titled “Add dependencies through the CLI”Start with the catalog, inspect the exact descriptor, and prefer its install command:
a4 explore catalog --query "token accounts" --jsona4 explore catalog program spl-token --jsona4 install program spl-token --tsFor a hosted stack:
a4 explore catalog --query "<intent>" --kind stack --mode subscribe --jsona4 explore catalog stack <slug> --jsona4 install stack <slug> --tsAdding a package saves what you asked for and resolves the complete set of
dependencies. Run plain a4 install later to restore everything the project
declares.
Manifest structure
Section titled “Manifest structure”manifest_version = 1
[project]name = "my-analytics-app"private = true
[install]allow_outside_project = false
[sdk]targets = ["typescript", "rust"]
[sdk.typescript]output_dir = "./src/generated"package = "@my-org/arete-generated"
[sdk.rust]output_dir = "./crates/generated"module_mode = truecrate_prefix = "my_app"
[sdk.python]output_dir = "./python/generated"module_mode = falsepackage_prefix = "my_app"
[dependencies.programs.token]source = { registry = "spl-token" }version = "^1.0.0" # use the requirement saved by the current install commandtargets = ["typescript"]
[dependencies.programs.token.outputs]typescript = "./src/generated/programs/token"
# Illustrative: replace with a stack slug and version returned by its descriptor.[dependencies.stacks.market-data]source = { registry = "market-data" }version = "^1.0.0"targets = ["typescript", "rust"]The package names and versions above are illustrative, so check the catalog
before copying any of them. Better still, let a4 install write the correct
table from the descriptor you selected.
Sources
Section titled “Sources”A dependency has exactly one source:
| Source | Meaning |
|---|---|
registry | Resolve a published package by slug and version requirement |
path | Use an exact local ProgramSpec or StackManifest artifact |
workspace | Refer to a same-kind entry under [authoring], including a composed stack |
A registry requirement expresses what you want. The lockfile records the exact package release and artifact identities that satisfied it.
Registry versions use Arete’s semantic versioning system. They describe compatibility of the published Arete package.
Output layout
Section titled “Output layout”Without dependency-specific overrides, outputs are namespaced by kind:
- TypeScript:
<output_dir>/stacks/<alias>and<output_dir>/programs/<alias>; - Rust:
<output_dir>/stacks/<prefix>-<alias>-stackand<output_dir>/programs/<prefix>-<alias>-program; - Python:
<output_dir>/stacks/<prefix>-<alias>-stackand<output_dir>/programs/<prefix>-<alias>-program.
This permits a stack and standalone program to share an alias. Aliases must be unique within their own kind.
Protocol clients ([dependencies.protocols], added with
a4 install protocol <ref> --ts, --rust or --python) are registry-only and
generate TypeScript, Rust or Python clients. They generate
<output_dir>/protocols/<alias>/ (Rust and Python: <alias>-protocol/), with the stacks and programs the
protocol hoists nested under stacks/ and programs/. A program the
protocol pins only by its local IDL (no program package, so the package leaves
it unpinned) is not generated: the client’s README.md lists it, and you
install it yourself with a4 install program if your app needs its SDK. A
protocol records the deployment its client calls, never a credential: your
app’s own key mints a protocol session at runtime.
A dependency-level output is an exact override and does not receive the automatic kind directory.
Install and update
Section titled “Install and update”a4 installa4 install --lockeda4 install --dry-runa4 updatea4 update program tokena4 remove program tokenImportant behaviors:
a4 installresolves the complete declared graph.--lockedrequires a fresh existing lock and never changes resolution.--dry-runvalidates and prints the plan without writing.- a package add saves intent unless
--no-saveis explicit. - generated output and
arete.lockare committed only after successful generation of the complete graph. a4 updatechanges resolution; plain install does not silently replace an exact fresh lock.
Generated directories belong to the installer. Don’t hand-edit entry files,
extensions, SDK manifests, or provenance records. Your edits are replaced the
next time the code is generated. And if you add files of your own to a generated
directory, a4 install refuses to touch it until they are gone.
Lockfile
Section titled “Lockfile”Commit arete.lock for applications and services that need reproducible
generation. It pins exact package and artifact identities, not only semantic
versions.
After merging dependency changes, CI should run:
a4 install --lockedA stale lock is a project health warning reported by a4 doctor.
Local authoring
Section titled “Local authoring”Authored artifacts have stable project names under [authoring]:
[authoring.stacks.local-indexer]manifest = "./.arete/LocalIndexer.stack-manifest.json"artifact_roots = ["./.arete"]deployment_name = "local-indexer"
[dependencies.stacks.indexer]source = { workspace = "local-indexer" }artifact_roots grants explicit access to the related content-addressed files.
Workspace dependencies make local authored content part of normal project SDK
generation.
Composed stacks
Section titled “Composed stacks”An [authoring.stacks] entry can also compose a stack from parts instead of
naming a StackManifest file: live views from published stacks or LiveSpec
files, and program SDKs from program packages or ProgramSpec files.
a4 stack compose writes the entry; you can also write it by hand.
[authoring.stacks.ore-plus-token]live.ore = { stack = "ore", version = "^1", views = ["OreRound/latest", "OreMiner/state"] }programs = [{ package = "spl-token", version = "^1" }]
[dependencies.stacks.ore-plus-token]source = { workspace = "ore-plus-token" }targets = ["typescript"]live.<alias> names the views the composed stack serves under <alias>:
| Key | Meaning |
|---|---|
stack | A published stack |
version | Its version requirement. Omitted: any version; arete.lock pins the release |
live_alias | Which of the stack’s live aliases, when it has more than one |
path | A LiveSpec file, instead of stack |
views | The selected views, in order. Omitted: every view the stack serves (or the file defines) |
programs lists program SDKs: { package = "...", version = "..." } for a
program package, or { path = "..." } for a ProgramSpec file. An entry has
either manifest or live (with optional programs), never both.
When a4 install generates the composed stack:
- the programs the views index come with them, as the program SDKs their stack
references. A
programsentry for the same program replaces that SDK, and the install output says so. Other entries are independent programs. - selected views must exist in the LiveSpec, and be views the stack serves.
- a live alias from a stack with hosted delivery reads that stack’s deployment,
and its sessions name the version the deployment serves. An alias from a
definition-only stack or a LiveSpec file has no endpoints until you deploy
the composed stack with
a4 up <name>. arete.lockpins every part, from package releases to the composed StackManifest, soa4 install --lockeddetects any drift anda4 update stack <alias>advances the parts.
See Composed stacks for details. Publishing a composed stack to the registry is not available yet.
The lower-level a4 sdk create command is useful for direct artifact work. It
does not write arete.toml or arete.lock and should not replace dependency-
backed installation for application projects.
Validate
Section titled “Validate”a4 config validatea4 doctor --jsonValidation runs offline. It checks strict keys, source and workspace kinds, local artifact closure, path policy, output collisions, and lock freshness. It can’t tell you whether a hosted service is healthy. When that matters, inspect the exact descriptor and perform a small bounded read.
Credentials and environment
Section titled “Credentials and environment”Authentication is stored separately from the project manifest. Use:
a4 auth signupa4 auth login --key <a4_ak_...>Never commit credentials. In headless environments, configure the supported secret environment through the CI secret manager.
| Variable | Purpose |
|---|---|
ARETE_API_URL | Intentional API origin override |
ARETE_API_KEY | Headless authentication |
Overriding the API origin changes who you are trusting. Never send a production key to an origin you don’t trust.