source_monitor 0.14.0 → 0.15.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 +4 -4
- data/.claude/skills/sm-upgrade/reference/version-history.md +14 -0
- data/AGENTS.md +145 -38
- data/CHANGELOG.md +14 -0
- data/CLAUDE.md +6 -116
- data/Gemfile.lock +86 -86
- data/README.md +3 -3
- data/VERSION +1 -1
- data/docs/setup.md +3 -3
- data/docs/upgrade.md +14 -0
- data/lib/source_monitor/version.rb +1 -1
- data/source_monitor.gemspec +1 -1
- metadata +3 -3
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 55bf050a9f74f18ed354d7d751f868bc98dc8bc5da59c3da6ce5e0aa0cedc833
|
|
4
|
+
data.tar.gz: 37a5906b19541de00ef3b860f266a1c7a12e737da58d1a7b80cb806a191936d5
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 0c0109e46a1ec8691592fd304095c833d5d78b9091ffa216e72011040a8683be820016dd51b4a2185d17b9780761410918297f9f4fdeb2fd31d1e952575fbf99
|
|
7
|
+
data.tar.gz: 9016293bb6d6339026ed811689db2a4f1b87cd90fb60bb7f270113fc698c9714f9935f2aec704c1581b3ef6b61137b2df5c5b21e0ecd8b2bea69be987152057f
|
|
@@ -2,6 +2,20 @@
|
|
|
2
2
|
|
|
3
3
|
Version-specific migration notes for each major/minor version transition. Agents should reference this file when guiding users through multi-version upgrades.
|
|
4
4
|
|
|
5
|
+
## 0.14.0 to 0.15.0
|
|
6
|
+
|
|
7
|
+
**Key changes:**
|
|
8
|
+
- **Security:** Rails bumped to 8.1.3 (security release), picking up fixes for five CVEs including XSS in tag/DebugExceptions helpers, an Active Storage path-traversal, and a NumberConverter issue.
|
|
9
|
+
- **ViewComponent 4.x:** the `view_component` dependency widens from `>= 3.0, < 4.0` to `>= 3.0, < 5.0`, allowing host apps to resolve ViewComponent 4.x (engine lockfile resolves to 4.5.0). Engine components use only stable APIs unaffected by v4.
|
|
10
|
+
- **Solid Queue 1.4.0:** bumped from 1.3.1 with race-condition and supervisor stability fixes; dynamic recurring tasks are opt-in.
|
|
11
|
+
- **Documentation:** engine conventions consolidated into `AGENTS.md`; `CLAUDE.md` now points to it.
|
|
12
|
+
|
|
13
|
+
**Action items:**
|
|
14
|
+
1. `bundle update source_monitor`
|
|
15
|
+
2. `bin/rails source_monitor:upgrade`
|
|
16
|
+
3. No migrations or breaking config/API changes.
|
|
17
|
+
4. If the host app has ViewComponent 3.x customizations (custom components, previews), test after upgrading and consult ViewComponent v4 migration guides if needed.
|
|
18
|
+
|
|
5
19
|
## 0.13.1 to 0.14.0
|
|
6
20
|
|
|
7
21
|
**Key changes:**
|
data/AGENTS.md
CHANGED
|
@@ -1,47 +1,74 @@
|
|
|
1
1
|
# Repository Guidelines
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
This file is the **canonical engine convention reference, shared across all AI coding agents** (Claude Code, Codex, etc.). It is the single source of truth for tech stack, architecture, testing, quality gates, CI, security, and commands.
|
|
4
|
+
|
|
5
|
+
`CLAUDE.md` holds only Claude Code-specific context (working-memory header, VBW commands, and the `.claude/` agent/skill catalogs) and references this file for conventions. When a convention changes, edit it **here**, not in `CLAUDE.md`.
|
|
4
6
|
|
|
5
7
|
Use rbenv for all ruby and bundler/gem commands, not the system ruby.
|
|
6
8
|
|
|
7
|
-
##
|
|
9
|
+
## Tech Stack
|
|
8
10
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
11
|
+
| Layer | Technology |
|
|
12
|
+
|-------|------------|
|
|
13
|
+
| Ruby | 4.0+ |
|
|
14
|
+
| Rails | 8.x |
|
|
15
|
+
| Testing | Minitest (no fixtures -- uses factory helpers + WebMock/VCR) |
|
|
16
|
+
| Authorization | Host app responsibility (mountable engine); **fail-closed by default** (#129) |
|
|
17
|
+
| Jobs | Solid Queue |
|
|
18
|
+
| Frontend | Hotwire (Turbo + Stimulus) + Tailwind CSS |
|
|
19
|
+
| Linting | RuboCop (omakase) + Brakeman |
|
|
20
|
+
| Database | PostgreSQL only |
|
|
16
21
|
|
|
17
|
-
##
|
|
22
|
+
## Project Structure & Module Organization
|
|
18
23
|
|
|
19
|
-
|
|
24
|
+
The engine follows the Rails mountable layout generated by `rails plugin new source_monitor --mountable`. Runtime code lives under `app/` (controllers, jobs, views) and is namespaced as `SourceMonitor`. Long-lived services, adapters, and instrumentation helpers belong in `lib/source_monitor/`. Generator templates and install scripts reside in `lib/generators/source_monitor/`. Tests sit in `test/`, with fixtures under `test/fixtures/feeds/`, and the dummy host app in `test/dummy/` for integration coverage. Keep shared UI assets under `app/assets/` and engine configuration in `config/initializers/`.
|
|
20
25
|
|
|
21
|
-
|
|
26
|
+
## Architecture Conventions
|
|
22
27
|
|
|
23
|
-
|
|
28
|
+
### Models First
|
|
29
|
+
- Business logic lives in models. Use concerns for horizontal sharing.
|
|
30
|
+
- Service objects ONLY for operations spanning 3+ models or external integrations.
|
|
31
|
+
- Query objects for complex queries that don't fit a single scope.
|
|
32
|
+
- Presenters (SimpleDelegator) for view-specific formatting.
|
|
24
33
|
|
|
25
|
-
|
|
34
|
+
### Everything-is-CRUD Routing
|
|
35
|
+
- Prefer creating a new resource over adding custom actions.
|
|
36
|
+
- `POST /posts/:id/publications` over `POST /posts/:id/publish`.
|
|
37
|
+
- RESTful routes only; no `member` or `collection` blocks with custom verbs.
|
|
26
38
|
|
|
27
|
-
|
|
39
|
+
### State as Records
|
|
40
|
+
- Track business state transitions as separate records (who/when/why).
|
|
41
|
+
- Boolean columns ONLY for technical flags (e.g., `email_verified`, `open_access`).
|
|
28
42
|
|
|
29
|
-
|
|
43
|
+
### Jobs
|
|
44
|
+
- Shallow jobs: call `_later` or `_now` methods on models/services.
|
|
45
|
+
- Jobs contain only deserialization + delegation. No business logic.
|
|
46
|
+
- Use Solid Queue recurring jobs for scheduled work.
|
|
30
47
|
|
|
31
|
-
|
|
48
|
+
### Frontend
|
|
49
|
+
- Turbo Frames for partial page updates.
|
|
50
|
+
- Turbo Streams for real-time broadcasts.
|
|
51
|
+
- Stimulus controllers: small, focused, one behavior each.
|
|
52
|
+
- Tailwind CSS utility classes; extract components for repeated patterns.
|
|
32
53
|
|
|
33
|
-
##
|
|
54
|
+
## Coding Style & Naming Conventions
|
|
34
55
|
|
|
35
|
-
-
|
|
36
|
-
|
|
37
|
-
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
56
|
+
Use two-space indentation and Ruby 4.0+ syntax. Keep engine classes under the `SourceMonitor::` namespace; new modules should mirror their directory, e.g., `lib/source_monitor/fetching/pipeline.rb`. Favor service objects ending in `Service`, jobs ending in `Job`, and background channels ending in `Channel`. Rails defaults handle formatting, but run `bin/rubocop` (configured via `.rubocop.yml`) before opening a PR. For views, stick with ERB and Tailwind utility classes.
|
|
57
|
+
|
|
58
|
+
Sub-module extraction pattern: create `module/submodule.rb` with `require_relative`, lazy accessors, and forwarding methods for backward compatibility. The project uses Ruby autoload for `lib/` modules (not Zeitwerk).
|
|
59
|
+
|
|
60
|
+
## Clean Coding Principles
|
|
61
|
+
|
|
62
|
+
- **SRP**: Classes and methods should have a single responsibility.
|
|
63
|
+
- **DRY**: Avoid duplication; changes should only need one edit.
|
|
64
|
+
- **Depend on behaviour, not data**: Wrap instance variables in methods (`attr_reader`); use Struct for data structures.
|
|
65
|
+
- **Minimise dependencies**: Use dependency injection, encapsulate external messages, prefer hash arguments.
|
|
66
|
+
- **Depend on things that change less often than you do.**
|
|
41
67
|
|
|
42
68
|
## Configuration DSL
|
|
43
69
|
|
|
44
|
-
- `SourceMonitor.configure`
|
|
70
|
+
- `SourceMonitor.configure` exposes structured namespaces:
|
|
71
|
+
- `config.authentication` gates the engine. With no `authenticate_with`/`authorize_with` handler configured, the engine is **fail-closed** and returns `403`. Set `config.authentication.open_access = true` (default `false`) only for local demos/sandboxes — never production.
|
|
45
72
|
- `config.http` for Faraday timeouts, retry policy, proxy, and default headers. Per the [Faraday retry docs](https://github.com/lostisland/faraday/blob/main/docs/middleware/index.md), middleware options map 1:1 to the settings we surface (max retries, interval, backoff, statuses).
|
|
46
73
|
- `config.scrapers` registers/overrides adapters by name; adapters must inherit from `SourceMonitor::Scrapers::Base` and are discovered before constant lookup.
|
|
47
74
|
- `config.retention` supplies global defaults for `items_retention_days`, `max_items`, and the pruning strategy (`:destroy` or `:soft_delete`). Runtimes treat blank source fields as “inherit from config”.
|
|
@@ -57,29 +84,109 @@ Run `bin/setup` to install gems, prepare the dummy database, and compile Tailwin
|
|
|
57
84
|
- `SourceMonitor::ItemCleanupJob` batches retention pruning across sources and can soft delete records (`rake source_monitor:cleanup:items` honours `SOFT_DELETE=true`, `SOURCE_IDS=1,2`). `SourceMonitor::LogCleanupJob` prunes old fetch/scrape logs (`rake source_monitor:cleanup:logs`, override `FETCH_LOG_DAYS` / `SCRAPE_LOG_DAYS`).
|
|
58
85
|
- Nightly recurring entries in `config/recurring.yml` enqueue both cleanup jobs by default; adjust schedules or disable via Solid Queue overrides as needed.
|
|
59
86
|
|
|
60
|
-
##
|
|
87
|
+
## Background Job Defaults
|
|
61
88
|
|
|
62
|
-
|
|
89
|
+
- SourceMonitor ensures Solid Queue is the default adapter when the host app is still using the async adapter, but respects any explicit `ActiveJob` configuration already in place. Override queues/concurrency via `SourceMonitor.configure`.
|
|
90
|
+
- Queue names are namespaced (`source_monitor_fetch`/`source_monitor_scrape` by default) and automatically honor host `queue_name_prefix`. Use `SourceMonitor.queue_name(:fetch)` helpers inside jobs.
|
|
91
|
+
- Dashboard queue metrics read directly from Solid Queue tables via `SourceMonitor::Jobs::SolidQueueMetrics`. Host apps must install the Solid Queue migrations (reuse the engine's `20251009140000_create_solid_queue_tables.rb` or run `rails solid_queue:install`) for the card to surface ready/scheduled/failed counts; otherwise the UI falls back to an availability warning. Mission Control remains optional for deeper drill-downs.
|
|
92
|
+
- The dummy host keeps Solid Queue tables in the primary database via `20251009140000_create_solid_queue_tables.rb`. Real apps can either reuse that migration or run `rails solid_queue:install` to manage a dedicated queue database—Mission Control expects one of those setups before it can surface data.
|
|
93
|
+
- Recurring schedules live in `config/recurring.yml`, scheduling `SourceMonitor::ScheduleFetchesJob` each minute plus the scraping scheduler every two minutes. Override the schedule path with `bin/jobs --recurring_schedule_file=...` (or `SOLID_QUEUE_RECURRING_SCHEDULE_FILE`) and disable recurring runners with `SOLID_QUEUE_SKIP_RECURRING=true` or `bin/jobs --skip-recurring`.
|
|
94
|
+
- Hosts that need to wrap Solid Queue command execution can set `config.recurring_command_job_class` in the generated initializer to point at their custom job class.
|
|
95
|
+
|
|
96
|
+
## Build, Test, and Development Commands
|
|
97
|
+
|
|
98
|
+
Run `bin/setup` to install gems, prepare the dummy database, and compile Tailwind. During feature work, `bin/dev` starts the dummy app with Solid Queue workers and Tailwind watcher.
|
|
99
|
+
|
|
100
|
+
```bash
|
|
101
|
+
bin/dev # Start dev server
|
|
102
|
+
bin/rails test # Run the MiniTest suite (NOT a substitute for CI -- see below)
|
|
103
|
+
bin/rubocop # Check style
|
|
104
|
+
bin/rubocop -a # Auto-fix style
|
|
105
|
+
bin/brakeman --no-pager # Security scan
|
|
106
|
+
bin/rails db:migrate # Run migrations
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
The dummy host app runs on **port 3002** (`cd test/dummy && bin/rails server -p 3002`).
|
|
110
|
+
|
|
111
|
+
## Testing
|
|
63
112
|
|
|
64
|
-
|
|
113
|
+
- **Framework:** Minitest. NEVER use RSpec or FactoryBot. Name files with `_test.rb` and wrap suites in `module SourceMonitor`. Tests live in `test/models`, `test/controllers`, `test/system`, `test/lib`, `test/integration`.
|
|
114
|
+
- **Helpers:** `create_source!` factory, `with_inline_jobs`, `with_queue_adapter`.
|
|
115
|
+
- **HTTP:** WebMock disables external HTTP; VCR for recorded cassettes under `test/vcr_cassettes/` (record new fixtures with descriptive names like `source_fetch_success.yml`).
|
|
116
|
+
- **Config isolation:** `test/test_helper.rb` calls `SourceMonitor.reset_configuration!` in every test's setup (rebuilding a fresh `Configuration`), so any config a test relies on must be set in setup, not the dummy initializer.
|
|
117
|
+
- **Coverage:** Target >90% for new services; cover every model validation, scope, public method, and controller action, plus regression tests for bug fixes.
|
|
118
|
+
- **Parallelism:** Coverage runs need `COVERAGE=1 PARALLEL_WORKERS=1` with **threads** (not forks) to avoid a PG segfault and SimpleCov data loss. Scope queries to a specific source/item to prevent cross-test contamination in parallel runs.
|
|
119
|
+
- **Automate what you can:** Anything verifiable programmatically (config defaults, job enqueue behavior, controller responses) should be a test, not a manual checkpoint.
|
|
120
|
+
|
|
121
|
+
## Quality Gates
|
|
122
|
+
|
|
123
|
+
- `bin/rubocop` — zero offenses before commit (omakase: only ~45/775 cops enabled, all Metrics cops disabled — no file-size enforcement).
|
|
124
|
+
- `bin/brakeman --no-pager` — zero warnings before merge.
|
|
125
|
+
- `bin/rails test` — all tests pass.
|
|
126
|
+
- `yarn build` — rebuild JS assets if any `.js` files changed (ESLint runs in CI).
|
|
127
|
+
- No N+1 queries (use `includes`/`preload`).
|
|
128
|
+
- No hardcoded credentials (use Rails credentials or ENV).
|
|
129
|
+
|
|
130
|
+
### Pre-Push CI Checklist (run ALL before pushing to GitHub)
|
|
131
|
+
|
|
132
|
+
Before pushing any branch (especially release branches), run the full CI equivalent locally:
|
|
133
|
+
|
|
134
|
+
1. `bin/rubocop` — catches Ruby lint issues.
|
|
135
|
+
2. `bin/test-coverage` — **this is what CI's `test` job actually runs.** Do NOT rely on `bin/rails test` to predict CI: `bin/rails test` uses a different harness/seed and does NOT run the diff-coverage gate, so it can be green (e.g. 1741/0) while CI fails. `bin/test-coverage` runs the real seed, the second `health_suite` pass, and the host-app-template test that **changes the process CWD mid-suite** (see gemspec note below).
|
|
136
|
+
3. `bundle exec ruby bin/check-diff-coverage` — run AFTER `bin/test-coverage` (it reads `coverage/.resultset.json`). Reproduces the CI diff-coverage gate locally (threshold 90% on changed `app/`/`lib/` lines vs `origin/main`). This is the only way to know the gate passes before pushing.
|
|
137
|
+
4. `bin/brakeman --no-pager` — catches security issues.
|
|
138
|
+
5. `yarn build` — rebuilds JS and catches ESLint issues (CI runs ESLint separately).
|
|
139
|
+
|
|
140
|
+
If legitimate coverage gaps remain after new code paths, refresh the baseline: `bin/test-coverage` then `bin/update-coverage-baseline`, and commit the regenerated `config/coverage_baseline.json`.
|
|
141
|
+
|
|
142
|
+
**Why:** CI failures cost ~5 min per round-trip. Hard-won lessons:
|
|
143
|
+
- **CI runs `bin/test-coverage`, not `bin/rails test`** — replicate the gate locally with steps 2 + 3. (v0.14.0: a green local `bin/rails test` masked a CI `bin/test-coverage` failure.)
|
|
144
|
+
- **Diff coverage covers EVERY changed `app/`/`lib/` line**, including defensive/edge branches with no natural caller. If a branch can't be reached through a normal engine route (e.g. the `#130` turbo_stream flash-append, which only fires when a turbo_stream request carries a Rails flash), add a **test-only probe controller in the dummy app** (pattern: `test/dummy/app/controllers/test_support_controller.rb` + a route in `test/dummy/config/routes.rb`); subclass `SourceMonitor::ApplicationController` if the branch lives in the engine's filter chain.
|
|
145
|
+
- Every `rescue`/fallback/error path in new source code needs test coverage.
|
|
146
|
+
- **Gemspec packaging must be CWD-independent.** Do NOT use a bare `Dir[...]` glob in `source_monitor.gemspec` for file selection — it resolves against the process CWD, and during `bin/test-coverage` a sibling test chdir's into a generated host app, so the glob returns nothing and files silently drop from the package (v0.14.0 `#131`). Drive packaging from `git ls-files` inside the existing `Dir.chdir(File.expand_path(__dir__))` block.
|
|
147
|
+
- JS files need `/* global */` declarations for browser APIs (MutationObserver, requestAnimationFrame, etc.); ESLint `no-undef` rejects them otherwise. Run `yarn build` after JS changes to sync sourcemaps.
|
|
148
|
+
|
|
149
|
+
## Contribution Workflow
|
|
65
150
|
|
|
66
|
-
|
|
151
|
+
- Treat the engine like any external contributor would: no direct commits to `main`.
|
|
152
|
+
- Before writing code, branch off the latest `origin/main` (use a descriptive `feature/` or `bugfix/` prefix) and open a draft PR on `github.com/dchuk/source_monitor`.
|
|
153
|
+
- Push early and often to that branch so history stays visible; keep commits scoped and rebases local to your branch only.
|
|
154
|
+
- Move the PR out of draft once tests pass and the slice is ready for review; request at least one review and wait for all CI jobs (lint, security, test + diff coverage, release_verification) to succeed before merging.
|
|
155
|
+
- Merge via the PR UI (squash or rebase as agreed) after approval; avoid rewriting shared history post-push.
|
|
156
|
+
- Tag releases only after the release PR merges, then follow the checklist in `CHANGELOG.md`. There are TWO version files — `lib/source_monitor/version.rb` AND the top-level `VERSION` — and both must match; run `bundle install` after a bump so `Gemfile.lock` stays in sync (CI runs `--frozen`).
|
|
67
157
|
|
|
68
158
|
## Commit & Pull Request Guidelines
|
|
69
159
|
|
|
70
|
-
|
|
160
|
+
Use Conventional Commit subjects in the format `type(scope): description`, e.g., `fix(fetch): resolve advisory lock contention`. Group unrelated work into separate commits. PRs should describe context, summarise the slice delivered, and list validation steps (`bin/test-coverage`, manual fetch run). Include screenshots or console output when altering UI or background jobs. Request at least one review and ensure CI completes before merge.
|
|
161
|
+
|
|
162
|
+
## Security
|
|
71
163
|
|
|
72
|
-
|
|
164
|
+
### Protected files (NEVER read or output)
|
|
165
|
+
- `.env`, `.env.*`
|
|
166
|
+
- `config/master.key`, `config/credentials.yml.enc`
|
|
167
|
+
- `.kamal/secrets`
|
|
168
|
+
- Any `*.pem` / `*.key` files
|
|
73
169
|
|
|
170
|
+
### Forbidden operations
|
|
171
|
+
- `git push --force` to main/master/production
|
|
172
|
+
- `git reset --hard` without explicit user confirmation
|
|
173
|
+
- `rm -rf` on root, home, or parent directories
|
|
174
|
+
- `chmod 777`
|
|
175
|
+
|
|
176
|
+
### General
|
|
74
177
|
Store secrets (API keys, webhook tokens) in `config/credentials/` and never commit plain-text values. When adding HTTP endpoints or webhooks, default to Solid Queue middleware for retries and respect the allowlist in `config/source_monitor.yml`. Document new environment variables in `config/application.yml.sample` and call out any migrations that impact host apps.
|
|
75
178
|
|
|
76
|
-
##
|
|
179
|
+
## Maintenance: Skills & Docs Alignment
|
|
77
180
|
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
-
|
|
181
|
+
Whenever engine code changes (models, configuration, pipeline, jobs, migrations, scrapers, events, health rules, or dashboard), the corresponding `sm-*` skill and its `reference/` files MUST be updated **in the same PR** so skills always reflect current engine behavior. Releases must also audit `README.md`, `docs/` (especially `docs/upgrade.md`), and the install initializer template against the source code.
|
|
182
|
+
|
|
183
|
+
## Library Documentation
|
|
184
|
+
|
|
185
|
+
- Use Context7 MCP constantly to look up fresh documentation for any task, especially tasks that rely on libraries or gems.
|
|
186
|
+
|
|
187
|
+
### Project Dependencies & context7 links
|
|
188
|
+
|
|
189
|
+
- Feedjira - https://context7.com/feedjira/feedjira
|
|
83
190
|
|
|
84
191
|
## Claude Code Skills
|
|
85
192
|
|
|
@@ -92,4 +199,4 @@ bin/rails source_monitor:skills:all # All skills
|
|
|
92
199
|
bin/rails source_monitor:skills:remove # Remove all sm-* skills
|
|
93
200
|
```
|
|
94
201
|
|
|
95
|
-
See `CLAUDE.md` for the full skills catalog and
|
|
202
|
+
See `CLAUDE.md` for the full skills catalog (consumer vs. contributor) and the `.claude/` agent catalog.
|
data/CHANGELOG.md
CHANGED
|
@@ -15,6 +15,20 @@ All notable changes to this project are documented below. The format follows [Ke
|
|
|
15
15
|
|
|
16
16
|
- No unreleased changes yet.
|
|
17
17
|
|
|
18
|
+
## [0.15.0] - 2026-06-18
|
|
19
|
+
|
|
20
|
+
### Security
|
|
21
|
+
- Bump Rails to 8.1.3 via the 8.1.2.1 security release (#104), picking up fixes for five CVEs including XSS in tag/DebugExceptions helpers, an Active Storage path-traversal, and a NumberConverter issue.
|
|
22
|
+
|
|
23
|
+
### Changed
|
|
24
|
+
- **Allow ViewComponent 4.x** (#96). The `view_component` dependency constraint widens from `>= 3.0, < 4.0` to `>= 3.0, < 5.0`, so host apps can now resolve ViewComponent 4.x (the engine's lockfile moves to 4.5.0). The engine's components use only stable ViewComponent APIs and are unaffected by the v4 upgrade — but a host app on its own ViewComponent 3.x customizations should review the v4 upgrade notes before running `bundle update`.
|
|
25
|
+
- Bump Solid Queue to 1.4.0 (#102) — race-condition and supervisor stability fixes; the new dynamic recurring-tasks feature is opt-in and off by default.
|
|
26
|
+
- Bump nokolexbor to 0.6.4 (#103) and json to 2.19.2 (#99).
|
|
27
|
+
- Development/CI dependency bumps: test-prof 1.6.0 (#101), webmock 3.26.2 (#100), brakeman 8.0.4 (#88), selenium-webdriver 4.41.0 (#78), stackprof 0.2.28 (#71), and the GitHub Actions artifact actions (#87, #86).
|
|
28
|
+
|
|
29
|
+
### Documentation
|
|
30
|
+
- Consolidate engine conventions into `AGENTS.md` as the canonical, cross-agent reference; `CLAUDE.md` now points to it instead of duplicating content (#134).
|
|
31
|
+
|
|
18
32
|
## [0.14.0] - 2026-05-28
|
|
19
33
|
|
|
20
34
|
### Security (BREAKING)
|
data/CLAUDE.md
CHANGED
|
@@ -2,6 +2,8 @@
|
|
|
2
2
|
|
|
3
3
|
**Core value:** Drop-in Rails engine for feed monitoring, content scraping, and operational dashboards.
|
|
4
4
|
|
|
5
|
+
> **Engine conventions live in [`AGENTS.md`](AGENTS.md)** — the canonical, cross-agent reference for tech stack, architecture, testing, quality gates, the pre-push CI checklist, security rules, configuration DSL, and commands. This file holds only Claude Code-specific context: working memory, VBW commands, and the `.claude/` agent/skill catalogs. When a convention changes, edit `AGENTS.md`, not here.
|
|
6
|
+
|
|
5
7
|
## Active Context
|
|
6
8
|
|
|
7
9
|
**Last shipped:** rails-audit-and-refactoring (7 phases, 30 plans)
|
|
@@ -10,7 +12,7 @@
|
|
|
10
12
|
## Key Decisions
|
|
11
13
|
|
|
12
14
|
- Keep PostgreSQL-only for now
|
|
13
|
-
- Keep host-app auth model
|
|
15
|
+
- Keep host-app auth model (fail-closed by default since #129)
|
|
14
16
|
- Ruby autoload for lib/ modules (not Zeitwerk)
|
|
15
17
|
- PG parallel fork segfault resolved: switched to thread-based parallelism in aia-ssl-fix milestone
|
|
16
18
|
|
|
@@ -23,13 +25,6 @@
|
|
|
23
25
|
- vastai (global)
|
|
24
26
|
- find-skills (global)
|
|
25
27
|
|
|
26
|
-
## Learned Patterns
|
|
27
|
-
|
|
28
|
-
- Sub-module extraction: create `module/submodule.rb` with `require_relative`, lazy accessors, forwarding methods for backward compat
|
|
29
|
-
- Coverage runs need `COVERAGE=1 PARALLEL_WORKERS=1` with threads (not forks) to avoid PG segfault and SimpleCov data loss
|
|
30
|
-
- Test isolation: scope queries to specific source/item to prevent cross-test contamination in parallel runs
|
|
31
|
-
- RuboCop omakase: only 45/775 cops enabled, all Metrics cops disabled -- no file size enforcement
|
|
32
|
-
|
|
33
28
|
## VBW Commands
|
|
34
29
|
|
|
35
30
|
This project uses VBW (Vibe Better with Claude Code).
|
|
@@ -38,111 +33,10 @@ Run /vbw:help for all commands.
|
|
|
38
33
|
|
|
39
34
|
---
|
|
40
35
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
## Tech Stack
|
|
44
|
-
|
|
45
|
-
| Layer | Technology |
|
|
46
|
-
|-------|------------|
|
|
47
|
-
| Ruby | 4.0+ |
|
|
48
|
-
| Rails | 8.x |
|
|
49
|
-
| Testing | Minitest (no fixtures -- uses factory helpers + WebMock/VCR) |
|
|
50
|
-
| Authorization | Host app responsibility (mountable engine) |
|
|
51
|
-
| Jobs | Solid Queue |
|
|
52
|
-
| Frontend | Hotwire (Turbo + Stimulus) + Tailwind CSS |
|
|
53
|
-
| Linting | RuboCop (omakase) + Brakeman |
|
|
54
|
-
| Database | PostgreSQL only |
|
|
55
|
-
|
|
56
|
-
## Architecture Conventions
|
|
57
|
-
|
|
58
|
-
### Models First
|
|
59
|
-
- Business logic lives in models. Use concerns for horizontal sharing.
|
|
60
|
-
- Service objects ONLY for operations spanning 3+ models or external integrations.
|
|
61
|
-
- Query objects for complex queries that don't fit a single scope.
|
|
62
|
-
- Presenters (SimpleDelegator) for view-specific formatting.
|
|
63
|
-
|
|
64
|
-
### Everything-is-CRUD Routing
|
|
65
|
-
- Prefer creating a new resource over adding custom actions.
|
|
66
|
-
- `POST /posts/:id/publications` over `POST /posts/:id/publish`.
|
|
67
|
-
- RESTful routes only; no `member` or `collection` blocks with custom verbs.
|
|
68
|
-
|
|
69
|
-
### State as Records
|
|
70
|
-
- Track business state transitions as separate records (who/when/why).
|
|
71
|
-
- Boolean columns ONLY for technical flags (e.g., `email_verified`).
|
|
72
|
-
|
|
73
|
-
### Jobs
|
|
74
|
-
- Shallow jobs: call `_later` or `_now` methods on models/services.
|
|
75
|
-
- Jobs contain only deserialization + delegation. No business logic.
|
|
76
|
-
- Use Solid Queue recurring jobs for scheduled work.
|
|
77
|
-
|
|
78
|
-
### Frontend
|
|
79
|
-
- Turbo Frames for partial page updates.
|
|
80
|
-
- Turbo Streams for real-time broadcasts.
|
|
81
|
-
- Stimulus controllers: small, focused, one behavior each.
|
|
82
|
-
- Tailwind CSS utility classes; extract components for repeated patterns.
|
|
83
|
-
|
|
84
|
-
## Testing Conventions
|
|
85
|
-
|
|
86
|
-
- **Framework:** Minitest. NEVER use RSpec or FactoryBot.
|
|
87
|
-
- **Helpers:** `create_source!` factory, `with_inline_jobs`, `with_queue_adapter`.
|
|
88
|
-
- **HTTP:** WebMock disables external HTTP; VCR for recorded cassettes.
|
|
89
|
-
- **Config:** Reset every test with `SourceMonitor.reset_configuration!`.
|
|
90
|
-
- **TDD workflow:** Red (failing test) -> Green (minimal pass) -> Refactor.
|
|
91
|
-
- **Coverage:** Every model validation, scope, and public method. Every controller action.
|
|
92
|
-
|
|
93
|
-
## Quality Gates
|
|
94
|
-
|
|
95
|
-
- `bin/rubocop` -- zero offenses before commit.
|
|
96
|
-
- `bin/brakeman --no-pager` -- zero warnings before merge.
|
|
97
|
-
- `bin/rails test` -- all tests pass.
|
|
98
|
-
- `yarn build` -- rebuild JS assets if any `.js` files changed (ESLint runs in CI).
|
|
99
|
-
- No N+1 queries (use `includes`/`preload`).
|
|
100
|
-
- No hardcoded credentials (use Rails credentials or ENV).
|
|
101
|
-
|
|
102
|
-
### Pre-Push CI Checklist (run ALL before pushing to GitHub)
|
|
103
|
-
|
|
104
|
-
Before pushing any branch (especially release branches), run the full CI equivalent locally:
|
|
105
|
-
|
|
106
|
-
1. `bin/rubocop` -- catches Ruby lint issues
|
|
107
|
-
2. `PARALLEL_WORKERS=1 bin/rails test` -- catches test failures AND diff coverage gaps
|
|
108
|
-
3. `bin/brakeman --no-pager` -- catches security issues
|
|
109
|
-
4. `yarn build` -- rebuilds JS and catches ESLint issues (CI runs ESLint separately)
|
|
110
|
-
|
|
111
|
-
**Why:** CI failures cost ~5 min per round-trip. In v0.8.0, skipping ESLint and diff coverage checks locally caused 2 wasted CI cycles. Common blind spots:
|
|
112
|
-
- JS files need `/* global */` declarations for browser APIs (MutationObserver, requestAnimationFrame, etc.)
|
|
113
|
-
- Every `rescue` / fallback / error path in new source code needs test coverage (CI diff coverage gate rejects uncovered lines)
|
|
114
|
-
- `yarn build` must run after JS changes to sync sourcemaps
|
|
115
|
-
|
|
116
|
-
## QA and UAT Rules
|
|
36
|
+
## QA and UAT Rules (Claude Code)
|
|
117
37
|
|
|
118
38
|
- **Browser-first verification:** During VBW QA (`/vbw:qa`) and UAT (`/vbw:verify`), ALWAYS start by using `agent-browser` to test UI scenarios yourself before presenting checkpoints to the user. Navigate to the dummy app (port 3002), take snapshots/screenshots, and verify visual and functional behavior with agents first.
|
|
119
|
-
- **Automate what you can:**
|
|
120
|
-
- **Dummy app port:** The SourceMonitor dummy app runs on port 3002 (`cd test/dummy && bin/rails server -p 3002`).
|
|
121
|
-
|
|
122
|
-
## Security Rules
|
|
123
|
-
|
|
124
|
-
### Protected Files (NEVER read or output)
|
|
125
|
-
- `.env`, `.env.*`
|
|
126
|
-
- `config/master.key`, `config/credentials.yml.enc`
|
|
127
|
-
- `.kamal/secrets`
|
|
128
|
-
- Any `*.pem`, `*.key` files
|
|
129
|
-
|
|
130
|
-
### Forbidden Operations
|
|
131
|
-
- `git push --force` to main/master/production
|
|
132
|
-
- `git reset --hard` without explicit user confirmation
|
|
133
|
-
- `rm -rf` on root, home, or parent directories
|
|
134
|
-
- `chmod 777`
|
|
135
|
-
|
|
136
|
-
## Development Commands
|
|
137
|
-
|
|
138
|
-
```bash
|
|
139
|
-
bin/dev # Start dev server
|
|
140
|
-
bin/rails test # Run all tests
|
|
141
|
-
bin/rubocop # Check style
|
|
142
|
-
bin/rubocop -a # Auto-fix style
|
|
143
|
-
bin/brakeman --no-pager # Security scan
|
|
144
|
-
bin/rails db:migrate # Run migrations
|
|
145
|
-
```
|
|
39
|
+
- **Automate what you can:** anything verifiable programmatically should be a test — see the Testing section in [`AGENTS.md`](AGENTS.md) — and only present truly visual/interactive checks to the user.
|
|
146
40
|
|
|
147
41
|
## Agent Catalog
|
|
148
42
|
|
|
@@ -200,7 +94,7 @@ These skills are available in `.claude/skills/`:
|
|
|
200
94
|
|
|
201
95
|
## Source Monitor Skills
|
|
202
96
|
|
|
203
|
-
Engine-specific skills (`sm-*` prefix). Consumer skills install by default; contributor skills are opt-in.
|
|
97
|
+
Engine-specific skills (`sm-*` prefix). Consumer skills install by default; contributor skills are opt-in. The **Skills & Docs Alignment** maintenance rule lives in [`AGENTS.md`](AGENTS.md).
|
|
204
98
|
|
|
205
99
|
### Consumer Skills (default install)
|
|
206
100
|
|
|
@@ -237,7 +131,3 @@ bin/rails source_monitor:skills:contributor # Contributor skills
|
|
|
237
131
|
bin/rails source_monitor:skills:all # All skills
|
|
238
132
|
bin/rails source_monitor:skills:remove # Remove all sm-* skills
|
|
239
133
|
```
|
|
240
|
-
|
|
241
|
-
## Maintenance Rules
|
|
242
|
-
|
|
243
|
-
- **Skills & docs alignment**: Whenever engine code changes (models, configuration, pipeline, jobs, migrations, scrapers, events, health rules, or dashboard), the corresponding `sm-*` skill and its `reference/` files MUST be updated in the same PR to ensure skills always reflect current engine behavior.
|
data/Gemfile.lock
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
PATH
|
|
2
2
|
remote: .
|
|
3
3
|
specs:
|
|
4
|
-
source_monitor (0.
|
|
4
|
+
source_monitor (0.15.0)
|
|
5
5
|
cssbundling-rails (~> 1.4)
|
|
6
6
|
faraday (~> 2.9)
|
|
7
7
|
faraday-follow_redirects (~> 0.4)
|
|
@@ -16,36 +16,36 @@ PATH
|
|
|
16
16
|
solid_cable (>= 3.0, < 4.0)
|
|
17
17
|
solid_queue (>= 0.3, < 3.0)
|
|
18
18
|
turbo-rails (~> 2.0)
|
|
19
|
-
view_component (>= 3.0, <
|
|
19
|
+
view_component (>= 3.0, < 5.0)
|
|
20
20
|
|
|
21
21
|
GEM
|
|
22
22
|
remote: https://rubygems.org/
|
|
23
23
|
specs:
|
|
24
|
-
action_text-trix (2.1.
|
|
24
|
+
action_text-trix (2.1.17)
|
|
25
25
|
railties
|
|
26
|
-
actioncable (8.1.
|
|
27
|
-
actionpack (= 8.1.
|
|
28
|
-
activesupport (= 8.1.
|
|
26
|
+
actioncable (8.1.3)
|
|
27
|
+
actionpack (= 8.1.3)
|
|
28
|
+
activesupport (= 8.1.3)
|
|
29
29
|
nio4r (~> 2.0)
|
|
30
30
|
websocket-driver (>= 0.6.1)
|
|
31
31
|
zeitwerk (~> 2.6)
|
|
32
|
-
actionmailbox (8.1.
|
|
33
|
-
actionpack (= 8.1.
|
|
34
|
-
activejob (= 8.1.
|
|
35
|
-
activerecord (= 8.1.
|
|
36
|
-
activestorage (= 8.1.
|
|
37
|
-
activesupport (= 8.1.
|
|
32
|
+
actionmailbox (8.1.3)
|
|
33
|
+
actionpack (= 8.1.3)
|
|
34
|
+
activejob (= 8.1.3)
|
|
35
|
+
activerecord (= 8.1.3)
|
|
36
|
+
activestorage (= 8.1.3)
|
|
37
|
+
activesupport (= 8.1.3)
|
|
38
38
|
mail (>= 2.8.0)
|
|
39
|
-
actionmailer (8.1.
|
|
40
|
-
actionpack (= 8.1.
|
|
41
|
-
actionview (= 8.1.
|
|
42
|
-
activejob (= 8.1.
|
|
43
|
-
activesupport (= 8.1.
|
|
39
|
+
actionmailer (8.1.3)
|
|
40
|
+
actionpack (= 8.1.3)
|
|
41
|
+
actionview (= 8.1.3)
|
|
42
|
+
activejob (= 8.1.3)
|
|
43
|
+
activesupport (= 8.1.3)
|
|
44
44
|
mail (>= 2.8.0)
|
|
45
45
|
rails-dom-testing (~> 2.2)
|
|
46
|
-
actionpack (8.1.
|
|
47
|
-
actionview (= 8.1.
|
|
48
|
-
activesupport (= 8.1.
|
|
46
|
+
actionpack (8.1.3)
|
|
47
|
+
actionview (= 8.1.3)
|
|
48
|
+
activesupport (= 8.1.3)
|
|
49
49
|
nokogiri (>= 1.8.5)
|
|
50
50
|
rack (>= 2.2.4)
|
|
51
51
|
rack-session (>= 1.0.1)
|
|
@@ -53,36 +53,36 @@ GEM
|
|
|
53
53
|
rails-dom-testing (~> 2.2)
|
|
54
54
|
rails-html-sanitizer (~> 1.6)
|
|
55
55
|
useragent (~> 0.16)
|
|
56
|
-
actiontext (8.1.
|
|
56
|
+
actiontext (8.1.3)
|
|
57
57
|
action_text-trix (~> 2.1.15)
|
|
58
|
-
actionpack (= 8.1.
|
|
59
|
-
activerecord (= 8.1.
|
|
60
|
-
activestorage (= 8.1.
|
|
61
|
-
activesupport (= 8.1.
|
|
58
|
+
actionpack (= 8.1.3)
|
|
59
|
+
activerecord (= 8.1.3)
|
|
60
|
+
activestorage (= 8.1.3)
|
|
61
|
+
activesupport (= 8.1.3)
|
|
62
62
|
globalid (>= 0.6.0)
|
|
63
63
|
nokogiri (>= 1.8.5)
|
|
64
|
-
actionview (8.1.
|
|
65
|
-
activesupport (= 8.1.
|
|
64
|
+
actionview (8.1.3)
|
|
65
|
+
activesupport (= 8.1.3)
|
|
66
66
|
builder (~> 3.1)
|
|
67
67
|
erubi (~> 1.11)
|
|
68
68
|
rails-dom-testing (~> 2.2)
|
|
69
69
|
rails-html-sanitizer (~> 1.6)
|
|
70
|
-
activejob (8.1.
|
|
71
|
-
activesupport (= 8.1.
|
|
70
|
+
activejob (8.1.3)
|
|
71
|
+
activesupport (= 8.1.3)
|
|
72
72
|
globalid (>= 0.3.6)
|
|
73
|
-
activemodel (8.1.
|
|
74
|
-
activesupport (= 8.1.
|
|
75
|
-
activerecord (8.1.
|
|
76
|
-
activemodel (= 8.1.
|
|
77
|
-
activesupport (= 8.1.
|
|
73
|
+
activemodel (8.1.3)
|
|
74
|
+
activesupport (= 8.1.3)
|
|
75
|
+
activerecord (8.1.3)
|
|
76
|
+
activemodel (= 8.1.3)
|
|
77
|
+
activesupport (= 8.1.3)
|
|
78
78
|
timeout (>= 0.4.0)
|
|
79
|
-
activestorage (8.1.
|
|
80
|
-
actionpack (= 8.1.
|
|
81
|
-
activejob (= 8.1.
|
|
82
|
-
activerecord (= 8.1.
|
|
83
|
-
activesupport (= 8.1.
|
|
79
|
+
activestorage (8.1.3)
|
|
80
|
+
actionpack (= 8.1.3)
|
|
81
|
+
activejob (= 8.1.3)
|
|
82
|
+
activerecord (= 8.1.3)
|
|
83
|
+
activesupport (= 8.1.3)
|
|
84
84
|
marcel (~> 1.0)
|
|
85
|
-
activesupport (8.1.
|
|
85
|
+
activesupport (8.1.3)
|
|
86
86
|
base64
|
|
87
87
|
bigdecimal
|
|
88
88
|
concurrent-ruby (~> 1.0, >= 1.3.1)
|
|
@@ -95,12 +95,12 @@ GEM
|
|
|
95
95
|
securerandom (>= 0.3)
|
|
96
96
|
tzinfo (~> 2.0, >= 2.0.5)
|
|
97
97
|
uri (>= 0.13.1)
|
|
98
|
-
addressable (2.
|
|
99
|
-
public_suffix (>= 2.0.2, <
|
|
98
|
+
addressable (2.9.0)
|
|
99
|
+
public_suffix (>= 2.0.2, < 8.0)
|
|
100
100
|
ast (2.4.3)
|
|
101
101
|
base64 (0.3.0)
|
|
102
|
-
bigdecimal (4.
|
|
103
|
-
brakeman (8.0.
|
|
102
|
+
bigdecimal (4.1.2)
|
|
103
|
+
brakeman (8.0.4)
|
|
104
104
|
racc
|
|
105
105
|
builder (3.3.0)
|
|
106
106
|
capybara (3.40.0)
|
|
@@ -125,7 +125,7 @@ GEM
|
|
|
125
125
|
digest (3.2.1)
|
|
126
126
|
docile (1.4.1)
|
|
127
127
|
drb (2.2.3)
|
|
128
|
-
erb (6.0.
|
|
128
|
+
erb (6.0.2)
|
|
129
129
|
erubi (1.13.1)
|
|
130
130
|
et-orbi (1.4.0)
|
|
131
131
|
tzinfo
|
|
@@ -163,11 +163,11 @@ GEM
|
|
|
163
163
|
reline (>= 0.4.2)
|
|
164
164
|
jsbundling-rails (1.3.1)
|
|
165
165
|
railties (>= 6.0.0)
|
|
166
|
-
json (2.
|
|
166
|
+
json (2.19.2)
|
|
167
167
|
language_server-protocol (3.17.0.5)
|
|
168
168
|
lint_roller (1.1.0)
|
|
169
169
|
logger (1.7.0)
|
|
170
|
-
loofah (2.25.
|
|
170
|
+
loofah (2.25.1)
|
|
171
171
|
crass (~> 1.0.2)
|
|
172
172
|
nokogiri (>= 1.12.0)
|
|
173
173
|
mail (2.9.0)
|
|
@@ -178,17 +178,17 @@ GEM
|
|
|
178
178
|
net-smtp
|
|
179
179
|
marcel (1.1.0)
|
|
180
180
|
matrix (0.4.3)
|
|
181
|
-
method_source (1.1.0)
|
|
182
181
|
mini_magick (5.3.1)
|
|
183
182
|
logger
|
|
184
183
|
mini_mime (1.1.5)
|
|
185
184
|
mini_portile2 (2.8.9)
|
|
186
|
-
minitest (6.0.
|
|
185
|
+
minitest (6.0.2)
|
|
186
|
+
drb (~> 2.0)
|
|
187
187
|
prism (~> 1.5)
|
|
188
188
|
minitest-mock (5.27.0)
|
|
189
189
|
net-http (0.9.1)
|
|
190
190
|
uri (>= 0.11.1)
|
|
191
|
-
net-imap (0.6.
|
|
191
|
+
net-imap (0.6.3)
|
|
192
192
|
date
|
|
193
193
|
net-protocol
|
|
194
194
|
net-pop (0.1.2)
|
|
@@ -198,18 +198,18 @@ GEM
|
|
|
198
198
|
net-smtp (0.5.1)
|
|
199
199
|
net-protocol
|
|
200
200
|
nio4r (2.7.5)
|
|
201
|
-
nokogiri (1.19.
|
|
201
|
+
nokogiri (1.19.2)
|
|
202
202
|
mini_portile2 (~> 2.8.2)
|
|
203
203
|
racc (~> 1.4)
|
|
204
|
-
nokogiri (1.19.
|
|
204
|
+
nokogiri (1.19.2-aarch64-linux-gnu)
|
|
205
205
|
racc (~> 1.4)
|
|
206
|
-
nokogiri (1.19.
|
|
206
|
+
nokogiri (1.19.2-aarch64-linux-musl)
|
|
207
207
|
racc (~> 1.4)
|
|
208
|
-
nokogiri (1.19.
|
|
208
|
+
nokogiri (1.19.2-arm-linux-gnu)
|
|
209
209
|
racc (~> 1.4)
|
|
210
|
-
nokogiri (1.19.
|
|
210
|
+
nokogiri (1.19.2-arm-linux-musl)
|
|
211
211
|
racc (~> 1.4)
|
|
212
|
-
nokolexbor (0.6.
|
|
212
|
+
nokolexbor (0.6.4)
|
|
213
213
|
ostruct (0.6.3)
|
|
214
214
|
parallel (1.27.0)
|
|
215
215
|
parser (3.3.10.1)
|
|
@@ -229,12 +229,12 @@ GEM
|
|
|
229
229
|
psych (5.3.1)
|
|
230
230
|
date
|
|
231
231
|
stringio
|
|
232
|
-
public_suffix (
|
|
232
|
+
public_suffix (7.0.5)
|
|
233
233
|
puma (7.2.0)
|
|
234
234
|
nio4r (~> 2.0)
|
|
235
235
|
raabro (1.4.0)
|
|
236
236
|
racc (1.8.1)
|
|
237
|
-
rack (3.2.
|
|
237
|
+
rack (3.2.5)
|
|
238
238
|
rack-session (2.1.1)
|
|
239
239
|
base64 (>= 0.1.0)
|
|
240
240
|
rack (>= 3.0.0)
|
|
@@ -242,30 +242,30 @@ GEM
|
|
|
242
242
|
rack (>= 1.3)
|
|
243
243
|
rackup (2.3.1)
|
|
244
244
|
rack (>= 3)
|
|
245
|
-
rails (8.1.
|
|
246
|
-
actioncable (= 8.1.
|
|
247
|
-
actionmailbox (= 8.1.
|
|
248
|
-
actionmailer (= 8.1.
|
|
249
|
-
actionpack (= 8.1.
|
|
250
|
-
actiontext (= 8.1.
|
|
251
|
-
actionview (= 8.1.
|
|
252
|
-
activejob (= 8.1.
|
|
253
|
-
activemodel (= 8.1.
|
|
254
|
-
activerecord (= 8.1.
|
|
255
|
-
activestorage (= 8.1.
|
|
256
|
-
activesupport (= 8.1.
|
|
245
|
+
rails (8.1.3)
|
|
246
|
+
actioncable (= 8.1.3)
|
|
247
|
+
actionmailbox (= 8.1.3)
|
|
248
|
+
actionmailer (= 8.1.3)
|
|
249
|
+
actionpack (= 8.1.3)
|
|
250
|
+
actiontext (= 8.1.3)
|
|
251
|
+
actionview (= 8.1.3)
|
|
252
|
+
activejob (= 8.1.3)
|
|
253
|
+
activemodel (= 8.1.3)
|
|
254
|
+
activerecord (= 8.1.3)
|
|
255
|
+
activestorage (= 8.1.3)
|
|
256
|
+
activesupport (= 8.1.3)
|
|
257
257
|
bundler (>= 1.15.0)
|
|
258
|
-
railties (= 8.1.
|
|
258
|
+
railties (= 8.1.3)
|
|
259
259
|
rails-dom-testing (2.3.0)
|
|
260
260
|
activesupport (>= 5.0.0)
|
|
261
261
|
minitest
|
|
262
262
|
nokogiri (>= 1.6)
|
|
263
|
-
rails-html-sanitizer (1.
|
|
264
|
-
loofah (~> 2.
|
|
263
|
+
rails-html-sanitizer (1.7.0)
|
|
264
|
+
loofah (~> 2.25)
|
|
265
265
|
nokogiri (>= 1.15.7, != 1.16.7, != 1.16.6, != 1.16.5, != 1.16.4, != 1.16.3, != 1.16.2, != 1.16.1, != 1.16.0.rc1, != 1.16.0)
|
|
266
|
-
railties (8.1.
|
|
267
|
-
actionpack (= 8.1.
|
|
268
|
-
activesupport (= 8.1.
|
|
266
|
+
railties (8.1.3)
|
|
267
|
+
actionpack (= 8.1.3)
|
|
268
|
+
activesupport (= 8.1.3)
|
|
269
269
|
irb (~> 1.13)
|
|
270
270
|
rackup (>= 1.0.0)
|
|
271
271
|
rake (>= 12.2)
|
|
@@ -321,7 +321,7 @@ GEM
|
|
|
321
321
|
rubyzip (3.2.2)
|
|
322
322
|
sax-machine (1.3.2)
|
|
323
323
|
securerandom (0.4.1)
|
|
324
|
-
selenium-webdriver (4.
|
|
324
|
+
selenium-webdriver (4.41.0)
|
|
325
325
|
base64 (~> 0.2)
|
|
326
326
|
logger (~> 1.4)
|
|
327
327
|
rexml (~> 3.2, >= 3.2.5)
|
|
@@ -338,18 +338,18 @@ GEM
|
|
|
338
338
|
activejob (>= 7.2)
|
|
339
339
|
activerecord (>= 7.2)
|
|
340
340
|
railties (>= 7.2)
|
|
341
|
-
solid_queue (1.
|
|
341
|
+
solid_queue (1.4.0)
|
|
342
342
|
activejob (>= 7.1)
|
|
343
343
|
activerecord (>= 7.1)
|
|
344
344
|
concurrent-ruby (>= 1.3.1)
|
|
345
345
|
fugit (~> 1.11)
|
|
346
346
|
railties (>= 7.1)
|
|
347
347
|
thor (>= 1.3.1)
|
|
348
|
-
stackprof (0.2.
|
|
348
|
+
stackprof (0.2.28)
|
|
349
349
|
stringio (3.2.0)
|
|
350
|
-
test-prof (1.
|
|
350
|
+
test-prof (1.6.0)
|
|
351
351
|
thor (1.5.0)
|
|
352
|
-
timeout (0.6.
|
|
352
|
+
timeout (0.6.1)
|
|
353
353
|
tsort (0.2.0)
|
|
354
354
|
turbo-rails (2.0.23)
|
|
355
355
|
actionpack (>= 7.1.0)
|
|
@@ -362,11 +362,11 @@ GEM
|
|
|
362
362
|
uri (1.1.1)
|
|
363
363
|
useragent (0.16.11)
|
|
364
364
|
vcr (6.4.0)
|
|
365
|
-
view_component (
|
|
366
|
-
|
|
365
|
+
view_component (4.5.0)
|
|
366
|
+
actionview (>= 7.1.0)
|
|
367
|
+
activesupport (>= 7.1.0)
|
|
367
368
|
concurrent-ruby (~> 1)
|
|
368
|
-
|
|
369
|
-
webmock (3.26.1)
|
|
369
|
+
webmock (3.26.2)
|
|
370
370
|
addressable (>= 2.8.0)
|
|
371
371
|
crack (>= 0.3.2)
|
|
372
372
|
hashdiff (>= 0.4.0, < 2.0.0)
|
|
@@ -377,7 +377,7 @@ GEM
|
|
|
377
377
|
websocket-extensions (0.1.5)
|
|
378
378
|
xpath (3.2.0)
|
|
379
379
|
nokogiri (~> 1.8)
|
|
380
|
-
zeitwerk (2.7.
|
|
380
|
+
zeitwerk (2.7.5)
|
|
381
381
|
zlib (3.2.2)
|
|
382
382
|
|
|
383
383
|
PLATFORMS
|
data/README.md
CHANGED
|
@@ -9,8 +9,8 @@ SourceMonitor is a production-ready Rails 8 mountable engine for ingesting, norm
|
|
|
9
9
|
In your host Rails app:
|
|
10
10
|
|
|
11
11
|
```bash
|
|
12
|
-
bundle add source_monitor --version "~> 0.
|
|
13
|
-
# or add `gem "source_monitor", "~> 0.
|
|
12
|
+
bundle add source_monitor --version "~> 0.15.0"
|
|
13
|
+
# or add `gem "source_monitor", "~> 0.15.0"` manually, then run:
|
|
14
14
|
bundle install
|
|
15
15
|
```
|
|
16
16
|
|
|
@@ -46,7 +46,7 @@ This exposes `bin/source_monitor` (via Bundler binstubs) so you can run the guid
|
|
|
46
46
|
Before running any SourceMonitor commands inside your host app, add the gem and install dependencies:
|
|
47
47
|
|
|
48
48
|
```bash
|
|
49
|
-
bundle add source_monitor --version "~> 0.
|
|
49
|
+
bundle add source_monitor --version "~> 0.15.0"
|
|
50
50
|
# or edit your Gemfile, then run
|
|
51
51
|
bundle install
|
|
52
52
|
```
|
data/VERSION
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
0.
|
|
1
|
+
0.15.0
|
data/docs/setup.md
CHANGED
|
@@ -7,7 +7,7 @@ This guide consolidates the new guided installer, verification commands, and rol
|
|
|
7
7
|
| Requirement | Minimum | Notes |
|
|
8
8
|
| --- | --- | --- |
|
|
9
9
|
| Ruby | 4.0.1 | Use rbenv and match the engine's `.ruby-version`. |
|
|
10
|
-
| Rails | 8.1.
|
|
10
|
+
| Rails | 8.1.3 | Run `bin/rails about` inside the host to confirm. |
|
|
11
11
|
| PostgreSQL | 14+ | Required for Solid Queue tables and item storage. |
|
|
12
12
|
| Node.js | 18+ | Needed for Tailwind/esbuild assets when the host owns node tooling. |
|
|
13
13
|
| Background jobs | Solid Queue (>= 0.3, < 3.0) | Add `solid_queue` to the host Gemfile if not present. |
|
|
@@ -18,8 +18,8 @@ This guide consolidates the new guided installer, verification commands, and rol
|
|
|
18
18
|
Run these commands inside your host Rails application before invoking the guided workflow:
|
|
19
19
|
|
|
20
20
|
```bash
|
|
21
|
-
bundle add source_monitor --version "~> 0.
|
|
22
|
-
# or add gem "source_monitor", "~> 0.
|
|
21
|
+
bundle add source_monitor --version "~> 0.15.0"
|
|
22
|
+
# or add gem "source_monitor", "~> 0.15.0" to Gemfile manually
|
|
23
23
|
bundle install
|
|
24
24
|
```
|
|
25
25
|
|
data/docs/upgrade.md
CHANGED
|
@@ -46,6 +46,20 @@ If a removed option raises an error (`SourceMonitor::DeprecatedOptionError`), yo
|
|
|
46
46
|
|
|
47
47
|
## Version-Specific Notes
|
|
48
48
|
|
|
49
|
+
### Upgrading to 0.15.0
|
|
50
|
+
|
|
51
|
+
**What changed:**
|
|
52
|
+
- **Security:** Rails bumped to 8.1.3 (security release), fixing five CVEs including XSS in tag/DebugExceptions helpers, an Active Storage path-traversal, and a NumberConverter issue.
|
|
53
|
+
- **ViewComponent 4.x compatibility:** The `view_component` dependency constraint widens from `>= 3.0, < 4.0` to `>= 3.0, < 5.0`, so host apps can now resolve ViewComponent 4.x (the engine's lockfile moves to 4.5.0). The engine's components use only stable ViewComponent APIs unaffected by the v4 upgrade, but host apps with their own ViewComponent 3.x customizations should review the [ViewComponent v4 release notes](https://github.com/ViewComponent/view_component/releases) before running `bundle update`.
|
|
54
|
+
- **Solid Queue 1.4.0:** Bumped from 1.3.1 with race-condition and supervisor stability fixes. The new dynamic recurring-tasks feature is opt-in and off by default.
|
|
55
|
+
- **Documentation:** Engine conventions consolidated into `AGENTS.md` as the canonical cross-agent reference; `CLAUDE.md` now points to it.
|
|
56
|
+
|
|
57
|
+
**Action items:**
|
|
58
|
+
1. `bundle update source_monitor`
|
|
59
|
+
2. `bin/rails source_monitor:upgrade`
|
|
60
|
+
3. No database migrations and no breaking API or configuration changes.
|
|
61
|
+
4. If your host app has its own ViewComponent 3.x customizations, test after upgrading and consult the ViewComponent v4 migration guide if issues arise.
|
|
62
|
+
|
|
49
63
|
### Upgrading to 0.14.0
|
|
50
64
|
|
|
51
65
|
**What changed:**
|
data/source_monitor.gemspec
CHANGED
|
@@ -51,5 +51,5 @@ Gem::Specification.new do |spec|
|
|
|
51
51
|
spec.add_dependency "solid_queue", ">= 0.3", "< 3.0"
|
|
52
52
|
spec.add_dependency "solid_cable", ">= 3.0", "< 4.0"
|
|
53
53
|
spec.add_dependency "ransack", "~> 4.2"
|
|
54
|
-
spec.add_dependency "view_component", ">= 3.0", "<
|
|
54
|
+
spec.add_dependency "view_component", ">= 3.0", "< 5.0"
|
|
55
55
|
end
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: source_monitor
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.15.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- dchuk
|
|
@@ -238,7 +238,7 @@ dependencies:
|
|
|
238
238
|
version: '3.0'
|
|
239
239
|
- - "<"
|
|
240
240
|
- !ruby/object:Gem::Version
|
|
241
|
-
version: '
|
|
241
|
+
version: '5.0'
|
|
242
242
|
type: :runtime
|
|
243
243
|
prerelease: false
|
|
244
244
|
version_requirements: !ruby/object:Gem::Requirement
|
|
@@ -248,7 +248,7 @@ dependencies:
|
|
|
248
248
|
version: '3.0'
|
|
249
249
|
- - "<"
|
|
250
250
|
- !ruby/object:Gem::Version
|
|
251
|
-
version: '
|
|
251
|
+
version: '5.0'
|
|
252
252
|
description: SourceMonitor is a mountable Rails 8 engine that ingests RSS, Atom, and
|
|
253
253
|
JSON feeds, scrapes full article content, and surfaces Solid Queue powered dashboards
|
|
254
254
|
for monitoring and remediation.
|