Project 10: Signed Pocket APT Repository

Turn the PocketOps tools into a versioned Termux package and a signed release channel that a second phone can install, upgrade, verify, and recover without the developer’s filesystem.

Quick Reference

Attribute Value
Difficulty Level 3 - Advanced
Time estimate 22-36 hours
Main language Shell build orchestration plus YAML/JSON/Debian metadata
Alternatives Python, Make, CI workflow configuration
Prerequisite projects P01-P02; P08 service layout; P09 native probe
Primary concepts PREFIX relocation, package ownership, dependencies, conffiles, migration, APT metadata, GPG signing, reproducibility
Main tools Official termux-packages environment, termux-create-package, termux-apt-repo, Debian package tools, GPG
Observable outcome A second supported phone installs and upgrades PocketOps from signed metadata while tampered artifacts are rejected and mutable state is preserved

1. Learning Objectives

By completing this project, you will be able to:

  1. Explain why packaging defines an installation and lifecycle contract rather than merely compressing files.
  2. Choose deliberately between the official termux-packages build system and termux-create-package.
  3. Build for explicit Termux architectures, Bionic, Android API levels, and PREFIX-relocated paths.
  4. Classify every path as package-owned, configuration, mutable state, cache, log, secret, or export.
  5. Declare runtime dependencies so a clean device behaves like the development device.
  6. Design idempotent, journaled migrations and a realistic downgrade/rollback policy.
  7. Explain how signed repository metadata binds a trusted publisher identity to package hashes.
  8. Bootstrap repository trust independently, rotate keys, and respond to compromise without trusted=yes.
  9. Test clean install, upgrade, repeated migration, removal, wrong ABI, missing dependency, tampered index, and tampered package.
  10. Produce release provenance and two-build comparison evidence without embedding secrets.

2. Theoretical Foundation

2.1 Core Concepts

A package is a state-transition promise. The payload identifies files to install, but metadata defines name, version, architecture, dependencies, conflicts, descriptions, configuration handling, and lifecycle actions. Installation transforms a clean supported environment into a usable one. Upgrade transforms one supported state into another while preserving defined user data. Removal reverses package ownership without pretending all application data is disposable.

Termux is not a conventional Debian root filesystem. Packages install beneath $PREFIX, normally /data/data/com.termux/files/usr, under the Termux application UID. Desktop shebangs and hard-coded /usr, /bin, /etc, or /var paths are suspect. Termux package tooling and patches relocate expected paths and target Android’s Bionic environment. An artifact that happened to work from HOME may fail once installed if it relied on an interactive shell profile or undeclared files.

Use the build path that matches the artifact. termux-create-package is suitable for a straightforward package made from existing scripts or files. The official README notes that the old PyPI copy is obsolete, so use its supported distribution. The official termux-packages environment is the production-minded path for source builds, Termux-specific patches, verified source archives, multiple architectures, dependency integration, and ecosystem conventions. P09’s native probe should graduate to that environment when the release claims extend beyond the development phone.

Architecture is package metadata and runtime truth. Architecture-independent scripts can be all only if no bundled file or generated behavior is architecture-specific. A package containing the native probe must be built and indexed for its actual target, such as aarch64. A clean client must reject unavailable or wrong-architecture builds rather than receive a loader surprise after installation.

Ownership boundaries make upgrades safe. Package-owned executables, manuals, completions, immutable schemas, and service templates may be replaced by the package manager. User configuration may need conffile-like mediation. Databases, queues, keys, runtime logs, and generated state are mutable and should be created privately by the application, outside the package payload’s destructive ownership. A service definition can be installed, but enabling a persistent service requires explicit user consent.

  package-owned                         mutable private state
  +---------------------------+         +---------------------------+
  | bin/pocketctl             |         | config                    |
  | bin/pocketprobe           |         | database + queue          |
  | share/man                 |         | SSH/HMAC/application keys |
  | completions               |         | logs + migration journal  |
  | service template          |         | recovery metadata         |
  | immutable default schema  |         +---------------------------+
  +-------------+-------------+                       ^
                | package manager replaces            |
                +------------------ migration reads ---+

  Invariant: payload replacement cannot silently erase mutable state.

Version ordering is operational behavior. A version is not a marketing label. The package manager compares versions to choose upgrade/downgrade behavior. Release metadata must match the artifact and migration policy. A state schema may advance independently from the package version; the application should record it transactionally and refuse an unsupported downgrade before changing data.

A migration is a recoverable state machine. It starts from a recognized schema, records intent, stages or transactionally applies a change, commits the new schema marker, and leaves evidence. Repeating the action must return the same logical state. If rollback is not possible after a destructive migration, the package must require a verified backup and say so before proceeding. Maintainer hooks should remain minimal because they run during fragile package-manager transitions.

APT trust is rooted outside the repository. Repository metadata names available package versions and includes hashes that bind downloaded bytes. A signature lets a client verify that authorized repository key material signed the metadata. This proves publisher authorization and integrity since signing; it does not prove the source is benign, the build is reproducible, or the signing workstation is uncompromised.

  authentic fingerprint (independent channel)
                  |
                  v
           trusted public key
                  |
                  v verifies
  signed Release/InRelease ----hash----> Packages index
                                        |
                                        +----hash----> pocketops.deb
                                                          |
                                                          v
                                               package files + scripts

Setting a repository to trusted=yes bypasses this verification and destroys the intended production trust path. A lab may demonstrate the consequence, but the completed channel must not rely on it.

Signing identity is not an Android APK signing lineage. This project signs APT repository metadata. The Termux app and classic add-on APKs have their own shared signing compatibility requirement and must come from the same official source family. Do not imply that a GPG-signed .deb repairs mixed F-Droid/GitHub APK signatures or makes the Play and classic tracks interchangeable.

Reproducibility narrows the supply-chain gap. Controlled source, checksums, toolchain identity, dependency versions, locale, timestamps, file ordering, and network inputs all matter. Bit-for-bit equivalence is the strongest result, but explaining a bounded difference is still valuable. Record source and package hashes, build logs, a dependency inventory or SBOM, and independent installation evidence.

Termux is rolling release. Partial upgrades are unsupported because dynamically linked packages move together. Acceptance should update the supported environment as a whole rather than pinning an arbitrary subset and blaming the package when ABI dependencies no longer align.

2.2 Why This Matters

Manual copying hides dependency, version, ownership, and trust assumptions in the developer’s memory. A signed package channel makes those assumptions reviewable and gives another device an authenticated, repeatable path. The project teaches deployment engineering at a small enough scale to inspect end to end: source, build, package, index, signature, key bootstrap, install, migration, service state, removal, and recovery.

These skills transfer to Linux distribution packaging, mobile fleet channels, container registries, firmware updates, CI artifact promotion, and software supply-chain reviews. The core lesson is that release trust combines cryptography with operational discipline; neither substitutes for the other.

2.3 Historical Context / Background

Debian packages evolved a structured model for declaring dependencies and managing files across install, upgrade, and removal. APT added repository indexes and authenticated metadata so users could select versions and verify downloaded bytes. Modern repositories commonly use signed release metadata rather than asking users to trust each download ad hoc.

Termux adapted Debian-style packaging to an Android-hosted, PREFIX-relocated userspace. The official package build system carries patches and build logic needed for Android ABIs and Bionic. termux-create-package and termux-apt-repo provide smaller workflows for assembling packages and repository trees, including signed repository metadata. The underlying trust questions remain the same, but Android installation tracks and app/add-on signing add a separate compatibility layer outside APT.

2.4 Common Misconceptions

  • “A .deb is just a tarball.” It declares lifecycle, dependencies, ownership, architecture, and version semantics.
  • “The package may write everything into PREFIX.” Mutable state and secrets must not overlap replaceable payload files.
  • “Signing means the code is safe.” It authenticates publication and integrity, not correctness or intent.
  • “Downloading the key beside the repository is independent verification.” One attacker can replace both.
  • trusted=yes is acceptable on a private LAN.” Network location is not a cryptographic publisher identity.
  • “ARM64 is enough.” A native package must still target Android/Bionic, API, loader, and Termux paths.
  • “APT package signing and APK signing are the same trust system.” They protect different artifacts and compatibility rules.
  • “Upgrade scripts can be retried manually.” Package transitions must be idempotent and failure-aware by design.

3. Project Specification

3.1 What You Will Build

Create a pocketops package that contains:

  • the stable pocketctl entry point and architecture-independent modules;
  • the P09 native probe for each explicitly supported architecture;
  • manual pages, shell completions, schemas, and immutable default templates;
  • a runit service template installed disabled by default;
  • first-run logic that creates private mutable state with restrictive permissions;
  • a versioned state migration contract and backup preconditions;
  • package metadata with exact dependencies and supported architecture/API policy.

Publish the resulting package through a small signed APT repository produced with supported Termux tooling. A second supported phone must bootstrap the public key through an independently verified fingerprint, add the source, install, upgrade, and validate the product. Produce a redacted release evidence bundle and a compromise/rotation runbook.

3.2 Functional Requirements

  1. Declare package name, version, architecture, dependencies, description, and installed paths accurately.
  2. Reject desktop shebangs, forbidden FHS paths, unapproved ELF interpreters, and undeclared runtime lookups during release checks.
  3. Install package-owned files beneath PREFIX and mutable application state beneath private HOME/state paths.
  4. Create mutable state only at first run or through a documented initialization operation.
  5. Install the service definition disabled; require explicit opt-in before persistent execution.
  6. Migrate state transactionally from version 1 to version 2 and treat replay as success.
  7. Refuse an unsupported downgrade before modifying state and provide the recovery path.
  8. Generate Packages/Release-style metadata and sign the repository using protected key material.
  9. Document a public-key fingerprint verification channel independent of the repository transport.
  10. Reject a modified index, modified package, wrong architecture, and missing dependency.
  11. Preserve queued events, user configuration, and key material across a normal upgrade.
  12. Define removal and purge behavior without silently deleting the only recovery copy.

3.3 Non-Functional Requirements

  • No signing private key is stored in the repository web root, package payload, mobile client, ordinary build log, or shell history.
  • Build inputs, source checksums, toolchain identity, and output digests are recorded.
  • Two clean builds are compared and differences are explained.
  • Installation succeeds on a clean supported second device without developer HOME files.
  • Maintainer actions are minimal, bounded, noninteractive, and idempotent.
  • Logs and evidence redact secrets and stable device identifiers.
  • Production repository configuration never uses trusted=yes.
  • The classic F-Droid/GitHub reference track and current Play track differences are documented; package support does not imply add-on parity.

3.4 Example Usage / Output

$ pkg install pocketops
Repository     pocketops-stable  SIGNATURE_VERIFIED
Package        pocketops 1.1.0 aarch64
Dependencies   satisfied
Install root   $PREFIX
State schema   1 -> 2             MIGRATED
Service        installed          DISABLED_BY_DEFAULT
Doctor         READY
Result         INSTALLED
$ pocketctl release verify pocketops_1.1.0_aarch64.deb
Artifact hash  sha256:79c4...1a20
Index hash     MATCH
Release sig    VALID key=POCKETOPS-RELEASE-2026
Architecture   aarch64
ELF policy     PASS
Path policy    PASS
Assessment     AUTHORIZED_RELEASE

After one byte of the lab copy is changed, verification must fail before installation with PACKAGE_HASH_MISMATCH or an equivalent stable code.

3.5 Real World Outcome

A second supported Android phone begins with the official Termux track, compatible same-source add-ons, and no PocketOps developer files. An operator verifies the repository-key fingerprint through a separately documented channel, configures the repository, updates indexes, and installs PocketOps. The package lands in PREFIX, creates private state on first run, and leaves its service disabled. Upgrading from 1.0.0 to 1.1.0 preserves seeded configuration, queued events, and keys while recording one migration. Repeating the migration changes nothing. Tampered package and index fixtures are rejected. Removal deletes package-owned files and leaves recovery behavior exactly as documented.


4. Solution Architecture

4.1 High-Level Design

                     RELEASE WORKSTATION / CONTROLLED BUILDER
  +------------------------------------------------------------------+
  | source tag + source hashes + dependency policy + patches          |
  |                 |                                                |
  |        official Termux build / package assembly                  |
  |                 |                                                |
  |        package policy checks + two-build comparison              |
  |                 |                                                |
  |             pocketops_VERSION_ARCH.deb                           |
  +------------------------------+-----------------------------------+
                                 |
                           artifact digest
                                 v
  +------------------------------------------------------------------+
  | PUBLIC REPOSITORY                                                 |
  | .deb artifacts <- hashes <- Packages <- hashes <- signed Release |
  +------------------------------+-----------------------------------+
                                 |
                   verify with pre-trusted public key
                                 v
  +------------------------------------------------------------------+
  | SECOND TERMUX DEVICE                                              |
  | APT policy -> install package-owned PREFIX files                  |
  |                    |                                             |
  |                    +-> first run/migration -> private mutable data|
  |                    +-> service template remains disabled         |
  |                    +-> doctor + acceptance evidence              |
  +------------------------------------------------------------------+

  OFFLINE SIGNING MATERIAL is outside the public repository and package.

4.2 Key Components

Component Responsibility Trust rule
Source verifier Pin source revision/archive and checksum Network source is not trusted before verification
Builder Produce declared architecture artifacts Build inputs are controlled and logged
Package assembler Map payload and metadata into PREFIX paths No mutable secrets in payload
Policy checker Inspect paths, shebangs, ELF, dependencies, permissions Fails release closed on required violations
Migration runner Advance private state under a journal/transaction Repetition is safe; backup preconditions explicit
Repository indexer Bind package names/versions to hashes Index generated only from approved artifacts
Signer Authorize release metadata Private key isolated from public host and clients
Publisher Upload immutable release artifacts/metadata Cannot silently become signing authority
Client bootstrap Install key/source policy Fingerprint checked independently
Acceptance runner Test clean install/upgrade/tamper/remove Evidence redacted and versioned

4.3 Data Structures

Illustrative metadata shape—not a complete runnable package manifest:

Package: pocketops
Version: 1.1.0
Architecture: aarch64
Depends:
  - python
  - openssh
  - termux-services
Optional-Capabilities:
  - termux-api-classic-track
Install-Classes:
  package-owned:
    - bin
    - share/man
    - share/completions
    - service-template
  mutable-private:
    - config
    - database
    - queue
    - keys
Migration:
  from-schema: 1
  to-schema: 2
  invariant: commit-data-before-schema-marker
Service-Policy: installed-disabled

Release and migration records should model:

ReleaseRecord = {
  release_id, source_revision, source_hashes[],
  builder_identity, declared_inputs[],
  artifact_hashes[], repository_metadata_hash,
  signing_key_id, signature_time, promotion_state
}

MigrationJournal = {
  operation_id, package_from, package_to,
  schema_from, schema_to, backup_identity?,
  phase: PLANNED | STAGED | COMMITTED | ROLLED_BACK | NEEDS_RECOVERY,
  safe_error?, committed_at?
}

4.4 Algorithm Overview

BUILD_RELEASE(version, architecture):
    verify source and declared dependencies
    build in controlled Termux environment
    assemble package according to ownership map
    inspect shebangs, paths, modes, ABI, loader, dependencies
    run package tests and calculate digest
    compare independent clean build
    approve artifact for indexing

PUBLISH(approved_artifacts):
    generate package indexes and release metadata
    verify metadata refers only to approved digests
    sign release metadata with protected key
    publish immutable artifacts and metadata

CLIENT_UPGRADE(target):
    verify signed metadata and package digest
    preflight architecture, dependencies, space, schema, backup policy
    install package-owned content
    run minimal idempotent migration
    commit schema marker after data commit
    leave service desired state unchanged
    run doctor and record result

Index generation is O(P) in the number/bytes of published packages. Package-policy inspection is O(F + B) for file count and inspected bytes, both bounded by the artifact. Migration complexity is domain-specific but must have a declared space and time budget before install.


5. Implementation Guide

5.1 Development Environment Setup

Use a separate controlled build environment and a supported second Termux device. Begin by recording:

  • source repository and signed/reviewed release revision;
  • reference Termux track, Android/API support, architectures, and add-on assumptions;
  • official Termux build environment revision;
  • GPG implementation and key-storage plan;
  • clean repository staging directory and public hosting boundary;
  • second-device baseline doctor, installed package inventory, and backup state.

Generate training signing material only after writing the key policy. Keep it outside the workspace/public directory. The guide does not provide a key-generation command because key protection, identity, expiry, backup, and revocation are decisions rather than a copy-paste step.

The classic track requires main Termux and add-on APKs from one compatible source/signing family. The Play track is a separate product line with merged/missing integrations. Record the track as package capability metadata; do not promise classic add-ons merely because pocketops installed.

5.2 Project Structure

pocketops-release/
|-- packaging/
|   |-- ownership-map.md
|   |-- package-metadata/
|   |-- service-template/
|   `-- migration-contracts/
|-- builds/
|   |-- input-locks/
|   |-- evidence/
|   `-- approved-artifacts/
|-- repository/
|   |-- unsigned-staging/
|   |-- signed-public/
|   `-- retention-policy.md
|-- policy/
|   |-- path-policy.md
|   |-- elf-policy.md
|   |-- dependency-policy.md
|   `-- key-policy.md
|-- tests/
|   |-- clean-install/
|   |-- upgrades/
|   |-- tamper/
|   `-- removal/
`-- runbooks/
    |-- bootstrap-trust.md
    |-- key-rotation.md
    `-- compromise-recovery.md

5.3 The Core Question You Are Answering

How can another phone verify, install, upgrade, and remove this Termux product while preserving user state and rejecting unauthorized artifacts?

Answer with a chain of evidence from independently verified key fingerprint through signed metadata, artifact hash, installed inventory, migration journal, and acceptance report.

5.4 Concepts You Must Understand First

  1. Termux build model: Android/Bionic target, PREFIX relocation, architecture, and API policy.
  2. Debian package semantics: control metadata, dependencies, versions, conffiles, lifecycle, and ownership.
  3. Mutable-state separation: package replacement and application data have different lifetimes.
  4. Migration safety: preflight, journal, transaction, repeatability, backup, and incompatible downgrade.
  5. Repository verification: signed metadata, hashes, public-key bootstrap, expiry, rotation, and revocation.
  6. Reproducibility/provenance: declared inputs, isolated builds, digests, difference analysis, and promotion.

5.5 Questions to Guide Your Design

  1. Why is each file package-owned, configuration, state, cache, log, secret, or export?
  2. Does any entry point depend on an interactive profile or developer HOME path?
  3. Which dependencies are required, recommended, or capability-gated?
  4. What happens if the phone dies after data changes but before the schema marker?
  5. Which downgrade paths are safe, restore-based, or unsupported?
  6. How is a repository key fingerprint authenticated outside the channel it protects?
  7. Can the publisher host alter artifacts without the signing key, and will clients reject them?
  8. How are key rotation and compromise different procedures?
  9. What must be retained so an older supported version remains reinstallable?

5.6 Thinking Exercise

Draw and annotate:

source tag -> verified source -> build inputs -> .deb -> Packages
           -> Release/InRelease -> signature -> trusted key -> install
           -> migration -> health

At every arrow, name an attacker action, the detecting evidence, and the recovery owner. Then redraw the chain assuming the online publishing server is compromised but the signing key is not.

5.7 The Interview Questions They Will Ask

  1. What belongs in a Debian package control record?
  2. When should a Termux package be architecture all versus aarch64?
  3. Why are package-owned and mutable paths separated?
  4. What does APT repository signing prove and not prove?
  5. Why is independent key-fingerprint verification necessary?
  6. What makes a migration idempotent?
  7. Why are partial upgrades unsupported in a rolling distribution?
  8. How would you rotate a repository key without locking out offline devices?
  9. How is Android APK signing lineage different from APT metadata signing?

5.8 Hints in Layers

Hint 1: Inventory before package format

List every installed and created path, owner, mode, lifetime, backup class, and removal behavior.

Hint 2: Package the simple core first

Prove architecture-independent scripts, docs, and completions before adding the P09 native artifact.

Hint 3: Install clean

If the package needs a file from the development HOME, treat it as an undeclared dependency.

Hint 4: Separate signing and publishing

Generate metadata in staging, authorize it with protected signing material, then publish only signed public outputs.

Hint 5: Attack the channel

Change an index and a package independently and prove the client rejects both.

5.9 Books That Will Help

Topic Book Suggested chapters
Native artifacts “Linkers and Loaders” Ch. 1-3, 9-10
Distributed trust “Security Engineering,” 3rd ed. Ch. 21
Release failure and recovery “Release It!” Stability and deployment patterns
Deployment pipelines “Continuous Delivery” Build, acceptance, and deployment pipeline chapters
Data migration “Designing Data-Intensive Applications” Ch. 4 and 7

5.10 Implementation Phases

Phase 1: Support and ownership contract

  • Declare Termux track, Android/API, architecture, and add-on support.
  • Inventory paths, permissions, ownership, backup, and removal behavior.
  • Define versions, dependencies, and service opt-in policy.

Phase 2: Architecture-independent package

  • Package CLI modules, manuals, completions, schemas, and defaults.
  • Reject desktop shebang/FHS paths.
  • Install on the clean second phone and compare filesystem inventory.

Phase 3: Native probe integration

  • Build P09 in the official Termux environment for the declared architecture.
  • Gate release on ELF and dependency policy.
  • Confirm package architecture selection and runtime output.

Phase 4: Mutable state and migration

  • Implement first-run private initialization.
  • Seed schema-1 state, upgrade to schema 2, interrupt safely, and replay.
  • Define downgrade, removal, purge, backup, and restore behavior.

Phase 5: Repository and signing

  • Build repository metadata from approved artifacts.
  • Sign through the protected key workflow.
  • Publish public key/fingerprint through the designed independent channel.
  • Configure the clean client without trusted=yes.

Phase 6: Adversarial acceptance

  • Modify index and package lab copies.
  • Test wrong architecture, missing dependency, expired/revoked key scenario, and unsupported downgrade.
  • Prove service remains disabled unless the user opted in.

Phase 7: Reproducibility and operations

  • Rebuild from clean inputs and compare artifacts.
  • Produce promotion, rotation, compromise, rollback, and retention runbooks.
  • Assemble a redacted release evidence bundle.

5.11 Key Design Decisions

Decision Recommended default Reason
Build route termux-create-package for early simple files; official termux-packages for native/release path Matches complexity and ecosystem support
Service state Installed disabled Persistent execution requires user consent
Mutable state Private HOME application directory Survives package-owned file replacement
Signing Protected release key separate from publisher Limits compromise blast radius
Client trust Dedicated keyring/source policy and independent fingerprint Avoids global or circular trust
Upgrade Preflight + journaled idempotent migration Makes interruption and replay explicit
Downgrade Refuse unless schema-compatible or restore plan exists Prevents silent corruption
Repository artifacts Immutable per version Makes hashes, rollback, and investigation meaningful

6. Testing Strategy

6.1 Test Categories

  • Metadata tests: version ordering, architecture, dependencies, descriptions, and declared files.
  • Path tests: PREFIX relocation, shebangs, forbidden FHS paths, modes, ownership, and symlinks.
  • Native tests: ELF class/machine/interpreter, NEEDED libraries, minimum API, and clean runtime.
  • Lifecycle tests: fresh install, repeated install, upgrade, interrupted migration, downgrade, removal, and purge policy.
  • Trust tests: valid signature, unknown key, expired/revoked key policy, modified index, modified package, and replayed old metadata.
  • Clean-device tests: no developer files, explicit add-on capability, disabled service, and first-run private state.
  • Reproducibility tests: two clean builds, artifact diff, source/input hashes, and build-path leakage.

6.2 Critical Test Cases

Case Expected result
Clean install on supported aarch64 device Package and doctor succeed; service disabled
Required dependency missing Package manager resolves it or refuses before a broken install
Developer HOME file absent Install/runtime still succeeds
Upgrade with queued work and config Logical state preserved; one committed migration
Migration invoked twice Same schema/data; no duplicate transformation
Process dies during migration Journal permits safe retry or explicit recovery
Unsupported downgrade Refused before state mutation with restore instructions
Index changed after signing Signature/hash verification rejects repository metadata
.deb changed after indexing Package hash verification rejects artifact
Wrong architecture Client selection/install rejects package
Signing key absent from publisher Publisher cannot create an authorized new release
Package removed Owned files removed; state/recovery follows documented policy
Classic/Play capability mismatch Doctor reports unsupported add-on surface, not false readiness

6.3 Test Data

Prepare two package versions, schema-1 state with representative config/queue/key references, a valid clean repository, a modified index, a one-byte-modified package, wrong-architecture metadata/artifact, an unknown signing key, an expired metadata scenario, a missing dependency, and a package containing a forbidden shebang/path. Use canary secrets and assert they never enter artifacts, metadata, logs, or evidence.


7. Common Pitfalls & Debugging

7.1 Frequent Mistakes

  1. Packaging the development virtual environment or HOME tree.
  2. Marking a package all while bundling an aarch64 ELF.
  3. Leaving /usr/bin/env or desktop paths without a documented Termux policy.
  4. Storing mutable database or keys inside package-owned directories.
  5. Enabling a service automatically during install.
  6. Running a complex network-dependent migration in a maintainer hook.
  7. Fetching the public key through the same unauthenticated channel it validates.
  8. Using trusted=yes to make a signature problem disappear.
  9. Mixing APK source/signing lineages and assuming the package can fix it.
  10. Deleting old artifacts before clients can safely roll back.

7.2 Debugging Strategies

  • Compare pre/post installation inventories on the clean phone.
  • Resolve every runtime command and shared library to its owning package.
  • Inspect package metadata and payload separately.
  • Re-run the migration against a restored snapshot and inspect journal phases.
  • Verify signature, metadata hash, package hash, then package internals in that order.
  • Reproduce client verification from a clean keyring to detect hidden global trust.
  • When builds differ, compare environment, timestamps, ordering, compression, generated paths, and network inputs before changing source.

7.3 Performance Traps

  • Shipping caches or build outputs that inflate downloads.
  • Rehashing an entire large repository for every single-file promotion without staged manifests.
  • Performing expensive migrations without disk-space and time preflight.
  • Compressing already-compressed data repeatedly.
  • Running native builds on the phone as the fleet release path.
  • Keeping unlimited versions without a signed retention/rollback policy.

8. Extensions & Challenges

8.1 Beginner Extensions

  • Add a package inventory command that separates owned and mutable paths.
  • Generate a human-readable release note from approved metadata.
  • Add a dry-run migration plan that calculates storage requirements without mutation.

8.2 Intermediate Extensions

  • Publish separate stable and candidate channels with explicit promotion.
  • Add architecture-independent and aarch64 packages rather than bundling everything together.
  • Produce an SBOM/dependency inventory and bind its digest into release evidence.
  • Practice a planned key rotation with an overlap period and an offline client.

8.3 Advanced Extensions

  • Build aarch64, arm, i686, and x86_64 artifacts in official infrastructure and test selection.
  • Add reproducible-build verification from two independent builders.
  • Design threshold/offline signing so one compromised operator cannot publish alone.
  • Add mirror-consistency and rollback/freeze protection appropriate to the private fleet.
  • Stage P12 rollout to one canary phone before promotion to the fleet.

9. Real-World Connections

9.1 Industry Applications

The same chain appears in Linux repositories, enterprise mobile deployment, container registries, language package indexes, firmware update systems, and signed CI release pipelines. Production systems add stronger key custody, transparency, staged rollout, mirror policy, incident response, and fleet observability, but the small PocketOps channel exposes the same essential trust transitions.

9.3 Interview Relevance

This project supports release engineering, DevOps, SRE, supply-chain security, embedded distribution, and platform interviews. Strong evidence includes an actual tamper rejection, an interrupted idempotent migration, and a precise explanation of what the repository signature does not prove.


10. Resources

10.1 Essential Reading

10.2 Video Resources

  • Debian and reproducible-build conference talks on packaging and deterministic artifacts.
  • Supply-chain security talks on signing-key custody, promotion, and compromise recovery.
  • Android/Termux community build-system demonstrations, checked against current official documentation.

10.3 Tools & Documentation

  • GnuPG documentation for key lifecycle and signature verification.
  • Debian package inspection tools available in the supported environment.
  • LLVM/ELF inspection tools used in P09.
  • Android app signing for the separate APK trust model.
  • Termux Play Store track for current capability differences.
  • P02 supplies safe import/export and recovery data boundaries.
  • P08 supplies the disabled-by-default service template and state model.
  • P09 supplies the native artifact and ELF policy.
  • P11 audits trusted=yes, writable executables, secrets, and package trust.
  • P12 exercises staged upgrade, rollback, and full acceptance.

11. Self-Assessment Checklist

11.1 Understanding

  • I can explain package ownership, configuration, state, cache, log, and secret lifetimes.
  • I can choose between termux-create-package and official termux-packages for a given artifact.
  • I can trace trust from an independently verified key to installed package bytes.
  • I can explain what signing proves and what reproducibility adds.
  • I can distinguish APT signing from Android APK signing lineage.

11.2 Implementation

  • A clean device installs without developer filesystem artifacts.
  • Architecture, dependencies, PREFIX paths, shebangs, modes, and ELF policy pass.
  • Mutable state survives upgrade and repeated migration.
  • The service installs disabled and retains user desired state across upgrade.
  • Tampered metadata and package bytes are rejected.
  • No client uses trusted=yes, and no signing secret reaches public outputs.

11.3 Growth

  • I can design stable/candidate channel promotion.
  • I can write key rotation and compromise procedures for offline clients.
  • I can analyze a two-build difference without hand-waving.
  • I can state when public APK distribution or managed Android deployment requires a different product boundary.

12. Submission / Completion Criteria

Minimum completion

  • One correctly versioned package installs CLI/docs on a clean supported second phone.
  • Package-owned and mutable paths are documented and separated.
  • The repository metadata is signed and the client verifies an independently checked fingerprint.
  • A modified package is rejected.

Full completion

  • The P09 native artifact is packaged for its declared architecture with ELF policy evidence.
  • Clean install, upgrade, repeated/interrupted migration, unsupported downgrade, removal, wrong ABI, and missing dependency are tested.
  • Service installation is safe and disabled by default.
  • Modified index and modified package are independently rejected.
  • Two clean builds are compared, and a complete redacted release evidence bundle is produced.
  • Key bootstrap, rotation, retention, rollback, and compromise runbooks are usable by another operator.

Excellence criteria

  • Stable/candidate channels support explicit canary promotion.
  • Independent builders reproduce equivalent artifacts or explain every bounded difference.
  • Key roles reduce the blast radius of publisher compromise.
  • Multi-architecture client selection is demonstrated.
  • Another operator performs install and upgrade using only the repository, verified trust instructions, and runbook.

Generated from the Termux Android Apps and Tools Mastery parent guide and its expanded project index. This guide intentionally provides architecture, pseudocode, metadata, tests, and observable contracts rather than complete runnable source code.