phauthentic/cognitive-code-analysis
A PHP library for measuring cognitive complexity in source code. It parses PHP and reports complexity scores to help identify hard-to-understand methods, improve maintainability, and integrate code-quality checks into CI and static analysis.
Architecture fit
Phauthentic/cognitive-code-analysis (phpcca) is a standalone PHP CLI static-analysis tool, not a Laravel service-provider package. It has no runtime coupling to the application: no container bindings, no middleware, no request-path code. That is a good architectural fit for a Laravel/PHP estate because adoption is confined to the build/CI layer and the repo root (a phpcca.yaml plus a workflow file). It can be introduced as a dev-only Composer dependency or as a downloaded PHAR, so it does not enter the production dependency graph or the deployed artifact. The scope is narrow and advisory — cognitive-complexity scoring of methods, threshold filtering, console/Markdown reporting, plus a churn view — which makes it suitable as a quality gate or PR signal without touching application architecture.
Integration feasibility High. The 1.11.1 release substantially lowers adoption cost:
Phauthentic/cognitive-code-analysis-github-action@v1) removes the need for bespoke shell scripting, with install-mode: phar | composer, PR comments, workflow annotations, artifacts, SARIF upload, and optional threshold-failure.docs/CI-Integration.md provides end-to-end GitHub Actions and GitLab CI recipes, including the comma-separated changed-file invocation pattern (analyse "$ANALYSE_PATH"), which is the non-obvious part of any incremental-analysis setup.bin/phpcca init scaffolds config interactively or with --silent, so per-repo bootstrap is a one-liner.Config: ./phpcca.yaml, Cache: enabled) at command start removes a common class of "why is this report different locally vs CI" support tickets.Technical risk Moderate, concentrated in three areas:
config.yml → cca.yaml in 1.11.0 → phpcca.yaml in 1.11.1). Auto-discovery semantics changed with it. This is a semver smell for a patch release and will strand any repo scaffolded on 1.11.0. Mitigation is trivial (--config still wins, and the old name still works explicitly), but it must be communicated.showOnlyMethodsExceedingThreshold: true. Teams that adopt defaults will silently see a filtered report; if a threshold is mis-set, methods regress without appearing in output. This is a visibility risk rather than a correctness risk, and it is the change most likely to cause a false sense of "clean" PRs.@v1 tag, and its phar install mode downloads a binary at workflow runtime. That widens the trusted-code boundary beyond the package itself. SHA-pinning the Action and, ideally, verifying the PHAR (or using install-mode: composer with a lockfile) are the controls to ask for.Test discipline looks healthy — golden-file fixtures were updated for the new status lines, CognitiveMetricsCommandCoverageTest was decoupled from bundled defaults via an explicit test config, and RuntimeStatusRendererTest covers path formatting. That is a reasonable proxy for maintainability.
Key questions
cognitive-code-analysis-github-action repo covered by the same maintainer/release process and security posture as the core package? Is there a signed/checksummed PHAR?@v1?phpcca.yaml now considered stable, or should we expect further renames? What is the project's stated semver policy for config-surface changes?scoreThreshold?Stack fit
The tool sits alongside existing PHP quality tooling (PHPStan, Psalm, PHP-CS-Fixer, PHPUnit) rather than overlapping it — complexity scoring is orthogonal to type analysis and style. For a Laravel estate it maps cleanly onto three adoption tiers: local pre-push convenience (bin/phpcca analyse src/), PR advisory comment, and CI gate. It requires only a PHP runtime, so it works identically across monorepos, package repos, and Laravel applications, and the SARIF path lets results land in GitHub code scanning alongside existing static analysis.
Migration path There is no data or schema migration. The only migration surface is configuration:
cca.yaml (from 1.11.0) or config.yml, rename to phpcca.yaml, or retain the filename and pass --config explicitly — the latter is the lower-risk option for any repo currently in flight.bin/phpcca init only for repos with no existing config, to avoid clobbering tuned thresholds.showOnlyMethodsExceedingThreshold per repo. Recommendation: set it to false for the first two sprints to establish a baseline of all methods, then flip to true once scoreThreshold is calibrated.Compatibility
No breaking CLI changes: all commands, report types, and --config behaviour are preserved. Auto-discovery is additive (loads ./phpcca.yaml only when present and no --config is given), so unattended pipelines with explicit configs are unaffected. The one silent behaviour change is the default output filter in the bundled config, which does not affect repos that ship their own config. Composer and PHAR install modes are both supported; note the Action repo is versioned independently (@v1) of the package (1.11.1), so the two must be tracked as separate version axes.
Sequencing
phpcca analyse src/ locally against 2–3 representative repos (newest and most legacy). Use --report-type=markdown to read results in a familiar format. Capture the score distribution; do not set a threshold yet.scoreThreshold from the observed distribution (target: flags the worst decile, near-zero false positives). Enable churn to see whether hotspots cluster where incidents actually occur — this is the argument that sells the tool to engineering leadership.post-comment: true, emit-annotations: true, no threshold failure. Pin the Action to a SHA. Validate that changed-file-only analysis actually runs (this depends on fetch-depth: 0).upload-artifact: true and SARIF upload if code scanning is already in use.Maintenance
Low steady-state cost. The tool is dev-only, so it cannot page anyone and cannot break production. Ongoing work is (a) bumping the package and the Action, (b) occasionally re-tuning scoreThreshold as the codebase improves, and (c) pruning the config as modules are added or retired. The config file is small and YAML-based, so review burden is minutes, not hours. Watch the config-surface churn — budget one small PR per minor release for filename/discovery changes until the maintainer signals stability.
Support
Support load is front-loaded. The main anticipated tickets are "the report differs locally vs CI" (now largely self-diagnosing via the Config:/Cache: lines — a genuinely useful addition) and "my method disappeared from the report" (caused by the new default showOnlyMethodsExceedingThreshold: true; document this explicitly in the internal runbook). The new docs/CI-Integration.md and docs/Configuration.md are good enough to shift first-line support to the docs rather than to the platform team. Assign a named owner for threshold policy — an unowned threshold drifts into either noise or irrelevance.
Scaling Scales well on the dimensions that matter: analysis is per-changed-file in CI, so cost grows with PR size, not repo size; caching is supported and now visible at runtime; and the tool runs on the CI runner without added infrastructure. Two scaling caveats. First, on very large PRs, comma-separated changed-file lists can hit command-line length limits — batch by directory if that materialises. Second, the PR-comment mode writes to every matching PR, so on high-velocity monorepos expect comment volume; consider annotations-only for repos with >50 PRs/week rather than PR comments.
Failure modes
showOnlyMethodsExceedingThreshold: false) and a documented threshold rationale../phpcca.yaml in the working directory; running from a subdirectory or a container with a different working dir silently falls back to bundled defaults. The new runtime Config: line is the primary detection mechanism — make "check the config line in the CI log" step one of the runbook.@v1 tag from a separate repo in the PR path of every repository. If that tag is moved or the repo compromised, every consumer's workflow executes it. Pin to SHA.install-mode: phar fetches a binary per run; registry/network hiccups become red builds. install-mode: composer with a committed lockfile trades speed for determinism.Ramp-up
Very short. An engineer familiar with CI YAML can go from zero to an advisory PR check in under an hour using the documented workflow, and init removes config authoring entirely. Budget half a day for the evaluating engineer to calibrate a threshold and write a three-paragraph internal runbook (what the score means, what the threshold is and why, what to do when the check fails). The cognitive-complexity concept itself needs a short explainer for reviewers — a score failing a check is only actionable if the reader knows what to refactor. Total: roughly one engineer-day to production-advisory, plus two sprints of observation before gating.
How can I help you explore Laravel packages today?