Merge pull request #111320 from NousResearch/docs/plugin-catalog-no-self-update
Plugin catalog: no self-updaters instead of a 2-week pin age, enforced in CI
This commit is contained in:
19
.github/workflows/plugin-catalog-ci.yml
vendored
19
.github/workflows/plugin-catalog-ci.yml
vendored
@@ -126,12 +126,23 @@ jobs:
|
||||
fi
|
||||
|
||||
# Manifest schema + declared-vs-registered capability check.
|
||||
if hermes plugins validate "$PLUGIN_DIR"; then
|
||||
echo "✅ PASS: $entry"
|
||||
else
|
||||
if ! hermes plugins validate "$PLUGIN_DIR"; then
|
||||
echo "::error file=$entry::hermes plugins validate failed"
|
||||
FAILED=1
|
||||
FAILED=1; echo "::endgroup::"; continue
|
||||
fi
|
||||
|
||||
# SELF-UPDATER GATE (README rule 3): the pin is the only update path.
|
||||
# A desktop bundle that both fetches from GitHub AND writes/renames
|
||||
# plugin files is a self-updater; either half alone is fine (a
|
||||
# plugin may read the API, or manage its own data files).
|
||||
SELF_UPDATE=$(grep -rlE 'releases/latest|raw\.githubusercontent\.com' \
|
||||
--include='*.js' --include='*.mjs' --include='*.cjs' --include='*.ts' "$PLUGIN_DIR" \
|
||||
| xargs -r grep -lE 'writeTextFile|renamePath|writeFile\(' || true)
|
||||
if [ -n "$SELF_UPDATE" ]; then
|
||||
echo "::error file=$entry::self-updating code in catalog build (fetches GitHub AND writes plugin files): $SELF_UPDATE"
|
||||
FAILED=1; echo "::endgroup::"; continue
|
||||
fi
|
||||
echo "✅ PASS: $entry"
|
||||
echo "::endgroup::"
|
||||
done <<< "$CHANGED_FILES"
|
||||
|
||||
|
||||
@@ -16,10 +16,13 @@ meaningful:
|
||||
2. **Exact SHA pins are mandatory.** Every entry pins a full 40-character
|
||||
commit SHA. Branches, tags, and short SHAs are rejected by the loader.
|
||||
Installs clone the repository and check out exactly that commit.
|
||||
3. **Pin maturity.** The pinned release should be **at least 2 weeks old**
|
||||
at pin time, mirroring the supply-chain policy used for `optional-mcps/`
|
||||
and pyproject dependencies. This gives the community time to notice a
|
||||
compromised release before Hermes ships a pointer to it.
|
||||
3. **No self-updating code.** A listed plugin must not fetch and replace
|
||||
its own files (in-app "check for updates", signed release downloaders,
|
||||
remote `plugin.js` loaders). The exact SHA pin *is* the trust model; a
|
||||
self-updater lets an installed copy move to a commit nobody reviewed.
|
||||
Updates reach users only through a SHA-bump PR here plus
|
||||
`hermes plugins update <name>`. Keep the updater in the standalone
|
||||
distribution if you want one; strip it from the catalog build.
|
||||
4. **SHA bumps are new PRs.** Updating an entry's pin is a new PR whose diff
|
||||
(old SHA → new SHA) is re-reviewed like any other change — reviewers are
|
||||
expected to look at the upstream commit range being adopted.
|
||||
|
||||
@@ -150,8 +150,9 @@ in short, an entry must be:
|
||||
3. **Released** — the repo has real releases/tags, not just a default branch.
|
||||
4. **Passing validation** — the catalog validation GitHub Action is green on
|
||||
the PR (schema, SHA format, reachability).
|
||||
5. **Pinned to settled code** — the pinned SHA is at least **2 weeks old**, so
|
||||
the catalog never points at code pushed moments before review.
|
||||
5. **Not self-updating** — the catalog build must not download and replace
|
||||
its own files; the pinned SHA is the only update path (a SHA-bump PR plus
|
||||
`hermes plugins update <name>`).
|
||||
|
||||
Pin updates (bumping `sha` to a newer commit) follow the same PR + review
|
||||
process.
|
||||
|
||||
Reference in New Issue
Block a user