# Changelog

## Score

- CAI 65 → 62 (-2.9)
- Rubric changed (rubric-2026.10.1 → rubric-2026.10.5) — scores are not directly comparable.

## Lenses

- Code Health 97 → 90 (-7.6)
- Architecture 82 → 93 (+10.6)
- Maturity 53 → 46 (-7.0)
- Readiness 76 → 76 (+0.0)
- Security 72 → 72 (+0.0)

## Resolved (7)

- Base-context workflow trigger runs with an unscoped token
- Fork-triggerable workflow runs with an unscoped write token
- Inconsistent action method naming: `client_credentials` (noun-like) vs `exchange_token` (verb-noun)
- Inconsistent boolean method naming: `?` suffix vs `is_` prefix vs no suffix
- Inconsistent collection retrieval method names: `all` vs `checkouts` vs `base_find`
- Inconsistent equality operator naming: `==` vs `equals` or `eql?`
- Projects may be oversized for their cohesion

## New (19)

- Base-context workflow trigger runs with an unscoped token (.github/workflows/remove-labels-on-activity.yml)
- Fork-triggerable workflow runs with an unscoped write token (.github/workflows/cla.yml)
- Inconsistent equality method naming. Most types use the standard Ruby `==` operator, but `ShopifyAPI.Auth` itself exposes `const_missing` which is a hook, not an equality check. However, within the Auth sub-namespace, the naming is consistent (`==`). The real inconsistency is between `ShopifyAPI.Auth.==(other)` (if it exists as a class method or instance method on the Auth module/class) and the specific sub-types. Looking closely, `ShopifyAPI.Auth` is a module/class, while `Session`, `JwtPayload` etc are classes. The signature `Auth.==(other)` suggests an instance method on the Auth class, whereas `AuthScopes.==(other)` is on AuthScopes. This is actually consistent Ruby style. 

Wait, looking closer at `ShopifyAPI.Auth.AssociatedUser` having `Method: AssociatedUser.==(other)` and `ShopifyAPI.Auth.Session` having `Method: Session.==(other)`. This is consistent.

Let's look for actual duplicates.

`ShopifyAPI.Clients.Graphql.Admin` and `ShopifyAPI.Clients.Rest.Admin` both have `initialize(session, api_version)`. This is consistent.

`ShopifyAPI.Clients.Graphql.Client` and `ShopifyAPI.Clients.Graphql.Storefront` both have `query(...)`. This is consistent.

`ShopifyAPI.Rest.Base` has `base_find(session, ids, params)`. Many resource classes like `ApplicationCharge` have `find(id, fields, session)`. This is a significant inconsistency. The base class exposes a low-level `base_find`, while the concrete resources expose a high-level `find` with different argument ordering and semantics (e.g., `id` vs `ids`, `fields` vs `params`).

`ShopifyAPI.Rest.Base` has `save!()` and `save(update_object)`. Concrete resources inherit this, so it's consistent.

`ShopifyAPI.Rest.Base` has `delete(params)`. Concrete resources like `ApplicationCharge` have `find(id, ...)` but do they have `delete`? `Article` has `delete(id, blog_id, session)`. `AndroidPayKey` has `delete(id, session)`. The base class `delete` takes `params`, while concrete classes take specific IDs and session. This is an inconsistency in the public API surface of the resources vs the base.

Actually, the most glaring issue is `ShopifyAPI.Auth.==(other)` vs `ShopifyAPI.Auth.Session.==(other)`. If `Auth` is a module, `Auth.==` is weird. If it's a class, it's fine. But `ShopifyAPI.Auth` is listed as a type. `ShopifyAPI.Auth.AssociatedUser` is a type. 

Let's look at `ShopifyAPI.Clients.HttpClient.request(request, response_as_struct)` vs `ShopifyAPI.Clients.Graphql.Client.query(...)`. These are different domains (HTTP vs GraphQL), so not inconsistent.

Let's look at `ShopifyAPI.Rest.Base.base_find` vs `ShopifyAPI.ApplicationCharge.find`. 
`Base.base_find(session, ids, params)` 
`ApplicationCharge.find(id, fields, session)`

The base class method is named `base_find` and takes `ids` (plural) and `params`. The resource method is named `find` and takes `id` (singular) and `fields`. This is a naming and signature inconsistency for the same logical operation (retrieving a resource).

Also, `ShopifyAPI.Rest.Base` has `delete(params)`. `Article` has `delete(id, blog_id, session)`. `AndroidPayKey` has `delete(id, session)`. The base class `delete` is likely a helper or internal, but it's exposed. The resource `delete` methods vary in arguments (some take `blog_id`, some don't). This is an inconsistency in the `delete` operation signature across resources.

However, the prompt asks for operations that appear to do the same thing under different names. `base_find` vs `find` is the strongest candidate. `base_find` is clearly the implementation of `find` for the base class, but it's exposed publicly with a different name and signature.

Another one: `ShopifyAPI.Auth.Session.temp` vs `ShopifyAPI.Auth.Session.from`. These are distinct.

`ShopifyAPI.Clients.Graphql.Admin` and `ShopifyAPI.Clients.Rest.Admin` are distinct clients.

Let's stick with `base_find` vs `find`.
- Inconsistent naming and signature for resource retrieval. The base class exposes `base_find` with `ids` (plural) and `params`, while concrete resource classes expose `find` with `id` (singular) and `fields`. This forces developers to use different method names and argument structures for the same logical operation depending on whether they are using the base class or a specific resource.
- Orphaned file (lib/shopify_api/auth/jwt_payload.rb)
- Orphaned file (lib/shopify_api/auth/token_exchange.rb)
- Orphaned file (lib/shopify_api/clients/http_client.rb)
- Orphaned file (lib/shopify_api/clients/rest/admin.rb)
- Orphaned file (lib/shopify_api/rest/base.rb)
- Orphaned file (lib/shopify_api/utils/attributes_comparator.rb)
- Orphaned file (lib/shopify_api/webhooks/registration.rb)
- Orphaned file (lib/shopify_api/webhooks/registrations/event_bridge.rb)
- Orphaned file (lib/shopify_api/webhooks/registrations/http.rb)
- Orphaned file (lib/shopify_api/webhooks/registrations/pub_sub.rb)
- Orphaned file (lib/shopify_api/webhooks/registry.rb)
- Workflow token permissions not restricted (.github/workflows/api_update_reminder.yml)
- Workflow token permissions not restricted (.github/workflows/api_update_reminder_on_release.yml)
- Workflow token permissions not restricted (.github/workflows/build.yml)
- Workflow token permissions not restricted (.github/workflows/close-waiting-for-response-issues.yml)

## Changes since last survey

- 5 commits — 5 feature/other, 0 fixes

## By area

- (root) — 2 commits
- (repo) — 1 commit
- lib/shopify_api — 1 commit
- test/auth — 1 commit

## Notable commits

- change: Link changelog entries to pull request
- change: Merge pull request #1472 from Shopify/liz/trusted-admin-host-validation
- change: Trim redundant auth test cases
- change: Validate trusted Admin hosts in auth flows
- change: Validate unified Admin store handles
