explanationView source

Packages and the lockfile#

A workspace is one alpha.project, the packages it names, and alpha.lock, which pins every package by content. There is no registry, no download, no version solving and no package build script: a dependency is a directory on this machine, named in the manifest and pinned by content in the lockfile.

The manifest#

alpha.project is line-oriented: one key value per line, with -- comments. The first line must be format alpha-project-v1 or format alpha-project-v2. An unknown key, an empty value, a repeated single-valued key or a repeated package name is reported with its line number, and the command exits with status 2.

KeyRequiredMeaning
formatyesalpha-project-v2 validates each package's alpha.package before resolving modules; v1 does not
nameyesThe workspace's name; also its entry in the lockfile
editionyesThe default edition (--edition overrides it, checked against docs/editions/)
default-rootyesThe root a command uses without --root: a path ending in .alpha is a workspace-relative file; a bare module name resolves only under source-root
source-rootnoSearched first for modules (default alpha-src)
package NAME PATHno, repeatableA package root, searched after source-root in declaration order
profileno, repeatableThe build profiles offered: any of check, dev, release, tune; the first listed is the default (default: all four)
targetnoThe default target (x86_64-linux; --target overrides it)
cachenoThe interface cache directory (.alpha-cache; --cache and --no-cache override it)
closure, stdlibnoAccepted and recorded

The repository's own manifest, abbreviated:

format alpha-project-v2
name alpha
edition alpha-2027
source-root packages/tooling/cli/src
package foundation-standard packages/foundation/standard/src
package compiler packages/compiler/src
package bob-system systems/bob/src
default-root packages/tooling/cli/src/Main.alpha
profile check
profile dev
profile release
profile tune
target x86_64-linux
closure language-platform
cache .alpha-cache

Without an alpha.project (and for alpha doctor --init), the edition defaults to alpha-2026.

Packages#

Under alpha-project-v2, each package root has an alpha.package, found in the declared root or its parent. Alpha reads it before resolving any module and requires its name to match the project's package line and its src to resolve to the declared root:

format alpha-package-v2
name bob-system
area systems
namespace Bob
src src
tests tests
test-suite tests/alpha-tests
maintained true
FieldMeaning
formatalpha-package-v1 or alpha-package-v2
name, area, src, maintainedRequired; maintained is true or false
namespaceOne or more module namespaces; every module the package provides must fall under one
tests DIR(v2) Repeatable; implies the suite DIR/alpha-tests
test-suite PATH(v2) Names the package's suite directly
tests-classification REASON(v2) Recorded by a package without local tests; alpha test --list --strict rejects an unclassified package

alpha test --package NAME runs a package's suite.

Module resolution#

A module name maps to a file under a root: Std.Natural is ROOT/Std/Natural.alpha. source-root is tried first, then each package root in order. The file's module line must equal the imported name, and import cycles are refused. Two roots providing the same module are rejected with ALPHA-MODULE-DUPLICATE-PROVIDER, naming both paths; alpha-project-v1 keeps declaration-order, first-provider resolution. A module no root provides reports every location searched:

module Geometry is in none of the 2 searched location(s): ./src/Geometry.alpha (workspace), ./packages/geometry/src/Geometry.alpha (package geometry)

When the missing module was imported, the message ends with (imported by MODULE).

The lockfile#

alpha package lock writes alpha.lock atomically. It pins each package by the content digest of every .alpha file in its full declared source root, not only the files the current build reaches, so a module outside today's closure cannot drift unnoticed. For v2 packages the alpha.package file is hashed too.

format alpha-lock-v1
package alpha 0.1.0
  digest c314000000000000a5aa030000000000
  origin workspace
  edition alpha-2027
  interface-schema alpha-checked-interface-v7
  depends foundation-probe execution-telemetry observability …
  path packages/tooling/cli/src
package foundation-probe 0.1.0
  digest e62c0000000000003cbc0e0000000000
  origin path
  edition alpha-2027
  interface-schema alpha-checked-interface-v7
  path packages/foundation/probe/src

The workspace entry (origin workspace) lists every package under depends; each package entry (origin path) records its own digest and path. Every entry carries the workspace's edition and the checked-interface schema. Because the digests are separate, drift is attributed: editing one package's source drifts that package's entry and no other.

alpha package verify checks every recorded field against the workspace: digest, edition, version, origin, interface schema, path and dependency list. It also requires the two sets of packages to match, refusing a package the workspace has and the lockfile does not, and the reverse. It exits 1 on any difference. A field the lockfile records but nothing verifies would be decoration: a tampered origin once verified, and the security suite now holds that check.

alpha package list prints the lockfile; with --json it prints each package's manifest record.