Skip to content

feat: enforce skill and SDK attribution in the PreToolUse hook - #55

Open
henry-jackson wants to merge 1 commit into
mainfrom
henry-jackson/hook-skill-attribution
Open

feat: enforce skill and SDK attribution in the PreToolUse hook#55
henry-jackson wants to merge 1 commit into
mainfrom
henry-jackson/hook-skill-attribution

Conversation

@henry-jackson

@henry-jackson henry-jackson commented Aug 25, 2026

Copy link
Copy Markdown
Member

Description

The PreToolUse hook now enforces skill and SDK attribution on raw curl calls to the Spotify Ads API. When an agent bypasses the api() wrapper:

  • SDK header is injected verbatim (deterministic; read from api-request.sh --env).
  • Skill header is inferred from the session transcript and injected with an -inferred suffix (e.g. campaigns-inferred) so reporting can distinguish it from wrapper-set values. Only names matching a real skill are accepted.
  • When inference finds nothing, the agent gets a nudge toward api() and no header is invented.
  • Detection now covers $BASE_URL/... in addition to the literal host, so asset and audience uploads no longer bypass the hook.
  • Antigravity cannot rewrite commands, so it gets the nudge only.

Attribution lives in hooks/lib/attribution.sh, sourced by hooks/check-token.sh. It is not a separate hook registration because matching PreToolUse hooks race each other and the last rewrite wins.

Verification

$ bash tests/test-check-token.sh
=== Results: 88 passed, 0 failed ===

52 new assertions covering detection, curl injection edge cases, inference ordering, and per-platform behaviour. Seven independent mutations of the library each fail the suite.

Checklist

  • Tested against the Spotify Ads API with Codex, Claude Code, or Antigravity CLI
  • Existing skills still work as expected
  • SKILL.md frontmatter is valid (name, description, allowed-tools)
  • README or CHANGELOG updated (if user-facing change)
  • Curl commands follow API conventions documented in AGENTS.md

@henry-jackson
henry-jackson force-pushed the henry-jackson/api-request-env-quoting branch from b216510 to 19931c1 Compare August 31, 2026 15:10
@henry-jackson
henry-jackson force-pushed the henry-jackson/hook-skill-attribution branch from 82bc740 to af26e46 Compare August 31, 2026 15:13
Base automatically changed from henry-jackson/api-request-env-quoting to main September 2, 2026 17:25
Around 74% of requests from plugin 1.7+ have no skill attribution. The
request wrapper sets X-Spotify-Ads-Skill and X-Spotify-Ads-Sdk
deterministically, but agents sometimes hand-write curl instead, and
those calls are unattributable in per-skill usage and error-rate
reporting.

The hook now recovers what attribution is available:

- SDK header: deterministic, injected verbatim when missing. The value
  comes from `api-request.sh --env` rather than a second copy of the
  platform/version logic, so it cannot drift.
- Skill header: inferred from the most recent transcript lines,
  newest-first so recency wins, accepting only names that match a real
  skill in this plugin. Inferred values carry an "-inferred" suffix so
  reporting can separate best-effort attribution from the wrapper's
  exact value. When inference fails, no skill header is invented and the
  agent gets a nudge toward api() instead.

Detection also widens to catch `$BASE_URL/...` commands. The assets and
audiences upload flows use that form and were bypassing the hook
entirely, missing token refresh as well as attribution.

Attribution lives in a sourced library, not a second hook. Matching
PreToolUse hooks run in parallel against the original input and the last
updatedInput wins in non-deterministic order, so a separate rewriting
hook would race the token refresh and silently drop one of the two
edits. Antigravity cannot rewrite a command on any hook event, so there
the hook warns instead of injecting.

Adds 52 assertions to tests/test-check-token.sh. Seven independent
mutations of the library each fail the suite.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@henry-jackson
henry-jackson marked this pull request as ready for review September 3, 2026 18:23
@henry-jackson
henry-jackson force-pushed the henry-jackson/hook-skill-attribution branch from af26e46 to d2b4489 Compare September 3, 2026 18:23
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.

2 participants