#798·ponytail

ZCode: SessionStart rules never injected — raw-text stdout fails ZCode's JSON validation

Author: ArteiimisCreated Sep 3, 2026Updated Sep 14, 2026

Environment

  • ponytail 4.9.0 (ZCode plugin marketplace)
  • ZCode CLI 0.16.5, Windows 11

Summary

On ZCode, the SessionStart hook runs — the flag file ~/.claude/.ponytail-active is written at session start — but the ponytail ruleset never reaches the model. UserPromptSubmit context is lost the same way.

Root cause

writeHookOutput() in hooks/ponytail-runtime.js branches per harness (Codex / Copilot / Qoder); the default branch assumes Claude Code, which injects raw SessionStart stdout. ZCode instead parses hook stdout as strict JSON and only injects additionalContext; plain-text output fails validation and is silently discarded.

Repro

CLAUDE_PLUGIN_ROOT=/path/to/ponytail node hooks/ponytail-activate.js | head -c 120
# → "PONYTAIL MODE ACTIVE — level: full\n\n# Ponytail\n..."  (plain text, not JSON)

Suggested fix

Add a ZCode branch emitting the JSON shape ZCode accepts — identical to the existing Qoder output:

{"hookSpecificOutput": {"hookEventName": "SessionStart", "additionalContext": "..."}}

Note the Codex shape (top-level systemMessage + hookSpecificOutput) likely fails ZCode's strict schema too, so the Qoder shape is the safe reuse. Detection would need whatever env var ZCode exposes to plugin hooks (its Claude-compat CLAUDE_PLUGIN_ROOT alone can't distinguish the two).

Related: hooks/claude-codex-hooks.json registers a SubagentStart event. ZCode only supports SessionStart, UserPromptSubmit, PreToolUse, PermissionRequest, PostToolUse, PostToolUseFailure, Stop — the entry is silently dropped there. Harmless, but worth skipping on ZCode.