hyrums-law
Skill0 starsChanged 3 months agoMITView on GitHub
This skill should be used when the user asks "is this a breaking change", "can I change this undocumented behavior", "why did an internal change break a consumer", "how do I stop people depending on this", or is changing observable behavior never promised in a contract, such as iteration order, error message text, timing, sort stability, ID format, or JSON key order.
1 other project uses a version of this.
Adopted by
Most recently taken up by
- The-Artificer-of-Ciphers-LLC/skills-from-the-artificertheir own version, first seen Oct 14, 2026
Other versions1 project uses a version of this.
Word for word · 0
None found.
Edited · 0
None found.
Wrote their own version · 1
How matches are found. Word for word: the exact same text. Edited: shares passages with this file (“99% same” means 99% of its five-word phrases also appear here; 10% or more counts). Their own version: similar meaning, or, weakest, the same name. We can’t tell which project had it first. Projects are counted among the 200 most-starred candidates, and mentions are links to the repository we found, up to 50 per site, so both counts are a floor.
In this repository29 other files it gives its agents.
- algorithmic-complexity-attacksSkill
- cache-stampedeSkill
- clocks-and-timeSkill
- code-hotspotsSkill
- connascenceSkill
- connection-poolingSkill
- consistent-hashingSkill
- coordinated-omissionSkill
- cyclomatic-complexitySkill
- database-queuesSkill
- dependency-confusionSkill
- expand-contractSkill
- floating-pointSkill
- index-designSkill
- isolation-anomaliesSkill
- keyset-paginationSkill
- metamorphic-testingSkill
- module-depthSkill
- mutation-testingSkill
- mvcc-and-bloatSkill
- parse-dont-validateSkill
- query-plansSkill
- queueing-and-utilizationSkill
- retry-amplificationSkill
- start-hereSkill
- tail-latencySkill
- unicode-pitfallsSkill
- universal-scalability-lawSkill
- write-amplificationSkill
The file
We split this skill into the rules it gives an agent
5 rules. About 0 are common, 3 are distinctive, and 2 are very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈3
Distinctive · estimate
This author's own choices. Worth a look.
2
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Very specific: line 52
Do not rely on a changelog note: Use metrics, then deprecation with a deadline, then removal.
- Very specific: line 58
Supply what people are hacking around: If everyone parses the logs, ship a structured API.
- Distinctive: line 68
Test against major consumers, not only the local test suite.
- Distinctive: line 84
Can a user observe this difference?: If yes, it is potentially breaking regardless of the documentation.
- Distinctive: line 85
How would anyone know if someone depended on it?: If the answer is "we would not", add the metric before shipping the change.
≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
Hyrum's Law
With a sufficient number of users of an API, it does not matter what you promise in the contract: all observable behaviors of your system will be depended on by somebody.
Hyrum Wright, at Google. This is the practical definition of a breaking change. A documented contract describes what was intended. Users' code describes what was actually promised.
What gets depended on
| Behavior | How it becomes a dependency |
| Hash map iteration order | A test asserts on serialized output and passes for two years |
| Error message text | Consumer does if (err.message.includes("not found")) |
| Sort stability | UI relies on equal elements keeping insertion order |
| Timing | A call that took 5ms takes 50ms and a caller's timeout fires |
| Timing, inverted | A call gets faster and exposes a race the slowness was hiding |
| JSON key order | Consumer hashes the serialized body for a signature or cache key |
| Log line format | Someone's alerting greps it |
| ID format | Consumer parses a UUID for a timestamp, or assumes numeric ids |
| Float formatting | 0.1 versus 0.10 breaks a string comparison |
| Undefined-behavior results | An out-of-range index returned empty instead of throwing |
| Null versus missing field | Consumer distinguishes {"x": null} from {} |
| Header casing, redirect count, TLS cipher | Client hardcodes what it observed |
Rule of thumb: if a user can observe it, assume someone has written an if on it.
Primary defense: make unspecified behavior unstable
Deliberately vary behavior that was never promised, so no dependency can form. This surfaces the dependency as a fast, loud test failure instead of a slow production break years later.
Precedents:
- Go randomizes map iteration order on every run, specifically so no program can depend on it.
- Abseil randomizes its hash seed per process, so container ordering differs between runs.
- Some services inject a randomly named junk field into JSON responses, forcing consumers to tolerate unknown fields.
- Small random jitter in response latency stops consumers tuning timeouts to an observed p50.
- Randomized test execution order (
go test -shuffle=on) prevents inter-test dependencies.
Apply this to new APIs. Vary ordering, spacing, non-semantic identifiers, and optional-field presence.
For existing systems: measure first
The dependency already exists. Determine whether it does rather than reasoning about whether it should.
- Instrument the specific behavior, not the endpoint. Count reads of the field, calls hitting the deprecated path, clients sending the old header, tagged by caller identity.
- Watch for a full business cycle. Monthly billing, quarterly reports, and annual renewals surface after a release.
- Canary the change. Consumer breakage appears as their errors, so watch their error rate rather than only local metrics.
- Do not rely on a changelog note. Use metrics, then deprecation with a deadline, then removal. See
expand-contract.
Designing to retain freedom
- Return opaque types. A pagination cursor should be an opaque signed string, not base64-encoded offsets. Anything readable will be decoded and constructed by hand.
- Do not leak internals into observable output. Stack traces, internal ids, and enum numbering all become contracts.
- Supply what people are hacking around. If everyone parses the logs, ship a structured API. If everyone regexes an error message, ship a stable machine-readable
codefield. - Separate the two layers explicitly: a stable
codethat is promised, and amessageexplicitly reserved for rewording. Then reword it occasionally so the reservation stays credible. - Prefer loud failure to quiet drift. Removing a field breaks visibly. Silently changing its meaning produces wrong data.
Interaction with semver
Semantic versioning covers the documented contract. Hyrum's Law covers everything else, so a patch release can break real users.
This is not an argument against semver, but against treating a version number as a guarantee about impact rather than a claim about intent. Consequences:
- Test against major consumers, not only the local test suite.
- A behavior with enough dependents is part of the contract regardless of intent. Sometimes the correct action is to document what was accidentally promised and keep it.
- Bug-for-bug compatibility is a legitimate requirement. "It was a bug" is not by itself sufficient reason to change a mature interface.
The inverse: Chesterton's Fence
The same law running backwards. A strange conditional, a redundant check, or an uncommented sleep usually exists because something observable depended on it. Find out what before removing it:
git log -S 'the exact odd line' --oneline -- path/to/fileThe commit and its PR discussion usually answer the question in two minutes.
Two review questions
- Can a user observe this difference? If yes, it is potentially breaking regardless of the documentation.
- How would anyone know if someone depended on it? If the answer is "we would not", add the metric before shipping the change.
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

