Static copy
Copied from docs/en/adp/ADP-007-package-identity-and-distribution.md in https://github.com/poppy-team/aipo-lang (MIT). Pinned to revision ce47c4e070404fc41722ccd8e2b7b808b99062a8, blob b70f82eef2a32f52f6217757c70f6762ea6caa55. The source repository remains canonical; this copy is refreshed through a sync pull request, not live.
Status: accepted Date: 2026-09-24 Related: Fechamento Arquitetural §13, §14; docs/crates/crate-contracts.md; docs/canon/Aipo — Waves, Vertical Slices, Gauntlet LoopsAuthority: subordinate to the canon; this ADP fixes the first implementation without creating a platform service of its own.
A package coordinate has exactly two dot-separated segments:
namespace.packageExample: acme.http. The coordinate is the canonical identity used in the manifest, lockfile, SourceMap and diagnostics. Segments use the ASCII lowercase grammar [a-z][a-z0-9_]*; this decision does not yet accept submodules (acme.http.client).
The origin is explicit in the resolution chain: acme.http is not confused with the built-in module http or with a local package of the same name.
The import surface uses the full coordinate:
import acme.http
import acme.http as hThe alias remains local to the file that declares it. The original coordinate remains available for provenance, lockfile and diagnostics. Built-in modules remain simple (math, task, io, time).
The first slice supports only the entry module of each package. The submodule form is left for a later decision, so as not to blur the boundary between coordinate and internal path.
Aipo owns the package protocol; GitHub is only the initial distribution backend. The source model separates origin, revision and artifact:
path for local development;owner/repository slug, an exact 40-hex commit SHA and a relative subpath;The manifest accepts path and pinned GitHub dependencies. The canonical form for GitHub is type = "github", with repository, revision, subpath and an exact SemVer version. The lockfile records the coordinate, exact version, source, revision, checksum, targets and relevant capabilities. Branches, tags, URLs, credentials and mutable revisions are rejected. A GitHubFetcher and an offline in-memory store allow provenance to be tested without a network; the verified-cache API and the read-only package cache verify are available in the default build, while the http feature adds public GET, timeout, response limit, blocked redirects and an atomic local cache. Authentication is opt-in via --github-token-env <name> in the fetch/lock forms; the value comes from an explicitly named environment variable, is validated as a bearer token, and is never persisted, logged or included in diagnostics.
aipo package fetch-github and the explicit form aipo package lock <dir> --fetch-github --cache <dir> are the only operations that enable GitHub fetching. fetch-github recursively walks the pinned GitHub dependencies and writes the complete lockfile into the output snapshot. The mixed-lock form keeps local inputs in the project, fetches only the pinned GitHub edges and writes a single lockfile. Both optionally accept --github-token-env <name> to use a bearer credential supplied by the environment; without that flag, requests remain public and carry no Authorization. Local dependencies remain available in the local resolver; a path dependency declared inside a remote artifact is rejected because there is no trusted root filesystem in which to interpret it. run, check, build and disasm accept --package-cache to consume the mixed graph without a network; without the flag, these commands are local. aipo package cache verify <dir> audits all existing entries without creating, repairing, removing or fetching data. aipo package cache prune <dir> --lock <lockfile> is a dry run by default; only --apply removes verified entries that the lockfile does not reference, and any verification error prevents any removal. package lock without the explicit form and package audit remain local. OAuth, token discovery/persistence, automatic downloads, lifecycle and registry publication remain outside this slice. There are no arbitrary install scripts or lifecycle execution in V1.
Capabilities declared by packages are an upper bound. The project policy and the host policy can reduce that set; they never silently widen it. The transitive union is auditable and must fit within the limit declared by the root.
aipo-host remains the source of the grammar and the narrowing rules. aipo-stdlib publishes the API surface; the effective service is installed and verified in the host, as already happens with clock and Poppy. The first new services are env.read and the host-only slice fs.read_text/fs.roots: each provider lives in the VM's HostContext, installation does not grant capabilities, and the roots/paths policy belongs to the provider.
import no longer accepts only an identifier and now carries a qualified path.ModuleGraph; the latter remains the initialization graph of already-resolved modules.http feature allows explicit GitHub fetch, with optional authentication that is strictly opt-in via an environment variable name; signing, distributed cache and registries remain behind their own fixtures and security decisions.aipo-package: manifest, coordinate, lock and deterministic path resolver — done.env.read as the first per-VM proof — done.fs.read_text/fs.roots and the async-first contract — done in the host-only slice.fetch-github command — done in slice P04-G05; authentication remains opt-in and outside the manifest.--apply — done in slice P04-G10.