From 1614bcef23e803944c3147d27833aef8176370bf Mon Sep 17 00:00:00 2001 From: Defame1297 Date: Sat, 19 Sep 2026 21:33:43 +0000 Subject: [PATCH] docs: correct the executables.allow version-pinning claim gates.md's check-executables-allow-sync section and ADR-0019 both stated that apm matches executables.allow on an exact `#` dictionary lookup with no wildcard and no version-less form, and drew the conclusion that a kyberforge version bump silently stops the entry matching and the SessionStart hook deploying. Verified against apm 0.28.0: is_package_approved is an exact lookup, but install/exec_gate.py calls it across a candidate list carrying the version-blind name, materialize_exec_map stores each approved key under its version-blind name as well, and _map_grants matches exact key, version-blind name, or any stored key sharing that name. Approving kyberforge#2.0.0 therefore keeps covering kyberforge#2.1.0. The decision is unchanged: check-executables-allow-sync stays, justified by this repo's own requirement that the key track plugins/kyberforge/ apm.yml's version:, rather than by an apm-level failure mode. ADR-0019 keeps its original text with a dated correction, since whether apm behaved this way when it was written was not established. Follows the same correction applied to root apm.yml's comment in 82b7bbc. Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_01NwD8Egs5r4ndqeFLmhusX2 --- ...tart-hook-keeps-the-apm-install-current.md | 12 +++++++++- docs/spec/gates.md | 23 ++++++++++++------- 2 files changed, 26 insertions(+), 9 deletions(-) diff --git a/docs/adr/0019-session-start-hook-keeps-the-apm-install-current.md b/docs/adr/0019-session-start-hook-keeps-the-apm-install-current.md index 2baab56..9a0a576 100644 --- a/docs/adr/0019-session-start-hook-keeps-the-apm-install-current.md +++ b/docs/adr/0019-session-start-hook-keeps-the-apm-install-current.md @@ -75,7 +75,17 @@ to end, reintroduced through the mechanism meant to secure it. Matching is an exact dictionary lookup on the composed `name#version` string (`apm_cli/security/executables.py`, `is_package_approved`), so there is no wildcard or version-less key that would sidestep this — the key has to be edited on every bump, and the -question is only what catches a missed edit. A comment in the `executables:` block is not enough: +question is only what catches a missed edit. + +> **Correction (2026-09-19):** the mechanism above is wrong for apm 0.28.0, verified in source. +> `is_package_approved` is an exact lookup, but `install/exec_gate.py` calls it across a candidate +> list that includes the version-blind name, `materialize_exec_map` stores each approved key under +> its version-blind name too, and `_map_grants` matches exact key, version-blind name, or any stored +> key sharing that name. So approving `kyberforge#2.0.0` keeps covering `kyberforge#2.1.0`: a bump +> does not silently stop the hook deploying. Whether apm behaved this way when this ADR was written +> was not established. **The decision stands** — `scripts/check-executables-allow-sync.sh` is now +> justified by this repo's own requirement that the key track `plugins/kyberforge/apm.yml`'s +> `version:`, not by an apm-level failure mode. `docs/spec/gates.md` carries the same correction. A comment in the `executables:` block is not enough: this repo gates generated-content drift, marketplace mirror drift and vale style drift deterministically, and a silent-staleness failure is strictly worse than any of them. So `scripts/check-executables-allow-sync.sh` runs at pre-push, parsing `version:` out of diff --git a/docs/spec/gates.md b/docs/spec/gates.md index e73b682..55f79da 100644 --- a/docs/spec/gates.md +++ b/docs/spec/gates.md @@ -1085,15 +1085,22 @@ Plugin manifests get `lockfile-exists` and nothing else; they are not Unicode-sc ### `check-executables-allow-sync` -apm gates a package's `hooks/` and `bin/` on an **exact `#` dictionary lookup** in -root `apm.yml`'s `executables.allow` (`apm_cli/security/executables.py`, `is_package_approved`). -There is no wildcard and no version-less form. +apm gates a package's `hooks/` and `bin/` on root `apm.yml`'s `executables.allow` +(`apm_cli/security/executables.py`). `is_package_approved` is itself an exact dictionary lookup, but +it is never called with a single key: `install/exec_gate.py` builds a candidate list that includes +the version-blind name alongside `#`, and `materialize_exec_map` stores every +approved key **under its version-blind name as well**. `_map_grants` matches the same three ways. -So bumping `plugins/kyberforge/apm.yml`'s `version:` without bumping the key **errors nowhere**: the -entry simply stops matching, the gate blocks the hook, kyberforge's `SessionStart` hook stops -deploying, and the apm install goes quietly stale — the exact failure ADR-0019 exists to end, -reintroduced through the mechanism meant to secure it. ADR-0019 records this as a live failure mode; -the release that shipped the hook hit it immediately. +**Correction (2026-09-19):** verified against apm 0.28.0, a kyberforge version bump therefore does +*not* stop the entry matching — approving `owner/repo#2.0.0` also covers `owner/repo#2.1.0` through +the version-blind alias. The earlier claim here ("no wildcard and no version-less form", so the +entry silently stops matching and the `SessionStart` hook stops deploying) described apm's behaviour +wrongly, and ADR-0019 carries the same correction. + +The gate is still required, for a repo-level reason rather than an apm-level one: +`scripts/check-executables-allow-sync.sh` asserts the key matches `plugins/kyberforge/apm.yml`'s +`version:`, so a bump without a key edit fails *this repo's* pre-push, and the key stays an accurate +record of what was approved. `scripts/check-executables-allow-sync.sh` parses `version:` out of `plugins/kyberforge/apm.yml` and asserts root `apm.yml` carries the matching `kyberforge#` key. A comment in the