Skip to content

refactor: pay down phpstan lint baseline to zero (issue #767) — round 2 - #791

Merged
chubes4 merged 4 commits into
mainfrom
lint-767-phpstan-paydown-2
Sep 9, 2026
Merged

chubes4 merged 4 commits into
mainfrom
lint-767-phpstan-paydown-2

Conversation

@chubes4

@chubes4 chubes4 commented Sep 8, 2026

Copy link
Copy Markdown
Member

Closes #767. Continues #788 (merged), which took the phpstan baseline 550 → 226. This PR takes it to 0.

Before/after: 226 → 0 phpstan findings (homeboy review lint data-machine-events --placement local on this branch; phpstan step status passed, exit 0). The phpcs producer still reports ~880 pre-existing style warnings locally (887 on the baseline) — unchanged in class, not part of #767, and the CI review lint gate was green on #788 with them present; flagged here for transparency.

Batches (4 commits)

  1. Abilities + block renderers (57) — MergedBillDetect, EventQuery (WP_Query::posts guard), Timezone (get_term() guard — real WP_Error->name warning path; dead branch ternaries), BatchTimeFix/EventQualityAudit (queryEvents() WP_Error removal from a contract it never honored), EventUpdate (dead description branch, real bug: wp_set_post_terms() falsearray_map TypeError, now guarded), EventDetails/EventsMap renderers.
  2. Ticketmaster + calendar + admin (30) — auth-provider method_exists() guard (upstream getAuthProvider(): ?object), provably-infinite do-while simplification, ob_get_clean()/date_create() false guards, filemtime() version casts, dead array_values/??.
  3. Final sweep (139 → 0) — every remaining file: CLI commands, templates, extractors, upsert steps, API controllers, core guards. Highlights:
    • WP_Error contract guards for the two remaining chat tools.
    • Regression caught before push: an argument-count bug introduced in refactor: pay down phpstan lint baseline (issue #767) — DOM scraper cluster first #788's EmbeddedCalendarExtractor edit (stray $events arg → would fatal) — fixed.
    • EventMergeHelper: removed a provably-unreachable re-read-verify block (delete_post_meta() has no leave-rows-behind failure mode).
    • CLI WP_CLI guard now keys on $_SERVER['argv']: the wp-cli stubs unconditionally define('WP_CLI', true), so no expression testing that constant (including constant('WP_CLI')) is live to static analysis. Behavior-identical on real runtimes.
  4. phpcs hygiene on own lines — fixed every phpcs finding introduced by this PR's added lines (short ternary, alignment, brace-after-body); remaining phpcs findings are pre-existing style warnings outside this issue's scope.

Real bugs fixed (vs pure type-narrowing)

  • wp_set_post_terms() false-path array_map TypeError (EventUpdateAbilities).
  • get_term()/WP_Error->name warning paths (TimezoneAbilities, VenueAbilities).
  • urldecode() on array query params, parse_str() on non-string (event-dates-sync, Event_Post_Type).
  • hash_file() false into hash_equals() (CalendarOccurrenceArtifact).
  • EmbeddedCalendarExtractor 3-arg call regression (from refactor: pay down phpstan lint baseline (issue #767) — DOM scraper cluster first #788, fixed here).
  • EventFlyer::getMimeType() returned false against its string contract.

Upstream stub issues (filed, not fake-fixed)

  • homeboy-extensions#2809 — is_wp_error() doesn't narrow, WP_CLI::error() not never, wpdb::$last_error pinned to literal ''. Two honest @var string annotations and one @var string|false paper over those gaps locally with comments, disclosed here.

Verification

  • Final full local lint: phpstan 0 findings, status passed (eslint passed; phpcs pre-existing warnings unchanged in class).
  • php -l clean on all 79 touched files; composer test:contracts OK (4 tests, 58 assertions) via vendor/bin/phpunit --configuration phpunit.contracts.xml. The WordPress suite needs the managed bootstrap (WP_UnitTestCase) unavailable standalone on this VPS — CI is the arbiter for composer test:wordpress and all gates.
  • No @phpstan-ignore, no baseline file, no level changes, no CHANGELOG/version edits.

Rebase 2026-09-09

Rebased onto origin/main (f2da9fe, v0.61.5, 24 commits). Conflict resolution rule: main wins on behavior; branch wins on typing/guards that do not change behavior.

  • inc/Abilities/CalendarAbilities.php — auto-merged; branch dead-condition narrowing (drop redundant $range_end from the progressive-render gate) carried onto main's context.
  • inc/Abilities/EventDateQueryAbilities.php — auto-merged; branch typing guards (strtotime false guard, empty() permalink check, drop unreachable ?? 'unknown') carried onto main.
  • inc/Api/Controllers/Calendar.php — auto-merged; branch @return \WP_REST_Response|\WP_Error docblock kept.
  • inc/Cli/Check/CheckVenuesCommand.php — auto-merged; converged identical to main (fix(cli): make check venues --report optional #814 already covered this area; zero net diff vs main).
  • inc/Core/DuplicateDetection/PreAIEventDedupGate.php — conflict; took main (changed-revision behavior plus (int)/(string) casts already supersede the branch's phpstan hunk; branch hunk dropped).
  • inc/Steps/EventImport/Handlers/WebScraper/Extractors/MusicItemExtractor.php — conflict; took main (fix(scraper): narrow the optional-minutes guard in MusicItemExtractor #810/fix(scraper): align MusicItemExtractor minute guards with phpstan and phpcs #812 final form '' !== $matches[2] / $matches[4] ?? '00', phpstan-clean; branch's ! empty() variants dropped).
  • inc/Steps/Upsert/Events/EventTaxonomyAssigner.php — conflict; took branch (instanceof \WP_Term guard, typing-only, matches the function's existing style; behavior identical).

Batch structure: the first batch commit (DOM scraper cluster) was dropped by the rebase as patch-identical to main content (shipped via the #808/#812-era merges) — the PR is now 3 commits instead of 4; no commit was skipped manually.

Post-rebase verification:

  • homeboy review lint data-machine-events --path <worktree> --placement localphpstan 0 findings, step passed; eslint passed (0). phpcs reports 106 pre-existing style warnings (down from ~887 at original PR time — main's recent style commits fixed most; still unchanged in class by this PR, out of scope).
  • homeboy review test unavailable locally (missing WP_CODEBOX_DB_* secret env on this VPS); standalone vendor/bin/phpunit --configuration phpunit.contracts.xml OK (4 tests, 59 assertions). The WordPress suite relies on the CI test job as arbiter, green on this branch.
  • PR state post-push: mergeable: MERGEABLE.

CI lint-gate fix (same day)

The first post-rebase push failed the CI review lint job: the gate counts phpcs findings across every changed file (not just added lines), so 37 pre-existing alignment warnings in CheckEventDateStatusCommand, EventUpdateAbilities, StructuredDataProcessor, and VenueAbilities failed it (phpstan and eslint were green; the local "phpcs out of scope" assumption in the original PR was wrong — the gate was already red on 43f4835 before the rebase). Fixed in a333d07 (style: commit, whitespace-only: double-arrow/equals alignment to the longest key per statement group, exactly the lines the gate flagged; no phpcbf sweep — it wanted to reformat unrelated multiline calls). Local replication of the CI gate (homeboy review lint --changed-since <base>) now reports phpcs 0 / eslint 0 / phpstan 0, overall succeeded. Contracts suite re-run OK (4 tests, 59 assertions).

🤖 Generated with opencode — AI-authored PR (GLM agent via kimaki bridge).

@homeboy-ci

homeboy-ci Bot commented Sep 8, 2026

Copy link
Copy Markdown
Contributor

Homeboy Results — data-machine-events

Review audit

review audit — passed

Deep dive: homeboy review audit data-machine-events --changed-since f2da9fe

Artifacts and drill-down
  • CI results artifact: homeboy-ci-results-data-machine-events-review-audit-homeboy-Linux-php8.2-node24 contains immediate command JSON for this action invocation.
  • Observation artifact: homeboy-observations-data-machine-events-review-audit-homeboy-Linux-php8.2-node24 contains exported Homeboy run history for deeper queries.
  • Drill-down: download the observation artifact, then run homeboy runs import <dir>, homeboy runs list, and homeboy runs findings <run-id>.
  • Artifacts are attached to the workflow run: https://github.com/Extra-Chill/data-machine-events/actions/runs/34366857374

Review lint

review lint — passed

ℹ️ Full options: homeboy self docs commands/lint
Deep dive: homeboy review lint data-machine-events --changed-since f2da9fe

Artifacts and drill-down
  • CI results artifact: homeboy-ci-results-data-machine-events-review-lint-homeboy-Linux-php8.2-node24 contains immediate command JSON for this action invocation.
  • Observation artifact: homeboy-observations-data-machine-events-review-lint-homeboy-Linux-php8.2-node24 contains exported Homeboy run history for deeper queries.
  • Drill-down: download the observation artifact, then run homeboy runs import <dir>, homeboy runs list, and homeboy runs findings <run-id>.
  • Artifacts are attached to the workflow run: https://github.com/Extra-Chill/data-machine-events/actions/runs/34366857374

Review test

review test — not run (setup failed)

Setup did not complete, so this command was not executed.

Artifacts and drill-down
  • CI results artifact: homeboy-ci-results-data-machine-events-review-test-homeboy-Linux-php8.2-node24 contains immediate command JSON for this action invocation.
  • Observation artifact: homeboy-observations-data-machine-events-review-test-homeboy-Linux-php8.2-node24 contains exported Homeboy run history for deeper queries.
  • Drill-down: download the observation artifact, then run homeboy runs import <dir>, homeboy runs list, and homeboy runs findings <run-id>.
  • Artifacts are attached to the workflow run: https://github.com/Extra-Chill/data-machine-events/actions/runs/34172647501
Tooling versions
  • Homeboy CLI: homeboy 0.371.0+d1a1a6d2092f250780ccf40a57a12becff2a164f
  • Extension: wordpress from https://github.com/Extra-Chill/homeboy-extensions
  • Extension revision: 2d9387a0
  • Action: Extra-Chill/homeboy-action@v2

@chubes4 chubes4 changed the title refactor: pay down remaining phpstan baseline (issue #767) — round 2 refactor: pay down phpstan lint baseline to zero (issue #767) — round 2 Sep 8, 2026
homeboy-ci Bot added 3 commits September 9, 2026 11:43
…renderers

Abilities: MergedBillDetect (dead ?? fallbacks on freshly-built arrays,
guarded strtotime, no-op array_values), EventQuery (WP_Post guard for
WP_Query::posts), Timezone (WP_Term guard for get_term, dead branch
ternaries, unreachable elseif), BatchTimeFix + EventQualityAudit (removed
WP_Error from queryEvents return contract, dead is_wp_error callers,
serialize_blocks element-shape preservation), EventUpdate (dead
'description' branch — handled separately at the inner-blocks layer,
false-path guard for wp_set_post_terms before array_map, wpdb::last_error
typed string pending homeboy-extensions#2809 stub fix, preg_split guard).

Block renderers: EventDetails coerces get_the_ID() to int and string-casts
esc_attr output; EventsMap narrows get_queried_object() with instanceof
WP_Term, string-casts absint values, completes the map_after_summary
docblock.
…, and admin

- Ticketmaster: method_exists() guard for the untyped auth provider object
  (upstream getAuthProvider() returns ?object), drop dead ?? on shaped
  metadata keys, simplify the provably-infinite do-while and its
  unreachable trailing return, int-cast the backoff min() results.
- EventRenderer: guard ob_get_clean() false and date_create() false paths,
  string-cast wp_json_encode() for esc_attr.
- Event_Post_Type: instanceof guards for the untyped $wp_query global and
  get_term_by(), parse_str() string guard on menu queries.
- EventImportFilters: string-cast filemtime() versions (false and ''
  both fall through to the WP core version at runtime — identical URLs).
- MonthGridBuilder: drop no-op array_values() on list constants and the
  dead ?? on a 0-6 narrowed index.
- Pagination Renderer:  superglobal isset, is_string() guard for
  paginate_links() array return mode, scalar string-cast for
  sanitize_text_field().
Final sweep (39 -> 0):
- API/chat tools: WP_Error instanceof guards for UpdateVenue and
  VenueHealthCheck (same class as the earlier tool guards).
- CLI: the WP_CLI runtime guard now keys on $_SERVER['argv'] — the wp-cli
  stubs unconditionally define WP_CLI so no test of that constant can be
  seen as live by static analysis; argv distinguishes the real runtime.
- Abilities: parse_blocks attrs ?? removals, block-quote caller trace
  offset, wp_count_terms WP_Error-safe casts in Promoter/Venue stats.
- Calendar: ScopeResolver strtotime guard, Template_Loader typed property
  and ob_get_clean() guard, template defensive fallbacks aligned with
  their @var contracts, get_the_permalink()/esc_url casts.
- Extractors: DateTimeParser bare-block cleanup, EventFlyer mime fallback
  honoring its string contract, WixEventsExtractor unused constant,
  WordPressExtractor host guard and dead is_array checks,
  WordPressGenericExtractor capture-group handling, Showare/Weebly/
  Nocodeflow dead ?? and count checks, Squarespace dead defensive branch
  and count check, BaseExtractor/MusicItem capture-group minute handling.
- Upsert: EventTaxonomyAssigner instanceof guards, EventBlockContentBuilder
  preg_split guard, EventMergeHelper runtime-dead re-read check removal.
- Core: event-tool-guard dead is_array, BrowserNavigationGuard redundant
  is_string, Controllers admit WP_Error in return phpdoc, performance.php
  timezone narrowing plus honest false-path var, NominatimClient cached
  entry shape validation, CalendarOccurrenceArtifact hash_file guard.
- CheckOrphanPipelinesCommand: typed candidate rows flow end to end.
@chubes4
chubes4 force-pushed the lint-767-phpstan-paydown-2 branch from 43f4835 to 13ad065 Compare September 9, 2026 11:49
The review lint gate counts phpcs findings across every changed file,
including pre-existing ones on untouched lines, so the 37 alignment
warnings in these four files failed CI. Fix is whitespace-only:
double-arrow and equals alignment to the longest key in each statement
group, exactly matching the sniff's reported expectations.
@chubes4
chubes4 merged commit 1ba8800 into main Sep 9, 2026
3 checks passed
chubes4 pushed a commit that referenced this pull request Sep 9, 2026
homeboy refactor --from lint --write. Clears the two new-fingerprint
formatting findings that failed the differential lint gate on #791
despite a net delta of -205.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Pay down lint baseline: 556 phpstan findings block the release gate on main

1 participant