Skip to content
Development
Skill

/night-market-debugging-playbook

Triage night-market failures by symptom (hooks, CI, tests). Use when a check fails unexpectedly. Do not use for routine gates; use night-market-operations.

From plugin
claude-night-market
343200 skills60 agents162 commands1 MCP

Claude Code

$ npx -y skills add athola/claude-night-market --skill night-market-debugging-playbook --agent claude-code

SKILL.md

night-market-debugging-playbook.SKILL.md
name: night-market-debugging-playbook
description: Triage night-market failures by symptom (hooks, CI, tests). Use when a check fails unexpectedly. Do not use for routine gates; use night-market-operations.

Night Market Debugging Playbook

Match the symptom to a row, run the one discriminating command, apply the known fix. Every row below is a failure this repo has already paid for, with the commit hash that settled it. Do not re-derive a diagnosis that archaeology already produced.

Vocabulary

Terms used throughout, defined once:

  • **Hook**: a script Claude Code runs on events (PreToolUse,

PostToolUse, Stop, SessionStart). Registered in a plugin's `hooks/hooks.json` with a `command` and a `timeout`.

  • **Hook budget**: that registered `timeout` in seconds. The harness

kills the hook when it expires, before any output is honored.

  • **Host interpreter**: hooks run as `python3 ...` under the machine's

system Python (floor: 3.9), NOT the repo's uv-managed 3.12 venv. Third-party packages a plugin declares are not guaranteed present.

  • **skrills**: optional Rust binary for skill validation and analysis.

Every Makefile target that uses it has a Python fallback.

  • **Import chain**: everything a `import x` transitively pulls in,

including the plugin's `__init__.py`.

Symptom index

| # | Symptom | Likely cause | Story | |---|---------|--------------|-------| | 1 | PreToolUse hook error / ModuleNotFoundError on every `git commit` | Unguarded third-party import in a plugin `__init__.py` reachable from a hook | 45dd77ef, 9bfc0a7a | | 2 | `python39-compat` is the only failing CI check | A 3.10+/3.11+ construct (`datetime.UTC`, bare `X \| Y` union) entered a hook import chain | 18c9340d, PR #511 | | 3 | Hook exits 0 but never does anything | Hook reads `CLAUDE_TOOL_*` env vars instead of stdin JSON | CHANGELOG 1.9.14 | | 4 | `capabilities-sync` CI fails | plugin.json registrations drifted from the book reference | capabilities-sync.yml | | 5 | Root `pytest` raises ImportPathMismatchError | Plugin tests collected from repo root instead of per plugin | conftest.py, pyproject norecursedirs | | 6 | `slop-check` fails on a PR | Slop score over 3.0 in a `docs/` or `book/src/` markdown file | slop-check.yml | | 7 | Stop hook produces no verdict at all | Inner subprocess timeout >= registered hook budget | 268cff89 | | 8 | CI broken on a GitHub action or tool pin | Stale or nonexistent pinned version | f81d89a5, 25bf5a9d | | 9 | Scanner reports nothing on input you know is bad | Swallowed exception (except-and-continue) drops files silently | 666171c3, b6de71cf | | 10 | `skrills: not found` | Missing optional binary (a Python fallback exists) | Makefile validate-skills |

Triage runbooks

1. ModuleNotFoundError from a hook on every commit

First command (substitute the hook path from the error message):

echo '{}' | python3 plugins/gauntlet/hooks/precommit_gate.py; echo "exit=$?"

What the result means: a traceback names the module whose import chain pulls in a package the host interpreter lacks. Exit 0 with no output means the hook is import-safe and the problem is elsewhere (check the hook registration in `hooks/hooks.json`).

Fix: guard the import at module level or defer it into the function that needs it. The gauntlet incident: `precommit_gate.py` imported `gauntlet.knowledge_store`, whose `__init__.py` eagerly imported modules doing bare `import yaml` and `import anthropic`. Guarded in 45dd77ef (#518), deferred in 9bfc0a7a. Add a regression test that blocks the package via a `sys.meta_path` blocker and re-imports the hook (pattern in `plugins/gauntlet/tests/unit/test_challenges.py`).

2. python39-compat is the only failing check

The repo is Python 3.12, but hook scripts and their transitive imports must stay importable under Python 3.9 (`.github/workflows/ python39-compat.yml`). First command:

uv run ruff check --select UP007 --target-version py39 plugins/<plugin>/hooks/
rg -n 'datetime\.UTC|from datetime import UTC' plugins/<plugin>/

What the result means: UP007 hits are bare `X | Y` union annotations that raise TypeError at import time on 3.9. The `rg` hits are the `datetime.UTC` alias (3.11+), which UP007 does not catch. Either one in a hook import chain breaks every hook at once: on PR #511 a single `datetime.UTC` in `leyline.quota_tracker` produced three cascade failures (18c9340d).

Fix: use `from datetime import timezone` with `timezone.utc`, and `typing.Union`/`Optional` or a `from __future__ import annotations` line for unions. To mirror CI's Gate 2 locally (verified 2026-07-02):

uv venv --python 3.9 /tmp/hook39
VIRTUAL_ENV=/tmp/hook39 uv pip install pytest pyyaml
cd plugins/abstract
/tmp/hook39/bin/python -m pytest tests/hooks --override-ini="addopts="

The `addopts` override strips per-plugin coverage flags that need packages the bare venv lacks. See also the linter trap below: ruff will fight this fix.

3. Hook exits 0 but never does anything

First command:

rg -l 'CLAUDE_TOOL_' plugins/*/hooks/
rg -ln 'read_hook_payload' plugins/*/hooks/

What the result means: Claude Code never sets `CLAUDE_TOOL_*` environment variables. The payload arrives as JSON on stdin. A hook reading only env vars is a silent no-op: it exits 0, CI is green, and nothing downstream ever happens. This starved the `[Learning]` discussion digests for two months (last digest 2026-04-25) before anyone noticed (CHANGELOG 1.9.14).

Fix: read stdin first via the canonical reader `plugins/abstract/hooks/shared/hook_io.py` (`read_hook_payload`, stdin-first with env-var fallback for the test harness). Then verify the hook actually fires: pipe a realistic payload in and check for the side effect rather than the exit code alone.

4. capabilities-sync CI fails

First command:

bash scripts/capabilities-sync-check.sh

What the result means: the script diffs every plugin's `.claude-plugin/plugin.json` registrations agai

Read more
@athola
Ships withclaude-night-market

A plugin marketplace for Claude Code. Install only the plugins you need to run git workflows, code review, spec-driven development, and autonomous agents from inside your Claude Code session.

343200 skills60 agents1 MCP
Get the whole plugin

Stars on GitHub

Momentum

stars in total
343
Star history of athola/claude-night-market on GitHub, a chart by star-history.com

Other skills on claude-night-market.

More skills from other plugins.

brainstorming
Auto-invoked

brainstorming

You MUST use this before any creative work - creating features, building components, adding functionality, modifying behavior, or…

@obra@obraInstall Skill
ask-matt

ask-matt

Ask which skill or flow fits your situation. A router over the skills in this repo.

skills11d309k
@mattpocock@mattpocockInstall Skill
accessibility
Auto-invoked

accessibility

Design, implement, and audit accessible UI to WCAG 2.2 Level AA across Web, iOS, and Android — semantic ARIA roles and labels,…

ecc13d293k
@affaan-m@affaan-mInstall Skill
compiler-commit

compiler-commit

Use when you want to verify compiler changes and commit with the correct convention. Runs tests, lint, and format, then commits…

react2d252k
@facebook@facebookInstall Skill

Questions about night-market-debugging-playbook.

Which coding agents can use night-market-debugging-playbook?
night-market-debugging-playbook installs in Claude Code, Codex, Cursor, Gemini CLI, GitHub Copilot, OpenCode and Windsurf with the skills CLI, using each agent's flag shown on this page. Flowy's auto-invocation, which fires a skill when your prompt matches, runs in Claude Code only.