Numan Registry Overview
Relevant source files
The following files were used as context for generating this wiki page:
The Numan Official Registry is a data-only repository that serves as the curated catalog for the Numan Nushell package manager. It publishes a signed registry index (index.json) containing metadata, artifact URLs, and cryptographic digests for Nushell plugins, modules, scripts, and completions. The repository does not host a web server or long-running service; instead, it provides a command-line toolchain for maintaining, validating, and signing the catalog.
The registry operates on a trust model where production clients verify Ed25519 signatures over the canonical JSON representation of the index using a built-in trust root. The infrastructure is built around GitHub Pages for distribution and GitHub Actions for secure, protected signing workflows.
Sources: README.md:3-15, AGENTS.md:7-12, SECURITY.md:46-51
Registry Architecture and Trust Model
The Numan Registry architecture is centered on a signed JSON index. Trust is established through a detached Ed25519 signature that ensures the integrity of the package metadata and artifact hashes.
Trust Invariants
- Ed25519 Signatures: Clients verify signatures over the canonical bytes of
index.json. - Artifact Integrity: Every plugin artifact must include a SHA-256 digest. Numan refuses installation if the digest does not match.
- Immutability: Published artifact URLs and digests are immutable; remediation for security issues requires a newly signed index revision (yank or new version).
- No Private Keys in Tree: Signing keys are managed externally and injected via protected GitHub environment secrets.
Sources: SECURITY.md:46-56, REVIEW.md:32-35
Distribution Flow
The following diagram illustrates the lifecycle of a package update from local staging to production distribution.
The diagram shows the transition from automated validation to human-reviewed production signing.
Sources: README.md:88-100, REVIEW.md:39-45
Data Schema (index-v1.json)
The registry uses a strictly defined JSON schema (v1). The index must contain schema_version, updated_at, and a list of packages.
Key Schema Components
| Field | Type | Description |
|---|---|---|
schema_version | Integer | Must be 1. |
updated_at | String | ISO 8601 timestamp of last update. |
packages | Array | List of package objects (plugins, modules, scripts, completions). |
trust | Object | Optional successor key declarations for key rotation. |
Sources: schemas/index-v1.json:7-40
Package Object Structure
Each package in the packages array follows a specific hierarchy, defining versions and target-specific artifacts.
The relationship between packages, their versioned releases, and platform-specific binaries.
Sources: schemas/index-v1.json:41-118
Tooling and CI Validation
The repository includes a Python-based toolchain under scripts/ to manage the registry. CI runs multiple gates to ensure catalog safety and parser parity.
Essential Scripts
validate.py: Performs schema validation, canonical-JSON checks, and Ed25519 signature verification.add-package.py: Scaffolds new package entries and automatically computes SHA-256 digests from downloads to prevent hand-typing errors.provision-production-key.sh: Generates Ed25519 keypairs locally and provides verification of committed public keys without exposing private material.lifecycle-prove.py: A maintainer-only gate used to prove a package works on a clean environment with a real Nushell instance before promotion.render_catalog_compat.py: Generates a human-readable compatibility matrix (docs/catalog-compat.md) from the raw JSON index.
Sources: README.md:46-64, AGENTS.md:17-30, scripts/render_catalog_compat.py:12-25
CI Gates Table
| Check | Tool / Command | Purpose |
|---|---|---|
| Secret Scan | scan_for_secrets.py | Detects accidentally committed private keys. |
| Preflight | preflight.py | Checks key/workflow consistency without network. |
| Schema/Sig | validate.py | Validates JSON schema and Ed25519 signature. |
| Parser Parity | numan-parser-check | Ensures the index is parsable by the production Rust parser. |
| Lint Manifest | lint-manifest-index.py | Checks for version drift between plugins and the registry. |
Sources: AGENTS.md:17-30, REVIEW.md:11-23
Key Management and Security
Private keys are never committed to the repository. The registry uses a "WSL-first" maintainer process for key generation.
Production Signing Sequence
Production signing happens only within a protected GitHub environment.
The sequence of secure key handling and production publication.
Sources: scripts/provision-production-key.sh:10-25, README.md:102-110, SECURITY.md:65-71
Signature Envelope Format
The detached signature registry/index.json.sig follows a specific JSON structure:
{
"key_id": "official-YYYY-MM",
"algorithm": "ed25519",
"signature": "base64..."
}
Sources: README.md:77-85
Package Promotion and Lifecycle
Promotion to the official catalog follows a "Stage 1" evidence process. Activatable packages (plugins and modules) must be verified against specific Nushell versions.
- Provisional Entry: New packages are added with
add-package.py --provisional. - Staging: The package is committed to
main, which triggers an ephemeral signing for the staging environment. - Lifecycle Proof: Maintainers run
lifecycle-prove.pyagainst a realnubinary. Successful tests are recorded in theverified_withfield of the index. - Promotion: Once evidence is collected, the provisional flag is removed, and the package is eligible for production signing.
Sources: README.md:120-136, REVIEW.md:36-40
The Numan Registry ensures a secure, verified distribution channel for Nushell extensions by combining strict schema enforcement, mandatory cryptographic signing, and automated CI validation gates. High-level maintainer workflows guarantee that every entry in the production catalog has been verified for both structural integrity and functional compatibility.