Package System
AILANG's package system enables multi-package projects with deterministic dependency resolution, export enforcement, and effect ceilings. Packages are the primary unit of autonomous coordination — they define what an agent can see, change, what authority it has, and what guarantees it must preserve.
Quick Start
# Create a package
ailang init package --name myorg/mylib
# Add a dependency
ailang add --path ../shared-utils
# Resolve dependencies and generate lock file
ailang lock
# View dependency tree
ailang tree
# Run (package resolution is automatic)
ailang run main.ail
Package Structure
A package is defined by an ailang.toml manifest:
my-package/
ailang.toml # Package manifest (human-written)
ailang.lock # Resolved dependencies (machine-generated)
src/
core.ail # Source modules
helpers.ail
tests/
core_test.ail
Manifest (ailang.toml)
[package]
name = "sunholo/docparse"
version = "0.3.0"
edition = "1"
description = "Parse documents into structured blocks"
license = "MIT"
[exports]
modules = [
"sunholo/docparse/parser",
"sunholo/docparse/types"
]
[dependencies]
"sunholo/json" = { path = "../json" }
[effects]
max = ["IO", "FS"]
[stability]
level = "experimental"
Required Fields
[package].name— Two-levelvendor/nameformat[package].version— Semantic version[package].edition— Language edition (currently"1")
Exports
Only modules listed in [exports].modules are accessible to dependents. Modules not in this list are package-private.
[exports]
modules = ["sunholo/docparse/parser"]
# sunholo/docparse/internal/helpers is NOT accessible from outside
Effect Ceiling
Packages declare their maximum allowed effects:
[effects]
max = ["IO"] # Only IO allowed; Net, FS, etc. would be a compile error
If a function in the package declares an effect not in max, compilation fails:
effect ceiling violation in package sunholo/mylib: effects [FS] not in max [IO]
Add missing effects to [effects].max in ailang.toml
An empty max = [] means the package is pure — no effects allowed.
Stability
[stability]
level = "experimental" # or "stable" | "frozen"
Lock File (ailang.lock)
Generated by ailang lock. Committed to version control. Contains:
- Content hash (SHA256 of all
.ailsource files) - Interface hash (SHA256 of exports + effects — stays same on internal refactor)
- Resolved dependency paths
The lock file is validated at build time — if a dependency's content has changed, you'll see:
Warning: dependency sunholo/json content changed (locked: sha256:a1b2c3... current: sha256:d4e5f6...)
Run 'ailang lock' to update
Importing from Packages
Use the pkg/ prefix for external package imports:
-- Stdlib (always available)
import std/io (println)
-- Local module (same project)
import myproject/parser (parse)
-- External package
import pkg/sunholo/json/parser (parseJson)
The pkg/ prefix tells the compiler to resolve against the lock file instead of the local filesystem.
Dependencies
Path Dependencies
Link to local packages:
[dependencies]
"shared/utils" = { path = "../utils" }
"shared/types" = { path = "../types" }
Git Dependencies
Pin to a specific tag or commit in a git repository:
[dependencies]
"sunholo/auth" = { git = "https://github.com/sunholo-data/ailang-packages", subdir = "packages/auth", tag = "main" }
Registry Dependencies
Install from the AILANG package registry:
[dependencies]
"sunholo/auth" = "0.1.0"
Resolution priority: path > git > registry.
CLI Commands
| Command | Description |
|---|---|
ailang init package --name vendor/name | Create ailang.toml |
ailang add --path ../dep | Add path dependency |
ailang add --git URL --subdir DIR --tag TAG | Add git dependency |
ailang install vendor/name@version | Install from registry |
ailang lock | Resolve deps, generate ailang.lock |
ailang tree | Display dependency tree |
ailang search "query" | Search registry packages |
ailang publish | Publish to registry |
ailang pkg-docs vendor/name | View package AGENT.md |
Registry
The AILANG package registry is hosted on GCP at https://storage.googleapis.com/ailang-registry.
Publishing
cd my-package/
ailang publish # Upload to registry (requires AILANG_REGISTRY_API_KEY)
ailang publish --dry-run # Preview without uploading
The validator service automatically:
- Compiles your package (
ailang check) - Verifies effect ceilings match
[effects].max - Runs contract verification (
ailang verify, best-effort) - Computes content + interface + tarball hashes
- Rejects duplicate versions (immutable once published)
Searching
ailang search "auth" # Keyword search on name, ai_summary, tags
ailang search --tag gcp # Filter by tag
ailang search # List all packages
Installing
ailang install sunholo/auth@0.1.0 # Download, verify hash, add to ailang.toml
Package Documentation
ailang pkg-docs sunholo/auth # Display AGENT.md usage guide
Each package can include an AGENT.md — a structured guide for AI agents with quick start, exported functions, and common patterns.
Environment Variables
| Variable | Purpose |
|---|---|
AILANG_REGISTRY | Registry URL (default: https://storage.googleapis.com/ailang-registry) |
AILANG_REGISTRY_VALIDATOR | Validator service URL (for ailang publish) |
AILANG_REGISTRY_API_KEY | API key for publishing |
Admin: Rebuild Index
If the registry index becomes corrupted, an admin can rebuild it from all published metadata:
curl -X POST https://<validator-url>/rebuild-index \
-H "X-API-Key: $AILANG_REGISTRY_API_KEY"
This scans all metadata.json files in the bucket and reconstructs index.json. Same API key auth as publish.
Available Packages
| Package | Description | Effects |
|---|---|---|
sunholo/auth | API key validation, HMAC hashing, bearer tokens | Pure |
sunholo/gcp_auth | GCP ADC OAuth2 token exchange, project detection | FS, Net, Env |
sunholo/http_helpers | HTTP request builders, auth headers, JSON response parsing | Net |
sunholo/logging | Structured JSON logging for Cloud Run | IO |
sunholo/config | Config loading from env vars with validation | Env |
sunholo/testing_utils | Test assertion helpers | Pure |
sunholo/registry_validator | Package validator written in AILANG (dogfooding) | IO, FS |
Source: github.com/sunholo-data/ailang-packages
Dual Hash Model
Each package in the lock file has two hashes:
| Hash | Changes When | Purpose |
|---|---|---|
| Content hash | Any source file changes | Reproducibility |
| Interface hash | Exports or effects change | Coordination — internal refactors don't cascade |
Backward Compatibility
Projects without ailang.toml work exactly as before. The package system is opt-in — existing module imports (std/..., local modules) are unaffected.
Workspace Pattern
Multi-package repos use path dependencies without needing a registry:
workspace/
types/
ailang.toml # name = "myorg/types"
parser/
ailang.toml # name = "myorg/parser", depends on types via path
app/
ailang.toml # depends on types + parser via path
Each package is independently valid. Workspaces are emergent from path-linked packages, not a separate manifest type.
AI Agent Coordination
The registry is more than a package manager — it's the coordination layer through which AI agents discover, share, and compose capabilities.
Why This Matters for Multi-Agent Workflows
When multiple AI agents work on a project (or across projects), the registry provides the shared vocabulary:
-
Effect ceilings — An agent can inspect
[effects].maxto know exactly what authority a package has. A package withmax = ["IO"]cannot access the network, filesystem, or environment. This lets agents reason about trust boundaries without reading source code. -
Interface hashes — The interface hash changes only when exports or effects change. An internal refactor (same exports, same effects) produces a new content hash but the same interface hash. Downstream agents can skip re-verification when only content changes.
-
AGENT.md discovery — Each package can include an
AGENT.md— a structured guide written for AI consumption, not human prose. The registry indexes whether a package has one (has_agent_doc: true), andailang pkg-docs vendor/nameserves it directly. -
Immutability — Once published, a version can never be overwritten. This means agents working concurrently can safely depend on a version without worrying about it changing underneath them.
-
Machine-readable metadata —
ai_summary,tags,effects, andhas_agent_docare all in the registry index as structured JSON. Agents can programmatically search and filter without parsing documentation.
Typical Agent Workflow
# 1. Discover what's available
ailang search "auth" --tag gcp
# 2. Read the AI-specific documentation
ailang pkg-docs sunholo/gcp-auth
# 3. Install with hash verification
ailang install sunholo/gcp-auth@0.1.0
# 4. Use in code
# import pkg/sunholo/gcp-auth/token (getAccessToken)
# 5. Publish reusable work back to the registry
ailang publish --dry-run # Validate first
ailang publish # Share with other agents
Writing Good AGENT.md
Structure your AGENT.md for machine consumption:
- Quick Start — minimal import + usage example (copy-pasteable)
- Exported Functions — signatures with effect requirements
- Common Patterns — typical workflows with the package
- Effect Requirements — what
--capsflags the consumer needs
Troubleshooting
Common Errors
| Error | Cause | Fix |
|---|---|---|
409 Conflict on publish | Version already exists | Bump version in ailang.toml |
401 Unauthorized | Missing or invalid API key | Set AILANG_REGISTRY_API_KEY |
hash mismatch on install | Corrupted download or tampered package | Retry; if persistent, report to registry admin |
effect ceiling violation | Package uses effects not in [effects].max | Add missing effects to ailang.toml |
package not found | Wrong name or not yet published | Check spelling with ailang search |