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 `<package>#<version>`
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 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NwD8Egs5r4ndqeFLmhusX2
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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 `<package>#<version>` 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 `<package>#<version>`, 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#<version>` key. A comment in the
|
||||
|
||||
Reference in New Issue
Block a user