acc-create-psalm-config
SKILL.md
Psalm Configuration Generator
Generates optimized Psalm configurations for PHP 8.4+ projects.
Generated Files
psalm.xml # Main configuration
psalm-baseline.xml # Error baseline (if needed)
Configuration by Project Type
New Project (Level 1-2)
<?xml version="1.0"?>
<psalm
errorLevel="2"
resolveFromConfigFile="true"
findUnusedBaselineEntry="true"
findUnusedCode="true"
findUnusedVariablesAndParams="true"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="https://getpsalm.org/schema/config"
xsi:schemaLocation="https://getpsalm.org/schema/config vendor/vimeo/psalm/config.xsd"
>
<projectFiles>
<directory name="src"/>
<ignoreFiles>
<directory name="vendor"/>
</ignoreFiles>
</projectFiles>
<plugins>
<pluginClass class="Psalm\PhpUnitPlugin\Plugin"/>
</plugins>
</psalm>
Existing Project with Baseline
<?xml version="1.0"?>
<psalm
errorLevel="4"
resolveFromConfigFile="true"
errorBaseline="psalm-baseline.xml"
findUnusedBaselineEntry="true"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="https://getpsalm.org/schema/config"
xsi:schemaLocation="https://getpsalm.org/schema/config vendor/vimeo/psalm/config.xsd"
>
<projectFiles>
<directory name="src"/>
<ignoreFiles>
<directory name="vendor"/>
<directory name="src/Legacy"/>
</ignoreFiles>
</projectFiles>
<issueHandlers>
<!-- Gradually enable -->
<MixedAssignment errorLevel="suppress"/>
<MixedMethodCall errorLevel="suppress"/>
<MixedArgument errorLevel="suppress"/>
</issueHandlers>
</psalm>
DDD Project Configuration
<?xml version="1.0"?>
<psalm
errorLevel="1"
resolveFromConfigFile="true"
findUnusedBaselineEntry="true"
findUnusedCode="true"
findUnusedVariablesAndParams="true"
strictBinaryOperands="true"
phpVersion="8.4"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="https://getpsalm.org/schema/config"
xsi:schemaLocation="https://getpsalm.org/schema/config vendor/vimeo/psalm/config.xsd"
>
<projectFiles>
<directory name="src"/>
<ignoreFiles>
<directory name="vendor"/>
<directory name="src/Infrastructure/Migrations"/>
</ignoreFiles>
</projectFiles>
<!-- Domain layer - strictest -->
<projectFiles>
<directory name="src/Domain">
<errorLevel type="error">
<MixedAssignment/>
<MixedMethodCall/>
<MixedArgument/>
</errorLevel>
</directory>
</projectFiles>
<plugins>
<pluginClass class="Psalm\PhpUnitPlugin\Plugin"/>
<pluginClass class="Weirdan\DoctrinePsalmPlugin\Plugin"/>
<pluginClass class="Psalm\SymfonyPsalmPlugin\Plugin"/>
</plugins>
<issueHandlers>
<!-- Doctrine entities -->
<PropertyNotSetInConstructor>
<errorLevel type="suppress">
<directory name="src/Infrastructure/Doctrine/Entity"/>
</errorLevel>
</PropertyNotSetInConstructor>
<!-- Value Objects immutability -->
<ImmutablePropertyAssignment>
<errorLevel type="error">
<directory name="src/Domain"/>
</errorLevel>
</ImmutablePropertyAssignment>
<!-- Allow missing return types in interfaces (for contravariance) -->
<MissingReturnType>
<errorLevel type="suppress">
<directory name="src/Domain/Repository"/>
</errorLevel>
</MissingReturnType>
</issueHandlers>
<!-- Stubs for external libraries -->
<stubs>
<file name="stubs/Doctrine.phpstub"/>
</stubs>
</psalm>
Plugin Configuration
PHPUnit Plugin
<plugins>
<pluginClass class="Psalm\PhpUnitPlugin\Plugin"/>
</plugins>
Doctrine Plugin
<plugins>
<pluginClass class="Weirdan\DoctrinePsalmPlugin\Plugin">
<enableObjectManagerGenerator value="true"/>
</pluginClass>
</plugins>
Symfony Plugin
<plugins>
<pluginClass class="Psalm\SymfonyPsalmPlugin\Plugin">
<containerXml>var/cache/dev/App_KernelDevDebugContainer.xml</containerXml>
</pluginClass>
</plugins>
Laravel Plugin
<plugins>
<pluginClass class="Psalm\LaravelPlugin\Plugin"/>
</plugins>
Issue Handlers
Common Suppressions
<issueHandlers>
<!-- Allow mixed in legacy code -->
<MixedAssignment>
<errorLevel type="suppress">
<directory name="src/Legacy"/>
</errorLevel>
</MixedAssignment>
<!-- Allow property initialization in setUp() -->
<PropertyNotSetInConstructor>
<errorLevel type="suppress">
<directory name="tests"/>
</errorLevel>
</PropertyNotSetInConstructor>
<!-- Suppress for mocks -->
<UndefinedMagicMethod>
<errorLevel type="suppress">
<directory name="tests"/>
</errorLevel>
</UndefinedMagicMethod>
<!-- Allow unused parameters in event handlers -->
<UnusedParam>
<errorLevel type="suppress">
<file name="src/Application/EventHandler/*.php"/>
</errorLevel>
</UnusedParam>
<!-- Suppress deprecated in migrations -->
<DeprecatedMethod>
<errorLevel type="suppress">
<directory name="src/Infrastructure/Migrations"/>
</errorLevel>
</DeprecatedMethod>
</issueHandlers>
Strict Mode for Domain
<issueHandlers>
<!-- Enforce strict types in Domain -->
<MixedAssignment>
<errorLevel type="error">
<directory name="src/Domain"/>
</errorLevel>
<errorLevel type="suppress">
<directory name="src/Infrastructure"/>
</errorLevel>
</MixedAssignment>
<!-- Enforce immutability -->
<ImmutablePropertyAssignment>
<errorLevel type="error">
<directory name="src/Domain/ValueObject"/>
</errorLevel>
</ImmutablePropertyAssignment>
</issueHandlers>
Taint Analysis Configuration
<?xml version="1.0"?>
<psalm
errorLevel="2"
runTaintAnalysis="true"
>
<!-- Taint sources -->
<taintAnalysis>
<taintSource name="$_GET"/>
<taintSource name="$_POST"/>
<taintSource name="$_REQUEST"/>
<taintSource name="$_COOKIE"/>
<!-- Custom sources -->
<taintSource name="Request::input"/>
<taintSource name="Request::query"/>
</taintAnalysis>
<!-- Taint sinks -->
<issueHandlers>
<TaintedSql errorLevel="error"/>
<TaintedHtml errorLevel="error"/>
<TaintedShell errorLevel="error"/>
<TaintedFile errorLevel="error"/>
<TaintedHeader errorLevel="error"/>
<TaintedSSRF errorLevel="error"/>
</issueHandlers>
</psalm>
Baseline Management
Generate Baseline
# Generate baseline for all errors
vendor/bin/psalm --set-baseline=psalm-baseline.xml
# Update baseline (remove fixed issues)
vendor/bin/psalm --update-baseline
# Analyze with baseline
vendor/bin/psalm
Baseline Format
<?xml version="1.0" encoding="UTF-8"?>
<files psalm-version="5.x">
<file src="src/SomeClass.php">
<MixedAssignment>
<code>$variable</code>
</MixedAssignment>
</file>
</files>
Level Migration Guide
Error Levels
| Level | Description | Use Case |
|---|---|---|
| 1 | Strictest | New projects, Domain layer |
| 2 | Very strict | Clean codebases |
| 3 | Strict | Recommended default |
| 4 | Relaxed | Mixed codebases |
| 5-7 | Permissive | Legacy code |
| 8 | Very permissive | Initial analysis only |
Migration Steps
<!-- Step 1: Start with baseline -->
<psalm errorLevel="8" errorBaseline="psalm-baseline.xml">
<!-- Step 2: Decrease level, update baseline -->
<psalm errorLevel="7" errorBaseline="psalm-baseline.xml">
<!-- Step 3: Continue until target level -->
<psalm errorLevel="3">
CI Configuration
GitHub Actions
psalm:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: shivammathur/setup-php@v2
with:
php-version: '8.4'
- run: composer install
- run: vendor/bin/psalm --output-format=github
GitLab CI
psalm:
script:
- vendor/bin/psalm --output-format=checkstyle > psalm-report.xml
artifacts:
paths:
- psalm-report.xml
Security Scan
psalm-taint:
script:
- vendor/bin/psalm --taint-analysis
allow_failure: true
Generation Instructions
-
Analyze project:
- Check
composer.jsonfor Psalm version - Check existing
psalm.xml - Identify framework
- Count existing errors
- Check
-
Determine level:
- New project: Level 1-2
- Existing clean: Level 3
- Legacy: Level 5+ with baseline
-
Add plugins:
- PHPUnit always
- Doctrine if ORM
- Symfony/Laravel if framework
-
Configure issue handlers:
- Strict for Domain
- Relaxed for Infrastructure/Legacy
Usage
Provide:
- Project type (new/existing/legacy)
- Framework (Symfony, Laravel, none)
- Target level (optional)
- Taint analysis (yes/no)
The generator will:
- Create appropriate configuration
- Add relevant plugins
- Configure issue handlers
- Set up baseline if needed
- Include taint analysis if requested
Weekly Installs
1
Repository
dykyi-roman/awe…ude-codeGitHub Stars
39
First Seen
Feb 11, 2026
Security Audits
Installed on
opencode1
claude-code1