Repository navigation
epic: CLI provenance, safe updates, and project state #248
Copy link
Copy link
Closed
5 / 55 of 5 issues completedClosed
5 / 55 of 5 issues completed
Copy link
Description
Context
zerodep is a code-distribution CLI: modules are copied into a project as
single files. That makes provenance and safe updates the product, not
extras. Today:
update/update --alloverwrite every file withforce=True, yes=True.
_scan_outdated()marks a fileoutdatedwhenever its hash differs from
upstream, so a local edit is indistinguishable from an upstream change and is
silently destroyed on the next update.- Installs fetch
manifest.jsonand module files from the mutablemaster
branch (BRANCH = "master") and never verify the fetched bytes against the
manifest'scontent_hash. The same CLI version can install different code on
different days, and a compromised mirror/CDN cannot be detected. - Nothing records what was installed.
outdatedhas to guess by scanning a
directory;--nested, custom vendor dirs, and renamed files confuse it.
There is nostatus, noremove, and no way to tell "locally modified" from
"upstream updated".
Downstream projects (toolregistry, toolregistry-server, toolregistry-hub)
already vendor modules under [tool.zerodep] vendor-dir and run an automated
zerodep-update.yml that calls outdated --json and update --all. They
inherit every one of these problems.
Workstreams
- State: record installs in
<vendor-dir>/zerodep.lock.json
(version, upstream hash, installed file hashes, requested vs dependency)
and addzerodep status. - Safe update: three-state comparison (up-to-date / upstream-updated /
locally-modified), refuse to clobber modified files without--force,
add--diffand--check. - Trust: pin installs to a release ref (
v<CLI version>by default for
installed CLIs) and verify every fetched file against the manifest's
content_hash. - Lifecycle:
zerodep remove,--dry-run, JSON output forstatus. - Downstream CI: update the
zerodep-updateworkflows to commit the
lock and handle skipped (locally modified) modules instead of forcing. - Release checks: extend
zerodep release-checkwith the checks that
only exist as conventions today (stdlib-only imports, declared
dependencies,bench-*coverage, Makefile wiring) plus--with-lint/
--with-tests(feat(cli): add --with-lint/--with-tests and repo consistency checks to release-check #258). - Release checks in PR CI: run the same command on every PR so those
rules fail before merge instead of at tag time (ci: run zerodep release-check on every PR #259).
Acceptance criteria
- A project that edited a vendored file can run
zerodep update --allwithout
losing the edit; the file is reported and skipped. zerodep statusdistinguishes up-to-date, upstream-updated,
locally-modified, missing, and missing-dependency, with--jsonand
--exit-code.- An installed CLI fetches from the release tag that matches its version by
default; a file whose bytes do not match the manifest hash aborts the install. zerodep update --diffshows what would change without writing.- toolregistry's vendored modules can be inventoried and updated with a lock,
and its update workflow no longer force-overwrites local patches.
Non-goals
- A runtime package manager, dependency resolver for third-party packages, or
importing modules instead of copying them. - Replacing
[tool.zerodep] vendor-dir; the lock lives inside that directory.
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
No labels
Activity
zerodep status#249zerodep updaterefuse to clobber local modifications #250Oaklight commentedon Oct 23, 2026
Workstream 1 landed in #254 (merge commits 5540a7e, 83532fe):
zerodep.lock.jsonprovenance, release pinning + integrity verification, safeadd/update,status, and a lock-awareoutdated. This closes #249, #250 and #251. Docs and changelog are updated in both worktrees.Remaining: #252 (remove/dry-run/search) and #253 (downstream CI). #253 needs a release that includes the new CLI — downstream installs
zerodepfrom PyPI, and the PyPI publisher is still bound topypi.yml(#247), so publishing fromrelease.ymlfails until that is resolved.Oaklight commentedon Oct 23, 2026
#253 is done (three downstream repos adopted locks and the new update workflow). Remaining from the epic: #252 (remove / dry-run / search). The CLI workstream (#249–#251) shipped in 2026.10.23.1 on PyPI; the release plumbing is now single-publisher (#247) with a verified re-publish path.
Oaklight commentedon Oct 23, 2026
All five workstreams plus the release-check follow-ups are done: #249–#253 and #252/#258/#259 are closed, the CLI shipped in 2026.10.23.1/.2, the three downstream repos carry locks and the new update workflow, and PR CI now runs zerodep release-check. Remaining CLI ideas (if any) belong in new issues.