fix: Remediate 2026-08-09 audit findings - #38
Conversation
Transport refactor (JooClientTransport -> ClientTransport, HttpTransport
enum, CircuitOpenException, connect timeout, upload content_type
guessing) plus fixes from the accompanying audit:
- Bump jooservices/dto to 1.6.0 and jooservices/exceptions to 1.0.0;
add psr/log as an explicit direct dependency instead of relying on
it transitively.
- Close real coverage gaps: all 8 guessContentType() branches,
FavoriteService::getListPages(), PeopleService::getPhotosPages(),
and the PeopleService::getInfo('') guard (95.03% -> 96.63%).
- Replace the disabled Gitleaks placeholder in secret-scanning.yml
with a working TruffleHog OSS scan (no license required, unlike
Gitleaks for org-owned repos).
- Fix the self-contradictory v2-roadmap.md, which still claimed the
circuit breaker/rate limiter were "not wired yet" after they shipped
in v2.0.0.
- De-duplicate the pagination pattern shared by FavoriteService and
PeopleService into AbstractRawService::paginatePhotoListMethod().
- FlickrConfig now rejects connectTimeoutSeconds > timeoutSeconds;
FlickrFactory::make() accepts an optional logger; mark a few
single-dependency constructor properties readonly.
- Port ci-triage/release-readiness Claude commands adapted from the
jooservices/dto sibling for AI-contributor tooling parity.
See audit_260809.md for the full findings this addresses.
|
ⓘ Qodo reviews are paused because the subscription is no longer active. Ask your workspace admin to reactivate the subscription to resume reviews. Manage billing |
|
Important Review skippedAuto reviews are disabled on base/target branches other than the default branch. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Plus Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Not up to standards ⛔
|
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## develop #38 +/- ##
=============================================
+ Coverage 95.95% 97.04% +1.08%
- Complexity 765 776 +11
=============================================
Files 124 124
Lines 2052 2096 +44
=============================================
+ Hits 1969 2034 +65
+ Misses 83 62 -21
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
Bring flickr's GitHub Actions in line with sibling packages (dto, exceptions, client), which already run both scans.
|
You are seeing this message because GitHub Code Scanning has recently been set up for this repository, or this pull request contains the workflow file for the Code Scanning tool. What Enabling Code Scanning Means:
For more information about GitHub Code Scanning, check out the documentation. |
9 similar comments
|
You are seeing this message because GitHub Code Scanning has recently been set up for this repository, or this pull request contains the workflow file for the Code Scanning tool. What Enabling Code Scanning Means:
For more information about GitHub Code Scanning, check out the documentation. |
|
You are seeing this message because GitHub Code Scanning has recently been set up for this repository, or this pull request contains the workflow file for the Code Scanning tool. What Enabling Code Scanning Means:
For more information about GitHub Code Scanning, check out the documentation. |
|
You are seeing this message because GitHub Code Scanning has recently been set up for this repository, or this pull request contains the workflow file for the Code Scanning tool. What Enabling Code Scanning Means:
For more information about GitHub Code Scanning, check out the documentation. |
|
You are seeing this message because GitHub Code Scanning has recently been set up for this repository, or this pull request contains the workflow file for the Code Scanning tool. What Enabling Code Scanning Means:
For more information about GitHub Code Scanning, check out the documentation. |
|
You are seeing this message because GitHub Code Scanning has recently been set up for this repository, or this pull request contains the workflow file for the Code Scanning tool. What Enabling Code Scanning Means:
For more information about GitHub Code Scanning, check out the documentation. |
|
You are seeing this message because GitHub Code Scanning has recently been set up for this repository, or this pull request contains the workflow file for the Code Scanning tool. What Enabling Code Scanning Means:
For more information about GitHub Code Scanning, check out the documentation. |
|
You are seeing this message because GitHub Code Scanning has recently been set up for this repository, or this pull request contains the workflow file for the Code Scanning tool. What Enabling Code Scanning Means:
For more information about GitHub Code Scanning, check out the documentation. |
|
You are seeing this message because GitHub Code Scanning has recently been set up for this repository, or this pull request contains the workflow file for the Code Scanning tool. What Enabling Code Scanning Means:
For more information about GitHub Code Scanning, check out the documentation. |
|
You are seeing this message because GitHub Code Scanning has recently been set up for this repository, or this pull request contains the workflow file for the Code Scanning tool. What Enabling Code Scanning Means:
For more information about GitHub Code Scanning, check out the documentation. |
There was a problem hiding this comment.
Phpmd (reported by Codacy) found more than 20 potential problems in the proposed changes. Check the Files changed tab for more details.
There was a problem hiding this comment.
Markdownlint (reported by Codacy) found more than 20 potential problems in the proposed changes. Check the Files changed tab for more details.
…dacy) Add the Dependency Review job (security -> dependency-review, PR-only, non-blocking) and Codacy coverage upload step that all sibling packages already run, so flickr's CI shape matches the rest of the jooservices ecosystem: security -> dependency-review/lint -> tests.
Not up to standards ⛔🟢 Coverage
|
| Metric | Results |
|---|---|
| Coverage variation | Report missing for 0d720ba1 |
| Diff coverage | ✅ 100.00% diff coverage |
Coverage variation details
Coverable lines Covered lines Coverage Common ancestor commit (0d720ba) Report Missing Report Missing Report Missing Head commit (b4380ec) 1638 1582 96.58% Coverage variation is the difference between the coverage for the head and common ancestor commits of the pull request branch:
<coverage of head commit> - <coverage of common ancestor commit>
Diff coverage details
Coverable lines Covered lines Diff coverage Pull request (#38) 112 112 100.00% Diff coverage is the percentage of lines that are covered by tests out of the coverable lines that the pull request added or modified:
<covered lines added or modified>/<coverable lines added or modified> * 100%
1 Codacy didn't receive coverage data for the commit, or there was an error processing the received data. Check your integration for errors and validate that your coverage setup is correct.
NEW Get contextual insights on your PRs based on Codacy's metrics, along with PR and Jira context, without leaving GitHub. Enable AI reviewer
TIP This summary will be updated as you push new changes.
There was a problem hiding this comment.
Pull request overview
This PR remediates the 2026-08-09 audit findings by shipping the pending transport refactor and tightening reliability/security posture across config validation, pagination helpers, upload multipart handling, docs, dependencies, and CI workflows. It keeps the SDK’s architecture intact (factory → services → raw API → transport) while improving transport configurability and test coverage around previously uncovered branches.
Changes:
- Introduces
ClientTransport(replacingJooClientTransport) withHttpTransportselection, connect timeout support, optional PSR-3 logging/configure hook, and circuit/rate-limit exception mapping. - Adds upload multipart
content_typeguessing and de-duplicates photo-list pagination wiring intoAbstractRawService::paginatePhotoListMethod(), with new unit tests and fakes. - Updates dependencies (
jooservices/*,psr/log) and strengthens CI/security tooling (TruffleHog secret scanning, optional Codacy/Fortify scans, dependency review), plus documentation/changelog updates.
Reviewed changes
Copilot reviewed 39 out of 40 changed files in this pull request and generated 7 comments.
Show a summary per file
| File | Description |
|---|---|
| tests/Unit/PaginationHelpersTest.php | New tests for shared pagination behavior in FavoriteService / PeopleService and PeopleService::getInfo() guard. |
| tests/Unit/MultipartRequestBuilderTest.php | New tests covering multipart build/close behavior and content_type guessing branches. |
| tests/Unit/JooClientTransportTest.php | Removes obsolete unit tests for renamed transport. |
| tests/Unit/ConfigAndDtoTest.php | Adds config validation tests for connect-timeout constraints. |
| tests/Unit/ClientTransportTest.php | New unit tests for ClientTransport config wiring and exception mapping. |
| tests/Unit/ClientAndParserTest.php | Updates upload and transport tests to use ClientTransport and assert multipart content type. |
| tests/Fakes/FakePagedPhotoListRawApiService.php | Adds a fake raw service to support pagination tests with photos.photo response shape. |
| tests/Fakes/FakeHttpClient.php | Extends fake client with head() to match expanded client surface. |
| src/Testing/MethodAwareFlickrFakeTransport.php | Marks injected transport readonly for immutability. |
| src/Testing/FlickrFake.php | Switches fake factory wiring from JooClientTransport to ClientTransport. |
| src/Services/PeopleService.php | Refactors getPhotosPages() to use shared pagination helper. |
| src/Services/FavoriteService.php | Refactors getListPages() to use shared pagination helper. |
| src/Services/AbstractRawService.php | Adds paginatePhotoListMethod() shared helper for photos.photo paginated endpoints. |
| src/FlickrFactory.php | Adds optional PSR-3 logger parameter and forwards it to default transport creation. |
| src/Exceptions/TransportException.php | Makes TransportException extensible (non-final) to support specialized subclasses. |
| src/Exceptions/CircuitOpenException.php | New Flickr-domain exception for circuit-open transport short-circuits. |
| src/Enums/HttpTransport.php | New enum selecting HTTP backend for ClientTransport. |
| src/Config/FlickrConfig.php | Adds connectTimeoutSeconds + httpTransport and centralizes validations, including connect>timeout rejection. |
| src/Client/MultipartRequestBuilder.php | Adds extension-based content_type guessing and updates multipart shape docs. |
| src/Client/JooClientTransport.php | Removes old transport implementation (replaced by ClientTransport). |
| src/Client/ClientTransport.php | New transport adapter with connect timeout, transport backend selection, logger/configure hooks, and exception mapping. |
| src/Cache/Psr16Cache.php | Marks cache dependency readonly. |
| README.md | Documents optional httpTransport and connect timeout settings in the quick-start snippet. |
| docs/05-maintenance/04-v1-to-v2-migration.md | Notes current jooservices/client requirement (^2.4). |
| docs/05-maintenance/03-v2-roadmap.md | Marks roadmap as delivered and corrects stale transport/circuit wiring notes. |
| docs/04-development/08-ai-contributor-workflow.md | Updates transport path reference to ClientTransport. |
| docs/04-development/07-ci-cd.md | Updates secret scanning workflow description (TruffleHog). |
| docs/01-getting-started/02-configuration.md | Adds/updates documentation for timeouts, transport backend, host-scoped circuit breaker, logging, and stores. |
| composer.lock | Locks updated dependency versions (client/dto/exceptions and related transitive updates). |
| composer.json | Bumps jooservices/client to ^2.4, jooservices/exceptions to ^1.0, adds direct psr/log. |
| CHANGELOG.md | Adds Unreleased entries documenting transport/config/upload/pagination/CI changes. |
| audit_260809.md | Adds the audit report referenced by the PR description. |
| ai/skills/README.md | Points contributors to new .claude/commands/ tooling. |
| AGENTS.md | Updates architecture map transport naming (ClientTransport). |
| .github/workflows/secret-scanning.yml | Replaces placeholder with real TruffleHog OSS scanning across PR/push/history. |
| .github/workflows/fortify.yml | Adds optional Fortify AST workflow (skips cleanly when secrets absent). |
| .github/workflows/codacy.yml | Adds Codacy Analysis CLI workflow with SARIF upload. |
| .github/workflows/ci.yml | Adds dependency review job and optional Codacy coverage upload. |
| .claude/commands/release-readiness.md | Adds Claude Code command for release readiness checks aligned with repo workflow. |
| .claude/commands/ci-triage.md | Adds Claude Code command for structured CI failure triage aligned with repo workflow. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
| 'retryTimes' => 2, | ||
| // Optional: 'httpTransport' => HttpTransport::Curl, // requires ext-curl | ||
| // Optional: 'connectTimeoutSeconds' => 5, |
| @unlink($path); | ||
| } | ||
|
|
||
| $photo = $multipart[array_search('photo', array_column($multipart, 'name'), true)]; |
| @unlink($path); | ||
| } | ||
|
|
||
| $photo = $multipart[array_search('photo', array_column($multipart, 'name'), true)]; |
| @unlink($path); | ||
| } | ||
|
|
||
| $photo = $multipart[array_search('photo', array_column($multipart, 'name'), true)]; |
| $this->assertContains('title', $names); | ||
| $this->assertContains('is_public', $names); | ||
|
|
||
| $title = $multipart[array_search('title', $names, true)]; |
| file_put_contents($path, 'bytes'); | ||
|
|
||
| $multipart = $this->builder->build($path, []); | ||
| $photo = $multipart[array_search('photo', array_column($multipart, 'name'), true)]; |
| $this->assertContains('photo', $names); | ||
| $this->assertContains('oauth_signature', $names); | ||
| $this->assertContains('is_friend', $names); | ||
| $this->assertSame('image/jpeg', $photo['content_type'] ?? null); |
- Add missing `use JOOservices\Flickr\Enums\HttpTransport;` import to the README config snippet (Copilot review: uncommenting the httpTransport line as-shown would not resolve). - Harden multipart part lookups in tests: `array_search(..., true)` returns false on a missing part, and `$multipart[false]` silently reads index 0 instead of failing (Copilot review, 6 call sites). Added a shared `TestCase::findMultipartPart()` helper that asserts the part exists before indexing. - Add `.codacy.yml`, matching the config already present in the sibling dto/exceptions/client packages, to scope PHPMD/PHPCS to `src/`, disable Agentlinter noise on agent docs, and exclude `.claude/**` — remark-lint was misreading the `argument-hint: [placeholder]` Claude Code slash-command convention in `.claude/commands/*.md` frontmatter as an undefined markdown reference link.
- Add missing `use JOOservices\Flickr\Enums\HttpTransport;` import to the README config snippet (Copilot review: uncommenting the httpTransport line as-shown would not resolve). - Harden multipart part lookups in tests: `array_search(..., true)` returns false on a missing part, and `$multipart[false]` silently reads index 0 instead of failing (Copilot review, 6 call sites). Added a shared `TestCase::findMultipartPart()` helper that asserts the part exists before indexing. - Add `.codacy.yml`, matching the config already present in the sibling dto/exceptions/client packages, to scope PHPMD/PHPCS to `src/`, disable Agentlinter noise on agent docs, and exclude `.claude/**` — remark-lint was misreading the `argument-hint: [placeholder]` Claude Code slash-command convention in `.claude/commands/*.md` frontmatter as an undefined markdown reference link. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
7468f07 to
b4380ec
Compare
Summary
Ships the pending transport refactor (
JooClientTransport→ClientTransport,HttpTransportenum,CircuitOpenException, connect timeout, uploadcontent_typeguessing) together with fixes from the accompanying audit (audit_260809.md):jooservices/dtoto 1.6.0 andjooservices/exceptionsto 1.0.0; addpsr/logas an explicit direct dependency instead of relying on it transitively.guessContentType()branches,FavoriteService::getListPages(),PeopleService::getPhotosPages(), and thePeopleService::getInfo('')guard (coverage 95.03% → 96.63%, giving real margin above the CI's 95% gate).secret-scanning.ymlwith a working TruffleHog OSS scan (no license required, unlike Gitleaks for org-owned repos).v2-roadmap.md, which still claimed the circuit breaker/rate limiter were "not wired yet" after they shipped inv2.0.0.FavoriteServiceandPeopleServiceintoAbstractRawService::paginatePhotoListMethod().FlickrConfignow rejectsconnectTimeoutSeconds > timeoutSeconds;FlickrFactory::make()accepts an optionallogger; mark a few single-dependency constructor propertiesreadonly.ci-triage/release-readinessClaude commands adapted from thejooservices/dtosibling for AI-contributor tooling parity.Full findings and evidence:
audit_260809.md.Test plan
composer ci(lint matrix, static analysis, registry/API-index verification, coverage, consumer smoke test) passes locallycomposer auditclean, no vulnerability advisories🤖 Generated with Claude Code