activeadmin-graphql 0.3.0 → 0.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +4 -0
- data/docs/changelogs/20260818111600_rfc-0002-problems.md +25 -0
- data/docs/changelogs/20260818114000_rfc-as-built-coverage.md +27 -0
- data/docs/changelogs/20260818114700_rfc-design-not-version.md +27 -0
- data/docs/changelogs/20260907141000_advisory-lockfile-refresh.md +21 -0
- data/docs/changelogs/20260921103000_mutation-attribute-allowlists.md +24 -0
- data/docs/changelogs/20260921111000_release-0-3-0.md +42 -0
- data/docs/changelogs/20260921112800_drop-standard-rubocop-direct.md +35 -0
- data/docs/changelogs/20260921120000_graphql-floor-and-activeadmin-4.md +41 -0
- data/docs/changelogs/20261010101500_nonconventional-id-fields.md +34 -0
- data/docs/changelogs/20261010103800_release-0-3-1.md +32 -0
- data/docs/dependencies/20260907141000_json-cve-2026-71847.md +68 -0
- data/docs/dependencies/20260907141000_sqlite3-ghsa-mwm8-39rw-8826.md +62 -0
- data/docs/dependencies/20260921114000_rails-json-parse-kwargs.md +61 -0
- data/docs/dependencies/20260921114500_graphql-ghsa-rmxg-5p3r-j6hh.md +69 -0
- data/docs/dependencies/20261007161308_association-list-combobox.md +23 -0
- data/docs/graphql-api.md +13 -0
- data/docs/issues/20260907141000_engineering-and-dependency-audit.md +30 -0
- data/docs/issues/20260917123253_ci-drop-automatic-dependency-audit.md +29 -0
- data/docs/issues/20260921103000_mutation-attribute-allowlists.md +40 -0
- data/docs/issues/20260921104400_convention-alignment-audit.md +60 -0
- data/docs/issues/20260921114500_dependency-audit.md +90 -0
- data/docs/issues/20260921115500_file-length-metrics.md +31 -0
- data/docs/plan/20260817201500_rfc-starter.md +31 -0
- data/lib/active_admin/graphql/policy_set_cache.rb +3 -1
- data/lib/active_admin/graphql/record_source.rb +3 -2
- data/lib/active_admin/graphql/resource_query_proxy/identity.rb +38 -0
- data/lib/active_admin/graphql/resource_query_proxy.rb +13 -8
- data/lib/active_admin/graphql/schema_builder/types_object.rb +15 -2
- data/lib/active_admin/graphql/version.rb +1 -1
- data/lib/active_admin/primary_key.rb +13 -4
- metadata +24 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 5fc45489403fdf5c4d16bd66966cc4c7c5641440663d3f5b229b0d627a0d0978
|
|
4
|
+
data.tar.gz: '04786131baffbec749af13c347660836c1ca31efa074c73eddfc49c5fbfb588e'
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 1c93c24f91a208c8eb00076d1fd3d8b398c99d155a8ce92f4aaa075b6615ea321a3303b2186e85fa32178a4e8ad158fb4ab1f081752993c6a44e5466fad1ac83
|
|
7
|
+
data.tar.gz: f5c1acc62e5f1aa0cd925234c4df76d9870dd592cb97aeae7927df578340d70936e02bcf727635a8f07d7caacfb84316e037383c7666b35cb472d11b8776240e
|
data/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,10 @@
|
|
|
2
2
|
|
|
3
3
|
## Unreleased
|
|
4
4
|
|
|
5
|
+
## 0.3.1 (2026-10-10)
|
|
6
|
+
|
|
7
|
+
- Fix GraphQL identity handling for database views and nonconventional primary keys: keep one `id` field, support inferred `id` lookups, reject ambiguous identifiers, and honor attribute filters.
|
|
8
|
+
|
|
5
9
|
## 0.3.0 (2026-09-21)
|
|
6
10
|
|
|
7
11
|
- BREAKING: omit `created_at` and `updated_at` from default create and update inputs. List them on `permit_params` to keep them writable.
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# RFC 0002 problems and process motivation
|
|
2
|
+
|
|
3
|
+
## Participants
|
|
4
|
+
|
|
5
|
+
Andrei Makarov
|
|
6
|
+
|
|
7
|
+
## Decisions
|
|
8
|
+
|
|
9
|
+
RFC 0002 is the as-built problem statement: concrete operator or implementer failures, the shipped solution, rejected alternatives, and which surfaces still need a later Standards Track RFC.
|
|
10
|
+
|
|
11
|
+
RFC 0001 Motivation names those same surfaces as the reason a numbered process exists here.
|
|
12
|
+
|
|
13
|
+
## Effects
|
|
14
|
+
|
|
15
|
+
rfcs/0002-problem-and-positioning.md rewritten. rfcs/0001-rfc-process.md Motivation updated. Unreleased changelog line expanded.
|
|
16
|
+
|
|
17
|
+
## Next
|
|
18
|
+
|
|
19
|
+
Discuss RFC 0001 until 2026-08-31. Commit when asked.
|
|
20
|
+
|
|
21
|
+
## Source
|
|
22
|
+
|
|
23
|
+
Upstream: README, CHANGELOG, and (where present) SPEC.md or docs/graphql-api.md in this tree.
|
|
24
|
+
|
|
25
|
+
Downstream: rfcs/0001-rfc-process.md, rfcs/0002-problem-and-positioning.md.
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# As-built RFC coverage
|
|
2
|
+
|
|
3
|
+
## Participants
|
|
4
|
+
|
|
5
|
+
Andrei Makarov
|
|
6
|
+
|
|
7
|
+
## Decisions
|
|
8
|
+
|
|
9
|
+
Starter pack RFC 0001 and RFC 0002 is not enough. Each public contract named in RFC 0002 gets its own Informational Stable RFC with Describes pinned to the current version.
|
|
10
|
+
|
|
11
|
+
As-built Informational RFCs are Stable. A later change to those contracts is a new Standards Track RFC.
|
|
12
|
+
|
|
13
|
+
## Effects
|
|
14
|
+
|
|
15
|
+
Wrote RFC 0003 HTTP endpoint, RFC 0004 schema and DSL, RFC 0005 authorization and filters. Claimed ids/0003 through ids/0005. Updated rfcs/README.md Current set, RFC 0002 Relates and Unresolved, and CHANGELOG Unreleased.
|
|
16
|
+
|
|
17
|
+
Later pass 2026-08-18: RFC 0003 and later rewritten as Standards Track design specifications. Describes dropped. Version numbers belong in changelogs. The Informational Describes dump from this file is reversed.
|
|
18
|
+
|
|
19
|
+
## Next
|
|
20
|
+
|
|
21
|
+
Discuss RFC 0001 until 2026-08-31. Commit when asked. Schema layout and cap registrar remain later Standards Track candidates.
|
|
22
|
+
|
|
23
|
+
## Source
|
|
24
|
+
|
|
25
|
+
Upstream: docs/graphql-api.md, CHANGELOG 0.2.1, lib/active_admin/graphql/integration.rb.
|
|
26
|
+
|
|
27
|
+
Downstream: rfcs/0003-http-endpoint.md, rfcs/0004-schema-and-dsl.md, rfcs/0005-authorization-and-filters.md.
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# RFCs specify design
|
|
2
|
+
|
|
3
|
+
## Participants
|
|
4
|
+
|
|
5
|
+
Andrei Makarov
|
|
6
|
+
|
|
7
|
+
## Decisions
|
|
8
|
+
|
|
9
|
+
An RFC proposes a design: suggestion, motivation, specification, effects, alternatives, and prior art. Version numbers belong in changelogs. Implementation notes stay optional evidence.
|
|
10
|
+
|
|
11
|
+
RFC 0002 stays Informational positioning. RFC 0003 and later are Standards Track. Shipped design specified after the fact is Stable.
|
|
12
|
+
|
|
13
|
+
## Effects
|
|
14
|
+
|
|
15
|
+
Rewrote product RFCs 0002 and later, RFC 0001 process text, rfcs/README.md, and the template. Dropped Describes. Updated CHANGELOG Unreleased.
|
|
16
|
+
|
|
17
|
+
Later pass 2026-08-18: dropped fence tags that only blocked a misreading in process text. Contract negation stayed.
|
|
18
|
+
|
|
19
|
+
## Next
|
|
20
|
+
|
|
21
|
+
Discuss RFC 0001 until 2026-08-31. Commit when asked.
|
|
22
|
+
|
|
23
|
+
## Source
|
|
24
|
+
|
|
25
|
+
Upstream: conversation on RFC shape for product libraries.
|
|
26
|
+
|
|
27
|
+
Downstream: rfcs/.
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
## Participants
|
|
2
|
+
|
|
3
|
+
- amkisko
|
|
4
|
+
|
|
5
|
+
## Decisions
|
|
6
|
+
|
|
7
|
+
- Relock json to 2.21.2 in Gemfile.lock and appraisal lockfiles that still carried a vulnerable pin.
|
|
8
|
+
- Relock sqlite3 to 2.9.6 where the test graph still pinned an affected line, and raise the development gemspec floor to >= 2.9.6 when this gemspec declared sqlite3.
|
|
9
|
+
- Keep json on the 2.x line in library and appraisal locks because rubocop declares json ~> 2.3.
|
|
10
|
+
- Leave Dependabot bundler at directory /. Appraisal lockfiles stay on the CI security matrix.
|
|
11
|
+
|
|
12
|
+
## Effects
|
|
13
|
+
|
|
14
|
+
- CI bundler-audit jobs that failed on CVE-2026-71847 and GHSA-mwm8-39rw-8826 now have patched pins in the lockfiles touched this pass.
|
|
15
|
+
- CHANGELOG.md was not given an Unreleased bullet. This is a lockfile and development-graph refresh, not a public gem contract change.
|
|
16
|
+
|
|
17
|
+
## Source
|
|
18
|
+
|
|
19
|
+
- usr/docs/issues/20260907141000_engineering-and-dependency-audit.md
|
|
20
|
+
- usr/docs/dependencies/20260907141000_json-cve-2026-71847.md
|
|
21
|
+
- usr/docs/dependencies/20260907141000_sqlite3-ghsa-mwm8-39rw-8826.md
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
# Mutation attribute allowlists
|
|
2
|
+
|
|
3
|
+
## Participants
|
|
4
|
+
|
|
5
|
+
Andrei Makarov
|
|
6
|
+
|
|
7
|
+
## Decisions
|
|
8
|
+
|
|
9
|
+
Ship RFC 0006 as Proposed with running request specs. CHANGELOG Unreleased names the four graphql DSL methods and the RFC number.
|
|
10
|
+
|
|
11
|
+
## Effects
|
|
12
|
+
|
|
13
|
+
Consumers can keep query fields such as timestamps and derived columns while listing authored keys on create and update inputs. Default schema is unchanged.
|
|
14
|
+
|
|
15
|
+
Later pass 2026-09-21: CHANGELOG Unreleased names permit_params and nested create / update, not create_only.
|
|
16
|
+
|
|
17
|
+
## Next
|
|
18
|
+
|
|
19
|
+
0.3.0 metadata includes the graphql 2.6.9 floor and ActiveAdmin 4 Rails 8 matrix. Downstream apps replace initializer patches with graphql permit_params and keep their introspection regression spec after the gem is tagged.
|
|
20
|
+
|
|
21
|
+
## Source
|
|
22
|
+
|
|
23
|
+
usr/docs/issues/20260921103000_mutation-attribute-allowlists.md
|
|
24
|
+
rfcs/0006-mutation-permit-params.md
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
# Release 0.3.0 metadata
|
|
2
|
+
|
|
3
|
+
## Participants
|
|
4
|
+
|
|
5
|
+
Andrei Makarov
|
|
6
|
+
|
|
7
|
+
## Decisions
|
|
8
|
+
|
|
9
|
+
Cut 0.3.0, not 0.2.2. Default create and update inputs omit created_at and updated_at unless listed on permit_params. That is a GraphQL schema break for clients that sent those fields on 0.2.1.
|
|
10
|
+
|
|
11
|
+
CHANGELOG 0.3.0 dated 2026-09-21. Version constant is 0.3.0. Path gem pins in Gemfile.lock and appraisal lockfiles match.
|
|
12
|
+
|
|
13
|
+
RFC 0006 stays Proposed until 2026-10-05 lazy consensus. Shipping the implementation does not close that window.
|
|
14
|
+
|
|
15
|
+
make release (usr/bin/release.rb) still owns gem build, gem push, git tag, and GitHub release. This pass only prepares metadata.
|
|
16
|
+
|
|
17
|
+
## Effects
|
|
18
|
+
|
|
19
|
+
lib/active_admin/graphql/version.rb VERSION is 0.3.0.
|
|
20
|
+
|
|
21
|
+
CHANGELOG Unreleased bullets moved under 0.3.0. BREAKING line names the timestamp omission.
|
|
22
|
+
|
|
23
|
+
PATH specs for activeadmin-graphql in Gemfile.lock, gemfiles/rails72.gemfile.lock, gemfiles/rails8ruby4.gemfile.lock, and gemfiles/rails8ruby34.gemfile.lock are 0.3.0.
|
|
24
|
+
|
|
25
|
+
## Next
|
|
26
|
+
|
|
27
|
+
Run make release from a clean tree when ready to push the gem and tag 0.3.0.
|
|
28
|
+
|
|
29
|
+
## Later pass 2026-09-21
|
|
30
|
+
|
|
31
|
+
0.3.0 is still unpublished. RubyGems latest is 0.2.1. Git tags stop at 0.2.1. Fold the post-cut Unreleased work into 0.3.0 instead of cutting 0.3.1.
|
|
32
|
+
|
|
33
|
+
CHANGELOG 0.3.0 now also names BREAKING graphql-ruby 2.6.9 and the ActiveAdmin 4.0.0.beta23 Rails 8 test matrix. Lockfile graphql is 2.6.10. Gemspec floor is graphql >= 2.6.9. Development lint (drop standard, Metrics/FileLength) stays out of CHANGELOG.md.
|
|
34
|
+
|
|
35
|
+
## Source
|
|
36
|
+
|
|
37
|
+
usr/docs/issues/20260921103000_mutation-attribute-allowlists.md
|
|
38
|
+
usr/docs/issues/20260921104400_convention-alignment-audit.md
|
|
39
|
+
usr/docs/changelogs/20260921103000_mutation-attribute-allowlists.md
|
|
40
|
+
usr/docs/changelogs/20260921120000_graphql-floor-and-activeadmin-4.md
|
|
41
|
+
rfcs/0006-mutation-permit-params.md
|
|
42
|
+
usr/bin/release.rb
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
## Participants
|
|
2
|
+
|
|
3
|
+
Andrei Makarov
|
|
4
|
+
|
|
5
|
+
## Decisions
|
|
6
|
+
|
|
7
|
+
Drop the standard gem. Lint stays on rubocop with a snapshot of standard 1.56.0 config/base.yml plus standard-custom, standard-performance, and standard-rails.
|
|
8
|
+
|
|
9
|
+
Raise the development rubocop floor to ~> 1.91. That gem allows json >= 2.3.
|
|
10
|
+
|
|
11
|
+
Keep json on 2.21.2. Rails 8.1.3.1 and 7.2.3.2 ActiveSupport::JSON.decode still pass a positional options hash to JSON.parse, which json 3 rejects. Pin development json >= 2.21.2, < 3 until a Rails release includes rails/rails#58601.
|
|
12
|
+
|
|
13
|
+
## Effects
|
|
14
|
+
|
|
15
|
+
make lint: bundle exec rubocop, 86 files inspected, 5 Metrics/FileLength info offenses, no failing offenses. bundle exec rbs validate succeeded.
|
|
16
|
+
|
|
17
|
+
bundle exec rspec: 106 examples, 0 failures on json 2.21.2.
|
|
18
|
+
|
|
19
|
+
bundle-audit check --gemfile-lock on Gemfile.lock, gemfiles/rails72.gemfile.lock, gemfiles/rails8ruby34.gemfile.lock, and gemfiles/rails8ruby4.gemfile.lock: No vulnerabilities found.
|
|
20
|
+
|
|
21
|
+
json 3.0.2 in the same graphs made GraphQL request specs fail with Invalid JSON (ParseError wrapping ArgumentError given 2, expected 1). Relocked 2.21.2.
|
|
22
|
+
|
|
23
|
+
CHANGELOG.md Unreleased was not given a bullet. This is development lint and lockfile work.
|
|
24
|
+
|
|
25
|
+
## Next
|
|
26
|
+
|
|
27
|
+
Drop the json < 3 development pin after a Rails release that includes rails/rails#58601, then bundle update json.
|
|
28
|
+
|
|
29
|
+
## Source
|
|
30
|
+
|
|
31
|
+
usr/docs/dependencies/20260907141000_json-cve-2026-71847.md
|
|
32
|
+
usr/docs/dependencies/20260921114000_rails-json-parse-kwargs.md
|
|
33
|
+
usr/docs/issues/20260921114500_dependency-audit.md
|
|
34
|
+
https://github.com/standardrb/standard/blob/v1.56.0/config/base.yml
|
|
35
|
+
https://github.com/rails/rails/pull/58601
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
## Participants
|
|
2
|
+
|
|
3
|
+
Andrei Makarov
|
|
4
|
+
|
|
5
|
+
## Decisions
|
|
6
|
+
|
|
7
|
+
Raise the published graphql-ruby floor from >= 2.3 to >= 2.6.9 so consumers cannot resolve GHSA-rmxg-5p3r-j6hh. Lock graphql 2.6.10.
|
|
8
|
+
|
|
9
|
+
Pin ActiveAdmin 4.0.0.beta23 on the Rails 8 appraisal gemfiles. Keep ActiveAdmin 3.5.2 on Rails 7.2 and on the root Gemfile.lock. Hosts must pin the ActiveAdmin 4 prerelease themselves.
|
|
10
|
+
|
|
11
|
+
Apply patch-level lockfile updates: rack 3.2.7, zeitwerk 2.8.3, responders 3.2.1, net-imap 0.6.7, net-protocol 0.4.0 (with net-imap), bigdecimal 4.1.3, erb 6.0.7, unicode-display_width 3.3.0, unicode-emoji 4.3.0, polyrun 2.2.4, parallel_tests 5.8.0, sprockets 4.4.1, rbs 4.2.0, parallel 2.2.0, io-console 0.9.4, reline 0.7.0.
|
|
12
|
+
|
|
13
|
+
Leave json 2.21.2. Standard 1.56.0 still pins rubocop ~> 1.88.0, which pins json ~> 2.3.
|
|
14
|
+
|
|
15
|
+
## Effects
|
|
16
|
+
|
|
17
|
+
bundle-audit check --gemfile-lock on Gemfile.lock, gemfiles/rails72.gemfile.lock, gemfiles/rails8ruby34.gemfile.lock, and gemfiles/rails8ruby4.gemfile.lock: No vulnerabilities found.
|
|
18
|
+
|
|
19
|
+
make lint: bundle exec rubocop, 84 files inspected, no offenses detected. bundle exec rbs validate succeeded.
|
|
20
|
+
|
|
21
|
+
bundle exec rspec: 102 examples, 0 failures (ActiveAdmin 3.5.2). BUNDLE_GEMFILE=gemfiles/rails72.gemfile bundle exec rspec: 102 examples, 0 failures. BUNDLE_GEMFILE=gemfiles/rails8ruby34.gemfile bundle exec rspec: 102 examples, 0 failures (ActiveAdmin 4.0.0.beta23). BUNDLE_GEMFILE=gemfiles/rails8ruby4.gemfile bundle exec rspec: 102 examples, 0 failures (ActiveAdmin 4.0.0.beta23).
|
|
22
|
+
|
|
23
|
+
CHANGELOG Unreleased names the graphql floor and the ActiveAdmin 4 test matrix. Lockfile-only patches stay out of CHANGELOG.md.
|
|
24
|
+
|
|
25
|
+
## Next
|
|
26
|
+
|
|
27
|
+
Wait for a Rails release that includes rails/rails#58601 before json 3. The standard gem is no longer in the graph.
|
|
28
|
+
|
|
29
|
+
Folded into unpublished 0.3.0. Tag and gem push wait on make release.
|
|
30
|
+
|
|
31
|
+
## Later pass 2026-09-21
|
|
32
|
+
|
|
33
|
+
Dropped standard. Locked rubocop 1.91.0. json stayed 2.21.2 because Rails decode still uses positional JSON.parse options. See usr/docs/changelogs/20260921112800_drop-standard-rubocop-direct.md.
|
|
34
|
+
|
|
35
|
+
## Source
|
|
36
|
+
|
|
37
|
+
usr/docs/issues/20260921114500_dependency-audit.md
|
|
38
|
+
usr/docs/dependencies/20260921114500_graphql-ghsa-rmxg-5p3r-j6hh.md
|
|
39
|
+
https://github.com/rmosolgo/graphql-ruby/security/advisories/GHSA-rmxg-5p3r-j6hh
|
|
40
|
+
https://github.com/activeadmin/activeadmin/blob/master/UPGRADING.md
|
|
41
|
+
https://github.com/standardrb/standard/blob/main/standard.gemspec
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
# Nonconventional id fields
|
|
2
|
+
|
|
3
|
+
## Effects
|
|
4
|
+
|
|
5
|
+
Schema build no longer raises `GraphQL::Schema::DuplicateNamesError` when a
|
|
6
|
+
registered model has an `id` column that is not the ActiveRecord primary key
|
|
7
|
+
(`self.primary_key = nil`) or uses a non-`id` primary key.
|
|
8
|
+
|
|
9
|
+
`ActiveAdmin::PrimaryKey` falls back to an `id` column when the declared
|
|
10
|
+
primary key is blank. Object types skip emitting a column field named `id`
|
|
11
|
+
(interface owns GraphQL `id`) and expose a single non-`id` primary-key column
|
|
12
|
+
as a readable scalar unless the resource's attribute configuration omits it.
|
|
13
|
+
Models with neither a primary key nor an `id` column fail schema build with an
|
|
14
|
+
`ArgumentError` that asks for `self.primary_key`. Inferred `id` values must be
|
|
15
|
+
unique and non-null; ambiguous member and batched lookups fail closed.
|
|
16
|
+
|
|
17
|
+
Member lookup uses the inferred column while preserving an explicitly
|
|
18
|
+
configured ActiveAdmin finder. Request-local policy caching keeps separate
|
|
19
|
+
entries for distinct records when ActiveRecord has no declared primary key.
|
|
20
|
+
|
|
21
|
+
Dummy coverage includes SQLite views that project `code AS id` and
|
|
22
|
+
`id AS row_key`, plus a table with an `id` column and no primary key.
|
|
23
|
+
|
|
24
|
+
## Next
|
|
25
|
+
|
|
26
|
+
Folded into 0.3.1 release metadata. Tag and gem push wait on make release.
|
|
27
|
+
|
|
28
|
+
## Source
|
|
29
|
+
|
|
30
|
+
- Specs: `spec/requests/graphql_identity_columns_spec.rb`,
|
|
31
|
+
`spec/unit/primary_key_identity_spec.rb`,
|
|
32
|
+
`spec/unit/resource_query_proxy_identity_spec.rb`,
|
|
33
|
+
`spec/unit/policy_set_cache_spec.rb`
|
|
34
|
+
- Views: `spec/dummy/db/schema.rb` (`string_id_records`, `alternate_key_records`)
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
# Release 0.3.1 metadata
|
|
2
|
+
|
|
3
|
+
## Participants
|
|
4
|
+
|
|
5
|
+
Andrei Makarov
|
|
6
|
+
|
|
7
|
+
## Decisions
|
|
8
|
+
|
|
9
|
+
Cut 0.3.1 after published 0.3.0. One user-visible fix: GraphQL identity for database views and nonconventional primary keys.
|
|
10
|
+
|
|
11
|
+
CHANGELOG 0.3.1 dated 2026-10-10. Version constant is 0.3.1. Path gem pins in Gemfile.lock and appraisal lockfiles match.
|
|
12
|
+
|
|
13
|
+
Docs-only and pray-tooling commits since 0.3.0 stay out of CHANGELOG.md.
|
|
14
|
+
|
|
15
|
+
make release (usr/bin/release.rb) still owns gem build, gem push, git tag, and GitHub release. This pass only prepares metadata.
|
|
16
|
+
|
|
17
|
+
## Effects
|
|
18
|
+
|
|
19
|
+
lib/active_admin/graphql/version.rb VERSION is 0.3.1.
|
|
20
|
+
|
|
21
|
+
CHANGELOG Unreleased bullet moved under 0.3.1.
|
|
22
|
+
|
|
23
|
+
PATH specs for activeadmin-graphql in Gemfile.lock, gemfiles/rails72.gemfile.lock, gemfiles/rails8ruby4.gemfile.lock, and gemfiles/rails8ruby34.gemfile.lock are 0.3.1.
|
|
24
|
+
|
|
25
|
+
## Next
|
|
26
|
+
|
|
27
|
+
Run make release from a clean tree when ready to push the gem and tag 0.3.1.
|
|
28
|
+
|
|
29
|
+
## Source
|
|
30
|
+
|
|
31
|
+
docs/changelogs/20261010101500_nonconventional-id-fields.md
|
|
32
|
+
usr/bin/release.rb
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
## Dependency
|
|
2
|
+
|
|
3
|
+
- json (was below 2.21.2 on the 2.x line, now 2.21.2 in library and appraisal locks)
|
|
4
|
+
- Constraint in this repo: development gemspec json >= 2.21.2, < 3. Transitive via activesupport. rubocop 1.91 allows json >= 2.3.
|
|
5
|
+
- Lockfiles: Gemfile.lock and gemfiles/*.gemfile.lock where present
|
|
6
|
+
|
|
7
|
+
## Symptom
|
|
8
|
+
|
|
9
|
+
bundler-audit matches json 2.20.0 through 2.21.1 against CVE-2026-71847 / GHSA-9hj4-r449-hfvc. CI security jobs fail while that pin remains.
|
|
10
|
+
|
|
11
|
+
## Evidence
|
|
12
|
+
|
|
13
|
+
- Advisory: JSON::ResumableParser#partial_value use-after-free on truncated duplicate-key streams. Affected 2.20.0 through 2.21.1. Patched >= 2.21.2.
|
|
14
|
+
- This library does not call JSON::ResumableParser or partial_value.
|
|
15
|
+
|
|
16
|
+
## Suggested fix
|
|
17
|
+
|
|
18
|
+
Upgrade lockfiles to json 2.21.2. Stay on 2.x while Rails ActiveSupport::JSON.decode still calls JSON.parse with a positional options hash.
|
|
19
|
+
|
|
20
|
+
## Trigger
|
|
21
|
+
|
|
22
|
+
- bundler-audit scanner match during the 2026-09-07 CI failure review.
|
|
23
|
+
|
|
24
|
+
## Assessment target
|
|
25
|
+
|
|
26
|
+
- CI and test graphs: Gemfile.lock and appraisal locks.
|
|
27
|
+
- Published gem runtime: json is not a runtime gemspec dependency.
|
|
28
|
+
|
|
29
|
+
## Advisory
|
|
30
|
+
|
|
31
|
+
- CVE-2026-71847
|
|
32
|
+
- GHSA-9hj4-r449-hfvc
|
|
33
|
+
- CVSS 8.7 availability (CVSS:4.0). CISA KEV: not listed at the time of this record.
|
|
34
|
+
|
|
35
|
+
## Status
|
|
36
|
+
|
|
37
|
+
- CI and test graphs: fixed after lockfiles pin json 2.21.2.
|
|
38
|
+
- Published gem execute path: not_affected. The advisory names ResumableParser#partial_value.
|
|
39
|
+
|
|
40
|
+
## Applicability
|
|
41
|
+
|
|
42
|
+
- Vulnerable component present in the pre-fix lockfiles below 2.21.2.
|
|
43
|
+
- Exploit conditions require streaming parse through ResumableParser#partial_value on truncated duplicate-key input.
|
|
44
|
+
|
|
45
|
+
## Priority
|
|
46
|
+
|
|
47
|
+
- CI graph: high because bundler-audit fails the security job on version match.
|
|
48
|
+
- Published gem execute path: low. Exploit conditions do not hold on JSON.parse paths.
|
|
49
|
+
|
|
50
|
+
## Disposition
|
|
51
|
+
|
|
52
|
+
- Upgrade to 2.21.2. Pin development json < 3 until Rails decode accepts json 3 keyword options.
|
|
53
|
+
|
|
54
|
+
## Next
|
|
55
|
+
|
|
56
|
+
- Keep the runtime gemspec free of json unless a later feature streams JSON through ResumableParser.
|
|
57
|
+
- json 3.0.2 is blocked by Rails 8.1.3.1 and 7.2.3.2 ActiveSupport::JSON.decode (positional JSON.parse options). Drop the development json < 3 pin after a Rails release that includes rails/rails#58601, then bundle update json.
|
|
58
|
+
|
|
59
|
+
## Later pass 2026-09-21
|
|
60
|
+
|
|
61
|
+
Dropped the standard gem so rubocop 1.91 can resolve. That unblocked json 3 at the Bundler level. Dummy GraphQL request specs then failed: ActionDispatch::Http::Parameters::ParseError wrapping ArgumentError wrong number of arguments (given 2, expected 1). Relocked json 2.21.2 and added development gemspec json >= 2.21.2, < 3. See usr/docs/dependencies/20260921114000_rails-json-parse-kwargs.md.
|
|
62
|
+
|
|
63
|
+
## Source
|
|
64
|
+
|
|
65
|
+
- https://github.com/ruby/json/security/advisories/GHSA-9hj4-r449-hfvc
|
|
66
|
+
- https://www.cve.org/CVERecord?id=CVE-2026-71847
|
|
67
|
+
- usr/docs/issues/20260907141000_engineering-and-dependency-audit.md
|
|
68
|
+
- usr/docs/dependencies/20260921114000_rails-json-parse-kwargs.md
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
## Dependency
|
|
2
|
+
|
|
3
|
+
- sqlite3 (was at or below 2.9.5, now 2.9.6)
|
|
4
|
+
- Development gemspec floor now >= 2.9.6 where this gemspec declared sqlite3
|
|
5
|
+
- Dummy-app and test graph only. The published gem does not require sqlite3 at runtime.
|
|
6
|
+
|
|
7
|
+
## Symptom
|
|
8
|
+
|
|
9
|
+
bundler-audit matches sqlite3 <= 2.9.5 against GHSA-mwm8-39rw-8826. CI security jobs fail while that pin remains.
|
|
10
|
+
|
|
11
|
+
## Evidence
|
|
12
|
+
|
|
13
|
+
- Advisory: use-after-free in custom aggregate arguments when Database#create_aggregate, #create_aggregate_handler, or #define_aggregator takes two or more arguments over TEXT or BLOB values. Affected >= 1.4.0, <= 2.9.5. Patched 2.9.6.
|
|
14
|
+
- This repository has no create_aggregate, create_aggregate_handler, or define_aggregator callers.
|
|
15
|
+
|
|
16
|
+
## Suggested fix
|
|
17
|
+
|
|
18
|
+
Upgrade lockfiles to sqlite3 2.9.6 and raise the development gemspec floor so later resolves stay on the patched line.
|
|
19
|
+
|
|
20
|
+
## Trigger
|
|
21
|
+
|
|
22
|
+
- bundler-audit scanner match during the 2026-09-07 CI failure review.
|
|
23
|
+
|
|
24
|
+
## Assessment target
|
|
25
|
+
|
|
26
|
+
- CI and test graphs: dummy SQLite used by specs and appraisal.
|
|
27
|
+
- Published gem runtime: sqlite3 is a development dependency only.
|
|
28
|
+
|
|
29
|
+
## Advisory
|
|
30
|
+
|
|
31
|
+
- GHSA-mwm8-39rw-8826
|
|
32
|
+
- Maintainers: Medium, CVSS 4.0 score 6.3
|
|
33
|
+
- CISA KEV: not listed at the time of this record.
|
|
34
|
+
|
|
35
|
+
## Status
|
|
36
|
+
|
|
37
|
+
- CI and test graphs: fixed after lockfiles pin sqlite3 2.9.6.
|
|
38
|
+
- Published gem runtime: not_affected. Component not present in the published gem runtime.
|
|
39
|
+
|
|
40
|
+
## Applicability
|
|
41
|
+
|
|
42
|
+
- Vulnerable component present in the pre-fix development lockfiles at or below 2.9.5.
|
|
43
|
+
- Exploit conditions require custom multi-arg aggregates. Those APIs are absent from this tree.
|
|
44
|
+
|
|
45
|
+
## Priority
|
|
46
|
+
|
|
47
|
+
- CI graph: medium because bundler-audit fails the security job on version match.
|
|
48
|
+
- Published gem runtime: none. sqlite3 is not shipped to consumers of the gem.
|
|
49
|
+
|
|
50
|
+
## Disposition
|
|
51
|
+
|
|
52
|
+
- Upgrade. Prefer bundle lock --update=sqlite3 --conservative. Raise the development gemspec floor to >= 2.9.6 when sqlite3 is declared there.
|
|
53
|
+
|
|
54
|
+
## Next
|
|
55
|
+
|
|
56
|
+
- Keep sqlite3 as a development dependency.
|
|
57
|
+
|
|
58
|
+
## Source
|
|
59
|
+
|
|
60
|
+
- https://github.com/sparklemotion/sqlite3-ruby/security/advisories/GHSA-mwm8-39rw-8826
|
|
61
|
+
- https://github.com/sparklemotion/sqlite3-ruby/releases/tag/v2.9.6
|
|
62
|
+
- usr/docs/issues/20260907141000_engineering-and-dependency-audit.md
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
## Dependency
|
|
2
|
+
|
|
3
|
+
- activesupport / rails (locked 8.1.3.1 on Rails 8 appraisals and the root Gemfile.lock; 7.2.3.2 on rails72)
|
|
4
|
+
- json 3.0.2 (RubyGems latest as of 2026-09-09) versus development pin json >= 2.21.2, < 3
|
|
5
|
+
- Constraint in this repo: development gemspec only. json is not a runtime gemspec dependency.
|
|
6
|
+
|
|
7
|
+
## Symptom
|
|
8
|
+
|
|
9
|
+
With json 3.0.2, dummy GraphQL request specs that POST application/json fail with HTTP 400 and body errors message Invalid JSON. Rails raises ActionDispatch::Http::Parameters::ParseError. The cause is ArgumentError: wrong number of arguments (given 2, expected 1) from JSON.parse.
|
|
10
|
+
|
|
11
|
+
## Evidence
|
|
12
|
+
|
|
13
|
+
- json 3.0.0.rc1 (2026-08-11): JSON methods take keyword options, or options checked like keywords. A positional second Hash is no longer accepted by JSON.parse.
|
|
14
|
+
- ActiveSupport::JSON.decode in Rails 8.1.3.1 and 7.2.3.2 still calls JSON.parse(json, options) with a positional Hash. ActionDispatch JSON parameter parsing uses that decoder.
|
|
15
|
+
- This library's controller uses JSON.parse(body) with one argument. That call works on json 3. The dummy app fails before execute because Rails parses the request first.
|
|
16
|
+
- rails/rails#58601 merged 2026-08-28 (commit 0ca2c2c4cfbe7f0a709bca0589d2d74c1853ef27). It is not in 8.1.3.1 or 7.2.3.2.
|
|
17
|
+
|
|
18
|
+
## Suggested fix
|
|
19
|
+
|
|
20
|
+
Keep json on 2.21.2 in this repo's lockfiles until a Rails release includes the decode kwargs change. Then drop the development json < 3 pin and bundle update json.
|
|
21
|
+
|
|
22
|
+
Do not monkeypatch JSON.parse or ActiveSupport::JSON.decode in this library.
|
|
23
|
+
|
|
24
|
+
## Trigger
|
|
25
|
+
|
|
26
|
+
- bundle exec rspec after dropping the standard gem and resolving json 3.0.2. 71 request examples failed with Invalid JSON.
|
|
27
|
+
|
|
28
|
+
## Assessment target
|
|
29
|
+
|
|
30
|
+
- CI and test graphs: dummy Rails app used by spec/requests.
|
|
31
|
+
- Published gem execute path: JSON.parse of the request body with one argument.
|
|
32
|
+
|
|
33
|
+
## Status
|
|
34
|
+
|
|
35
|
+
- CI and test graphs: affected on json 3 with Rails 8.1.3.1 and 7.2.3.2. fixed after the development pin json < 3 and lockfiles at 2.21.2.
|
|
36
|
+
- Published gem execute path: not_affected for this ArgumentError. The one-argument JSON.parse path does not pass a positional options hash.
|
|
37
|
+
|
|
38
|
+
## Applicability
|
|
39
|
+
|
|
40
|
+
- Vulnerable component present: json 3 plus unreleased Rails decode.
|
|
41
|
+
- Exploit conditions: not a security advisory. Dummy JSON POST cannot complete parameter parsing.
|
|
42
|
+
|
|
43
|
+
## Priority
|
|
44
|
+
|
|
45
|
+
- CI graph: high because request specs fail on every GraphQL POST.
|
|
46
|
+
- Published gem execute path: low until a host on json 3 and unpatched Rails hits the same decoder.
|
|
47
|
+
|
|
48
|
+
## Disposition
|
|
49
|
+
|
|
50
|
+
- Pin. development gemspec json >= 2.21.2, < 3. Wait for a Rails patch release that includes rails/rails#58601.
|
|
51
|
+
|
|
52
|
+
## Next
|
|
53
|
+
|
|
54
|
+
- Watch Rails 8.1 / 7.2 patch notes for the json 3 decode kwargs fix. Then drop the json < 3 development pin and lock json 3.0.2 or newer.
|
|
55
|
+
|
|
56
|
+
## Source
|
|
57
|
+
|
|
58
|
+
- https://github.com/rails/rails/pull/58601
|
|
59
|
+
- https://github.com/ruby/json/blob/v3.0.2/CHANGES.md
|
|
60
|
+
- usr/docs/dependencies/20260907141000_json-cve-2026-71847.md
|
|
61
|
+
- usr/docs/issues/20260921114500_dependency-audit.md
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
## Dependency
|
|
2
|
+
|
|
3
|
+
- graphql (was 2.6.7, now 2.6.10 in Gemfile.lock and gemfiles/*.gemfile.lock; latest on RubyGems 2.6.10, published 2026-08-27)
|
|
4
|
+
- Constraint in this repo: gemspec add_runtime_dependency graphql >= 2.6.9
|
|
5
|
+
- Lockfiles: Gemfile.lock, gemfiles/rails72.gemfile.lock, gemfiles/rails8ruby34.gemfile.lock, gemfiles/rails8ruby4.gemfile.lock
|
|
6
|
+
|
|
7
|
+
## Symptom
|
|
8
|
+
|
|
9
|
+
bundle-audit matches graphql 2.6.7 against GHSA-rmxg-5p3r-j6hh on every lockfile. Solution text: update to >= 2.6.9.
|
|
10
|
+
|
|
11
|
+
## Evidence
|
|
12
|
+
|
|
13
|
+
- Advisory: GraphQL::Language::Cache#fetch reads parser cache files and passes contents to Marshal.load without authenticating payloads. If an attacker can place a crafted file on the expected path and the process calls GraphQL::Language::Parser.parse_file, attacker-controlled marshal_load or _load runs in the process.
|
|
14
|
+
- Affected versions: >= 1.12.6. Patched: 2.6.9. Latest registry version 2.6.10 is a later 2.6 patch (dataloader, parser, Execution::Next fixes). No CVE id on the GitHub advisory page as of 2026-09-21.
|
|
15
|
+
- This tree has no parse_file, parser_cache, or GraphQL::Language::Cache callers. Schema cache in ActiveAdmin::GraphQL is an in-process class cache, not the parser cache.
|
|
16
|
+
- Related older advisory GHSA-j7xr-4g94-r9h3 (Execution::Next authorization bypass) is patched in >= 2.6.6. Lockfiles already sit above that floor. The gemspec floor >= 2.3 still allows those versions for downstream resolvers.
|
|
17
|
+
|
|
18
|
+
## Suggested fix
|
|
19
|
+
|
|
20
|
+
Upgrade every lockfile to graphql 2.6.10. Raise the gemspec runtime floor to >= 2.6.9 so consumers cannot resolve the Marshal cache versions. Stay on 2.6; 2.6.10 changelog has no breaking-change heading.
|
|
21
|
+
|
|
22
|
+
## Trigger
|
|
23
|
+
|
|
24
|
+
- bundle-audit check against ruby-advisory-db commit 44784c295391577f25d198a9205eae4ba73ec4da (last updated 2026-09-16) during the 2026-09-21 dependency audit.
|
|
25
|
+
|
|
26
|
+
## Assessment target
|
|
27
|
+
|
|
28
|
+
- CI and test graphs: Gemfile.lock and appraisal locks.
|
|
29
|
+
- Published gem execute path: graphql is a direct runtime dependency. Exploit conditions require Parser.parse_file plus a writable parser cache path.
|
|
30
|
+
- Downstream products that resolve this gemspec: unassessed as unnamed consumers.
|
|
31
|
+
|
|
32
|
+
## Advisory
|
|
33
|
+
|
|
34
|
+
- GHSA-rmxg-5p3r-j6hh
|
|
35
|
+
- CWE-502
|
|
36
|
+
- Vendor severity High. bundler-audit criticality Unknown. No CVE. CISA KEV: not listed (no CVE id).
|
|
37
|
+
- Related: GHSA-j7xr-4g94-r9h3, patched >= 2.6.6, lockfiles already 2.6.7.
|
|
38
|
+
|
|
39
|
+
## Status
|
|
40
|
+
|
|
41
|
+
- CI and test graphs: fixed after lockfiles pin graphql 2.6.10 and the gemspec floor is >= 2.6.9.
|
|
42
|
+
- Published gem execute path: not_affected. Vulnerable code not in the execute path of this library or dummy app.
|
|
43
|
+
|
|
44
|
+
## Applicability
|
|
45
|
+
|
|
46
|
+
- Vulnerable component present: graphql 2.6.7 is a direct runtime gem.
|
|
47
|
+
- Exploit conditions: attacker-controlled parser cache file plus Parser.parse_file. Those APIs are absent from lib/ and spec/.
|
|
48
|
+
|
|
49
|
+
## Priority
|
|
50
|
+
|
|
51
|
+
- CI graph: high because bundle-audit fails on every lockfile.
|
|
52
|
+
- Published gem execute path: low. This library does not enable the parser cache.
|
|
53
|
+
- Downstream resolvers: medium until the gemspec floor moves. Consumers who set config.graphql.parser_cache = true on graphql < 2.6.9 meet the advisory conditions.
|
|
54
|
+
|
|
55
|
+
## Disposition
|
|
56
|
+
|
|
57
|
+
- Upgrade. bundle lock --update=graphql on the root Gemfile and each appraisal gemfile. Raise spec.add_runtime_dependency graphql to >= 2.6.9.
|
|
58
|
+
|
|
59
|
+
## Next
|
|
60
|
+
|
|
61
|
+
- Keep the gemspec floor at graphql >= 2.6.9. Do not drop it back to 2.3.
|
|
62
|
+
|
|
63
|
+
## Source
|
|
64
|
+
|
|
65
|
+
- https://github.com/rmosolgo/graphql-ruby/security/advisories/GHSA-rmxg-5p3r-j6hh
|
|
66
|
+
- https://rubysec.com/advisories/GHSA-rmxg-5p3r-j6hh/
|
|
67
|
+
- https://github.com/rmosolgo/graphql-ruby/blob/master/CHANGELOG.md (2.6.9 security note, 2.6.10 patch notes)
|
|
68
|
+
- https://rubysec.com/advisories/GHSA-j7xr-4g94-r9h3/
|
|
69
|
+
- usr/docs/issues/20260921114500_dependency-audit.md
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
## Dependency
|
|
2
|
+
|
|
3
|
+
activeadmin-graphql (this gem). List queries already expose paginated Ransack q, order, and first or last.
|
|
4
|
+
|
|
5
|
+
## Symptom
|
|
6
|
+
|
|
7
|
+
The gem has no Formtastic or Stimulus association picker that queries those lists as the person types. Hosts that need searchable associations either embed full catalogs in select or datalist, or keep a local combobox.
|
|
8
|
+
|
|
9
|
+
## Evidence
|
|
10
|
+
|
|
11
|
+
Schema and docs describe list fields with the same filter contract as the JSON index. There is no shipped input or controller that posts first and q, keeps a label plus hidden id, and replaces a bounded page on further typing.
|
|
12
|
+
|
|
13
|
+
## Suggested fix
|
|
14
|
+
|
|
15
|
+
When a second host needs the same control, or when packaging is requested, ship a Formtastic input and Stimulus controller that take GraphQL field name, node selection fields, search key, order, first, and optional extra q. Do not bake product model names into the gem. Keep host field maps and labels in the host. Until then, leave pickers host-local. Do not publish a third gem only for this picker.
|
|
16
|
+
|
|
17
|
+
## Next
|
|
18
|
+
|
|
19
|
+
Open an issue or pull request for the generic picker when packaging is requested. Index filter sidebars and multi-select include or exclude catalogs are out of scope for that first slice. Loading and error states, multi-select, and filter-sidebar wiring remain open after a first single-select page.
|
|
20
|
+
|
|
21
|
+
## Source
|
|
22
|
+
|
|
23
|
+
- docs/graphql-api.md list query contract
|
data/docs/graphql-api.md
CHANGED
|
@@ -223,6 +223,19 @@ mutation keys. `permit_params` and nested `create` / `update` blocks narrow
|
|
|
223
223
|
create and update inputs without hiding query fields. Default mutation inputs
|
|
224
224
|
omit `created_at` and `updated_at`.
|
|
225
225
|
|
|
226
|
+
### Nonconventional primary keys
|
|
227
|
+
|
|
228
|
+
GraphQL `id` always comes from `ActiveAdminResource` (`ID!`). An ActiveRecord
|
|
229
|
+
`id` column is never added as a second field. When `self.primary_key` is blank
|
|
230
|
+
but the model still has an `id` column (common for database views that project
|
|
231
|
+
`… AS id`), that column supplies the GraphQL `id` value. When the model has
|
|
232
|
+
neither a primary key nor an `id` column, schema build raises until you set
|
|
233
|
+
`self.primary_key` on the model (for example a view keyed by `row_key`). A
|
|
234
|
+
single-column primary key named something other than `id` is also exposed as
|
|
235
|
+
its own readable field beside `id`, unless `only` or `exclude` omits it. An
|
|
236
|
+
inferred `id` column must contain a unique, non-null value for every row;
|
|
237
|
+
ambiguous member and batched lookups fail instead of selecting one row.
|
|
238
|
+
|
|
226
239
|
### Composite primary keys (Rails 7.1+)
|
|
227
240
|
|
|
228
241
|
For models with `self.primary_key = [:book_code, :seq]` (and no separate `id`
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
Recorded 2026-09-07. Library gem. Scheduled CI bundler-audit failed on json CVE-2026-71847 and, where present, sqlite3 GHSA-mwm8-39rw-8826.
|
|
2
|
+
|
|
3
|
+
## Participants
|
|
4
|
+
|
|
5
|
+
- amkisko
|
|
6
|
+
|
|
7
|
+
## Decisions
|
|
8
|
+
|
|
9
|
+
- Bump json to 2.21.2 in Gemfile.lock and appraisal lockfiles. Keep json on 2.x because rubocop declares json ~> 2.3.
|
|
10
|
+
- Bump sqlite3 to 2.9.6 in the test graph where the pin was still affected. Raise the development gemspec floor to >= 2.9.6 when this gemspec declared sqlite3.
|
|
11
|
+
- Treat CVE-2026-71847 as not_affected for this gem execute path. The advisory names JSON::ResumableParser#partial_value.
|
|
12
|
+
- Treat GHSA-mwm8-39rw-8826 as not_affected for the published gem runtime when sqlite3 is development-only. Still bump the test graph so bundler-audit can pass.
|
|
13
|
+
- Leave Dependabot bundler at directory /. Appraisal *.gemfile names are not a working Dependabot directory.
|
|
14
|
+
|
|
15
|
+
## Effects
|
|
16
|
+
|
|
17
|
+
- Root and appraisal lockfiles pin json 2.21.2. sqlite3 pins 2.9.6 where that gem was in the graph.
|
|
18
|
+
- Dependency records live under usr/docs/dependencies.
|
|
19
|
+
|
|
20
|
+
## Next
|
|
21
|
+
|
|
22
|
+
- Appraisal lockfiles stay outside Dependabot directory /. Keep CI bundler-audit as the gate unless a later pass finds a supported Dependabot layout for those files.
|
|
23
|
+
|
|
24
|
+
## Source
|
|
25
|
+
|
|
26
|
+
- usr/docs/changelogs/20260907141000_advisory-lockfile-refresh.md
|
|
27
|
+
- usr/docs/dependencies/20260907141000_json-cve-2026-71847.md
|
|
28
|
+
- usr/docs/dependencies/20260907141000_sqlite3-ghsa-mwm8-39rw-8826.md
|
|
29
|
+
- https://github.com/ruby/json/security/advisories/GHSA-9hj4-r449-hfvc
|
|
30
|
+
- https://github.com/sparklemotion/sqlite3-ruby/security/advisories/GHSA-mwm8-39rw-8826
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
CI quality failed on a trailing blank line in spec/support/junit_formatter.rb. Test CI also ran bundler-audit or osv-scanner, which fail whenever an advisory lands even when a separate dependency audit already exists.
|
|
2
|
+
|
|
3
|
+
## Participants
|
|
4
|
+
|
|
5
|
+
- amkisko
|
|
6
|
+
|
|
7
|
+
## Decisions
|
|
8
|
+
|
|
9
|
+
- Drop bundler-audit and security jobs from test.yml so tests no longer wait on advisory freshness.
|
|
10
|
+
- Drop the advisory osv-scanner job from test.yml.
|
|
11
|
+
- Add dependency-audit.yml with workflow_dispatch only. Do not run it on push, pull request, or schedule.
|
|
12
|
+
- Disable osv-scanner in Trunk Check.
|
|
13
|
+
- Disable markdownlint MD013 in .markdownlint.yaml. Keep AGENTS.md in Trunk so other markdownlint rules still run.
|
|
14
|
+
- Keep lockfile and spec fixes that were already blocking quality or tests.
|
|
15
|
+
|
|
16
|
+
## Effects
|
|
17
|
+
|
|
18
|
+
- Test CI runs lint and specs without an advisory gate.
|
|
19
|
+
- Trunk Check no longer treats dependency CVEs as a required check.
|
|
20
|
+
- On-demand bundler-audit of every Gemfile.lock is available through workflow_dispatch.
|
|
21
|
+
|
|
22
|
+
## Next
|
|
23
|
+
|
|
24
|
+
- Run dependency audit on demand when a release or a known advisory needs it.
|
|
25
|
+
- Do not reintroduce advisory scanners into test.yml.
|
|
26
|
+
|
|
27
|
+
## Source
|
|
28
|
+
|
|
29
|
+
- GitHub Actions test and Trunk Check failures on 2026-09-17
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
# Mutation attribute allowlists
|
|
2
|
+
|
|
3
|
+
## Participants
|
|
4
|
+
|
|
5
|
+
Andrei Makarov
|
|
6
|
+
|
|
7
|
+
## Decisions
|
|
8
|
+
|
|
9
|
+
RFC 0006 Proposed adds assignable, create_only, update_only, and except_assignable (alias unassignable) on the per-resource graphql block.
|
|
10
|
+
|
|
11
|
+
only and except stay the readable ceiling. Mutation lists intersect that set and cannot widen it.
|
|
12
|
+
|
|
13
|
+
Default create and update inputs stay the current assignable column set, including timestamps. Changing that default would break clients.
|
|
14
|
+
|
|
15
|
+
ResourceQueryProxy#build_new still permits graphql_assignable_attribute_names so a resolve_create hook can set server-owned readable columns. The GraphQL input type and the mutation resolver slice use the mutation lists.
|
|
16
|
+
|
|
17
|
+
## Effects
|
|
18
|
+
|
|
19
|
+
Request spec spec/requests/graphql_mutation_allowlists_spec.rb failed first: six examples raised NoMethodError on the new DSL. Default examples passed and showed PostCreateInput includes created_at, updated_at, and starred, and that create_post persists a client-supplied created_at of 2020-01-02T03:04:05Z.
|
|
20
|
+
|
|
21
|
+
After the implementation that spec file: 8 examples, 0 failures (bundle exec rspec spec/requests/graphql_mutation_allowlists_spec.rb).
|
|
22
|
+
|
|
23
|
+
Claims from the downstream dependency note, checked in this tree at version 0.2.1:
|
|
24
|
+
|
|
25
|
+
1. Gem version is 0.2.1. Source: lib/active_admin/graphql/version.rb VERSION = "0.2.1". Outcome: supported.
|
|
26
|
+
2. Generated create and update inputs expose every assignable database column. Source: ActiveAdmin::Resource#default_attributes walks resource_class.columns minus primary key, STI, counter cache, and application filter_attributes (encrypted_password, password, password_confirmation). SchemaBuilder TypesInputs used graphql_assignable_attribute_names for both input types. Dummy PostCreateInput in the new spec includes title, body, starred, created_at, updated_at. Outcome: supported for ActiveAdmin resource_attributes, not every SQL column in the abstract (filtered password columns stay out).
|
|
27
|
+
3. The package mutations therefore accepted calculated values and internal timestamps that the server owns. Source: the same spec persisted created_at on create. Package column names (budget status, velocity, usage totals) are not in this repository. Outcome: supported for timestamps on Post; unverifiable for named Package columns.
|
|
28
|
+
4. only limits output fields, so it cannot express a mutation-only allowlist without hiding fields from queries. Source: attributes_for_graphql applies only_attributes and exclude_attributes; types_object and graphql_assignable_attribute_names both use that list. Outcome: supported.
|
|
29
|
+
5. The schema builder derives both mutation inputs from graphql_assignable_attribute_names and provides no separate create or update configuration. Source: types_inputs.rb before this change; ResourceConfig had only_attributes and exclude_attributes only. Outcome: supported for 0.2.1; outdated after RFC 0006 ships.
|
|
30
|
+
6. The application resolves the gem from its published package and records it in Gemfile.lock. Source: not this repository. Outcome: unverifiable here.
|
|
31
|
+
|
|
32
|
+
## Next
|
|
33
|
+
|
|
34
|
+
Keep RFC 0006 Proposed until 2026-10-05 lazy consensus. 0.3.0 metadata includes the graphql 2.6.9 floor and ActiveAdmin 4 Rails 8 matrix; tag and gem push wait on make release.
|
|
35
|
+
|
|
36
|
+
Later pass 2026-09-21: DSL renamed to ActiveAdmin permit_params with nested create and update blocks. create_only, update_only, assignable, and except_assignable were dropped before release. Spec path is spec/requests/graphql_mutation_permit_params_spec.rb. RFC file is rfcs/0006-mutation-permit-params.md. Default mutation inputs omit created_at and updated_at.
|
|
37
|
+
|
|
38
|
+
## Source
|
|
39
|
+
|
|
40
|
+
Downstream dependency note that described PackageCreateInput. RFC 0004. lib/active_admin/graphql/integration.rb. lib/active_admin/graphql/schema_builder/types_inputs.rb. vendor activeadmin-3.5.2 lib/active_admin/resource/attributes.rb and application_settings.rb filter_attributes. spec/requests/graphql_mutation_allowlists_spec.rb.
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
# Convention alignment engineering audit
|
|
2
|
+
|
|
3
|
+
## Participants
|
|
4
|
+
|
|
5
|
+
Andrei Makarov
|
|
6
|
+
|
|
7
|
+
## Decisions
|
|
8
|
+
|
|
9
|
+
Mutation write lists use ActiveAdmin permit_params. Per-operation lists live in nested create and update blocks with graphql-ruby resolve pairing, matching member_action_mutation. create_only, update_only, assignable, except_assignable, and unassignable are not in the public DSL.
|
|
10
|
+
|
|
11
|
+
Empty GraphQL input objects call has_no_arguments(true) so graphql-ruby 2.6 does not warn toward a future raise.
|
|
12
|
+
|
|
13
|
+
HTML permit_params is copied when the HTML call is a static argument list. A request-time block is not copied.
|
|
14
|
+
|
|
15
|
+
Default mutation inputs omit created_at and updated_at unless listed on permit_params.
|
|
16
|
+
|
|
17
|
+
destroy_post is registered as an alias of delete_post. graphql_name is an alias of type_name.
|
|
18
|
+
|
|
19
|
+
Failed save and update raise GraphQL::ExecutionError with extensions.errors. CRUD fields still return the resource object.
|
|
20
|
+
|
|
21
|
+
GraphqlController logs namespace, operation name, and error_count without the query body or current user.
|
|
22
|
+
|
|
23
|
+
ResourceMethods lives in lib/active_admin/graphql/resource_methods.rb.
|
|
24
|
+
|
|
25
|
+
## Effects
|
|
26
|
+
|
|
27
|
+
First pass used create_only. Second pass replaced it after a convention check against graphql-ruby 2.6.7, Rails 8.1 nested_attributes update_only, upsert_all update_only, and ActiveAdmin 3.5.2 permit_params.
|
|
28
|
+
|
|
29
|
+
bundle exec rspec spec/requests/graphql_mutation_permit_params_spec.rb: 8 examples, 0 failures after the rename.
|
|
30
|
+
|
|
31
|
+
## Findings
|
|
32
|
+
|
|
33
|
+
Severity high. Confidence high. Location SchemaBuilder TypesInputs default create and update inputs. Why it matters: extra-field write of created_at on create, observed in spec/requests/graphql_mutation_permit_params_spec.rb. Evidence kind observed. Security disposition confirmed. Smallest credible fix: graphql { permit_params :title, :body } in the host app. Deeper fix: omit created_at and updated_at from default mutation inputs in a later RFC, matching ActiveAdmin generators/boilerplate.rb assignable_attributes.
|
|
34
|
+
|
|
35
|
+
Severity medium. Confidence high. Location ResourceDefinitionDSL versus ActiveAdmin::ResourceDSL#permit_params. Why it matters: HTML and GraphQL write lists can drift. Evidence kind observed that GraphQL never calls HTML permit_params. Inference that a static argument list could be copied; confirming check is to parse the controller permitted_params method or store the original args on the resource. Smallest credible fix: document that graphql permit_params should match HTML. Deeper fix: seed GraphQL from a static HTML list when graphql permit_params is unset.
|
|
36
|
+
|
|
37
|
+
Severity medium. Confidence high. Location mutation_update_destroy.rb delete_ prefix versus actions.include?(:destroy). Why it matters: Rails and ActiveAdmin name the action destroy; GraphQL field is delete_post. Evidence kind observed. Smallest credible fix: none in this RFC; shipped client contract. Deeper fix: RFC to add destroy_* alias or rename.
|
|
38
|
+
|
|
39
|
+
Severity medium. Confidence high. Location mutation_create.rb returning the record and raising GraphQL::ExecutionError. Why it matters: graphql-ruby Schema::Mutation example returns hash with errors array. Evidence kind observed in graphql-2.6.7 lib/graphql/schema/mutation.rb. Smallest credible fix: none in this RFC. Deeper fix: payload type RFC.
|
|
40
|
+
|
|
41
|
+
Severity low. Confidence high. Location ResourceDefinitionDSL#type_name versus graphql-ruby graphql_name. Why it matters: two names for the same idea. Evidence kind observed. Smallest credible fix: alias graphql_name. Deeper fix: deprecate type_name after a release.
|
|
42
|
+
|
|
43
|
+
Severity low. Confidence high. Location ResourceDefinitionDSL#only versus ActiveAdmin action_item only: for controller actions. Why it matters: only already means attribute list in this gem since 0.2.1. Evidence kind observed. Smallest credible fix: keep only; document the split from ActiveAdmin action only.
|
|
44
|
+
|
|
45
|
+
Severity low. Confidence high. Location GraphqlController, no request correlation log. Why it matters: host logs may not show which GraphQL operation failed. Evidence kind observed absence of log calls in graphql_controller.rb. Smallest credible fix: none required of a library; host can log. Deeper fix: optional around_action.
|
|
46
|
+
|
|
47
|
+
Severity low. Confidence high. Location lib/active_admin/graphql/integration.rb line count 176. Why it matters: file is above the 150 line preference. Evidence kind observed. Smallest credible fix: extract ResourceMethods. Not done this pass.
|
|
48
|
+
|
|
49
|
+
## Next
|
|
50
|
+
|
|
51
|
+
Findings from the 2026-09-21 audit pass are addressed except replacing CRUD return types with graphql-ruby payload objects, which would break RFC 0004 field types. Keep RFC 0006 Proposed. 0.3.0 metadata includes the graphql 2.6.9 floor and ActiveAdmin 4 Rails 8 matrix; tag and gem push wait on make release.
|
|
52
|
+
|
|
53
|
+
## Source
|
|
54
|
+
|
|
55
|
+
rfcs/0006-mutation-permit-params.md
|
|
56
|
+
spec/requests/graphql_mutation_permit_params_spec.rb
|
|
57
|
+
vendor activeadmin-3.5.2 lib/active_admin/resource_dsl.rb permit_params
|
|
58
|
+
vendor activerecord-8.1.3.1 lib/active_record/nested_attributes.rb update_only
|
|
59
|
+
vendor graphql-2.6.7 lib/graphql/schema/mutation.rb
|
|
60
|
+
usr/docs/issues/20260921103000_mutation-attribute-allowlists.md
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
# Dependency audit 2026-09-21
|
|
2
|
+
|
|
3
|
+
Full audit: recon, security, freshness, ecosystem. Depth reached: full for hot-path direct packages; GitHub REST rate-limited after activeadmin, graphql-ruby, and ransack so remaining repo strain counts use registry dates, release pages, and fetched repo summaries.
|
|
4
|
+
|
|
5
|
+
## Participants
|
|
6
|
+
|
|
7
|
+
Andrei Makarov
|
|
8
|
+
|
|
9
|
+
## Decisions
|
|
10
|
+
|
|
11
|
+
Do not bump the whole graph to every registry latest. Hot-path and advisory matches first. Skip ActiveAdmin 4.0.0.beta23, json 3, arbre 2, inherited_resources 2, marcel 2, diff-lcs 2, and net-protocol 0.4. Those majors are either prerelease, pinned by ActiveAdmin 3.5.2, or required by rubocop json ~> 2.3.
|
|
12
|
+
|
|
13
|
+
Upgrade graphql to 2.6.10 and raise the gemspec floor to >= 2.6.9. That is the only security-driven change from this pass.
|
|
14
|
+
|
|
15
|
+
Optional same-pass lockfile patches with no major jump: rack 3.2.7, zeitwerk 2.8.3, responders 3.2.1, net-imap 0.6.7, bigdecimal 4.1.3, erb 6.0.7, unicode-display_width 3.3.0, unicode-emoji 4.3.0, polyrun 2.2.4, parallel_tests 5.8.0. rbs 4.2.0, io-console 0.9.4, reline 0.7.0, parallel 2.2.0, sprockets 4.4.1, and rubocop 1.91 sit behind Standard and Rails pins; bump only if those parents allow it.
|
|
16
|
+
|
|
17
|
+
Keep sqlite3 2.9.6 and json 2.21.2. Those pins already match the 2026-09-07 advisory records.
|
|
18
|
+
|
|
19
|
+
Stay on ActiveAdmin 3.5.2. It is the latest stable on RubyGems. 4.0.0.beta23 (2026-09-20) is prerelease and pulls arbre ~> 2.0 and inherited_resources ~> 2.0.
|
|
20
|
+
|
|
21
|
+
Do not reverse the 2026-09-17 choice to keep bundle-audit off test.yml. The on-demand workflow remains the gate. Makefile still has no audit target that mirrors that workflow.
|
|
22
|
+
|
|
23
|
+
## Effects
|
|
24
|
+
|
|
25
|
+
ruby-advisory-db update: 1245 advisories, last updated 2026-09-16 10:35:37 -0400, commit 44784c295391577f25d198a9205eae4ba73ec4da.
|
|
26
|
+
|
|
27
|
+
bundle-audit check failed on all four lockfiles with GHSA-rmxg-5p3r-j6hh (graphql 2.6.7, solution >= 2.6.9). No other scanner matches.
|
|
28
|
+
|
|
29
|
+
bundle outdated --strict on the root Gemfile listed 16 outdated specs. graphql 2.6.7 vs 2.6.10 is the only outdated hot-path direct runtime gem.
|
|
30
|
+
|
|
31
|
+
Libyears from Gemfile.lock vs RubyGems stable (compact-graph band: about 10 low, about 100 medium): 124 locked packages, 27 outdated, total lag 17.94 years, average 0.145 years per package, 6 packages one major behind (arbre, inherited_resources, json, marcel, diff-lcs, rubocop-capybara). Coverage floor in config/polyrun_coverage.yml is 85 percent line. No upgrade spike was run this pass.
|
|
32
|
+
|
|
33
|
+
No person-facing surface in this pass.
|
|
34
|
+
|
|
35
|
+
## Findings
|
|
36
|
+
|
|
37
|
+
Tier hot path direct. Kind security. Severity high. Confidence high. Package graphql 2.6.7. Why it matters: Marshal.load of unauthenticated parser cache files is RCE when parse_file runs. Evidence kind observed (bundle-audit, GHSA text, repo grep with no parse_file). Sources: GHSA-rmxg-5p3r-j6hh, ruby-advisory-db. Smallest fix: lock 2.6.10 and gemspec >= 2.6.9. Deeper fix: none. Status: CI graphs affected; this library execute path not_affected. Disposition: upgrade. Next: apply when confirmed.
|
|
38
|
+
|
|
39
|
+
Tier hot path direct. Kind freshness. Severity low. Confidence high. Package activeadmin 3.5.2 equals RubyGems stable latest (2026-07-13). Why it matters: 4.0.0.beta23 is a different major with arbre 2 and inherited_resources 2. Evidence kind observed (rubygems.org/gems/activeadmin). Watch: stay on 3.5.2 until a stable 4.0. Recon: github.com/activeadmin/activeadmin last push 2026-09-21, 9709 stars, 30 open issues, MIT, not archived.
|
|
40
|
+
|
|
41
|
+
Tier hot path direct. Kind recon. Severity low. Confidence high. Package graphql locked 2.6.7, latest 2.6.10. Upstream rmosolgo/graphql-ruby last push 2026-09-17, 5445 stars, 63 open issues, MIT. Maintainer cluster: rmosolgo, protocol family graphql-ruby, already the runtime schema engine. Classification healthy. 2.6.10 changelog is patch-level after the 2.6.9 security fix.
|
|
42
|
+
|
|
43
|
+
Tier hot path transitive. Kind ecosystem. Severity low. Confidence medium. Package kaminari 1.2.2. Why it matters: latest gem is still 1.2.2 from 2021-12-25 while GitHub last push is 2026-02-20 and several June 2026 PRs sit open. ActiveAdmin 3.5.2 and 4.0.0.beta23 still depend on kaminari >= 1.2.1. Evidence kind observed (rubygems version date, github.com/kaminari/kaminari). Watch, not a CVE. Cannot upgrade independently of ActiveAdmin.
|
|
44
|
+
|
|
45
|
+
Tier hot path transitive. Kind freshness. Severity low. Confidence high. Packages arbre 1.7.0 (latest 2.2.1) and inherited_resources 1.14.0 (latest 2.1.0). Why it matters: ActiveAdmin 3.5.2 pins arbre ~> 1.2 and inherited_resources ~> 1.7. Evidence kind observed (Gemfile.lock activeadmin 3.5.2 dependencies). Do not force majors.
|
|
46
|
+
|
|
47
|
+
Tier hot path transitive. Kind recon. Severity low. Confidence medium. Package ransack 4.4.1 equals latest (2025-09-29). github.com/activerecord-hackery/ransack last push 2026-05-31, 5860 stars, 156 open issues (about 2.7 percent). Classification healthy. formtastic 6.0.0 equals latest (2026-02-20). has_scope 0.9.0 and jquery-rails 4.6.1 equal latest.
|
|
48
|
+
|
|
49
|
+
Tier hot path transitive. Kind security. Severity low. Confidence high. Package rack 3.2.6 vs latest 3.2.7. Why it matters: April 2026 Rack CVEs (including GHSA-g2pf-xv49-m2h5 / CVE-2026-34835 and GHSA-h2jq-g4cq-5ppq / CVE-2026-34785) are patched in 3.2.6. 3.2.7 restores Ruby 2.4/2.5 compatibility only. Evidence kind observed (rack changelog 3.2.6 security section, 3.2.7 note). Status: not_affected for those CVEs at 3.2.6. Optional patch bump.
|
|
50
|
+
|
|
51
|
+
Tier dev/test. Kind freshness. Severity low. Confidence high. json 2.21.2 vs 3.0.2 blocked by rubocop json ~> 2.3. sqlite3 2.9.6 is latest and matches GHSA-mwm8-39rw-8826. rails 8.1.3.1 and 7.2.3.2 match appraisal floors and are current on those lines. appraisal 2.5.0 equals latest (2023-07-14); stale but current.
|
|
52
|
+
|
|
53
|
+
Tier automation. Kind automation gap. Severity low. Confidence high. Why it matters: Dependabot bundler directory / does not refresh gemfiles/*.gemfile.lock. scorecard.yml still pins actions/checkout 9c091bb (v7.0.0) while test.yml uses 3d3c42e5 (v7.0.1). ossf/scorecard-action 4eaacf05 is v2.4.3; v2.4.4 exists. mschilde/auto-label-merge-conflicts is commented as master. Makefile has no audit target. Evidence kind observed (workflow files, dependabot.yml). Smallest fix: optional action SHA refresh via Dependabot; keep appraisal locks in the on-demand audit. Do not put advisory scanners back on test.yml.
|
|
54
|
+
|
|
55
|
+
## Next
|
|
56
|
+
|
|
57
|
+
Wait for a Rails release that includes rails/rails#58601. Then drop the development json < 3 pin and bundle update json. Leave marcel 2 and diff-lcs 2 alone until those parents move.
|
|
58
|
+
|
|
59
|
+
The standard gem is gone. Lint uses rubocop plus a snapshot of standard 1.56.0 rules.
|
|
60
|
+
|
|
61
|
+
Optional: align scorecard.yml checkout SHA with v7.0.1.
|
|
62
|
+
|
|
63
|
+
## Later pass 2026-09-21
|
|
64
|
+
|
|
65
|
+
This gem is supposed to support ActiveAdmin 4. The first pass skipped the beta. That decision is reversed for the Rails 8 appraisals only.
|
|
66
|
+
|
|
67
|
+
Decisions: pin ActiveAdmin 4.0.0.beta23 in gemfiles/rails8ruby34.gemfile and gemfiles/rails8ruby4.gemfile. Keep ActiveAdmin ~> 3.5, >= 3.5.2 on rails72. Raise graphql gemspec floor to >= 2.6.9 and lock 2.6.10. Apply the optional patch set. net-protocol 0.4.0 came in with net-imap 0.6.7. json stays 2.21.2.
|
|
68
|
+
|
|
69
|
+
Rubocop and json 3 path: Standard 1.56.0 (latest, 2026-07-15) depends on rubocop ~> 1.88.0. Locked rubocop 1.88.2 depends on json ~> 2.3, which rejects json 3. RuboCop 1.91.0 depends on json >= 2.3, which allows json 3.0.2. graphql 2.6.8 already dropped quirks_mode for JSON 3. This library uses JSON.parse, JSON.generate, and JSON.dump(hash, buffer). json 3.0.1 restored the dump positional limit argument. Do not add a Gemfile rubocop override that fights Standard.
|
|
70
|
+
|
|
71
|
+
Effects: bundle-audit check on all four lockfiles: No vulnerabilities found. make lint: 84 files, no offenses, rbs validate ok. bundle exec rspec: 102 examples, 0 failures on the root ActiveAdmin 3.5.2 bundle. BUNDLE_GEMFILE=gemfiles/rails72.gemfile bundle exec rspec: 102 examples, 0 failures. BUNDLE_GEMFILE=gemfiles/rails8ruby34.gemfile and gemfiles/rails8ruby4.gemfile: 102 examples, 0 failures each on ActiveAdmin 4.0.0.beta23. Dummy GraphQL request specs did not need cssbundling-rails or importmap-rails. AA4 HTML asset install is still a host-app concern.
|
|
72
|
+
|
|
73
|
+
## Later pass 2026-09-21 drop standard
|
|
74
|
+
|
|
75
|
+
Dropped the standard gem. Locked rubocop 1.91.0. json 3.0.2 failed dummy GraphQL POSTs through Rails JSON.decode. Kept json 2.21.2 with development gemspec json >= 2.21.2, < 3. See usr/docs/changelogs/20260921112800_drop-standard-rubocop-direct.md and usr/docs/dependencies/20260921114000_rails-json-parse-kwargs.md.
|
|
76
|
+
|
|
77
|
+
## Source
|
|
78
|
+
|
|
79
|
+
Commands: bundle-audit update; bundle-audit check --gemfile-lock on Gemfile.lock and gemfiles/*.gemfile.lock; bundle outdated --strict; RubyGems /api/v1/gems and /api/v1/versions for locked-vs-latest lag; GitHub REST /repos for activeadmin/activeadmin, rmosolgo/graphql-ruby, activerecord-hackery/ransack.
|
|
80
|
+
|
|
81
|
+
https://github.com/rmosolgo/graphql-ruby/security/advisories/GHSA-rmxg-5p3r-j6hh
|
|
82
|
+
https://rubygems.org/gems/activeadmin
|
|
83
|
+
https://rubygems.org/gems/graphql
|
|
84
|
+
usr/docs/dependencies/20260921114500_graphql-ghsa-rmxg-5p3r-j6hh.md
|
|
85
|
+
usr/docs/dependencies/20260907141000_json-cve-2026-71847.md
|
|
86
|
+
usr/docs/dependencies/20260907141000_sqlite3-ghsa-mwm8-39rw-8826.md
|
|
87
|
+
usr/docs/dependencies/20260921114000_rails-json-parse-kwargs.md
|
|
88
|
+
https://github.com/rails/rails/pull/58601
|
|
89
|
+
usr/docs/issues/20260917123253_ci-drop-automatic-dependency-audit.md
|
|
90
|
+
usr/docs/issues/20260907141000_engineering-and-dependency-audit.md
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
# File length metrics
|
|
2
|
+
|
|
3
|
+
## Participants
|
|
4
|
+
|
|
5
|
+
Andrei Makarov
|
|
6
|
+
|
|
7
|
+
## Decisions
|
|
8
|
+
|
|
9
|
+
Per-file line count is Metrics/FileLength. RuboCop core does not ship that cop. The local cop counts physical source lines, including blanks and comments.
|
|
10
|
+
|
|
11
|
+
WarnMax is 150 and reports as info. Max is 300 and reports as error. RuboCop fail-level is refactor, so a warning offense would fail make lint the same as an error. Info is the non-failing warning band. Error is the alert that fails the run.
|
|
12
|
+
|
|
13
|
+
Class and module length stay at 200 with CountAsOne for array, hash, heredoc, and method_call. That sits between the preferred file size and the file alert. Complexity cops stay at cyclomatic 18, perceived 18, and AbcSize 35.
|
|
14
|
+
|
|
15
|
+
spec/requests/graphql_spec.rb is over 300 lines. It has a file-level disable until that request matrix is split.
|
|
16
|
+
|
|
17
|
+
## Effects
|
|
18
|
+
|
|
19
|
+
bundle exec rspec spec/unit/file_length_cop_spec.rb: 4 examples, 0 failures.
|
|
20
|
+
|
|
21
|
+
make lint: bundle exec rubocop, 86 files inspected, 5 info Metrics/FileLength offenses, exit 0. bundle exec rbs validate succeeded.
|
|
22
|
+
|
|
23
|
+
## Next
|
|
24
|
+
|
|
25
|
+
Split spec/requests/graphql_spec.rb so the disable can drop. Files in the info band at this pass: app/controllers/active_admin/graphql_controller.rb, lib/active_admin/graphql/integration.rb, lib/active_admin/graphql/resource_query_proxy/controller.rb, lib/active_admin/graphql/schema_builder/query_type_policies.rb, spec/requests/graphql_mutation_permit_params_spec.rb.
|
|
26
|
+
|
|
27
|
+
## Source
|
|
28
|
+
|
|
29
|
+
.rubocop.yml Metrics/FileLength, Metrics/ClassLength, Metrics/ModuleLength
|
|
30
|
+
rubocop/cop/metrics/file_length.rb
|
|
31
|
+
spec/unit/file_length_cop_spec.rb
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
# RFC starter pack
|
|
2
|
+
|
|
3
|
+
## Participants
|
|
4
|
+
|
|
5
|
+
Andrei Makarov
|
|
6
|
+
|
|
7
|
+
## Decisions
|
|
8
|
+
|
|
9
|
+
Pilot the portable RFC form: README, template, RFC 0001 Proposed, RFC 0002 Informational positioning, ids/0001 and ids/0002, CONTRIBUTING and GOVERNANCE pointers.
|
|
10
|
+
|
|
11
|
+
Isolation is off. Sequential numbering. An RFC specifies a design. Version numbers belong in changelogs. Shipped design specified after the fact is Stable.
|
|
12
|
+
|
|
13
|
+
## Effects
|
|
14
|
+
|
|
15
|
+
Starter files written on plan/rfc-process. Process RFC remains Proposed until 2026-08-31.
|
|
16
|
+
|
|
17
|
+
Later pass 2026-08-18: RFC 0002 marked as positioning. Types and statuses cite rfcs/README.md. Relates dropped from RFC 0002. Process text stays aligned with kiskolabs/pray RFC 0001 until that RFC is Stable.
|
|
18
|
+
|
|
19
|
+
Later pass 2026-08-18: RFC 0002 rewritten with concrete problems, shipped solutions, and which surfaces need a later Standards Track RFC. RFC 0001 Motivation names those surfaces.
|
|
20
|
+
|
|
21
|
+
Later pass 2026-08-18: as-built Informational RFCs added for each public contract named in RFC 0002. Describes stays on the current version. Status is Stable. RFC 0002 Relates those documents.
|
|
22
|
+
|
|
23
|
+
Later pass 2026-08-18: product RFCs specify a design. Suggestion, motivation, specification, effects, alternatives, and prior art. Version numbers belong in changelogs. RFC 0002 stays Informational. RFC 0003 and later are Standards Track Stable. Describes dropped.
|
|
24
|
+
|
|
25
|
+
## Next
|
|
26
|
+
|
|
27
|
+
Discuss RFC 0001. Extract amkisko/rfc-process after kiskolabs/pray RFC 0001 is Stable. Replace this hand-copied pack if the prayer differs.
|
|
28
|
+
|
|
29
|
+
## Source
|
|
30
|
+
|
|
31
|
+
Upstream: kiskolabs/pray rfcs/0001-rfc-process.md and usr/docs/plan/20260817200400_library-rfc-adoption.md.
|
|
@@ -53,7 +53,9 @@ module ActiveAdmin
|
|
|
53
53
|
elsif subject.is_a?(ActiveAdmin::Page)
|
|
54
54
|
"page:#{subject.name}"
|
|
55
55
|
elsif subject.is_a?(ActiveRecord::Base)
|
|
56
|
-
|
|
56
|
+
identity = PrimaryKey.graphql_id_value(subject)
|
|
57
|
+
identity = "#{identity}:object:#{subject.object_id}" if subject.class.primary_key.blank?
|
|
58
|
+
"record:#{subject.class.name}:#{identity}"
|
|
57
59
|
else
|
|
58
60
|
"object:#{subject.object_id}"
|
|
59
61
|
end
|
|
@@ -6,13 +6,14 @@ module ActiveAdmin
|
|
|
6
6
|
class RecordSource < ::GraphQL::Dataloader::Source
|
|
7
7
|
def initialize(model_class)
|
|
8
8
|
@model_class = model_class
|
|
9
|
-
@
|
|
9
|
+
@pk_columns = ActiveAdmin::PrimaryKey.columns(model_class)
|
|
10
|
+
@pk = ActiveAdmin::PrimaryKey.composite?(model_class) ? model_class.primary_key : @pk_columns.first
|
|
10
11
|
end
|
|
11
12
|
|
|
12
13
|
def fetch(ids)
|
|
13
14
|
keys = normalized_keys(ids)
|
|
14
15
|
uniq = keys.compact.uniq
|
|
15
|
-
return Array.new(ids.size) { nil } if uniq.empty?
|
|
16
|
+
return Array.new(ids.size) { nil } if uniq.empty? || @pk.nil?
|
|
16
17
|
|
|
17
18
|
indexed = load_records(uniq)
|
|
18
19
|
keys.map { |key| key.nil? ? nil : indexed[key] }
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module ActiveAdmin
|
|
4
|
+
module GraphQL
|
|
5
|
+
class ResourceQueryProxy
|
|
6
|
+
module Identity
|
|
7
|
+
private
|
|
8
|
+
|
|
9
|
+
def find_inferred_member(controller, model, id)
|
|
10
|
+
primary_key = ActiveAdmin::PrimaryKey.columns(model).first
|
|
11
|
+
raise ActiveRecord::RecordNotFound unless primary_key
|
|
12
|
+
|
|
13
|
+
records = controller.send(:scoped_collection).where(primary_key => id).limit(2).to_a
|
|
14
|
+
raise_ambiguous_id!(model) if records.size > 1
|
|
15
|
+
|
|
16
|
+
records.first || raise(ActiveRecord::RecordNotFound)
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def index_records_by_id(relation, model, primary_key)
|
|
20
|
+
if model.primary_key.present?
|
|
21
|
+
return relation.index_by { |record| record.public_send(primary_key).to_s }
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
grouped = relation.to_a.group_by { |record| record.public_send(primary_key).to_s }
|
|
25
|
+
if grouped.any? { |_id, matches| matches.size > 1 }
|
|
26
|
+
raise_ambiguous_id!(model)
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
grouped.transform_values(&:first)
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def raise_ambiguous_id!(model)
|
|
33
|
+
raise ::GraphQL::ExecutionError, "ambiguous GraphQL id for #{model.name}"
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
|
@@ -4,14 +4,14 @@ require "rack/mock"
|
|
|
4
4
|
require "stringio"
|
|
5
5
|
|
|
6
6
|
require_relative "resource_query_proxy/controller"
|
|
7
|
+
require_relative "resource_query_proxy/identity"
|
|
7
8
|
|
|
8
9
|
module ActiveAdmin
|
|
9
10
|
module GraphQL
|
|
10
|
-
# Reuses
|
|
11
|
-
# +find_resource+, authorization scoping, Ransack, menu scopes, +sorting+, +includes+)
|
|
12
|
-
# so GraphQL list/detail mutations align with the HTML/JSON list and member REST endpoints.
|
|
11
|
+
# Reuses ResourceController data access so GraphQL operations align with the REST endpoints.
|
|
13
12
|
class ResourceQueryProxy
|
|
14
13
|
include Controller
|
|
14
|
+
include Identity
|
|
15
15
|
|
|
16
16
|
def initialize(aa_resource:, user:, namespace:, graph_params: {})
|
|
17
17
|
@aa_resource = aa_resource
|
|
@@ -26,7 +26,12 @@ module ActiveAdmin
|
|
|
26
26
|
|
|
27
27
|
def find_member(id)
|
|
28
28
|
extra = member_route_params_for_find(id)
|
|
29
|
-
controller_for("show", extra)
|
|
29
|
+
controller = controller_for("show", extra)
|
|
30
|
+
model = @aa_resource.resource_class
|
|
31
|
+
finder = controller.send(:method_for_find)
|
|
32
|
+
return controller.send(:find_resource) if model.primary_key.present? || finder != :find
|
|
33
|
+
|
|
34
|
+
find_inferred_member(controller, model, extra.fetch("id"))
|
|
30
35
|
rescue ActiveRecord::RecordNotFound
|
|
31
36
|
nil
|
|
32
37
|
end
|
|
@@ -42,10 +47,10 @@ module ActiveAdmin
|
|
|
42
47
|
|
|
43
48
|
controller = controller_for("index")
|
|
44
49
|
relation = controller.send(:apply_authorization_scope, controller.send(:scoped_collection))
|
|
45
|
-
primary_key = model.
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
50
|
+
primary_key = ActiveAdmin::PrimaryKey.columns(model).first&.to_sym
|
|
51
|
+
return string_ids.index_with { nil } if primary_key.nil?
|
|
52
|
+
|
|
53
|
+
indexed = index_records_by_id(relation.where(primary_key => string_ids), model, primary_key)
|
|
49
54
|
string_ids.index_with { |identifier| indexed[identifier] }
|
|
50
55
|
end
|
|
51
56
|
|
|
@@ -83,12 +83,25 @@ module ActiveAdmin
|
|
|
83
83
|
end
|
|
84
84
|
|
|
85
85
|
pk_cols = ActiveAdmin::PrimaryKey.columns(model)
|
|
86
|
+
if pk_cols.empty?
|
|
87
|
+
raise ArgumentError,
|
|
88
|
+
"#{model.name} has no primary key for GraphQL `id`; set self.primary_key on the model"
|
|
89
|
+
end
|
|
86
90
|
|
|
87
91
|
type_class.field :id, ::GraphQL::Types::ID, null: false, authorize: false
|
|
88
92
|
type_class.define_method(:id) { ActiveAdmin::PrimaryKey.graphql_id_value(object) }
|
|
89
93
|
|
|
90
|
-
|
|
91
|
-
|
|
94
|
+
# ActiveAdmin omits a single-column primary key from resource_attributes; still expose
|
|
95
|
+
# non-id key columns as scalars (composite keys already remain in attributes).
|
|
96
|
+
# ActiveAdminResource owns GraphQL `id`; never emit a second field from an `id` column.
|
|
97
|
+
configured_pk_cols = pk_cols
|
|
98
|
+
if (only = aa_res.graphql_config.only_attributes)
|
|
99
|
+
configured_pk_cols &= only.map(&:to_s)
|
|
100
|
+
end
|
|
101
|
+
configured_pk_cols -= aa_res.graphql_config.exclude_attributes.map(&:to_s)
|
|
102
|
+
readable_names = (attr_names + configured_pk_cols).uniq
|
|
103
|
+
readable_names.each do |name|
|
|
104
|
+
next if name == "id"
|
|
92
105
|
|
|
93
106
|
col = cols_by_name[name]
|
|
94
107
|
next unless col
|
|
@@ -14,13 +14,22 @@ unless defined?(ActiveAdmin::PrimaryKey)
|
|
|
14
14
|
end
|
|
15
15
|
|
|
16
16
|
def ordered_columns(model)
|
|
17
|
-
|
|
18
|
-
|
|
17
|
+
cols = case (pk = model.primary_key)
|
|
18
|
+
when nil, false then []
|
|
19
|
+
when Array then pk.map(&:to_s).reject(&:empty?)
|
|
20
|
+
else
|
|
21
|
+
(name = pk.to_s).empty? ? [] : [name]
|
|
22
|
+
end
|
|
23
|
+
return cols if cols.any?
|
|
24
|
+
return %w[id] if model.respond_to?(:columns_hash) && model.columns_hash.key?("id")
|
|
19
25
|
|
|
20
|
-
|
|
21
|
-
|
|
26
|
+
[]
|
|
27
|
+
rescue ActiveRecord::StatementInvalid, ActiveRecord::ConnectionNotEstablished
|
|
28
|
+
[]
|
|
22
29
|
end
|
|
23
30
|
|
|
31
|
+
def columns(model) = ordered_columns(model)
|
|
32
|
+
|
|
24
33
|
def composite_attribute_hash(model, id_param)
|
|
25
34
|
cols = ordered_columns(model)
|
|
26
35
|
hash = normalize_composite_input(cols, id_param)
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: activeadmin-graphql
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.3.
|
|
4
|
+
version: 0.3.1
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Andrei Makarov
|
|
@@ -366,7 +366,29 @@ files:
|
|
|
366
366
|
- README.md
|
|
367
367
|
- activeadmin-graphql.gemspec
|
|
368
368
|
- app/controllers/active_admin/graphql_controller.rb
|
|
369
|
+
- docs/changelogs/20260818111600_rfc-0002-problems.md
|
|
370
|
+
- docs/changelogs/20260818114000_rfc-as-built-coverage.md
|
|
371
|
+
- docs/changelogs/20260818114700_rfc-design-not-version.md
|
|
372
|
+
- docs/changelogs/20260907141000_advisory-lockfile-refresh.md
|
|
373
|
+
- docs/changelogs/20260921103000_mutation-attribute-allowlists.md
|
|
374
|
+
- docs/changelogs/20260921111000_release-0-3-0.md
|
|
375
|
+
- docs/changelogs/20260921112800_drop-standard-rubocop-direct.md
|
|
376
|
+
- docs/changelogs/20260921120000_graphql-floor-and-activeadmin-4.md
|
|
377
|
+
- docs/changelogs/20261010101500_nonconventional-id-fields.md
|
|
378
|
+
- docs/changelogs/20261010103800_release-0-3-1.md
|
|
379
|
+
- docs/dependencies/20260907141000_json-cve-2026-71847.md
|
|
380
|
+
- docs/dependencies/20260907141000_sqlite3-ghsa-mwm8-39rw-8826.md
|
|
381
|
+
- docs/dependencies/20260921114000_rails-json-parse-kwargs.md
|
|
382
|
+
- docs/dependencies/20260921114500_graphql-ghsa-rmxg-5p3r-j6hh.md
|
|
383
|
+
- docs/dependencies/20261007161308_association-list-combobox.md
|
|
369
384
|
- docs/graphql-api.md
|
|
385
|
+
- docs/issues/20260907141000_engineering-and-dependency-audit.md
|
|
386
|
+
- docs/issues/20260917123253_ci-drop-automatic-dependency-audit.md
|
|
387
|
+
- docs/issues/20260921103000_mutation-attribute-allowlists.md
|
|
388
|
+
- docs/issues/20260921104400_convention-alignment-audit.md
|
|
389
|
+
- docs/issues/20260921114500_dependency-audit.md
|
|
390
|
+
- docs/issues/20260921115500_file-length-metrics.md
|
|
391
|
+
- docs/plan/20260817201500_rfc-starter.md
|
|
370
392
|
- lib/active_admin/graphql.rb
|
|
371
393
|
- lib/active_admin/graphql/auth_context.rb
|
|
372
394
|
- lib/active_admin/graphql/engine.rb
|
|
@@ -384,6 +406,7 @@ files:
|
|
|
384
406
|
- lib/active_admin/graphql/resource_methods.rb
|
|
385
407
|
- lib/active_admin/graphql/resource_query_proxy.rb
|
|
386
408
|
- lib/active_admin/graphql/resource_query_proxy/controller.rb
|
|
409
|
+
- lib/active_admin/graphql/resource_query_proxy/identity.rb
|
|
387
410
|
- lib/active_admin/graphql/run_action_mutation_config.rb
|
|
388
411
|
- lib/active_admin/graphql/run_action_mutation_dsl.rb
|
|
389
412
|
- lib/active_admin/graphql/run_action_payload.rb
|