Skip to content
PROCTOR Form 0.5.0
Menu

Checks#

This page lists every check PROCTOR runs in a single vendor/bin/proctor check run, and how each one reports. The proctor asks the same questions in the same order on every run; only the hall changes.

Nine real lines from PROCTOR's text report, one per check shown: FAIL php-floor, WARN unpatched, FAIL unbounded-constraints, PASS lock-committed, WARN portability, WARN mysql56, WARN ci-pipelines, PASS composer-audit, FAIL overrides. Each line is written in words; color only repeats what the word says.

Nine of the seventeen checks shown, asked in this order on every run; policy-age stays silent while the policy is fresh. The lines are real output from the test fixtures.

How a check reports#

Every finding carries one of four statuses: pass, warning, info or fail. A fail is a resit; a warning is a note in the margin that never changes the exit code; an info is the proctor thinking out loud, such as a missing composer or a lookup that could not run.

Every finding also carries a stable, namespaced rule id: proctor/<check-id> for a check's default finding, proctor/<check-id>/<rule> for a named rule. The id is the finding's identity in the machine formats: rule_id in json, ruleId in sarif, and check_name in codequality. A rule keeps the same id across runs and across formats even when its message changes. The full table lives on the Rule ids page.

Composer#

The six checks that read composer.json and composer.lock. Details and fixes: Composer checks.

  • unbounded-constraints: fails for every runtime constraint that is *, names a dev- branch, carries @dev, has a lower bound with no upper bound, or matches the policy's banned_constraints; warns on path and vcs repositories, on a minimum-stability below stable, and on a repository URL that is plain http. require-dev, php, ext-* and lib-* are not checked.
  • composer-config: warns when composer.json opens a door Composer closes by default: allow-plugins set to true, secure-http set to false, lock set to false, audit.block-insecure set to false, config.policy set to false, policy.malware set to false or policy.advisories set to false; notes when require.php is set without config.platform.php. Warning and info only, never a fail.
  • lock-committed: fails when composer.lock is missing from the app path. When the lock is present and its content-hash is a real 32-hex hash, it warns (proctor/lock-committed/out-of-sync) when the hash no longer matches composer.json, so a stale lock that still installs is visible instead of silent; the warning never changes the exit code.
  • composer-audit: fails for advisories at or above the policy's audit_severity_threshold, warns for lower ones, and reports info when composer or the lock file is absent. Fails (proctor/composer-audit/could-not-run) when the audit runs but its stdout is not parseable JSON, because a green run that audited nothing is worse than a red one.
  • composer-version: fails when the Composer on PATH is Composer 1 (end of life) or carries the command-injection holes CVE-2024-35241 and CVE-2024-35242 (2.2.x below 2.2.24, or any other 2.x below 2.7.7); warns when composer cannot be run.
  • repo-url-credentials: warns when a credential is written into a package source URL: a deploy token in the userinfo of a composer.json repository URL or a composer.lock source/dist URL, a bare token user of 20+ characters, a private_token, access_token, token or password query parameter, or a .npmrc line that sets _authToken, _auth or _password to a literal value. The secret is masked as *** in the message, so the report itself is safe to hand back.

PHP and database#

The checks that grade the PHP floor, patch currency, MySQL 5.6 compatibility and the age of the policy in use. Details and fixes: PHP checks.

  • php-floor: fails when the lowest PHP version allowed by require.php is past security support plus the grace window, when composer.json has no usable php constraint, or when there is no composer.json at all.
  • unpatched: warns when a locked component is behind the policy's latest_patch for its version line, and passes when it is current. Reads laravel from composer.lock (laravel/framework), vue and inertia from package-lock.json (vue, @inertiajs/vue3), and the PHP runtime from --php-runtime. No finding when the component, its version line, or latest_patch is absent from the policy.
  • mysql56: warns when migrations or app code use MySQL features the shared 5.6 server rejects: JSON columns (in database/) and JSON queries, generated columns, renameColumn/renameIndex, vector, invisible and spatial columns, Schema::hasColumn-style introspection, raw SQL with 5.7+ syntax, the upsert row alias, indexed strings over 191 characters, date columns defaulting to the current time, and the db:show/db:monitor commands. Warnings, not failures: an app on its own newer database is not affected.
  • policy-age: warns when the policy in use is more than 60 days old (its refreshed_on date is more than 60 days before --today), or when a non-bundled policy has no refreshed_on date. Warning only: an old policy never fails a run.

The portability and destructive-deploy checks also read PHP and deploy scripts; they are covered on the CI checks page.

CI and deploy#

Details and fixes: CI checks.

  • ci-pipelines: for stack packages (composer.json name starting with waynestate/), fails when .gitlab-ci.yml or .github/workflows/ci.yml is missing or runs no composer ci; for any other project, a missing or incomplete .gitlab-ci.yml is a warning and .github/workflows/ci.yml is optional. Warns when a GitHub uses: ref is not a 40-hex commit SHA, and when the pipeline environment switches Composer's audit or blocking policy off.
  • preflight-pinned: warns, never fails, when an app includes a Preflight component at a moving ref or re-declares what an included Preflight job runs.
  • portability: warns when code hard-codes a platform fact: an absolute host path, a hard-coded proxy address, a local-disk session store, or a php_value/php_flag line in .htaccess.
  • destructive-deploy: fails when a deploy script runs an artisan command that drops or rebuilds the database (migrate:fresh, migrate:refresh, migrate:reset, db:wipe), which erases production data on every deploy.
  • instant-client-committed: warns when Oracle Instant Client is committed to the repo: an archive, an unzipped install under an instantclient directory, or a loose client library.

WayneUI#

Details and fixes: WayneUI checks.

  • wayneui-forked-views: warns when forked copies of WayneUI are committed under resources/views/vendor/wayne-ui/ or public/vendor/wayne-ui/; those copies silently override the package, so an app keeps old layouts after a WayneUI upgrade and nobody sees it.
  • wayneui-outdated: warns when the WayneUI an app carries is behind the latest release of the same major; by default a warning, not a failure, and an offline run never breaks.

Overrides#

  • overrides: fails for every expired entry in policy-overrides.json; warns for an active entry that expires within 14 days of --today and for an active entry that matches no failure. How the file works: Overrides.