rails_ai_admin 0.1.0
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 +7 -0
- data/CHANGELOG.md +458 -0
- data/LICENSE +21 -0
- data/README.md +292 -0
- data/SECURITY.md +14 -0
- data/THIRD_PARTY_NOTICES.md +19 -0
- data/app/assets/builds/rails_ai_admin.LICENSE.txt +55 -0
- data/app/assets/builds/rails_ai_admin.css +345 -0
- data/app/assets/builds/rails_ai_admin.js +33 -0
- data/app/controllers/rails_ai_admin/application_controller.rb +255 -0
- data/app/controllers/rails_ai_admin/assistant_controller.rb +164 -0
- data/app/controllers/rails_ai_admin/audit_controller.rb +16 -0
- data/app/controllers/rails_ai_admin/collection_jobs_controller.rb +33 -0
- data/app/controllers/rails_ai_admin/collection_operations_controller.rb +79 -0
- data/app/controllers/rails_ai_admin/custom_controller.rb +26 -0
- data/app/controllers/rails_ai_admin/dashboard_controller.rb +17 -0
- data/app/controllers/rails_ai_admin/exports_controller.rb +31 -0
- data/app/controllers/rails_ai_admin/files_controller.rb +37 -0
- data/app/controllers/rails_ai_admin/imports_controller.rb +41 -0
- data/app/controllers/rails_ai_admin/mcp_controller.rb +81 -0
- data/app/controllers/rails_ai_admin/mcp_tokens_controller.rb +45 -0
- data/app/controllers/rails_ai_admin/operations_controller.rb +105 -0
- data/app/controllers/rails_ai_admin/references_controller.rb +16 -0
- data/app/controllers/rails_ai_admin/resources_controller.rb +290 -0
- data/app/controllers/rails_ai_admin/search_controller.rb +39 -0
- data/app/controllers/rails_ai_admin/selections_controller.rb +95 -0
- data/app/controllers/rails_ai_admin/surfaces_controller.rb +122 -0
- data/app/helpers/rails_ai_admin/dashboard_helper.rb +28 -0
- data/app/helpers/rails_ai_admin/fields_helper.rb +242 -0
- data/app/helpers/rails_ai_admin/filters_helper.rb +40 -0
- data/app/helpers/rails_ai_admin/history_helper.rb +36 -0
- data/app/helpers/rails_ai_admin/navigation_helper.rb +54 -0
- data/app/helpers/rails_ai_admin/tool_views_helper.rb +48 -0
- data/app/jobs/rails_ai_admin/assistant_turn_job.rb +15 -0
- data/app/jobs/rails_ai_admin/collections/execution_job.rb +12 -0
- data/app/jobs/rails_ai_admin/outbox/delivery_job.rb +13 -0
- data/app/models/rails_ai_admin/application_record.rb +8 -0
- data/app/models/rails_ai_admin/audit_event.rb +12 -0
- data/app/models/rails_ai_admin/batch_item.rb +8 -0
- data/app/models/rails_ai_admin/operation_run.rb +20 -0
- data/app/models/rails_ai_admin/selection.rb +9 -0
- data/app/models/rails_ai_admin/selection_item.rb +9 -0
- data/app/models/rails_ai_admin/work_item.rb +18 -0
- data/app/views/layouts/rails_ai_admin/application.html.erb +49 -0
- data/app/views/layouts/rails_ai_admin/frame.html.erb +5 -0
- data/app/views/layouts/rails_ai_admin/status.html.erb +13 -0
- data/app/views/rails_ai_admin/assistant/_ask.html.erb +16 -0
- data/app/views/rails_ai_admin/assistant/_transcript.html.erb +45 -0
- data/app/views/rails_ai_admin/assistant/frame.html.erb +1 -0
- data/app/views/rails_ai_admin/assistant/index.html.erb +14 -0
- data/app/views/rails_ai_admin/assistant/show.html.erb +44 -0
- data/app/views/rails_ai_admin/audit/index.html.erb +40 -0
- data/app/views/rails_ai_admin/collection_jobs/index.html.erb +5 -0
- data/app/views/rails_ai_admin/collection_jobs/show.html.erb +24 -0
- data/app/views/rails_ai_admin/collection_operations/confirmation.html.erb +25 -0
- data/app/views/rails_ai_admin/collection_operations/failure.html.erb +10 -0
- data/app/views/rails_ai_admin/collection_operations/new.html.erb +11 -0
- data/app/views/rails_ai_admin/dashboard/index.html.erb +33 -0
- data/app/views/rails_ai_admin/fields/_index.html.erb +1 -0
- data/app/views/rails_ai_admin/fields/_input.html.erb +21 -0
- data/app/views/rails_ai_admin/fields/_reference.html.erb +1 -0
- data/app/views/rails_ai_admin/fields/_reference_picker.html.erb +14 -0
- data/app/views/rails_ai_admin/fields/_row.html.erb +27 -0
- data/app/views/rails_ai_admin/fields/_show.html.erb +1 -0
- data/app/views/rails_ai_admin/imports/new.html.erb +34 -0
- data/app/views/rails_ai_admin/mcp_tokens/index.html.erb +33 -0
- data/app/views/rails_ai_admin/operations/confirmation.html.erb +32 -0
- data/app/views/rails_ai_admin/operations/failure.html.erb +5 -0
- data/app/views/rails_ai_admin/operations/form.html.erb +13 -0
- data/app/views/rails_ai_admin/resources/_associations.html.erb +12 -0
- data/app/views/rails_ai_admin/resources/_errors.html.erb +14 -0
- data/app/views/rails_ai_admin/resources/_recovery.html.erb +5 -0
- data/app/views/rails_ai_admin/resources/confirm_destroy.html.erb +11 -0
- data/app/views/rails_ai_admin/resources/edit.html.erb +1 -0
- data/app/views/rails_ai_admin/resources/form.html.erb +16 -0
- data/app/views/rails_ai_admin/resources/history.html.erb +27 -0
- data/app/views/rails_ai_admin/resources/index.html.erb +88 -0
- data/app/views/rails_ai_admin/resources/new.html.erb +1 -0
- data/app/views/rails_ai_admin/resources/show.html.erb +12 -0
- data/app/views/rails_ai_admin/search/index.html.erb +20 -0
- data/app/views/rails_ai_admin/selections/confirm_destroy.html.erb +13 -0
- data/app/views/rails_ai_admin/selections/destroyed.html.erb +15 -0
- data/app/views/rails_ai_admin/selections/show.html.erb +19 -0
- data/app/views/rails_ai_admin/shared/_input_fields.html.erb +23 -0
- data/app/views/rails_ai_admin/shared/_navigation.html.erb +8 -0
- data/app/views/rails_ai_admin/shared/_session.html.erb +5 -0
- data/app/views/rails_ai_admin/statuses/show.html.erb +4 -0
- data/app/views/rails_ai_admin/surfaces/_operation_review.html.erb +43 -0
- data/app/views/rails_ai_admin/surfaces/show.html.erb +4 -0
- data/config/locales/en.yml +549 -0
- data/config/routes.rb +64 -0
- data/db/assistant_migrate/20261103000001_create_rails_ai_admin_assistant.rb +138 -0
- data/db/assistant_migrate/20261112000001_upgrade_rails_ai_admin_assistant_to_ruby_llm_2_2.rb +102 -0
- data/db/assistant_migrate/20261114000001_add_streaming_and_access_tokens_to_rails_ai_admin_assistant.rb +29 -0
- data/db/migrate/20261029000001_create_rails_ai_admin_execution_tables.rb +35 -0
- data/db/migrate/20261029000002_add_callback_warning_to_rails_ai_admin_runs.rb +7 -0
- data/db/migrate/20261030000003_create_rails_ai_admin_work_items.rb +26 -0
- data/db/migrate/20261030000004_create_rails_ai_admin_selections.rb +28 -0
- data/db/migrate/20261030000005_create_rails_ai_admin_collection_runs.rb +41 -0
- data/db/migrate/20261113000001_add_record_index_to_rails_ai_admin_audit_events.rb +8 -0
- data/lib/generators/rails_ai_admin/assistant/assistant_generator.rb +25 -0
- data/lib/generators/rails_ai_admin/assistant/templates/admin_assistant.rb +18 -0
- data/lib/generators/rails_ai_admin/engine_migrations.rb +42 -0
- data/lib/generators/rails_ai_admin/install/engine_mounts.rb +19 -0
- data/lib/generators/rails_ai_admin/install/install_generator.rb +53 -0
- data/lib/generators/rails_ai_admin/install/templates/access_test.rb +17 -0
- data/lib/generators/rails_ai_admin/install/templates/admin_context.rb +25 -0
- data/lib/generators/rails_ai_admin/install/templates/admin_policy_adapter.rb +28 -0
- data/lib/generators/rails_ai_admin/install/templates/example_admin.rb +10 -0
- data/lib/generators/rails_ai_admin/install/templates/initializer.rb +7 -0
- data/lib/generators/rails_ai_admin/override/override_generator.rb +46 -0
- data/lib/generators/rails_ai_admin/resource/resource_generator.rb +88 -0
- data/lib/rails_ai_admin/assistant/continuation.rb +33 -0
- data/lib/rails_ai_admin/assistant/coordinator.rb +306 -0
- data/lib/rails_ai_admin/assistant/records.rb +71 -0
- data/lib/rails_ai_admin/assistant/runtime.rb +49 -0
- data/lib/rails_ai_admin/assistant/tools.rb +477 -0
- data/lib/rails_ai_admin/assistant/transcript.rb +140 -0
- data/lib/rails_ai_admin/assistant.rb +50 -0
- data/lib/rails_ai_admin/authorization/access.rb +296 -0
- data/lib/rails_ai_admin/authorization/adapter.rb +92 -0
- data/lib/rails_ai_admin/authorization/pundit_adapter.rb +195 -0
- data/lib/rails_ai_admin/collections/claim.rb +91 -0
- data/lib/rails_ai_admin/collections/contract.rb +113 -0
- data/lib/rails_ai_admin/collections/dispatcher.rb +126 -0
- data/lib/rails_ai_admin/collections/queries.rb +79 -0
- data/lib/rails_ai_admin/collections/result.rb +15 -0
- data/lib/rails_ai_admin/collections/runner.rb +208 -0
- data/lib/rails_ai_admin/configuration.rb +178 -0
- data/lib/rails_ai_admin/context.rb +29 -0
- data/lib/rails_ai_admin/doctor.rb +301 -0
- data/lib/rails_ai_admin/engine.rb +24 -0
- data/lib/rails_ai_admin/error.rb +16 -0
- data/lib/rails_ai_admin/field.rb +625 -0
- data/lib/rails_ai_admin/fields/association.rb +188 -0
- data/lib/rails_ai_admin/fields/computation.rb +43 -0
- data/lib/rails_ai_admin/fields/dependency_graph.rb +45 -0
- data/lib/rails_ai_admin/fields/file_value.rb +23 -0
- data/lib/rails_ai_admin/fields/hook_signatures.rb +18 -0
- data/lib/rails_ai_admin/fields/projection.rb +78 -0
- data/lib/rails_ai_admin/fields/registry.rb +48 -0
- data/lib/rails_ai_admin/fields/scalar_schema.rb +49 -0
- data/lib/rails_ai_admin/fields/type.rb +50 -0
- data/lib/rails_ai_admin/forms/plan.rb +90 -0
- data/lib/rails_ai_admin/input_schema.rb +76 -0
- data/lib/rails_ai_admin/integrations/propose_operation.rb +150 -0
- data/lib/rails_ai_admin/integrations/tool_views.rb +367 -0
- data/lib/rails_ai_admin/mcp.rb +130 -0
- data/lib/rails_ai_admin/navigation/list_state.rb +194 -0
- data/lib/rails_ai_admin/navigation/menu.rb +31 -0
- data/lib/rails_ai_admin/navigation/settings.rb +28 -0
- data/lib/rails_ai_admin/operation.rb +120 -0
- data/lib/rails_ai_admin/operations/default_handlers.rb +17 -0
- data/lib/rails_ai_admin/operations/execution_context.rb +38 -0
- data/lib/rails_ai_admin/operations/form_intent.rb +69 -0
- data/lib/rails_ai_admin/operations/registry.rb +80 -0
- data/lib/rails_ai_admin/operations/result.rb +21 -0
- data/lib/rails_ai_admin/operations/runner.rb +633 -0
- data/lib/rails_ai_admin/operations/runner_fingerprint.rb +12 -0
- data/lib/rails_ai_admin/outbox/delivery_context.rb +51 -0
- data/lib/rails_ai_admin/outbox/dispatcher.rb +189 -0
- data/lib/rails_ai_admin/outbox/registry.rb +36 -0
- data/lib/rails_ai_admin/outbox/request_digest.rb +42 -0
- data/lib/rails_ai_admin/outbox/writer.rb +43 -0
- data/lib/rails_ai_admin/presentation/association_panel.rb +90 -0
- data/lib/rails_ai_admin/presentation/audit_log.rb +63 -0
- data/lib/rails_ai_admin/presentation/csv_export.rb +85 -0
- data/lib/rails_ai_admin/presentation/csv_import.rb +142 -0
- data/lib/rails_ai_admin/presentation/dashboard.rb +122 -0
- data/lib/rails_ai_admin/presentation/history.rb +46 -0
- data/lib/rails_ai_admin/presentation/index_settings.rb +77 -0
- data/lib/rails_ai_admin/presentation/outcomes.rb +44 -0
- data/lib/rails_ai_admin/presentation/status.rb +40 -0
- data/lib/rails_ai_admin/prune.rb +61 -0
- data/lib/rails_ai_admin/queries/list.rb +162 -0
- data/lib/rails_ai_admin/queries/named_scope.rb +65 -0
- data/lib/rails_ai_admin/record_version.rb +40 -0
- data/lib/rails_ai_admin/registry.rb +45 -0
- data/lib/rails_ai_admin/request_log_filter.rb +24 -0
- data/lib/rails_ai_admin/resource.rb +249 -0
- data/lib/rails_ai_admin/resource_identity.rb +15 -0
- data/lib/rails_ai_admin/schema_suggestions.rb +105 -0
- data/lib/rails_ai_admin/selections/builder.rb +162 -0
- data/lib/rails_ai_admin/templates/catalog.rb +84 -0
- data/lib/rails_ai_admin/templates/inspector.rb +94 -0
- data/lib/rails_ai_admin/templates/metadata.rb +48 -0
- data/lib/rails_ai_admin/templates/safe_paths.rb +30 -0
- data/lib/rails_ai_admin/test_kit.rb +103 -0
- data/lib/rails_ai_admin/version.rb +5 -0
- data/lib/rails_ai_admin/work.rb +48 -0
- data/lib/rails_ai_admin.rb +112 -0
- data/lib/tasks/rails_ai_admin.rake +58 -0
- metadata +328 -0
data/README.md
ADDED
|
@@ -0,0 +1,292 @@
|
|
|
1
|
+
# Rails AI Admin
|
|
2
|
+
|
|
3
|
+
A self-hosted Rails admin engine with explicitly registered resources and one
|
|
4
|
+
policy-checked, audited execution boundary for conventional CRUD.
|
|
5
|
+
|
|
6
|
+
**0.1.0 Public Preview.** Current code supplies conventional CRUD with everyday
|
|
7
|
+
field types (text, numbers, dates, times, email, URL, JSON, write-only passwords,
|
|
8
|
+
Active Storage files and Action Text rich text), `belongs_to` references,
|
|
9
|
+
many-to-many `references` lists, readonly `has_many`/`has_one` panels, registered
|
|
10
|
+
field types and partials, CSV export and import, record history, the audit log,
|
|
11
|
+
dashboard metrics and trends, bulk delete, a search across resources, synchronous member operations, fixed Selection previews, bounded
|
|
12
|
+
asynchronous collection operations, opt-in admin review Surfaces and a durable
|
|
13
|
+
outbox for one declared post-commit effect. Opt-in admin Chat streams replies and
|
|
14
|
+
turns proposals into review Surfaces. An optional MCP endpoint exposes the same
|
|
15
|
+
grant-filtered tools. Native-provider verification, token and cost budgets,
|
|
16
|
+
nested and polymorphic association writes and broader job-center workflows
|
|
17
|
+
remain open. The
|
|
18
|
+
[development plan](docs/development-plan.md) describes the target product, not the
|
|
19
|
+
supported feature set.
|
|
20
|
+
|
|
21
|
+
The engine supports custom policy adapters and an optional Pundit adapter with
|
|
22
|
+
explicit policy mappings per resource. The host owns authentication, tenants,
|
|
23
|
+
policies and domain data. Missing context or policy grants deny access. Generic writes require a record version
|
|
24
|
+
(`lock_version`, or else `updated_at`) and the same Active Record connection pool for domain records,
|
|
25
|
+
operation receipts, audit and Work items. Resources with irreversible callback
|
|
26
|
+
effects should remain readonly until their host boundary is redesigned and tested.
|
|
27
|
+
|
|
28
|
+
See [Field Types](docs/site/_core_features/field-types.md) for custom normalization,
|
|
29
|
+
validation, fixed Select labels and authorized form/index/show partials. Plugins
|
|
30
|
+
refine a core scalar; they do not grant access. [Computed Fields](docs/site/_core_features/computed-fields.md)
|
|
31
|
+
derive readonly values from declared, currently readable scalar dependencies.
|
|
32
|
+
Neither API exposes arbitrary model methods.
|
|
33
|
+
|
|
34
|
+
Use [Template Overrides](docs/site/_advanced/template-overrides.md) to copy one
|
|
35
|
+
public presentation template and review source/context drift with doctor. Host
|
|
36
|
+
overrides remain trusted Rails code and must preserve the execution boundary.
|
|
37
|
+
|
|
38
|
+
Build ordinary host-owned Rails pages with the public
|
|
39
|
+
[Custom Controller and Status API](docs/site/_advanced/custom-controllers.md).
|
|
40
|
+
Scoped Access and the shared Runner preserve the execution boundary; host routes,
|
|
41
|
+
layouts and partials remain ordinary Rails. The native-session packaged consumer
|
|
42
|
+
includes an Order review workbench that shares its operation with native pages.
|
|
43
|
+
|
|
44
|
+
Link records with [Associations](docs/site/_core_features/associations.md):
|
|
45
|
+
references and child lists resolve through each target resource's own grants,
|
|
46
|
+
so an association never shows or attaches a record its policy hides.
|
|
47
|
+
|
|
48
|
+
Group, label, order or hide sidebar and Overview entries with
|
|
49
|
+
[Resource Navigation](docs/site/_core_features/resource-navigation.md). The menu
|
|
50
|
+
follows current index grants; hiding an entry changes no direct authorization.
|
|
51
|
+
|
|
52
|
+
## Develop
|
|
53
|
+
|
|
54
|
+
To see the admin before installing it anywhere, run the demo. It copies the
|
|
55
|
+
packaged session/SQLite host to `tmp/demo`, seeds sample data and serves it on
|
|
56
|
+
127.0.0.1 only; Ctrl-C stops it:
|
|
57
|
+
|
|
58
|
+
```sh
|
|
59
|
+
bin/demo --assistant # everything, incl. admin Chat and MCP against an offline fake model (no key)
|
|
60
|
+
bin/demo # everything except admin Chat and MCP
|
|
61
|
+
# then open http://127.0.0.1:3917/login and click "Sign in as Admin"
|
|
62
|
+
# Open Assistant → New conversation and send: search articles for upgrading
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
Follow the [demo walkthrough](docs/site/_getting_started/demo.md#ai-chat-and-mcp)
|
|
66
|
+
to try streamed replies, record links and a change that you review in Chat.
|
|
67
|
+
|
|
68
|
+
```sh
|
|
69
|
+
bundle install
|
|
70
|
+
bundle exec rake test
|
|
71
|
+
bundle exec rake build
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
The build creates `pkg/rails_ai_admin-<version>.gem` (currently `0.1.0`); it
|
|
75
|
+
does not publish. `bundle exec rake release:check` reports release readiness, and
|
|
76
|
+
[RELEASING.md](RELEASING.md) lists the next release's open gates and procedure. The
|
|
77
|
+
[ten-minute quickstart](docs/site/_getting_started/quickstart.md) goes from an app
|
|
78
|
+
with Rails 8 sign-in to a working, policy-checked Users admin. The
|
|
79
|
+
[installation guide](docs/site/_getting_started/getting-started.md) covers other
|
|
80
|
+
hosts and adding a local build or development checkout. Then run:
|
|
81
|
+
|
|
82
|
+
```sh
|
|
83
|
+
bin/rails generate rails_ai_admin:install
|
|
84
|
+
bin/rails db:migrate
|
|
85
|
+
bin/rails generate rails_ai_admin:resource Customer
|
|
86
|
+
bin/rails rails_ai_admin:doctor
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
Installation stays closed: the generated `AdminContext` returns nil and the
|
|
90
|
+
`AdminPolicyAdapter` stub denies all actions/fields. The install generator also
|
|
91
|
+
provides an unregistered `ExampleAdmin` and an anonymous HTTP test at
|
|
92
|
+
`test/rails_ai_admin/access_test.rb`. These are starting points, not a working
|
|
93
|
+
authentication integration.
|
|
94
|
+
|
|
95
|
+
The resource generator keeps only a readonly ID enabled and leaves the resource
|
|
96
|
+
unregistered. When model schema is available, it adds commented scalar field
|
|
97
|
+
suggestions for review. It does not sample records; sensitive/encrypted fields,
|
|
98
|
+
foreign keys and polymorphic type columns, STI inheritance columns,
|
|
99
|
+
`lock_version`, authority-like names such as role/permission/security_version,
|
|
100
|
+
and unsupported types are excluded from suggestions. A declared non-polymorphic
|
|
101
|
+
`belongs_to` is suggested as a commented `belongs_to` field.
|
|
102
|
+
Missing models or unavailable table metadata still leave the safe readonly scaffold.
|
|
103
|
+
Implement host authentication and explicit policies, then review fields and
|
|
104
|
+
register class-name strings in the initializer.
|
|
105
|
+
|
|
106
|
+
```ruby
|
|
107
|
+
RailsAiAdmin.configure do |config|
|
|
108
|
+
config.context_adapter = "AdminContext"
|
|
109
|
+
config.authorization_adapter = "AdminPolicyAdapter"
|
|
110
|
+
config.resources = ["CustomerAdmin"]
|
|
111
|
+
end
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
```ruby
|
|
115
|
+
class CustomerAdmin < RailsAiAdmin::Resource
|
|
116
|
+
model "Customer"
|
|
117
|
+
key :customers
|
|
118
|
+
title :name
|
|
119
|
+
|
|
120
|
+
fields do
|
|
121
|
+
id :id
|
|
122
|
+
text :name, required: true, nullable: false,
|
|
123
|
+
searchable: :prefix, sortable: true
|
|
124
|
+
end
|
|
125
|
+
end
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
Run the generated anonymous request test before and after adapting the host:
|
|
129
|
+
|
|
130
|
+
```sh
|
|
131
|
+
bin/rails test test/rails_ai_admin/access_test.rb
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
Doctor reports obviously incompatible public zero-argument constructors/signatures, schema,
|
|
135
|
+
field-type review hints, sortable-index and sensitive-declaration findings,
|
|
136
|
+
and default autoload-path diagnostics. Its metadata cannot prove authentication
|
|
137
|
+
or authorization. `TestKit` provides separate anonymous-context, action, tenant
|
|
138
|
+
and exact field-grant assertions; field-grant snapshots are not an AI exposure
|
|
139
|
+
report. See the [host verification guide](docs/site/_advanced/host-verification.md).
|
|
140
|
+
|
|
141
|
+
Resources can also declare named index tabs with `scopes`. Each tab needs its own
|
|
142
|
+
default-deny `named_scopes` grant and can only narrow the policy relation; see
|
|
143
|
+
the [Named Scopes guide](docs/site/_core_features/named-scopes.md). Fields can opt
|
|
144
|
+
into typed exact/range filters with `filterable:`, behind a separate default-deny
|
|
145
|
+
`:filter` field grant; see the [Typed Filters guide](docs/site/_core_features/typed-filters.md).
|
|
146
|
+
An `index` block chooses columns, a default sort, page size and an optional
|
|
147
|
+
bounded count; see the [Index Tables guide](docs/site/_core_features/index-tables.md).
|
|
148
|
+
|
|
149
|
+
The resource declaration grants no permission. See the runnable host contract
|
|
150
|
+
examples in the [configuration guide](docs/site/_getting_started/configuration.md).
|
|
151
|
+
Use one static-path engine mount whose final helper name is `rails_ai_admin`,
|
|
152
|
+
with no HTTP-verb restriction. Run installation inside the target Rails app; its
|
|
153
|
+
loaded routes are checked before writing, including drawn files and namespace
|
|
154
|
+
prefixes. Other helper names, dynamic path parameters and multiple mounts are
|
|
155
|
+
rejected. Admin CSS/ESM are
|
|
156
|
+
prebuilt in the gem, so a host does not need Node to compile them. No provider key,
|
|
157
|
+
AI table or provider call is required for conventional mode.
|
|
158
|
+
|
|
159
|
+
## Custom Operations and Follow-Up Delivery
|
|
160
|
+
|
|
161
|
+
Register a `RailsAiAdmin::Operation` on a resource for a synchronous member command.
|
|
162
|
+
Its native input form leads to input-bound preflight and a separate human
|
|
163
|
+
confirmation, using the same Runner/receipt/audit transaction as CRUD. Operation
|
|
164
|
+
inputs, committed-receipt reads and follow-up delivery have independent grants;
|
|
165
|
+
ordinary editable-field permissions do not grant them. Successful custom receipt
|
|
166
|
+
replay compares its already bound schema/input digest, not current input grants;
|
|
167
|
+
failed or changed replay input returns a generic conflict without field errors.
|
|
168
|
+
See the
|
|
169
|
+
[Operation guide](docs/site/_core_features/operations.md).
|
|
170
|
+
|
|
171
|
+
`RailsAiAdmin::Work` reuses the input DSL for post-commit delivery. Registered
|
|
172
|
+
`config.work_handlers` persist bounded payload/digest intent through
|
|
173
|
+
`context.outbox.enqueue`. Work performs one declared `context.effect(request:)`
|
|
174
|
+
using a stable downstream delivery key and a dedicated digest of its plain JSON
|
|
175
|
+
wire request. Typed values must be serialized first; normalized key collisions,
|
|
176
|
+
nonfinite floats and unsupported objects are rejected. Ordinary Active Record
|
|
177
|
+
writes in Work/effect execution are guarded, while trusted Ruby remains outside
|
|
178
|
+
a sandbox. A successful business result does not
|
|
179
|
+
mean the effect finished. Outbox auto-dispatch defaults to false; the host must
|
|
180
|
+
schedule `rails_ai_admin:work:scan` or bounded `work:drain` recovery. Optional
|
|
181
|
+
after-commit enqueue is only an accelerator.
|
|
182
|
+
|
|
183
|
+
The default exact record-version policy stops delivery after later record edits.
|
|
184
|
+
Unknown non-idempotent effects require reconciliation rather than automatic
|
|
185
|
+
retry. Leases/fencing and persistent payloads do not establish downstream
|
|
186
|
+
exactly-once execution. Read the [Durable Outbox guide](docs/site/_advanced/durable-outbox.md)
|
|
187
|
+
before enabling a real transport. Preflight's Active Record write guard is not a
|
|
188
|
+
trusted-Ruby sandbox, and operation duration checks do not hard-interrupt Ruby/SQL.
|
|
189
|
+
Global operations, CRUD handler replacement and AI/Surface dispatch remain
|
|
190
|
+
unavailable; complete release Gates remain open.
|
|
191
|
+
|
|
192
|
+
## Review Surfaces
|
|
193
|
+
|
|
194
|
+
Hosts that already use rails_tool_views can set `config.surfaces = true` and mark
|
|
195
|
+
member operations `surface: true`. A native review can then be saved as a
|
|
196
|
+
persistent Surface that confirms the same intent once, through admin-owned
|
|
197
|
+
endpoints that leave the host's rails_tool_views settings untouched. Operations
|
|
198
|
+
marked `assistant: true` can also be proposed by an assistant through the
|
|
199
|
+
on-demand `raa_propose_operation` RubyLLM tool; only the user's Surface
|
|
200
|
+
confirmation executes them. See the
|
|
201
|
+
[Review Surfaces guide](docs/site/_advanced/review-surfaces.md).
|
|
202
|
+
|
|
203
|
+
## Admin Assistant
|
|
204
|
+
|
|
205
|
+
Hosts that load ruby_llm can run `bin/rails generate rails_ai_admin:assistant`
|
|
206
|
+
and set `config.assistant = true`. The assistant reads records through each
|
|
207
|
+
admin's current grants plus a default-deny `assistant?` grant, reads audited
|
|
208
|
+
record history, and answers questions asked from a record or list page. It
|
|
209
|
+
cannot change data: a suggested create, update, delete (for resources that
|
|
210
|
+
declare `assistant_changes`) or business operation opens a review Surface with
|
|
211
|
+
before → after values, and only the person's confirmation writes it, once, as
|
|
212
|
+
that person, with a version check and an audit event. Creates are reviewed too.
|
|
213
|
+
Replies stream as they are written. With `config.mcp = true`, outside agents
|
|
214
|
+
(Claude Code, Cursor) use the same tools through an MCP endpoint under personal
|
|
215
|
+
access tokens, and their proposals wait for confirmation in the admin. Turns run in jobs through a leased inbox that
|
|
216
|
+
recovers after crashes without repeating messages. Provider settings come from
|
|
217
|
+
your own adapter, never from global RubyLLM configuration. See the
|
|
218
|
+
[Admin Assistant guide](docs/site/_advanced/admin-assistant.md).
|
|
219
|
+
|
|
220
|
+
## Fixed Selection Previews
|
|
221
|
+
|
|
222
|
+
A default-deny `export_records?` grant adds an Export CSV button for the current list
|
|
223
|
+
(same rows, columns and values as the pages; audited and bounded by `export_limit`).
|
|
224
|
+
A default-deny `view_history?` grant adds a record History page listing its audited
|
|
225
|
+
changes (fields named only when currently readable or writable).
|
|
226
|
+
|
|
227
|
+
A separate default-deny `select_records?` grant enables native index checkboxes
|
|
228
|
+
and a no-JavaScript preview of up to 100 explicit targets. `Selections::Builder`
|
|
229
|
+
captures exact canonical IDs/versions and revalidates ownership, security version,
|
|
230
|
+
expiry, resource contract and current record/field grants. Newly matching records
|
|
231
|
+
or same-count replacements cannot expand a captured manifest. Labels are freshly
|
|
232
|
+
projected; only IDs/versions/positions and parent binding metadata are persisted.
|
|
233
|
+
|
|
234
|
+
Capture is not operation approval and creates no OperationRun, business audit,
|
|
235
|
+
Work item or job. See [Fixed Selections](docs/site/_core_features/selections.md).
|
|
236
|
+
|
|
237
|
+
## Asynchronous Collection Operations
|
|
238
|
+
|
|
239
|
+
Register an `Operation` with `scope: :collection` to apply its per-record handler
|
|
240
|
+
to a fixed Selection of at most 100 targets. Native input, pure review and explicit
|
|
241
|
+
**Confirm and queue** create one approved parent with durable child intents/items;
|
|
242
|
+
admission performs no domain mutation. Each worker attempt rebuilds current host
|
|
243
|
+
authority and commits a target change, audit, receipt, optional outbox and item
|
|
244
|
+
completion in one transaction. Public member execution cannot execute child intents.
|
|
245
|
+
|
|
246
|
+
Items commit independently. Cancellation stops remaining uncommitted items and
|
|
247
|
+
preserves committed changes and their Work. Approval expiry controls admission;
|
|
248
|
+
a separate execution deadline bounds the admitted run. Job receipts use separate
|
|
249
|
+
current receipt grants; cancellation needs its own `cancel_operation?` grant.
|
|
250
|
+
The parent stores bounded typed input once, so exclude credentials and secrets.
|
|
251
|
+
|
|
252
|
+
`collection_auto_dispatch` defaults to false. The host supplies `resolve_job`, a
|
|
253
|
+
persistent queue and recurring `rails_ai_admin:collections:scan` (or bounded
|
|
254
|
+
`collections:drain`); after-commit enqueue only accelerates recovery. Read
|
|
255
|
+
[Collection Operations](docs/site/_core_features/collection-operations.md) before
|
|
256
|
+
enabling workers. All-filtered/10,000-target manifests, global operations, a full
|
|
257
|
+
job center and retention remain planned; this bounded slice does not close the
|
|
258
|
+
full roadmap or release Gates.
|
|
259
|
+
|
|
260
|
+
## Read the Contracts
|
|
261
|
+
|
|
262
|
+
- [Architecture](ARCHITECTURE.md), [public contract](docs/reference/public-contract.md)
|
|
263
|
+
and [operation semantics](docs/reference/operations.md).
|
|
264
|
+
- [Resources and fields](docs/site/_core_features/resources-and-fields.md),
|
|
265
|
+
[host verification](docs/site/_advanced/host-verification.md) and
|
|
266
|
+
[data/security boundaries](docs/site/_advanced/data-and-security.md).
|
|
267
|
+
- [Compatibility evidence](COMPATIBILITY.md), [roadmap](ROADMAP.md) and
|
|
268
|
+
[dependency integration constraints](docs/reference/dependency-contracts.md).
|
|
269
|
+
|
|
270
|
+
An independent [Devise/Pundit/PostgreSQL consumer](spec_hosts/devise_postgres)
|
|
271
|
+
exercises UUID tickets, verified tenant memberships, development reload and
|
|
272
|
+
fresh-process crash/replay using the built gem. Its Propshaft/jsbundling and
|
|
273
|
+
Sprockets/jsbundling modes are asset variants of one consumer. See the
|
|
274
|
+
[Pundit/Devise guide](docs/site/_advanced/pundit-and-devise.md) and
|
|
275
|
+
[host verification guide](docs/site/_advanced/host-verification.md). The engine
|
|
276
|
+
does not provide accounts or login routes. The fixture's separate product Chat
|
|
277
|
+
and Surface remain host-owned, beside its opt-in admin Chat.
|
|
278
|
+
|
|
279
|
+
Changing a resource's policy mapping changes its operation fingerprint. Reopen
|
|
280
|
+
existing development forms if their old intents are invalidated.
|
|
281
|
+
|
|
282
|
+
The Jekyll/RDoc site lives under `docs/site/`. Install its separate bundle, then
|
|
283
|
+
run `docs/site/bin/build.sh`. See [Releasing](RELEASING.md) for the Pages setup
|
|
284
|
+
and versioned builds.
|
|
285
|
+
|
|
286
|
+
Local automated checks and internal review do not establish production readiness,
|
|
287
|
+
independent security review, real-provider behavior or user acceptance. Release
|
|
288
|
+
gates remain in the plan; publishing requires explicit maintainer approval.
|
|
289
|
+
|
|
290
|
+
Licensed under [MIT](LICENSE). Dependencies retain their own licenses in
|
|
291
|
+
[third-party notices](THIRD_PARTY_NOTICES.md). Read [SECURITY.md](SECURITY.md) before
|
|
292
|
+
reporting a vulnerability and [CONTRIBUTING.md](CONTRIBUTING.md) before contributing.
|
data/SECURITY.md
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
# Security policy
|
|
2
|
+
|
|
3
|
+
0.1.0 is a Public Preview. Review the limitations in CHANGELOG.md and deploy
|
|
4
|
+
behind your host application's authentication and network controls. Verify
|
|
5
|
+
tenant scopes and action and field grants before granting access.
|
|
6
|
+
|
|
7
|
+
Report suspected vulnerabilities privately to wangyaodi@gmail.com. Include the
|
|
8
|
+
affected version, minimal synthetic reproduction, impact and suggested fix.
|
|
9
|
+
Do not open a public issue containing exploit details or sensitive data. Reports
|
|
10
|
+
are reviewed by the maintainer; no response-time SLA is currently offered.
|
|
11
|
+
|
|
12
|
+
Authentication and policies belong to the host. A logged-in actor alone grants
|
|
13
|
+
no resource access. Trusted Ruby extensions are not sandboxed. See the threat
|
|
14
|
+
model and public contract for the supported transaction and privacy boundaries.
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
# Third-party notices
|
|
2
|
+
|
|
3
|
+
Original project code is MIT licensed. No competitor source or assets are copied.
|
|
4
|
+
Runtime dependencies retain their own notices in their distributed packages:
|
|
5
|
+
|
|
6
|
+
| Dependency | License | Source |
|
|
7
|
+
| --- | --- | --- |
|
|
8
|
+
| Rails | MIT | https://github.com/rails/rails |
|
|
9
|
+
| rails_tool_views | MIT | https://github.com/yorzi/rails_tool_views |
|
|
10
|
+
| RubyLLM | MIT | https://github.com/crmne/ruby_llm |
|
|
11
|
+
| Turbo / turbo-rails | MIT | https://github.com/hotwired/turbo-rails |
|
|
12
|
+
| Stimulus / stimulus-rails | MIT | https://github.com/hotwired/stimulus-rails |
|
|
13
|
+
|
|
14
|
+
The prebuilt ESM contains Turbo 8.0.23, Stimulus 3.2.2 and the rails_tool_views 1.0.2
|
|
15
|
+
Stimulus controller. Their complete notices
|
|
16
|
+
ship in `app/assets/builds/rails_ai_admin.LICENSE.txt`, generated from the sources
|
|
17
|
+
recorded in `frontend/licenses/README.md`. The host needs no Node build for these
|
|
18
|
+
assets. Dependency installation and license declarations do not prove a security
|
|
19
|
+
audit or grant rights to third-party trademarks.
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
Turbo 8.0.23
|
|
2
|
+
Copyright (c) 37signals
|
|
3
|
+
|
|
4
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
|
5
|
+
a copy of this software and associated documentation files (the
|
|
6
|
+
"Software"), to deal in the Software without restriction, including
|
|
7
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
|
8
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
|
9
|
+
permit persons to whom the Software is furnished to do so, subject to
|
|
10
|
+
the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be
|
|
13
|
+
included in all copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
16
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
17
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
18
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
|
19
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
|
20
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
|
21
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
22
|
+
|
|
23
|
+
Stimulus 3.2.2
|
|
24
|
+
# MIT License
|
|
25
|
+
|
|
26
|
+
Copyright © 2021 Basecamp, LLC.
|
|
27
|
+
|
|
28
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
|
29
|
+
|
|
30
|
+
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
|
31
|
+
|
|
32
|
+
The Software is provided "as is," without warranty of any kind, express or implied, including but not limited to the warranties of merchantability, fitness for a particular purpose and noninfringement. In no event shall the authors or copyright holders be liable for any claim, damages or other liability, whether in an action of contract, tort or otherwise, arising from, out of or in connection with the Software or the use or other dealings in the Software.
|
|
33
|
+
|
|
34
|
+
rails_tool_views 1.0.2 (Stimulus controller)
|
|
35
|
+
MIT License
|
|
36
|
+
|
|
37
|
+
Copyright (c) 2026 Andy Wang
|
|
38
|
+
|
|
39
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
40
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
41
|
+
in the Software without restriction, including without limitation the rights
|
|
42
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
43
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
44
|
+
furnished to do so, subject to the following conditions:
|
|
45
|
+
|
|
46
|
+
The above copyright notice and this permission notice shall be included in all
|
|
47
|
+
copies or substantial portions of the Software.
|
|
48
|
+
|
|
49
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
50
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
51
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
52
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
53
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
54
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
55
|
+
SOFTWARE.
|