hacking-rules
**Scope**: H-series PEP 8 extensions enforced by `hacking` package. Does not cover standard PEP 8. **Version range**: hacking 6.x+ (flake8 5.x+, tox -e pep8) **Generated**: 2026-04-09
$ npx -y skills add notque/vexjoy-agent --agent claude-codeHow it fires
How this agent gets triggered: by you, by Claude, or both.
- Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.Auto-invocation is when the right skill fires by itself at the right moment, driven by a FLOW.md router and a hook, instead of you invoking it by name. It is the difference between a skill being installed and a skill actually getting used.Read the full definition →
- You can call itInvoke it directly when you want it.
Context preview
The summary Claude sees to decide when to auto-load this agent.
**Scope**: H-series PEP 8 extensions enforced by `hacking` package. Does not cover standard PEP 8. **Version range**: hacking 6.x+ (flake8 5.x+, tox -e pep8) **Generated**: 2026-04-09
Agent definition
hacking-rules.mdOpenStack Hacking Rules Reference
> **Scope**: H-series PEP 8 extensions enforced by `hacking` package. Does not cover standard PEP 8. > **Version range**: hacking 6.x+ (flake8 5.x+, tox -e pep8) > **Generated**: 2026-04-09
---
Rule Summary Table
| Rule | What It Checks | Severity | |------|---------------|----------| | H201 | No bare `except:` | Hard block | | H202 | No `except Exception:` without re-raise | Warning | | H301 | No `import` of multiple modules per line | Hard block | | H302 | No full module import when `from … import` available | Warning | | H303 | No wildcard imports | Hard block | | H304 | No relative imports | Hard block | | H306 | Alphabetical order within import groups | Warning | | H401 | No docstring starting with a space | Warning | | H501 | No `%s` formatting with `locals()` or `self.__dict__` | Hard block | | H701 | No i18n import from old `oslo.i18n` namespace | Hard block | | H903 | No Windows line endings | Hard block |
---
Correct Patterns
H201 — Specific Exception Handling
try:
result = nova_client.servers.get(server_id)
except nova_exceptions.NotFound:
raise exception.ServerNotFound(server_id=server_id)
except nova_exceptions.ClientException as exc:
LOG.error('Nova API error: %s', exc)
raise
# Exception acceptable when re-raising
try:
do_risky_thing()
except Exception:
LOG.exception('Unexpected error')
raise---
H301/H303/H304 — Import Conventions
One per line, no wildcards, no relative paths, ordered stdlib -> third-party -> project.
import os
import sys
from oslo_config import cfg
from oslo_log import log as logging
from myservice import exception
from myservice.db import api as db_api
from myservice import utils
---
H501 — No locals()/self.__dict__ in % formatting
LOG.error('Server %(server_id)s not found in zone %(zone)s',
{'server_id': server_id, 'zone': zone})
LOG.info('Created resource %s', resource.id)---
H701 — i18n Import from New Namespace
from myservice.i18n import _
raise exception.ResourceNotFound(msg=_('Resource %s not found') % res_id)---
Pattern Catalog
H201: Name the Exception Class
**Detection**:
grep -rn 'except:' --include="*.py"
rg 'except:\s*$' --type py
**Preferred action**:
try:
result = db.get_resource(context, resource_id)
except exception.ResourceNotFound:
LOG.warning('Resource %s not found', resource_id)
return None---
H303: Import Only What You Use
**Detection**:
grep -rn 'from .* import \*' --include="*.py"
**Preferred action**: `from oslo_config.cfg import CONF, StrOpt, IntOpt`
---
H304: Use Absolute Imports
**Detection**:
grep -rn 'from \.' --include="*.py" | grep -v "test\|#"
OpenStack enforces absolute imports. Relative imports break `oslo-config-generator`, tox, and Zuul.
**Preferred action**: `from myservice.common.utils import format_id`
---
H501: Use Explicit Dict for % Formatting
**Detection**:
grep -rn 'locals()\|self\.__dict__' --include="*.py" | grep '%'
`locals()` captures entire scope including sensitive values.
**Preferred action**:
LOG.debug('State: %s timeout: %s', self.state, self.timeout)---
Error-Fix Mappings
| `tox -e pep8` Output | Rule | Fix | |----------------------|------|-----| | `H201 no 'except:'` | H201 | Specific exception class | | `H303 no wildcard imports` | H303 | Explicit names | | `H304 No relative imports` | H304 | `from myservice.utils` | | `H306 imports not alphabetical` | H306 | Sort within groups | | `H501 Do not use self.__dict__` | H501 | Explicit dict | | `H701 DEPRECATED oslo.i18n` | H701 | `from myservice.i18n import _` |
---
Running the Checks
tox -e pep8 # Full check (same as CI)
flake8 --select=H myservice/ # Hacking only
flake8 --select=H myservice/api/v1/resources.py # Single file
grep -r "H[0-9]\{3\}" tox.ini setup.cfg # Show configured rules---
See Also
- `oslo-patterns.md` — Oslo library usage that hacking compliance depends on
- `rpc-versioning.md` — Version rules for API methods
Read more
OpenStack Hacking Rules Reference
> **Scope**: H-series PEP 8 extensions enforced by `hacking` package. Does not cover standard PEP 8. > **Version range**: hacking 6.x+ (flake8 5.x+, tox -e pep8) > **Generated**: 2026-04-09
---
Rule Summary Table
| Rule | What It Checks | Severity | |------|---------------|----------| | H201 | No bare `except:` | Hard block | | H202 | No `except Exception:` without re-raise | Warning | | H301 | No `import` of multiple modules per line | Hard block | | H302 | No full module import when `from … import` available | Warning | | H303 | No wildcard imports | Hard block | | H304 | No relative imports | Hard block | | H306 | Alphabetical order within import groups | Warning | | H401 | No docstring starting with a space | Warning | | H501 | No `%s` formatting with `locals()` or `self.__dict__` | Hard block | | H701 | No i18n import from old `oslo.i18n` namespace | Hard block | | H903 | No Windows line endings | Hard block |
---
Correct Patterns
H201 — Specific Exception Handling
try:
result = nova_client.servers.get(server_id)
except nova_exceptions.NotFound:
raise exception.ServerNotFound(server_id=server_id)
except nova_exceptions.ClientException as exc:
LOG.error('Nova API error: %s', exc)
raise
# Exception acceptable when re-raising
try:
do_risky_thing()
except Exception:
LOG.exception('Unexpected error')
raise---
H301/H303/H304 — Import Conventions
One per line, no wildcards, no relative paths, ordered stdlib -> third-party -> project.
import os import sys from oslo_config import cfg from oslo_log import log as logging from myservice import exception from myservice.db import api as db_api from myservice import utils
---
H501 — No locals()/self.__dict__ in % formatting
LOG.error('Server %(server_id)s not found in zone %(zone)s',
{'server_id': server_id, 'zone': zone})
LOG.info('Created resource %s', resource.id)---
H701 — i18n Import from New Namespace
from myservice.i18n import _
raise exception.ResourceNotFound(msg=_('Resource %s not found') % res_id)---
Pattern Catalog
H201: Name the Exception Class
**Detection**:
grep -rn 'except:' --include="*.py" rg 'except:\s*$' --type py
**Preferred action**:
try:
result = db.get_resource(context, resource_id)
except exception.ResourceNotFound:
LOG.warning('Resource %s not found', resource_id)
return None---
H303: Import Only What You Use
**Detection**:
grep -rn 'from .* import \*' --include="*.py"
**Preferred action**: `from oslo_config.cfg import CONF, StrOpt, IntOpt`
---
H304: Use Absolute Imports
**Detection**:
grep -rn 'from \.' --include="*.py" | grep -v "test\|#"
OpenStack enforces absolute imports. Relative imports break `oslo-config-generator`, tox, and Zuul.
**Preferred action**: `from myservice.common.utils import format_id`
---
H501: Use Explicit Dict for % Formatting
**Detection**:
grep -rn 'locals()\|self\.__dict__' --include="*.py" | grep '%'
`locals()` captures entire scope including sensitive values.
**Preferred action**:
LOG.debug('State: %s timeout: %s', self.state, self.timeout)---
Error-Fix Mappings
| `tox -e pep8` Output | Rule | Fix | |----------------------|------|-----| | `H201 no 'except:'` | H201 | Specific exception class | | `H303 no wildcard imports` | H303 | Explicit names | | `H304 No relative imports` | H304 | `from myservice.utils` | | `H306 imports not alphabetical` | H306 | Sort within groups | | `H501 Do not use self.__dict__` | H501 | Explicit dict | | `H701 DEPRECATED oslo.i18n` | H701 | `from myservice.i18n import _` |
---
Running the Checks
tox -e pep8 # Full check (same as CI)
flake8 --select=H myservice/ # Hacking only
flake8 --select=H myservice/api/v1/resources.py # Single file
grep -r "H[0-9]\{3\}" tox.ini setup.cfg # Show configured rules---
See Also
- `oslo-patterns.md` — Oslo library usage that hacking compliance depends on
- `rpc-versioning.md` — Version rules for API methods
Essays and writing behind this toolkit live at vexjoy.com. AI agents skip steps. "Looks correct" replaces running tests. "Trivial change" replaces verification.
Repo: notque/vexjoy-agent
Other agents on vexjoy-agent.
- ansible-automation-engineer
Ansible automation: playbooks, roles, collections, Molecule testing, Vault security.
Open agent - modules
**Scope**: Module selection patterns, builtin vs command/shell decisions, collection modules, and version-specific module changes **Version range**: ansible-core 2.14+ / Ansible Collections (community.general 7.0+) **Generated**: 2026-04-04 — verify against current Ansible
Open agent - testing
**Scope**: Molecule test scenarios, ansible-lint rules, idempotency validation, and check-mode patterns **Version range**: Molecule 6.0+ / ansible-lint 6.0+ / ansible-core 2.14+ **Generated**: 2026-04-04 — verify against current Molecule and ansible-lint documentation
Open agent - base-instructions
Universal operational rules injected by /do at agent dispatch. Domain-specific rules live in each agent's .md file.
Open agent - communication-patterns
**Scope**: Failure modes in agent output style — over-reporting, self-congratulation, verbose narration, and hedging. Covers what to detect and how to fix each. **Version range**: all versions **Generated**: 2026-05-11
Open agent - combat-effects-upgrade
Zero-dependency combat visual upgrades: CSS particle replacement, Framer Motion combat juice, CSS 3D card transforms.
Open agent

