# Version 1 adapter contract [`PRODUCT.md`](PRODUCT.md) incorporates this document as normative version 1 behavior. An ecosystem counts as supported only when its adapter satisfies the common minimum and the row in the capability table. A warning-only stub is not support. ## Common minimum Every shipped adapter must: 1. identify its ownership domain and manager installation instance without mutation; 2. detect absence, unusable executables, unsupported versions, and conflicting ownership; 3. discover at least one useful class of installed item, version, cache, or cleanup candidate from authoritative local metadata; 4. emit normalized bounded records with canonical identity, native identity, state, provenance, confidence, size or unknown, availability, and reason; 5. distinguish supported native states and emit `unknown`, never an inferred substitute, for states the manager does not maintain; 6. expose exact executable, argv, effective configuration, versions, network scope, and side effects; 7. establish operation-specific read-only planning and execution binding before offering an action; 8. refresh authoritative state after execution and normalize the observed result. Discovery-only capability is useful support when the ecosystem has no safely bindable cleanup operation. The UI must state `discovery only` and the exact missing planning or binding capability. An adapter that cannot produce authoritative discovery records is unavailable, not supported. ## State vocabulary Normalized package state uses these tagged values: - `explicit`: authoritative metadata says the operator directly requested the item; - `automatic`: authoritative metadata says it was installed as a dependency; - `orphan`: the manager says an automatic dependency is no longer required; - `active`: the manager or effective configuration selects this version; - `obsolete`: the manager identifies a superseded version with disposal semantics; - `cache_removable`: the manager identifies the exact cache scope as removable; - `unknown`: the manager does not expose the semantic or evidence is incomplete; - `conflicting`: authoritative sources disagree. Adapters never derive these states from access time, path names, or dependency-graph guesses when the manager does not expose the corresponding concept. Provenance is `manager_metadata`, `manager_query`, `documented_format`, or `operator_configuration`. Confidence is `authoritative`, `documented`, `observed`, `unknown`, or `contradicted`. Only authoritative or documented producer semantics can enable recommendation. Contradicted evidence disables execution. ## Supported version and configuration rule No open-ended version range is supported. An operation is supported only for an exact manager version, runtime version, and effective configuration tuple present in checked-in capability evidence. A different version, executable identity, configuration file, relevant environment value, plugin, hook policy, or destination scope is discovery-only until its evidence is repeated. The effective configuration profile is an allowlist containing only values required to determine manager state, disable incidental writes where supported, bind effects, control network use, and isolate logs, caches, and temporary files. Credentials are passed through only when the manager requires them and are never captured. ## Ownership domains and aliases - Termux `pkg` and APT are one `termux-apt` ownership domain. - npm, pnpm, and Yarn use separate domains unless authoritative store metadata proves shared ownership for a specific installation instance. - pip, pipx, and uv use separate domains; a tool-managed environment belongs to its creating tool. - Cargo and rustup are separate domains. - Gradle and Maven are separate domains. - RubyGems and Bundler share a domain only for a Bundler installation instance proven by its lock and configured path. - Android packages and files inside their app sandboxes remain separate ownership domains. Equal names never establish aliasing. The canonical identity rules in `PRODUCT.md` section 4.3 apply to every domain. ## Minimum capabilities Each item names required discovery, followed by its minimum useful action. - **Termux pkg/APT:** dpkg installed state, APT manual or automatic state, orphans, and archive-cache scope. Provide exact package removal or exact cache scope through reviewed APT planning and binding. - **Cargo:** `cargo install` roots and explicit crate records. Provide exact `cargo uninstall` only when installed state and effects bind. - **rustup:** toolchains, components, targets, defaults, overrides, and active state. Provide exact toolchain, component, or target removal with active-use checks. - **npm:** installation roots, package tree, top-level or dependency state, and cache scope. Provide exact uninstall when dependency effects bind; cache cleaning needs proven exact scope. - **pnpm:** installation roots, dependency state, content-addressed store records, and cache scope. Provide exact uninstall or a proven store-prune effect set. - **Yarn:** project or global installation state, dependency state, and cache records. Provide exact uninstall or exact cache scope for an evidenced Yarn generation. - **pip:** environment identity, installed distributions, requested markers, and metadata. Provide exact uninstall; explicit or automatic state is unknown without authoritative requested metadata. - **pipx:** managed environments and explicit applications. Provide exact environment uninstall. - **uv:** managed tools, environments, Python versions, and cache records. Provide exact tool or version removal, or exact native cache scope with binding. - **Gradle:** project identities, wrapper versions, and Gradle-owned cache records. Remain discovery-only until an exact producer-owned cleanup effect set is evidenced. - **Maven:** project identities and local-repository records. Remain discovery-only until an exact producer-owned cleanup effect set is evidenced. - **Zig:** compiler versions, project caches, and global caches. Remain discovery-only; generic cache deletion is manual-only without producer semantics. - **Go:** module cache, build cache, and toolchain identity. Remain discovery-only unless an exact `go clean` scope binds to reviewed entries. - **RubyGems:** installed specifications, versions, dependencies, and environment. Provide exact gem uninstall; explicit or automatic state is unknown without authoritative metadata. - **Bundler:** lockfile packages, direct or transitive state, configured path, and cache records. Provide exact bundle-managed cleanup only when lock and installation scope bind. - **Composer:** lockfile packages, root requirements, transitive state, and cache records. Provide an exact package operation or cache scope with effect binding. - **proot-distro:** installed roots, aliases, exposed versions, and active process evidence. Provide exact distro removal with namespace and active-use checks. - **mise:** installed tool versions, configured selections, and active versions. Provide exact inactive-version removal with configuration revalidation. - **Android Termux packages:** allowlisted identifiers, version, enabled state, and observable ownership. Launch system uninstall confirmation for exactly one allowlisted add-on. ## Effect-set schema Every package action effect set contains: - ownership domain and manager instance; - operation and canonical target identities; - reviewed manager/runtime/executable/configuration tuple; - direct additions, removals, upgrades, and retained items; - indirect dependency operations; - exact cache scope; - declared hooks with identity and invocation phase; - network scope; - manager locks and concurrency assumptions; - expected post-operation manager-state predicates; - unknown or unobservable effect tags. Execution binding must prevent widening or prove immediately before execution that the authoritative state, tuple, target set, indirect operations, hooks, cache scope, and postconditions are identical to the reviewed effect set. If no supported manager mechanism can bind that state, the action is unavailable. Whole-cache operations are unavailable unless the manager accepts an immutable reviewed entry set or a scope whose membership cannot change between review and execution. Any executable identity, manager/runtime version, effective configuration, plugin, hook policy, manager state, or effect-set change is material and returns to review. ## Result normalization Normalized results are `success`, `failure`, `cancelled`, `partial`, or `uncertain`. Exit zero alone is insufficient for success; refreshed authoritative state must satisfy every reviewed postcondition with no additional manager-level effect. A signal, timeout, malformed required output, output truncation affecting authority, detached process, unobservable hook, or Android result that cannot be observed is `uncertain` unless manager-state refresh proves a narrower result. Diagnostics truncation preserves status but is explicit. Authority-output truncation makes planning or execution unavailable. ## Android allowlist Version 1 recognizes only these package identifiers. Membership and role are canonical in `spec/model/android_packages.zon` and projected here: - `com.termux` (base) - `com.termux.api` (add_on) - `com.termux.boot` (add_on) - `com.termux.float` (add_on) - `com.termux.gui` (add_on) - `com.termux.styling` (add_on) - `com.termux.tasker` (add_on) - `com.termux.widget` (add_on) - `com.termux.x11` (add_on) The running base package `com.termux` is report-only and never offered for uninstall. Every add-on uninstall is manual-only and launches Android's system confirmation for exactly one identifier. `confirmed`, `cancelled`, `failed`, and `unknown` are the only normalized confirmation outcomes. Only a refreshed package query can establish removal. ## External-process registry Every production process call site must appear in a generated registry checked by lint. Each record contains source location, adapter, executable role, authoritative reason in-process logic is insufficient, allowed operation tags, argument and output bounds, timeout, cancellation policy, network scope, capability-evidence identifier, and owning tests. The initial allowed executable roles are the managers named in the capability table, Android's supported package API bridge, and VCS executables required for authoritative repository semantics. Shells, generic command interpreters, privilege tools, and unregistered helper executables are forbidden.