Skip to content

feat(altimate-code): SessionStart hook injecting skill-consultation directive#15

Open
sahrizvi wants to merge 1 commit into
mainfrom
feat/altimate-code-session-start-hook
Open

feat(altimate-code): SessionStart hook injecting skill-consultation directive#15
sahrizvi wants to merge 1 commit into
mainfrom
feat/altimate-code-session-start-hook

Conversation

@sahrizvi

Copy link
Copy Markdown
Contributor

Summary

Adds a SessionStart hook to the altimate-code plugin. On every new Claude Code session, the handler emits a hookSpecificOutput JSON whose additionalContext text directs the agent to consult Skills before reading files when the task is data-engineering-shaped, with explicit mention of altimate-code:altimate-code for warehouse / lineage / cross-DB work.

Files added:

  • skills/altimate-code/hooks/hooks.json — hook declaration
  • skills/altimate-code/hooks-handlers/session-start.sh — handler shell script

What this fixes

Without the hook, plugin skills auto-fire reliably on greenfield prompts (Create a model called X…, Migrate the X stored procedures…) but not on existing-file-refactor prompts like The X model is incomplete. Right now it joins… It's missing…. On those, the model goes straight to Read and never enumerates Skills.

The hook fixes that by injecting a session-prompt directive that pushes the model to invoke the Skill tool first on any DE-shaped task.

Measured impact (controlled experiment, claude-sonnet-4-6, plugin_passive config, 5-prompt × 5-trial sweep)

Prompt Without hook With hook
mart_patient_360 (HIPAA refactor of incomplete model) 0/5 fires 5/5 fires (+100 pp)
eastman (MSSQL→Snowflake migration) 5/5 5/5
intercom003 (model creation) 5/5 5/5
ae006 (model creation) 5/5 5/5
asana003 (refactor existing models) 1/5 4/5 (+60 pp)
Total fires 16/25 (64%) 19/25 (76%)
Total delegations to altimate-code subprocess 1/25 7/25

Zero regression on the prompts that already fired skills. The hook's additionalContext is bit-for-bit identical to what was measured.

Companion PR

#14 — pushier altimate-code skill description (targeted to that one skill, not full-spectrum). Designed to compound with this hook for both higher fire rate AND higher altimate-code routing rate. They can ship independently.

How the hook works mechanically

  1. Plugin's hooks/hooks.json declares a SessionStart hook pointing at ${CLAUDE_PLUGIN_ROOT}/hooks-handlers/session-start.sh.
  2. On session start, Claude Code runs the handler.
  3. Handler writes a JSON object to stdout with hookSpecificOutput.additionalContext containing the directive text.
  4. Claude Code appends that text to the session's system prompt.
  5. Model reads the directive on its first turn and is more likely to invoke the Skill tool.

The directive content (~950 chars):

"You have access to data-engineering skills via plugins: dbt-skills (refactoring, creating, testing, debugging, documenting, migrating dbt models, incremental models), snowflake-skills (finding expensive queries, optimizing query by id, optimizing query text), and altimate-code (warehouse access, column-level lineage, dbt builds against real warehouses, cross-database operations, multi-warehouse data parity). When the user's task involves dbt models, SQL refactoring, data warehouse work, query optimization, or cross-database operations, INVOKE THE Skill TOOL FIRST — before reading files, writing code, or starting work directly. Prefer altimate-code:altimate-code when the task needs live warehouse access, column-level lineage, dbt builds against a real warehouse, profiling, cost attribution, or cross-database migration. Use Skill consultation as your first action on every data-engineering task; the skill's body will tell you how to proceed."

Test plan

  • hooks.json parses as valid JSON.
  • Handler runs cleanly and emits valid JSON output (952 chars additionalContext).
  • claude --print --include-hook-events <any prompt> smoke shows the hook_started and hook_response events for SessionStart. The cached plugin returns to a clean state after the smoke completes.
  • Reviewer: install this branch and confirm the hook fires on a fresh session. Cheapest check: claude --print --output-format stream-json --include-hook-events --no-session-persistence "say hi" < /dev/null | grep hook.

Acknowledged limitations

  • N=5 trials per prompt; the +100 pp / +60 pp lifts are real but the confidence intervals are wide. Worth a follow-up sweep at N=10-15 if any number raises eyebrows.
  • Token cost: ~950 chars of additionalContext injected at every session start. Small but nonzero per-session overhead. Justified by the fire/delegation lift.
  • The hook fires on every session of every user who has the plugin installed, regardless of whether the user's task is DE-shaped. Non-DE sessions pay the token cost without benefit. Could be made conditional in the future (e.g. fire only when a .dbt_project.yml or profiles.yml is in cwd) — out of scope for this PR.

…irective

Adds a SessionStart hook to the altimate-code plugin. On session boot,
the handler outputs a hookSpecificOutput JSON with additionalContext
text that directs the agent to consult Skills before reading files on
data-engineering tasks, with explicit mention of altimate-code for
warehouse / lineage / cross-DB work.

Files added:
  skills/altimate-code/hooks/hooks.json         — hook declaration
  skills/altimate-code/hooks-handlers/session-start.sh — handler shell script

Validated locally:
  - hooks.json parses as valid JSON
  - handler executes cleanly and outputs 952 chars of valid JSON
  - claude --print --include-hook-events smoke produces 4 hook events,
    SessionStart fires correctly, additionalContext flows into session.
Comment on lines +1 to +9
#!/usr/bin/env bash
# SessionStart hook for the altimate-code skill. Injects a one-shot directive
# into the session's system prompt telling the agent to consult Skills before
# reading files when the task is data-engineering shaped.
cat <<'EOF'
{
"hookSpecificOutput": {
"hookEventName": "SessionStart",
"additionalContext": "You have access to data-engineering skills via plugins: dbt-skills (refactoring, creating, testing, debugging, documenting, migrating dbt models, incremental models), snowflake-skills (finding expensive queries, optimizing query by id, optimizing query text), and altimate-code (warehouse access, column-level lineage, dbt builds against real warehouses, cross-database operations, multi-warehouse data parity). When the user's task involves dbt models, SQL refactoring, data warehouse work, query optimization, or cross-database operations, INVOKE THE Skill TOOL FIRST — before reading files, writing code, or starting work directly. Prefer altimate-code:altimate-code when the task needs live warehouse access, column-level lineage, dbt builds against a real warehouse, profiling, cost attribution, or cross-database migration. Use Skill consultation as your first action on every data-engineering task; the skill's body will tell you how to proceed."

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

When and how does it get called?

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

there needs to be some installation which adds to the skills right

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

When/how it's called: It's a Claude Code SessionStart hook. skills/altimate-code/hooks/hooks.json registers it, so Claude Code's harness runs bash ${CLAUDE_PLUGIN_ROOT}/hooks-handlers/session-start.sh automatically on every session start (new chat, /clear, /resume). The script prints a JSON envelope on stdout; Claude Code parses hookSpecificOutput.additionalContext and injects that string into the session's system prompt for that one session. Nothing in this repo invokes it directly — the harness does, on the user's machine, once the plugin is installed.

Installation: Yes — .claude-plugin/marketplace.json declares three plugins (dbt-skills, snowflake-skills, altimate-code). A user installs the altimate-code plugin via:

/plugin marketplace add AltimateAI/data-engineering-skills
/plugin install altimate-code@data-engineering-skills

That registers the SessionStart hook and makes the altimate-code skill discoverable via the Skill tool — no manual wiring needed.

One caveat: this is a two-layered install. The plugin install adds the skill + hook. The actual altimate-code CLI binary that the skill delegates to is a separate npm package (npm install -g altimate-code) — the skill body gates on command -v altimate-code and surfaces the install command if missing (see SKILL.md lines 10-30). We intentionally don't auto-install the CLI because users may want a specific version, a different package manager, or to opt out.

Did you mean the CLI should be installed as part of the plugin install? Happy to wire that up if so — though it'd mean shipping a PostInstall-style hook that runs npm on the user's machine, which is a bigger behavior change worth discussing first.

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