Skip to content

feat(github-app): inject github-app-auth rule via SessionStart symlink - #590

Draft
jack-nsheaps[bot] wants to merge 1 commit into
mainfrom
claude/blissful-darwin-jkv3ji
Draft

jack-nsheaps[bot] wants to merge 1 commit into
mainfrom
claude/blissful-darwin-jkv3ji

Conversation

@jack-nsheaps

@jack-nsheaps jack-nsheaps Bot commented Jun 9, 2026

Copy link
Copy Markdown
Contributor

What this does

Adds a rules-injection mechanism to the github-app plugin, mirroring how agentic-behavior and common-sense inject their rules: a SessionStart hook symlinks the plugin's rules/ directory into the project's .claude/rules/github-app, so the rules load as context automatically.

The new rule (github-app-auth) tells the agent it has GitHub App auth available via this plugin, that the app's token grants access to whatever the app is installed in (not just the repos in the current session scope), and that it MUST use that app auth when committing, creating PRs, or interacting with the GitHub API.

Changes

  • plugins/github-app/rules/github-app-auth.md — new rule
  • plugins/github-app/hooks/scripts/sync-rules.sh — new SessionStart symlink hook (project-scope variant, copied from agentic-behavior)
  • plugins/github-app/hooks/hooks.json — wires sync-rules.sh as a second SessionStart hook
  • plugins/github-app/SPEC.md — adds a ## Rules section (also auto-regenerated by the sync-plugin-specs workflow on merge)

Status

Complete. Validated locally:

  • mise run validate ✅ (github-app passed)
  • mise run lint ✅ (Prettier clean)
  • jq / bash -n
  • End-to-end hook test: created .claude/rules/github-app -> .../plugins/github-app/rules and the rule resolved through the symlink.

Version not manually bumped — CI auto-bumps github-app on merge to main per the repo's versioning rule.

What to review

  • Wording/scope of the new rule.
  • That adding sync-rules.sh as a second hook in the existing SessionStart matcher is the preferred shape (vs. a separate matcher block).

🤖 Opened by an AI agent (Jack) on behalf of @nsheaps.

Add a rules/ directory to the github-app plugin and a sync-rules.sh
SessionStart hook (mirroring the agentic-behavior/common-sense pattern)
that symlinks the plugin's rules into project .claude/rules/github-app.

The new github-app-auth rule tells the agent it has GitHub App auth
available and MUST use the app's token (which grants access to whatever
the app is installed in, not just the session's repos) when committing,
creating PRs, or calling the GitHub API.

https://claude.ai/code/session_01DQvZRoDrJdhBStk4ycvrGE
@jack-nsheaps jack-nsheaps Bot added the request-review Force an AI code review on a draft PR (open non-draft PRs review automatically) label Jun 9, 2026
@henry-nsheaps henry-nsheaps Bot removed the request-review Force an AI code review on a draft PR (open non-draft PRs review automatically) label Jun 9, 2026
@github-actions

github-actions Bot commented Jun 9, 2026

Copy link
Copy Markdown
Contributor

Plugin Version Preview

Preview only — plugin versions and marketplace.json are bumped automatically on merge to main, not in this PR. Manual bumps to higher versions are preserved. See the file annotations for the pending change on each plugin.json.

Plugin Base Current Action
github-app 0.6.0 0.6.1 Auto-bumped

@henry-nsheaps henry-nsheaps Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

### 👍 Clean, low-risk addition that follows the established rules-injection pattern — looks ready to merge ![](https://img.shields.io/badge/97%25-?style=for-the-badge&label=QUALITY&labelColor=%23444&color=%2360A060) ![](https://img.shields.io/badge/N%2FA-?style=for-the-badge&label=SECURITY&labelColor=%23444&color=%23444444) ![](https://img.shields.io/badge/98%25-?style=for-the-badge&label=SIMPLICITY&labelColor=%23444&color=%2360A060) ![](https://img.shields.io/badge/96%25-?style=for-the-badge&label=CONFIDENCE&labelColor=%23444&color=%2360A060)

sync-rules.sh is a verbatim copy of the proven agentic-behavior variant — only name/link fields differ
shared-lib dependency declared in plugin.json (script sources hook-logging.sh)
✅ All rule references exist (github-app-token, github-app-session-env, github-app-git-identity skills + bin/generate-token.sh)
✅ hooks.json valid; sync-rules.sh added as a 2nd hook in the existing SessionStart matcher (the preferred shape)
⚠️ SPEC.md PreToolUse line inaccurately claims rules-sync — non-blocking, see inline

🖱️ Click to expand for full details

Code Quality

The new sync-rules.sh is a byte-for-byte copy of plugins/agentic-behavior/hooks/scripts/sync-rules.sh with only the four expected substitutions (PLUGIN_NAME, header comments, log prefix, LINK_NAME). I diffed the two files to confirm — no unexpected drift. Reusing a battle-tested script verbatim is the right call here (DRY relative to the existing pattern). The symlink logic correctly: creates .claude/rules/, replaces a stale symlink, refuses to clobber a real directory (warns + exits 0), and fails soft via hook_fail + exit 0 so a broken symlink never blocks the session.

The shared-lib dependency is declared in plugin.json, and the _wait_for_shared_lib/data-dir-resolution pattern matches the shared-libs rule in the repo. bash -n and jq empty both pass.

Documentation Accuracy

The new github-app-auth.md rule is accurate: every skill it names (github-app-token, github-app-session-env, github-app-git-identity) and the bin/generate-token.sh path it references all exist on disk. The "grants access to everything the app is installed in, not just session scope" framing is consistent with the repo's auth.md philosophy.

One minor inaccuracy in SPEC.md: the PreToolUse hook line picked up the "Also syncs the plugin's rules … on session start" note because bin/sync-plugin-specs.sh applies the single top-level hooks.json description to every event line. The PreToolUse hook (github-token-check.sh) doesn't sync rules. Flagged inline with a suggested event-neutral wording. Non-blocking — it's consistent with how agentic-behavior treats its combined descriptions, and the SPEC auto-regenerates on merge.

Security

N/A — no new secret handling, network calls, or privilege changes. The rule is advisory text; the script only creates a symlink within the project's own .claude/rules/.

Versioning

Correctly left unbumped — CI auto-bumps github-app (0.6.0 → 0.6.1) on merge per the repo's versioning rule, matching the version-preview bot comment.

Recommended follow-ups (non-blocking):

  • Consider making the hooks.json description event-neutral so the generated PreToolUse SPEC line stays accurate (see inline suggestion). Alternatively, a longer-term improvement to bin/sync-plugin-specs.sh could derive per-event descriptions rather than reusing one string — but that's well outside this PR's scope.

Notes:123

Footnotes

  1. Workflow Run: github.com/nsheaps/ai-mktpl/actions/runs/27234759036

  2. PR: nsheaps/ai-mktpl#590

  3. Persistent data directory reference: code.claude.com/docs/en/plugins-reference

- `SessionStart` (`bash`) — GitHub App token lifecycle: generate on session start, refresh before expiry via PreToolUse hook
- `PreToolUse` (`bash`) — GitHub App token lifecycle: generate on session start, refresh before expiry via PreToolUse hook
- `SessionStart` (`bash`) — GitHub App token lifecycle: generate on session start, refresh before expiry via PreToolUse hook. Also syncs the plugin's rules into project .claude/rules/ via symlink on session start.
- `PreToolUse` (`bash`) — GitHub App token lifecycle: generate on session start, refresh before expiry via PreToolUse hook. Also syncs the plugin's rules into project .claude/rules/ via symlink on session start.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Minor doc accuracy (non-blocking): this PreToolUse line now reads "Also syncs the plugin's rules into project .claude/rules/ via symlink on session start" — but the PreToolUse hook is github-token-check.sh, which only checks/refreshes the token; it does not sync rules, and "on session start" is contradictory for a PreToolUse hook.

Root cause: bin/sync-plugin-specs.sh (scan_hooks) reuses the single top-level description field from hooks/hooks.json for every event line. So appending the rules-sync note to that shared description leaks it onto the PreToolUse line too.

This mirrors the existing convention (e.g. agentic-behavior/SPEC.md applies one combined description to all its hook lines), so it's not strictly a regression — but agentic-behavior phrases its description as a neutral union of behaviors rather than one pinned to a specific event. If you want the SPEC to stay accurate, consider keeping the hooks.json description event-neutral, e.g.:

Suggested change
- `PreToolUse` (`bash`) — GitHub App token lifecycle: generate on session start, refresh before expiry via PreToolUse hook. Also syncs the plugin's rules into project .claude/rules/ via symlink on session start.
- `PreToolUse` (`bash`) — GitHub App token lifecycle (generate on session start, refresh before expiry) plus rules-sync into project .claude/rules/ via symlink on session start.

(Same wording would then apply cleanly to the SessionStart line on 18.) Purely a documentation nicety — nothing functional. The SPEC is also auto-regenerated on merge, so it'll re-derive from whatever hooks.json description ends up being.

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.

1 participant