Module Marketplace
SpecFact supports centralized marketplace distribution with local multi-source discovery.
For the curated official bundle list and trust/dependency quick reference, see Marketplace Bundles.
Registry Overview
- Official registry: https://github.com/nold-ai/specfact-cli-modules (index:
registry/index.json) - Marketplace module id format:
namespace/name(e.g.nold-ai/specfact-backlog). Marketplace modules must use this format; flat names are allowed only for custom/local modules with a warning. - Custom registries: You can add private or third-party registries. See Custom registries for adding, listing, removing, trust levels, and priority.
Custom registries and search
- Add a registry:
specfact module add-registry <index-url> [--id <id>] [--priority <n>] [--trust always|prompt|never] - List registries:
specfact module list-registries(official is always first; custom registries follow by priority) - Remove a registry:
specfact module remove-registry <registry-id> - Search:
specfact module search <query>queries all configured registries; results show which registry each module came from.
Trust levels for custom registries: always (trust without prompt), prompt (ask once), never (do not use). Config is stored in ~/.specfact/config/registries.yaml.
Discovery and Priority
Local module discovery scans these roots in priority order:
built-inmodules (src/specfact_cli/modules)projectmodules (<repo>/.specfact/modules)usermodules (~/.specfact/modules)- legacy/custom roots (
~/.specfact/marketplace-modules,~/.specfact/custom-modules,SPECFACT_MODULES_ROOTS)
If module names collide, higher-priority sources win and lower-priority entries are shadowed.
Trust vs Origin
SpecFact shows both trust semantics and origin details:
Trustcolumn (default):official,community,local-devOrigincolumn (--show-origin):built-in,marketplace,custom
Use:
specfact module list --show-origin
Security Model
Install workflow enforces integrity and compatibility checks:
- Fetch registry index
- Download module archive
- Validate SHA-256 checksum
- Validate module
core_compatibilityagainst current CLI version - Install into selected scope root (
~/.specfact/modulesor<repo>/.specfact/modules)
Checksum mismatch blocks installation.
Namespace enforcement:
- Modules installed from the marketplace must use the
namespace/nameformat (e.g.nold-ai/specfact-backlog). Invalid format is rejected. - If a module with the same logical name is already installed from a different source or namespace, install reports a collision and suggests using an alias or uninstalling the existing module.
Additional local hardening:
- Denylist enforcement via
~/.specfact/module-denylist.txt(orSPECFACT_MODULE_DENYLIST_FILE) - One-time trust gate for non-official publishers (
--trust-non-officialfor non-interactive automation) - Bundled bootstrap/install verifies bundled integrity metadata before copy
Release signing automation:
scripts/sign-modules.pyupdates manifest integrity metadata (checksum and optional signature)- Use
KEY_FILE="${SPECFACT_MODULE_PRIVATE_SIGN_KEY_FILE:-.specfact/sign-keys/module-signing-private.pem}"and runpython scripts/sign-modules.py --key-file "$KEY_FILE" <manifest...>for local/manual signing - Use changed-only automation to avoid re-signing all modules:
hatch run python scripts/sign-modules.py --key-file "$KEY_FILE" --changed-only --base-ref origin/dev --bump-version patch- this bumps/signs only changed modules and keeps module versioning decoupled from CLI package version
- Wrapper alternative:
bash scripts/sign-module.sh --key-file "$KEY_FILE" <manifest> - Without key material, the script fails by default and recommends
--key-file; checksum-only mode is explicit via--allow-unsigned(local testing only) - Encrypted keys are supported with passphrase via
--passphrase,--passphrase-stdin, orSPECFACT_MODULE_PRIVATE_SIGN_KEY_PASSPHRASE - CI workflows inject private key material via
SPECFACT_MODULE_PRIVATE_SIGN_KEY(inline PEM string) orSPECFACT_MODULE_PRIVATE_SIGN_KEY_FILE(path), and passphrase viaSPECFACT_MODULE_PRIVATE_SIGN_KEY_PASSPHRASE - Private signing keys must stay in CI secrets and never in repository history
Public key for runtime verification:
- Preferred bundled location (repo source):
resources/keys/module-signing-public.pem - Installed package location:
specfact_cli/resources/keys/module-signing-public.pem - Runtime checks key in this order: explicit arg ->
SPECFACT_MODULE_PUBLIC_KEY_PEM-> bundled key file
Scope boundary:
- This change set hardens local and bundled module safety.
- For publishing your own modules to a registry, see Publishing modules.
Marketplace vs Local Modules
specfact module installsupports source selection:--source auto(default): bundled-first, then marketplace fallback--source bundled: bundled sources only--source marketplace: marketplace only
- If a requested module already exists locally (
built-in/custom), install reports that no marketplace install is needed. specfact module uninstallsupports--scope user|projectand prevents ambiguous removals when same module id exists in both scopes.
Module Introspection
specfact module show <name> includes:
- Module metadata (publisher, license, trust, origin, compatibility)
- Full command tree, including subcommands
- Short command descriptions derived from Typer command registration