Skip to content

fix(registry): the CLI reads the flat checksum field — write, document and validate it - #83

Merged
acamarata merged 1 commit into
mainfrom
p6/registry-flat-checksum-field
Sep 4, 2026
Merged

acamarata merged 1 commit into
mainfrom
p6/registry-flat-checksum-field

Conversation

@acamarata

Copy link
Copy Markdown
Contributor

What / Why

nself plugin install <name> verifies a tarball's checksum against the
flat checksum field on a registry entry
(internal/plugin/registry_parse.go pluginEntry.Checksum, json:"checksum";
enforced by verifyChecksum in internal/plugin/installer_locked.go).
registry-schema.json and scripts/build-and-upload-tarballs.sh only ever
wrote/documented a nested checksums.sha256 field, which no code path
in nself-org/cli reads (git grep checksums origin/main -- internal
returns no registry-entry consumer — only unrelated checksums.txt
release-asset handling for the CLI's own binary). Net effect: every plugin
without a hand-populated flat checksum installs with checksum
verification silently skipped (a stderr warning only).

Changes

  1. scripts/build-and-upload-tarballs.sh — writes the flat checksum
    field alongside the nested checksums.sha256 (both raw lowercase hex,
    no sha256: prefix — the prior nested write had the prefix, which
    would have broken any future checksum == checksums.sha256 check).
  2. registry-schema.json — documents checksum as the field the CLI
    reads; makes it required (non-empty) when a plugin's status is the
    literal string "stable" via an allOf/if/then conditional;
    documents checksums as legacy/unread by the CLI. Validated with
    jsonschema.Draft7Validator against the current registry.json
    (0 errors) and against simulated stable-with/without-checksum entries.
  3. shared/validate-registry.sh — new CHECK-15: errors when a
    status=stable plugin lacks a valid flat checksum, when a present
    checksum isn't 64 lowercase hex chars, or when checksum and
    checksums.sha256 disagree.
  4. scripts/verify-published-checksums.sh (new) — read-only spot-check
    that downloads a release tag's real tarball assets and hashes them
    directly, since the other 121 plugins' checksums were never computed
    against what the CLI actually downloads (recomputing from the source
    tree wouldn't verify that — the published tarball's bytes depend on
    the exact tar invocation at release time). Never writes
    registry.json.

Not done here (explicitly out of scope)

No checksums were recomputed/written for the other 121 plugins. Only
PR #81's 8 entries (content-progress, cron, donorbox, maintenance,
notifications, notify, search, storage) currently carry a flat checksum,
and this PR does not touch those entries — rebase-safe with #81.

Spot-check: registry vs. real v1.0.0 assets (5 plugins)

scripts/verify-published-checksums.sh v1.0.0 ai-cli alerts api backup audit
— downloaded each plugin's real v1.0.0 tarball asset and hashed it:

plugin computed sha256 registry checksum registry checksums.sha256
ai-cli ec3c9163...8e660 (unset) (unset)
alerts 0dcc785e...68363 (unset) (unset)
api 840660cf...aacd6b (unset) (unset)
backup 05b46b1b...ea9bc (unset) (unset)
audit a18e941d...409fab (unset) (unset)

No registry value to compare against for any of the 5 (none of the 121
untouched plugins have ever had a checksum written) — 0 mismatches,
vacuously. This confirms the script works end-to-end against real
release assets and that these 5 have no stale/wrong checksum sitting in
the registry today.

CLI consumer check (item 5 of the ticket)

git -C <cli-checkout> grep -n "checksums" origin/main -- internal on
nself-org/cli finds no registry-entry consumer of checksums.sha256
every hit is either the CLI's own release-binary checksums.txt
mechanism (unrelated) or doc/test text. Confirms the nested field is
dead weight for install-time verification; no CLI change needed by this
PR. Separately (bigger finding, not fixed here — flagged to the
manager): verifyChecksum/verifyPluginSignature gate on the literal
string status == "stable", but PublishStatus (json:"status,omitempty")
is "" when the field is absent — so despite the registry schema's own
comment ("Missing status defaults to 'stable' for backwards
compatibility") and the lifecycle switch in installer_locked.go
explicitly treating "" and "stable" the same for warnings, the
checksum/signature enforcement gate does NOT treat absent status as
stable. Every one of this registry's 129 plugins currently has no
explicit status field, so checksum/signature enforcement is
effectively off registry-wide today, independent of this PR's field-name
fix. That's a cli behavior question (does "" mean stable for
enforcement, matching the docs, or not, matching current code?) outside
this PR's scope.

Local gate (self-hosted CI backlog — brief §8, not watched)

This is a PUBLIC repo — this account cannot self-approve, so left open
per the P6 crunch brief. GitHub-hosted Actions will run automatically;
not watched here per brief §8.

The CLI installer's registry parser (nself-org/cli
internal/plugin/registry_parse.go pluginEntry.Checksum, json:"checksum")
and installer_locked.go's verifyChecksum() only ever read the FLAT
`checksum` field on a plugin entry. build-and-upload-tarballs.sh and
registry-schema.json only ever wrote/documented the nested
`checksums.sha256` field, which no CLI code path consumes (confirmed via
`git grep checksums origin/main -- internal` on nself-org/cli). Result:
every plugin without a hand-written flat checksum installs with checksum
verification silently skipped by the CLI (a stderr warning only) for
any plugin not explicitly status=stable.

- build-and-upload-tarballs.sh: write the flat `checksum` field alongside
  the nested `checksums.sha256` (both raw lowercase hex, no "sha256:"
  prefix — the previous nested write had the prefix, which would have
  broken any future checksum == checksums.sha256 consistency check).
- registry-schema.json: document `checksum` as the field the CLI reads;
  require it (non-empty) when a plugin's `status` is the literal string
  "stable"; document `checksums` as legacy/unread.
- shared/validate-registry.sh: new CHECK-15 — errors when a status=stable
  plugin lacks a valid flat checksum, when a present checksum is not
  64 lowercase hex chars, or when checksum and checksums.sha256 disagree.
- scripts/verify-published-checksums.sh: new read-only spot-check that
  downloads a release tag's real tarball assets and hashes them, since
  the other 121 plugins' checksums were never computed against what the
  CLI would actually download and recomputing them from the source tree
  would not verify that. Does not write registry.json.

Does not touch the 8 plugin entries PR #81 already populated (both
fields, no "sha256:" prefix) for v1.0.1 — rebase-safe with that PR.

No plugin in the current registry has an explicit status=stable, so
this changes no install-time behavior yet; it fixes the field the
installer reads once entries are marked stable.
@acamarata
acamarata merged commit 4d48fae into main Sep 4, 2026
28 checks passed
@acamarata
acamarata deleted the p6/registry-flat-checksum-field branch September 4, 2026 10:56
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant