nddev-zcode-app produces a complete, reproducible ZCode home from source. It
does not run ZCode agent sessions. Its lifecycle does manage the installed
configuration and only the explicitly declared runtime paths during protected
backup and restore operations.
zcode_tools/ SOURCE: self-contained setup catalog in ZCode-native marketplaces
cli-tools/ SETUP MANAGER: discovery, status, lifecycle, and rendering
build/ CONTRACT: versions, artifact integrity, manifest, secret template
zcode_tools/marketplaces/nddev-builder/ is the managed setup installed by
default. It remains a native ZCode marketplace so the same tree can be edited,
validated, and distributed using ZCode's marketplace/plugin format. --setup nddev-builder is accepted for compatibility and --marketplace nddev-builder
is the storage-format alias.
| Marketplace source | Installed target | Treatment |
|---|---|---|
AGENTS.md |
<target>/AGENTS.md |
copied |
skills/, commands/, agents/ |
same paths under target | copied |
| full marketplace directory | <target>/marketplaces/<name>/ |
copied |
cli-config.template.json |
<target>/cli/config.json |
rendered |
v2-config.template.json |
<target>/v2/config.json |
rendered |
v2-setting.template.json |
<target>/v2/setting.json |
rendered |
hooks.json, mcp.json |
keys in cli/config.json |
merged |
Template rendering expands ${VAR} values from the process environment and
the local build/.env file through structured JSON substitution. Source
templates never contain real credentials. Rendered .env, provider configs,
MCP configs, credentials, and backups are runtime secrets and remain private to
the current user.
Every CLI template declares one explicit provider/model main-model reference,
the matching provider kind and base URL, and the referenced model metadata.
The pinned CLI contract in build/version.json requires that bootstrap
contract before it can create a desktop agent session. The bootstrap provider entry contains no credential;
ZCode mounts the restored OAuth credential through its runtime provider
registry after the CLI adapter has initialized.
The local env file is accepted only when it is a current-user-owned regular
non-symlink with no group/world permissions. Existing environment variables win
over file values. No shell expansion occurs; only ZCODE_TARGET and
ZCODE_BACKUPS_DIR recognize a leading literal $HOME or ${HOME} path
prefix.
nddev-builderenablescore@nddev-builder, a native component-authoring toolkit whose exact inventory is the convention-discovered plugin tree.
install uses nddev-builder when no setup flag is supplied. --posture full-auto is the default and keeps the full automatic builder posture; --posture safe renders the same setup with a stricter installed instruction layer for
explicit review before destructive work.
All preference templates keep modelProviderFamilyModes.zai set to oauth,
which is the verified ZCode account-authentication mode. The provider
objects in v2/config.json are a separate explicit API-key contract: Z.ai uses
https://api.z.ai/api/anthropic; BigModel uses
https://open.bigmodel.cn/api/anthropic. Both API-key providers are disabled
by default and must be enabled deliberately after their secret is configured.
Their custom:* identities never reuse ZCode-owned builtin:* provider IDs,
so rendering a setup cannot disable or replace the app-managed OAuth provider.
The entry point is cli-tools/scripts/install.sh. It validates the trusted
system /usr/bin/python3 interpreter, requires Python 3.9 or newer, scrubs
Python injection variables, and runs cli-tools/nddev_zcode.py with -I -B.
The Python manager owns setup lifecycle transactions; no fallback path bypasses
it.
Target-bound commands perform host and lexical option checks before filesystem
observation, then map every canonical target or backup path to one
role-independent digest anchor in a fixed same-UID system temporary namespace.
Path anchors retain the exact legacy anchor=target,target_digest marker bytes,
so old and new managers validate the same monotonic files during an upgrade.
Mutators retain the product anchor exclusively for their complete lifecycle.
Before touching transaction state, they boundedly acquire every existing path
anchor to wait out old managers that already completed the former product-to-
target handoff. They then retain the deterministic digest-sorted target,
requested-backup, and prepare-bound backup anchors through commit and recovery.
Pending prepare namespace identities and bounded file bytes are reread exactly
after final acquisition.
Read-only commands never create or repair anchors. Status coordinates only its
target, plans coordinate the target plus requested and pending backup roots, and
list --backups coordinates only its backup root. When a required path anchor
does not exist, the product shared lock remains held through the read. A cold
read is permitted only when the product anchor is absent and the existing
product namespace is boundedly empty; if the exact namespace snapshot changes,
the result is discarded and recomputed under coordination. Status preserves the
public product_anchor and target_anchor fields and paths.
The apply lifecycle:
- validates canonical target and backup endpoints, managed setup identity, runtime quiescence, and active placeholder requirements,
- drains any valid pending cleanup journal before active mutation,
- builds a private same-filesystem stage, writes a schema-2
BUILD-VERSIONbound tosetup_idandposture, and selectively restores credentials, certificates, task indexes, session snapshots, bot definitions, CLI databases, and artifacts, - verifies the complete staged tree, normalizes private permissions, and fsyncs it before commit,
- moves any previous target into a numbered backup slot, preserving exact object identity for rollback, atomically publishes the verified stage, and revalidates both complete graphs, retired-slot journal state, and parent identities at the actual commit decision before removing durable authority,
- promotes irreversible retired-slot cleanup through a durable prepare intent and immutable cleanup journal before destructive drain.
The cleanup namespace (.nddev-zcode-cleanup/<target-digest>/) is validated
component by component before prepare, journal, or tombstone work: every
manager-owned component is opened without following symlinks, checked for
current-user ownership, group owner, private mode, expected kind, and exact
open-vs-lstat identity. Lifecycle cleanup keeps those directory file
descriptors through child inspection, publication, rename, unlink, and drain
steps; status and plan expose only cleanup-pending booleans and bounded
relative metadata, not cleanup deletion paths.
If post-commit cleanup cannot finish after a valid final journal or verified bootstrap runtime is visible, the command returns success with explicit cleanup-pending state instead of rolling back committed state. Read-only commands expose the same state without repairing it. Malformed or incoherent cleanup state fails closed with exit code 2 before mutation. A post-rename identity, graph, journal, or parent mismatch leaves foreign objects untouched and retains durable prepare authority for bounded recovery or operator inspection.
Backup inventory is also fail-closed without becoming an output-injection surface. It validates a complete managed stamp or adopted envelope before displaying any metadata. Invalid names and marker values are represented by fixed redacted classifications; valid historical installer SemVer and canonical UTC timestamps remain readable.
Plan mode describes the operation without writes or live zcode execution, but
still parses, substitutes, merges, and validates config/setting/provider/MCP/hook
inputs. Missing or empty active placeholders in keys or values fail in both
modes; only explicitly disabled provider/MCP nodes may remain dormant. An
existing unstamped directory is never replaced implicitly: initial adoption
requires --adopt-unmanaged together with an explicit --target.
Live implementation:
cli-tools/nddev_zcode.pyowns setup selection, target coordination, status, plan, install, remove, restore, backup rotation, rollback, cleanup journals, and rendering.cli-tools/scripts/install.shis the trusted public compatibility shim.cli-tools/scripts/bootstrap.shretains native app/CLI bootstrap behavior and still sourceslib/common.shandlib/version.sh.
Bootstrap accepts only the exact canonical CDN base recorded in
build/version.json and HTTPS-only redirects. It verifies size plus SHA-512
before native identity checks. macOS uses the official ZIP artifact from
upstream latest.yml, not the DMG. The DEB path is fixed to
/opt/ZCode/resources/glm/zcode.cjs. Before the package transaction, private
extraction must find exactly one safe entry there and its CLI version must match
the pin; dpkg --dry-run -i must then pass. After installation, the exact
dpkg-owned path/version and SHA-512 equality with the verified payload entry are
required.
Deterministically ordered locks protect the installer-managed app endpoint and
the user launcher; dpkg owns the system package transaction on Debian systems.
App and launcher swaps retain rollback state until exact postconditions pass.
That point marks the bootstrap committed. Cleanup failure after commit is
reported as cleanup_pending=true, exits success, and does not roll back
verified state; pre-commit errors and handled signals recover the prior
app/launcher when state is unambiguous. New and old application/launcher
endpoints are identity-bound in both abort and success cleanup, and cleanup uses
exclusive quarantine plus fd-relative deletion for owned state.
Normal installs treat a missing, timed-out, failed, or over-limit runtime CLI
probe as advisory not-installed/unknown. Bootstrap treats the same bounded
probe as a strict version postcondition.
VERSION,build/version.json,build/manifest.json, thenddev-buildermarketplacecoreentry, and the core plugin manifest carry one strict SemVer for every repository release.build/version.jsonalso pins the verified ZCode app, CLI, runtime model, launcher locations, and each CDN artifact's filename, byte size, SHA-512, and available platform-native identity metadata. Linux launcher entries are explicit for the DEB (/opt/ZCode/resources/glm/zcode.cjs) and the default AppImage extraction (${HOME}/.local/opt/ZCode/resources/glm/zcode.cjs).build/manifest.jsondefines public layout, artifact/bootstrap, command-option, runtime-probe, transaction, backup/restore, adoption, and secrets contracts.- The release workflow validates every version source, requires the tagged
commit to be reachable from fetched
origin/main, and rejects publication before invoking the shared supply-chain workflow if any contract drifts.
ZCode discovers plugin components by convention:
marketplaces/<marketplace>/marketplace.json
marketplaces/<marketplace>/plugins/<plugin>/.zcode-plugin/plugin.json
marketplaces/<marketplace>/plugins/<plugin>/skills/<skill>/SKILL.md
marketplaces/<marketplace>/plugins/<plugin>/commands/<command>.md
marketplaces/<marketplace>/plugins/<plugin>/agents/<agent>.md
marketplaces/<marketplace>/plugins/<plugin>/.mcp.json
Plugin manifests are metadata, not component registries. User-scope components
live directly under <target>/{skills,commands,agents}/. Hooks and MCP servers
are installed into <target>/cli/config.json.
The public product contract is config/nddev-contract.json version 3. It
defines setup discovery, selection, status, stamp identity, and legacy recovery
compatibility. It also keeps
the two MCP namespaces explicit: plugin .mcp.json inputs use mcpServers,
while the installed CLI configuration uses mcp.servers. The installer remains
independent of this descriptive metadata and implements the same mapping
directly.
This repository is the public implementation module. It intentionally excludes repository-local agent configuration, development memories, validation implementations, tests, and benchmarks.
The module is independently usable. Its public runtime, compatibility, and
managed-surface contracts are owned by cli-tools/, build/,
config/nddev-contract.json, and references/zcode-baseline.json.