PHP was the one language with real code in two shapes here and no skill: a
Composer library held at PHPStan level max, and a plain PHP-FPM application
behind nginx with no framework. The rules come from reading both rather than
from general PHP advice, so each one names the failure it prevents.
The two halves differ enough to be separate sections. A library requires PSR
interfaces and ships no implementation; an application's rules are about
escaping, keeping the document root unwritable, atomic writes and sessions.
Everything in §1-§8 applies to both.
Three findings are worth the space they take because they were each paid for
once already: `json_encode` with JSON_UNESCAPED_SLASHES into an inline
<script> is an XSS hole, a web user that cannot write its own cache fails
silently on every request, and inside the dev container the host's own `php`
bridge shadows the real interpreter so every vendor/bin tool dies naming
distrobox.
docs(python): cover MCP servers, Red cogs and HA components, and correct three
rules the owner's own code contradicts
The skill described a toolchain and was silent on the four things most of this
Python actually is. Three of its rules are also wrong in context, and the code
is right: getLogger(__name__) puts a cog outside the red.* tree where Red's log
controls apply; TaskGroup's cancel-on-first-error is the wrong default for
fan-out over N providers, where the real pattern is a semaphore plus
gather(return_exceptions=True); and the gate runs locally and through
pre-commit, not through CI, which never runs under this account.
Also: ruff ALL-minus-documented-ignores is the preferred shape rather than the
explicit select list, lockfiles split by artifact type, and bare `python` and
bare `pip` are different interpreters on this host.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The existing warning only covered piping a self-match into kill. The quieter
failure is reading your own shell's PID as "the app is running" and refusing to
touch its config — which is exactly what happened while rotating webhooks in a
closed VRCNext.
Adds: always pass -a so a self-match is visible; prefer -ax (name only, never
scans arguments) for "is it running?"; -A/--ignore-ancestors as the fix when -f
is unavoidable; and why the [b]racket trick is weaker than it looks — the term
can appear elsewhere on the same command line. Points at systemctl is-active
for supervised units.
cli-tooling.md gains a one-line orientation pointer rather than a copy.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
A value with rules of its own — a URL, a path, a closed set, an identifier —
gets a type of its own. Passing it as a bare string discards those rules at the
first function boundary and leaves every consumer re-deriving them.
Added as a subsection of Architecture Preferences, with a table mapping the
common cases to the type to reach for in any language, the reasoning, and the
boundary rule: parse once at the edge, keep the type inward, serialize back only
where the wire actually demands a string. Notes the counter-case, so this is not
read as a mandate to wrap every string.
python.md gains the concrete choices: yarl.URL (already present wherever aiohttp
is), pathlib, StrEnum, and NewType for non-interchangeable identifiers.
Verified with `ruff rule PLR0915`: it is `too-many-statements` (default 50),
not a line-length rule. Ruff has no line-based function-length rule at all.
python.md now says so and points both limits at a pytest case; coding-dev.md
gains the general distinction between a real length lint and a proxy.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
A shell check only runs where that script runs. A test travels with the repo,
needs no extra tooling, and fails with a message naming the offending files.
Enforcement is now a preference order: native linter rule > test > build
script as fallback, with a worked example and a note on why a per-compile
build hook usually is not worth the incremental-build cost.
Propagated per language: rust (clippy has no file-length lint -> workspace
root test), js-typescript (ESLint max-lines covers both natively, no test
needed), go/python/csharp (linter for functions, test for files), bash (don't
reimplement in the gate what a test can assert).
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
- all nine files: trailing "Related" sections removed, their unique links
inlined where the topic actually arises (FFI boundary -> c-cpp, embedded
frontend -> js-typescript, build scripts -> bash, etc.)
- README conventions: rule 2 mandated a Related Skills section, which now
contradicts practice — replaced with inline-linking and one-home-per-fact
rules. The <repo>/<rel path> rule was appended after the wrong section
last commit; moved into the list where it belongs.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
All cross-skill links now spell out the repository: skills-public/foo.md,
skills-private/bar.md. These resolve from the shared parent directory, so one
spelling works from either repo and from code-languages/ subdirectories —
replacing the previous mix of ./, ../ and absolute file:// URLs. Link labels
normalised to match. Convention added to the README conventions list.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Extracted from the per-agent profile files and the private ai-agents skill,
where they were duplicated and environment-coupled:
- discovery over guessing: walk the help tree, never invent flags, never
hand-roll a script when a dedicated CLI exists
- non-interactive invocation: explicit targets, the tool's own --wait
- machine-readable output flags (json/compact/csv) vs. never filtering
diagnostics
- orient before starting: project instructions, git log, prior work records,
and verifying TODOs against the code
- script placement: dedicated version-controlled dir, symlinked into PATH
- destructive/outward-facing command care; environment drift verification
coding-dev.md and code-languages/bash.md now cross-reference it instead of
carrying their own one-line versions.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
- suppressions: prefer the narrowest scope that covers the problem (line,
function, module) with a reason comment; a project-wide disable silences
the rule in code nobody has written yet. Always name the specific rule.
Propagated to rust (#[allow]), csharp (#pragma/SuppressMessage).
- precedence: a project's own rules win only when contributing upstream.
For local/private work these rules win, adopting only the project's
load-bearing conventions.
- type checking must pass with zero errors *or warnings*.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Generic coding rules and preferences distilled from existing agent rule
files, project AGENTS.md/.rules, and saved memories:
- strictness maximal; suppressions must be reported to the user
- never filter build/lint/test output through grep/tail/head
- reuse > fork > self-implement; generic code becomes its own package
- 1000-line file / 100-line function limits, split by concern
- regression test every fixed bug; never test against real user data
- events over polling; scope discipline; honest reporting
Per-language: rust, js-typescript, bash, python, go, csharp-dotnet, c-cpp.
Each extends coding-dev.md rather than repeating it.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>