Before adding an instruction ANYWHERE (AGENTS.mds, rules, agents, skills, hooks, configs): prefer the NATIVE mechanism (frontmatter field, config key, existing rule, a router to the single source) over new prose, and prefer DELETING prose over adding it. Every added instruction is a contradiction-and-drift surface; condensed copies of another artifact's content drift silently. Success metric: the diff shrinks or holds while capability grows. Consistency beats token thrift.
Before doing anything read this file to ensure you are up to date with it.
- Install:
make install. - Require a new package:
make composer-require "PACKAGENAME"ormake composer-require "PACKAGENAME --dev".
- Do now use
cdfor everything, you're already in the root! - Check
make helpfor all available commands. - Check
make help-contribfor all available contrib commands. - Need something custom that is not in the list? Use
make run "YOUR COMMAND HERE"to run a command in the container and run whatever you require there. - If a package needs custom
makecommands, put them inetc/Makefile, then runmake installto make them available through the rootMakefile. - Always split tasks up in small chunks and feed those to sub agents, then collect what comes out of that, make logical groups for the next set of tasks to be split over subagents.
- After each logical block of changes made ensure
make contribpasses. - Before you return to the uses run
maketo ensure all QA checks pass. - Use
make unit-testing-filter TESTCLASSNAME_OR_TESTMETHODNAMEto run a specific test. - Always add unit tests for new code.
- If
composer.lockis out of sync withcomposer.json, runmake update.
- Keep things simple, once done implementing a feature, iterate on improving it. Less code is more.
- Make sure the code is readable and easy to understand.
- Prefer a logical block of code to be within one screen size over splitting it up in multiple smaller functions.
- Make a class static if it doesn't hold state.
- Put classes in logical folders.
- Once done writing code iterate of it to make sure it's easy to understand and maintain, that it's easy to test, and that it doesn't duplicate code.
- Search existing code for examples of how to do things.
- Search existing code for classes/methods you can use instead of writing your own.
- Always link every reference that has a URL (
[label](url)); never bare backticks or plain text alone - Composer packages → GitHub repo (resolve via Packagist); docs and specs → canonical URL
- Test the happy flows (PHPUnit)
- Test the unhappy flows (PHPUnit)
- Test the edge cases (PHPUnit)
- Test the fuzzy cases (PHPUnit)
- 100% coverage is required (PHPUnit)
- 100% MSI is required (mutation testing (InfectionPHP))
- 100% type coverage is required (PHPStan)
- Use dataproviders wherever possible (PHPUnit)
- Prefer creating subs and spies over mocks
- Look at
wyrihaximus/test-utilitiesandwyrihaximus/async-test-utilitiesfor some useful helpers - When tests are known to take longer than 10 seconds, when possible use
make unit-testing-filter TESTCLASSNAME_OR_TESTMETHODNAMEto run them in parallel across subagents
- Consistency is the key.
- Always add regressions to the test suite when fixing bugs or when the user tells you whatever you wrote is still broken.
- If several parts of the code rely on the same behavior (and data), centralize it in a single place.
- Always run
makebefore you're returning control to the user. - Always apply the boyscout rule: Leave the code better than you found it. But do not touch anything else than what you're touching.
- Always reload this file before you start processing a new request.
- Always show the plan. / When calling
CreatePlanalways show the plan. - When ever you're done, before returning to the user always done 1 to 3 passes of reducing the amount of code you wrote while keeping it readable and maintainable.
- Shutdown works by removing everything that uses the event loop; never call
Loop::stop()anywhere. - Always extend PHPUnit test classes from
WyriHaximus\AsyncTestUtilities\AsyncTestCaseorWyriHaximus\TestUtilities\TestCase.
wyrihaximus/psr-3-context-logger: PSR-3 decorator; merge default context (optional[Prefix]) into every log callwyrihaximus/psr-3-filter: PSR-3 filter decorators; pass or drop logs by context path, level, message keyword, or strip nested[Prefix]chains (pairs with context-logger)wyrihaximus/psr-3-callable-throwable-logger:CallableThrowableLogger::create()for react/promise rejection handlers and RxPHP error callbackswyrihaximus/monolog-processors: Monolog record processors (CopyProcessor,ExceptionClassProcessor,TraceProcessor,RuntimeProcessor, …)
- Never call, attempt or even consider to use
sudo - Never call, attempt or even consider to use
su - Never call, attempt or even consider to use
sudo su - Never call, attempt or even consider to use
cd - Never call, attempt or even consider to use
docker - Never call, attempt or even consider to use
git commit - Never call, attempt or even consider to use
git push - Any command not in the allowed commands list
- Never, ever, ever use
—in documentation!!!!!
- Create dead/unused methods/classes/functions/code
- Using the
assertfunction - Assigning a property to a variable without assigning a new value to it
- Never update
MakefileorAGENTS.mdoutsidewyrihaximus/makefiles; suggest changes to that repository instead