@hasna/skills 0.10.51 → 0.10.52

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -468,6 +468,34 @@ start. The hook excludes that exact leading policy from skill selection, so it
468
468
  does not displace the user's requested skill. Other hook context and user text
469
469
  remain part of the selection input.
470
470
 
471
+ Gemini discovery also covers the installed `@google/gemini-cli` package and its
472
+ bundled builtin skills. `skills hook install` finds the package through the
473
+ `gemini` command on its PATH and records the resolved executable and its
474
+ realpath target in the managed policy (`bridge.discoveryExecutables.gemini`).
475
+ Later checks always verify that recorded path, and also look `gemini` up on the
476
+ caller's PATH, because what PATH resolves is what that process would run:
477
+
478
+ - If PATH resolves a `gemini` whose realpath differs from the recorded target,
479
+ that runtime shadows the reviewed one, and the check refuses with
480
+ `NATIVE_SKILL_DRIFT`, naming both targets. Another launcher for the same
481
+ target is not a shadow.
482
+ - If PATH resolves no `gemini` at all (a narrower PATH such as
483
+ `env -i PATH=/usr/bin:/bin` or a launchd unit), the recorded path is the only
484
+ witness, so a Claude hook update or a Gemini hook still verifies the reviewed
485
+ runtime.
486
+ - A changed recorded target, package or builtin set refuses with
487
+ `NATIVE_SKILL_DRIFT`.
488
+ - When the recorded executable no longer resolves, or a policy written before
489
+ this record cannot find `gemini` on the caller's PATH, and nothing else in
490
+ the reviewed discovery changed, the refusal is `DISCOVERY_ROOT_UNRESOLVED`,
491
+ naming the agent and the command. That is an environment gap rather than
492
+ drift, and it still blocks. Any other change is still `NATIVE_SKILL_DRIFT`.
493
+
494
+ An install treats a recorded executable that no longer resolves as no record.
495
+ Run `skills hook install` from the reviewing environment to record or refresh
496
+ the path. The SDK exports `DISCOVERY_ROOT_UNRESOLVED` and
497
+ `isDiscoveryRootUnresolved` for callers that classify refusals.
498
+
471
499
  Known local plugin registrations are resolved automatically. Plugins with
472
500
  instruction-injecting hooks, unresolved runtime registrations, unsupported
473
501
  legacy command formats, and higher-precedence project discovery settings need
@@ -484,6 +512,29 @@ system configuration, process-specific overrides, and alternate agent home
484
512
  directories are outside automatic coverage and require their own integration
485
513
  review before declaring a station migrated.
486
514
 
515
+ The `pluginHooks` attestation is the reviewer's point-in-time statement; Skills
516
+ does not inspect hook behavior. When a Claude `.claude-plugin/plugin.json` is
517
+ listed as a plain byte witness (`hashMode` omitted or `"bytes"`) with a
518
+ non-null `sha256`, Skills also requires plain byte witnesses for that plugin's
519
+ `hooks/hooks.json` (when present) and any string `hooks` target in the
520
+ manifest. A manifest listed as `claude-plugin-manifest-v1` (the form Skills
521
+ writes into the stored policy) or as `path-bytes` triggers no such requirement.
522
+ For plugins outside receipt-backed admission (a `claude-plugin-registry`
523
+ witness, see the
524
+ [discovery transition contract](docs/plugin-admission.md#discovery-transition-contract)),
525
+ other plugin files such as hook modules, `bin/` files and `package.json` are
526
+ bound only if the review lists them (a reviewed `directories` membership witness
527
+ detects only added or removed files, not content changes), and the review is not
528
+ checked against the roots registered in
529
+ `~/.claude/plugins/installed_plugins.json`. Later checks
530
+ re-hash the stored sources, and drift makes the Skills hooks refuse with
531
+ `NATIVE_SKILL_DRIFT`; this detects a change but does not stop plugin code from
532
+ running. A process running as the same user can rewrite the plugin files and
533
+ the managed policy, so the witness is a tripwire, not a security boundary. See
534
+ [the full scope](docs/plugin-admission.md#reviewed-plugin-hook-attestation-scope).
535
+ A stronger witness for plugins outside receipt-backed admission is planned and
536
+ not yet implemented.
537
+
487
538
  When `hook install` omits `--discovery-inputs`, it reuses an existing reviewed
488
539
  binding only after rechecking its sources, directory membership, configuration
489
540
  coverage, managed bridge and native trust. Unchanged reviews need no new input
@@ -2602,3 +2653,30 @@ Upgrade an existing review with `skills hook rebind-settings --agent claude
2602
2653
  --expected-policy-sha256 <policy-hash> --expected-settings-sha256 <settings-hash>`.
2603
2654
  Review the plan before adding `--apply`. See
2604
2655
  [built-in theme reviews](docs/plugin-admission.md#explicit-v4-built-in-theme-reviews).
2656
+
2657
+ `claude-marketplace-entry-v1` witnesses one plugin entry of a Claude
2658
+ `marketplace.json` instead of the whole catalog, so Claude's own marketplace
2659
+ refreshes do not invalidate a review of a plugin declared only by its entry.
2660
+ It binds the marketplace name, `metadata.pluginRoot`,
2661
+ `allowCrossMarketplaceDependenciesOn` (its value, or its absence, for every
2662
+ entry) and the entry's identity, source and every component or command-bearing
2663
+ field; display metadata such as `description` and `version` is omitted. Its
2664
+ canonical JSON sorts object keys and is hashed under the domain prefix
2665
+ `hasna.skills.claude-marketplace-entry.v1\0`; this deliberately differs from
2666
+ `claude-plugin-manifest-v1`, which keeps key order. Unknown keys, a missing,
2667
+ duplicated or renamed entry, and unparsable JSON refuse. Capture with `skills
2668
+ hook witness --kind claude-marketplace-entry-v1 --path
2669
+ <.claude-plugin/marketplace.json> --marketplace <name> --plugin <name>`.
2670
+
2671
+ An unknown top-level, `metadata` or entry key refuses with the mode, the bound
2672
+ marketplace name and the exact key path, never the value, for example
2673
+ `claude-marketplace-entry-v1: unknown top-level key "x" in
2674
+ claude-plugins-official` or `unknown key "plugins[swift-lsp].x"`. The only way
2675
+ forward after such a refusal is a fresh human review of the changed catalog and
2676
+ a guarded exact re-pin: write the reviewed witnesses to a discovery inputs file,
2677
+ preview `skills hook install --agent claude --discovery-inputs <file>`, then
2678
+ run the same command with `--apply`. While the key is present this mode refuses
2679
+ capture as well, so the re-pinned review must bind the catalog another way, such
2680
+ as an exact `bytes` witness, until a reviewed version of this mode covers the
2681
+ key. There is no bypass, ignore list or relaxed mode. See
2682
+ [marketplace plugin entry witness](docs/plugin-admission.md#marketplace-plugin-entry-witness).