strategy-preserve-public-api
Skill4 starsChanged 4 months agoMITView on GitHub
Do not break public or exported signatures that other code depends on; add rather than change, deprecate before removing, and keep backward compatibility so existing callers keep working. Use when the task edits a public class, function, or interface that other modules, packages, or external consumers call; the task changes a library, SDK, or package whose interface is published and versioned for outside consumers; the task wants to remove, rename, or change the parameters of an existing public method, constant, or return type. Keywords: strategy, public-api, backward-compatibility, bc, signature, deprecate, exported, contract, semver, callers.
In this repository119 other files it gives its agents.
- strategy-bitrix-d7-incrementalSkill
- strategy-explicit-over-magicSkill
- strategy-framework-conventionsSkill
- strategy-legacy-safe-editsSkill
- strategy-minimal-diffSkill
- strategy-no-untested-refactorSkill
- strategy-readonly-immutabilitySkill
- strategy-security-firstSkill
- strategy-test-drivenSkill
- openapiSkill
- paginationSkill
- rest-designSkill
- versioningSkill
- cqrsSkill
- dependency-inversionSkill
- hexagonalSkill
- repository-patternSkill
- service-layerSkill
- bitrixSkill
- findings-reportSkill
- laravelSkill
- performanceSkill
- phpSkill
- project-analysisSkill
- refactoringSkill
- roi-prioritizationSkill
- securitySkill
- stack-detectionSkill
- cache-layersSkill
- component-engineSkill
- d7-eventsSkill
- d7-loaderSkill
- d7-orm-queriesSkill
- iblock-elementsSkill
- kernel-main-moduleSkill
- localizationSkill
- controllersSkill
- ormSkill
- validationSkill
- controllersSkill
- query-builderSkill
- routingSkill
- autoload-psr4Skill
- dependency-managementSkill
- scriptsSkill
- connection-poolingSkill
- mysql-indexingSkill
- redisSkill
- transactionsSkill
- ci-github-actionsSkill
- deployment-strategiesSkill
- docker-phpSkill
- env-configSkill
- associationsSkill
- entities-mappingSkill
- orm-basicsSkill
- entity-apiSkill
- module-developmentSkill
- routing-controllersSkill
- formsSkill
- The first 60 shown.
The file
We split this skill into the rules it gives an agent
6 rules. About 0 are common, 6 are distinctive, and 0 are very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈6
Distinctive · estimate
This author's own choices. Worth a look.
0
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Distinctive: line 66
Do not block a breaking change the user has explicitly approved as part of a planned major-version release with a migration guide.
- Distinctive: line 68
Do not impose backward-compatibility ceremony on private or internal-only code that has no external consumers and is free to change.
- Distinctive: line 86
Never change or remove a public or exported method signature, constant, or return type that outside code depends on without a deliberate, …
- Distinctive: line 91
Prefer adding new methods, optional parameters with defaults, or new overloads over changing existing ones, so current callers keep working …
- Distinctive: line 96
Avoid deleting or renaming a public member outright.
- Distinctive: line 143
Not applicable — no I/O, auth, or untrusted input.
≈ “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
<!-- generated: do not edit — source: knowledge/atoms/ai-rules/strategy-preserve-public-api/ --><!-- schema: atomVersion=3 skillVersion=2 graphVersion=1 --><!-- compile: @php-skills/compiler v1.0.0 (deterministic build) -->Strategy — Preserve Public API
When to use
- The task edits a public class, function, or interface that other modules, packages, or external consumers call.
- The task changes a library, SDK, or package whose interface is published and versioned for outside consumers.
- The task wants to remove, rename, or change the parameters of an existing public method, constant, or return type.
When NOT to use
- Do not block a breaking change the user has explicitly approved as part of a planned major-version release with a migration guide.
- Do not impose backward-compatibility ceremony on private or internal-only code that has no external consumers and is free to change.
Core guidance
- Add new parameters as optional with defaults — When a public method needs more inputs, add them as trailing optional parameters with sensible defaults rather than changing the existing parameter list.
- Search for callers before touching a public member — Before changing a public member, search the codebase and known consumers for its callers so you understand the blast radius of any change.
- Deprecate before removing anything public — Mark a public member as deprecated with a clear replacement and keep it working for at least one release cycle before removing it in a later major version.
- Keep a compatibility shim when reshaping internals — When you reshape the implementation behind a public member, keep the old signature as a thin shim that delegates to the new code.
- Preserve observable behavior, not just the signature — Keep not only the signature but also the observable behavior — return shapes, thrown exceptions, and null handling — that callers already rely on.
Never
- Never change or remove a public or exported method signature, constant, or return type that outside code depends on without a deliberate, versioned break.
Prefer
- Prefer adding new methods, optional parameters with defaults, or new overloads over changing existing ones, so current callers keep working unchanged.
Avoid
- Avoid deleting or renaming a public member outright; deprecate it first, keep it working for a transition period, and document the replacement.
Escalate to user when
- Escalate to the user when a correct fix truly requires breaking a public signature, so the break can be planned, versioned, and communicated to callers.
Quick recipe
- Determine which members are part of the public contract, then search the codebase and known consumers to map who depends on them. (verify: You know exactly which members are public and have a list of their callers or consuming packages.)
- Implement the change additively — new method, optional parameter, or delegating shim — and deprecate anything to be removed rather than deleting it now. (verify: Every existing caller still compiles and behaves the same, and any member slated for removal is deprecated with a documented replacement rather than deleted.)
Anti-patterns
| Anti-pattern | Why it fails | Do instead |
| Deleting a public member with no deprecation cycle | Consumers who upgrade within the same major version expect no breaks; a silent<br>removal violates that contract and strands their code. | Deprecate the member with a replacement, keep it functional across the current<br>major version, and remove it only in the next major with release notes. |
| Renaming a public method in place | Every caller of the old name breaks immediately, turning a cosmetic rename into a<br>widespread outage. | Add the new name as an alias that delegates to the old one, deprecate the old<br>name, and remove it only in a future major version. |
| Adding a required parameter to a public method | Every existing call becomes an error for missing an argument, breaking all callers<br>at once. | Add the parameter as optional with a safe default, or provide an overload, so<br>existing calls remain valid. |
See references/anti-patterns.md.
Common mistakes
- Narrowing a return type or throwing new exceptions — Narrowing a return type, returning null where a value was guaranteed, or throwing a new exception type breaks callers even with an unchanged signature. Fix: Keep the return shape and error behavior callers rely on, and introduce any new behavior through a separate method or an opt-in flag.
- Reordering parameters silently breaks callers — Reordering existing parameters keeps the arity the same, so positional calls still compile but now pass values into the wrong slots. Fix: Leave existing parameters in place and add new ones at the end as optional, or introduce a new method rather than reordering.
- Tightening a parameter type rejects valid callers — Making a public parameter type stricter — from a broad type to a narrow one — rejects arguments that were previously accepted. Fix: Keep the accepted input type at least as wide as before, and validate the narrower requirement inside the method instead of in the signature.
Version notes
- API-preservation discipline is version-agnostic (PHP >=7.4) — Preserving public signatures and deprecating before removing is a strategy that applies to any PHP version; it constrains how the agent evolves a contract, not which language features it uses, so it holds from PHP 7.4 upward.
Security
- Not applicable — no I/O, auth, or untrusted input.
Testing
- Activation and decision behavior are verified in
eval/scenarios/ai-rules/strategy-preserve-public-api.yaml.
Additional resources
- references/anti-patterns.md
- references/examples.md
- references/pitfalls.md
- references/recipes.md
- references/version-differences.md
Knowledge graph
Related: ai-rules/strategy-legacy-safe-edits, ai-rules/strategy-minimal-diff
<!-- graph-fragment: graph/fragments/ai-rules/strategy-preserve-public-api.yaml -->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.

