Add a tree-sitter–backed structural scanner for PHP so Laravel / Symfony codebases get first-class detection coverage. Today PHP runs through --deep only — fine as a stopgap, but it costs tokens for patterns the structural pass should catch deterministically.
Scope
- Wire up the
tree-sitter-php grammar in src/scanner/
- Add
rules/php/*.toml covering the core idioms below
- Add fixtures + tests under the existing scanner test harness
- Update
docs/corpus/ with a PHP entry (calibration repos + expected findings)
Framework coverage
| Source |
Pattern |
| Laravel Gates |
Gate::allows('update-post', $post), Gate::denies(...), Gate::define(...) |
| Laravel Policies |
$this->authorize('update', $post), policy classes (*Policy with update/view/etc. methods) |
| Laravel middleware |
Route::middleware('auth'), ->middleware(['auth', 'can:update,post']) |
| Symfony Voters |
classes extending Voter, $this->isGranted('ROLE_ADMIN', $subject), @IsGranted / #[IsGranted] attributes |
| Idiomatic conditionals |
if ($user->role === 'admin'), in_array('manager', $user->roles), $user->hasRole(...) |
Per-engine templates
Each new rule should ship both rego_template and (where shape-appropriate) cedar_template, matching the convention established in the existing rulesets.
Acceptance criteria
Out of scope
- WordPress capability checks (
current_user_can) — separate ticket if there's demand
- CodeIgniter / Yii / CakePHP framework patterns — separate tickets if there's demand
Add a tree-sitter–backed structural scanner for PHP so Laravel / Symfony codebases get first-class detection coverage. Today PHP runs through
--deeponly — fine as a stopgap, but it costs tokens for patterns the structural pass should catch deterministically.Scope
tree-sitter-phpgrammar insrc/scanner/rules/php/*.tomlcovering the core idioms belowdocs/corpus/with a PHP entry (calibration repos + expected findings)Framework coverage
Gate::allows('update-post', $post),Gate::denies(...),Gate::define(...)$this->authorize('update', $post), policy classes (*Policywithupdate/view/etc. methods)Route::middleware('auth'),->middleware(['auth', 'can:update,post'])Voter,$this->isGranted('ROLE_ADMIN', $subject),@IsGranted/#[IsGranted]attributesif ($user->role === 'admin'),in_array('manager', $user->roles),$user->hasRole(...)Per-engine templates
Each new rule should ship both
rego_templateand (where shape-appropriate)cedar_template, matching the convention established in the existing rulesets.Acceptance criteria
tree-sitter-phpintegrated;cargo test --all-featurespasses on PHP fixturesisGrantedruledocs/corpus/php.mdOut of scope
current_user_can) — separate ticket if there's demand