Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

You are reading the development version (master). For the latest release (v3.5.0) see the stable docs.

Package Ecosystem Specification

Overview

Deterministic, content-addressed package system for the Boruna platform. No remote registries, no version ranges, no dynamic loading. All resolution is exact and reproducible.

Package Manifest (package.ax.json)

Every package has a manifest at its root:

{
  "name": "example.package",
  "version": "0.1.0",
  "description": "Short description",
  "dependencies": {
    "other.package": "0.2.1"
  },
  "required_capabilities": ["net.fetch", "db.query"],
  "exposed_modules": ["core", "utils"],
  "integrity": "sha256:<hex>"
}

Fields

FieldTypeRequiredDescription
namestringyesDotted package name (e.g. std.collections)
versionstringyesSemver (MAJOR.MINOR.PATCH)
descriptionstringyesHuman-readable description
dependenciesmapnoPackage name → exact version
required_capabilitiesarraynoCapability strings from boruna-bytecode::Capability
exposed_modulesarrayyesModule names this package exposes
integritystringcomputedContent hash, set by boruna-pkg publish

Validation Rules

  • name must match ^[a-z][a-z0-9]*(\.[a-z][a-z0-9]*)*$
  • version must be valid semver: MAJOR.MINOR.PATCH
  • dependencies must specify exact versions (no ranges, no wildcards)
  • required_capabilities must be valid capability names from boruna-bytecode::Capability
  • exposed_modules must contain at least one entry
  • integrity is computed at publish time; absent in development

Lockfile (llm.lock.json)

Generated only by the resolver. Never hand-edited.

{
  "lockfile_version": 1,
  "resolved": {
    "[email protected]": {
      "integrity": "sha256:abc123...",
      "dependencies": {
        "other.package": "0.2.1"
      }
    },
    "[email protected]": {
      "integrity": "sha256:def456...",
      "dependencies": {}
    }
  }
}

Rules

  • Generated by boruna-pkg resolve and boruna-pkg install
  • Only boruna-pkg writes the lockfile. The compiler, VM and boruna CLI do not read it, so a missing or stale lockfile does not stop a build or run
  • Lockfile must be committed to version control
  • Changing lockfile requires reviewer approval (orchestrator gate)

Package Storage (Local Registry)

Content-addressed layout:

packages/
  registry/
    <package-name>/
      <version>/
        package.ax.json
        src/
          <module>.ax
        bytecode/
          <module>.axbc
        HASH

Content Hash

The HASH file contains sha256:<hex> computed over:

  1. All source files (src/**/*.ax) sorted by path
  2. The manifest (package.ax.json) with integrity field removed
  3. Dependency hashes (sorted by package name)

This produces a Merkle-like hash: changing any transitive dependency changes the root hash.

Publish Flow

  1. Validate manifest
  2. Compile all exposed modules to bytecode
  3. Compute content hash
  4. Set integrity field in manifest
  5. Copy to registry under <name>/<version>/

Resolver

Algorithm

  1. Parse root manifest dependencies
  2. For each dependency, load its manifest from registry
  3. Recursively resolve transitive dependencies
  4. Topological sort (Kahn’s algorithm)
  5. Detect circular dependencies → hard error
  6. Detect conflicts (two versions of same package) → hard error
  7. Generate lockfile with all resolved packages and their hashes

Invariants

  • Same manifest + same registry → identical lockfile (deterministic)
  • No version range resolution
  • No SAT solver
  • Fail fast on any ambiguity

Capability Enforcement

Checked by boruna-pkg install (not at compile time):

  1. Resolve the root manifest’s dependencies
  2. For each dependency (transitively), collect required_capabilities
  3. Union all capabilities
  4. Check against the application policy, if policy.ax.json exists
  5. If any dependency requires a forbidden capability → install fails with a capability policy violation

Policy Format

Application policy is read only from policy.ax.json next to the root manifest. Without that file, no capability check runs:

{
  "allowed_capabilities": ["net.fetch", "time.now"],
  "denied_capabilities": ["fs.write", "random"]
}

If allowed_capabilities is present, only those are permitted. If denied_capabilities is present, those are blocked. Cannot specify both. If neither, all capabilities are allowed.

CLI Commands

CommandDescription
boruna-pkg initCreate package.ax.json in current directory
boruna-pkg add <pkg> <version>Add dependency to manifest
boruna-pkg remove <pkg>Remove dependency from manifest
boruna-pkg resolveGenerate llm.lock.json from manifest + registry
boruna-pkg installResolve, check all packages exist in registry, write llm.lock.json, check policy.ax.json
boruna-pkg publishCompile, hash, copy to local registry
boruna-pkg verifyVerify all installed packages match their hashes
boruna-pkg treePrint dependency tree

Orchestrator Integration

The orchestrator library has two package gate adapters: PackageResolveAdapter (runs boruna-pkg resolve, passes on exit code 0) and PackageVerifyAdapter (runs boruna-pkg verify). Neither is wired into boruna-orch apply/review, and there is no automatic detection of bundles that touch package.ax.json or llm.lock.json. Lockfile changes go through the normal two-person review like any other patch.

Security Model (MVP)

  • Local registry only (no remote fetch)
  • No auto-download
  • Manual publish/install
  • Hash verification against each package’s HASH file runs via boruna-pkg verify; install recomputes hashes into the lockfile but does not compare them
  • No code execution during install

Non-Goals (MVP)

  • Remote package registry
  • Version range resolution
  • Optional dependencies
  • Platform-specific packages
  • Pre/post install scripts
  • Binary distribution