source_monitor 0.7.0 → 0.8.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.
Files changed (141) hide show
  1. checksums.yaml +4 -4
  2. data/.claude/commands/release.md +45 -22
  3. data/.claude/skills/sm-configure/SKILL.md +10 -1
  4. data/.claude/skills/sm-configure/reference/configuration-reference.md +44 -0
  5. data/.claude/skills/sm-host-setup/reference/initializer-template.md +17 -0
  6. data/.claude/skills/sm-host-setup/reference/setup-checklist.md +2 -0
  7. data/.claude/skills/sm-job/reference/job-conventions.md +26 -0
  8. data/.claude/skills/sm-upgrade/reference/version-history.md +22 -0
  9. data/.gitignore +10 -0
  10. data/AGENTS.md +1 -1
  11. data/CHANGELOG.md +56 -0
  12. data/CLAUDE.md +11 -5
  13. data/Gemfile.lock +1 -1
  14. data/README.md +6 -4
  15. data/VERSION +1 -1
  16. data/app/assets/builds/source_monitor/application.css +43 -0
  17. data/app/assets/builds/source_monitor/application.js +127 -0
  18. data/app/assets/builds/source_monitor/application.js.map +3 -3
  19. data/app/assets/javascripts/source_monitor/application.js +2 -0
  20. data/app/assets/javascripts/source_monitor/controllers/notification_container_controller.js +138 -0
  21. data/app/assets/javascripts/source_monitor/controllers/notification_controller.js +11 -0
  22. data/app/controllers/source_monitor/source_favicon_fetches_controller.rb +38 -0
  23. data/app/controllers/source_monitor/sources_controller.rb +11 -0
  24. data/app/helpers/source_monitor/application_helper.rb +51 -0
  25. data/app/jobs/source_monitor/favicon_fetch_job.rb +71 -0
  26. data/app/jobs/source_monitor/import_opml_job.rb +9 -0
  27. data/app/jobs/source_monitor/source_health_check_job.rb +10 -0
  28. data/app/models/source_monitor/source.rb +2 -0
  29. data/app/views/layouts/source_monitor/application.html.erb +23 -2
  30. data/app/views/source_monitor/shared/_toast.html.erb +1 -0
  31. data/app/views/source_monitor/sources/_details.html.erb +34 -5
  32. data/app/views/source_monitor/sources/_row.html.erb +11 -6
  33. data/config/routes.rb +1 -0
  34. data/docs/configuration.md +1 -1
  35. data/docs/upgrade.md +22 -0
  36. data/lib/generators/source_monitor/install/templates/source_monitor.rb.tt +15 -1
  37. data/lib/source_monitor/configuration/favicons_settings.rb +42 -0
  38. data/lib/source_monitor/configuration/http_settings.rb +1 -1
  39. data/lib/source_monitor/configuration/scraping_settings.rb +1 -1
  40. data/lib/source_monitor/configuration.rb +3 -1
  41. data/lib/source_monitor/favicons/discoverer.rb +196 -0
  42. data/lib/source_monitor/fetching/feed_fetcher/source_updater.rb +21 -0
  43. data/lib/source_monitor/fetching/feed_fetcher.rb +1 -0
  44. data/lib/source_monitor/http.rb +5 -3
  45. data/lib/source_monitor/version.rb +1 -1
  46. data/lib/source_monitor.rb +4 -0
  47. data/lib/tasks/test_fast.rake +11 -0
  48. data/source_monitor.gemspec +1 -1
  49. metadata +7 -93
  50. data/.vbw-planning/PROJECT.md +0 -51
  51. data/.vbw-planning/ROADMAP.md +0 -32
  52. data/.vbw-planning/SHIPPED.md +0 -63
  53. data/.vbw-planning/STATE.md +0 -27
  54. data/.vbw-planning/codebase/ARCHITECTURE.md +0 -147
  55. data/.vbw-planning/codebase/CONCERNS.md +0 -99
  56. data/.vbw-planning/codebase/CONVENTIONS.md +0 -97
  57. data/.vbw-planning/codebase/DEPENDENCIES.md +0 -100
  58. data/.vbw-planning/codebase/INDEX.md +0 -86
  59. data/.vbw-planning/codebase/META.md +0 -42
  60. data/.vbw-planning/codebase/PATTERNS.md +0 -262
  61. data/.vbw-planning/codebase/STACK.md +0 -101
  62. data/.vbw-planning/codebase/STRUCTURE.md +0 -324
  63. data/.vbw-planning/codebase/TESTING.md +0 -154
  64. data/.vbw-planning/config.json +0 -53
  65. data/.vbw-planning/discovery.json +0 -26
  66. data/.vbw-planning/milestones/default/ROADMAP.md +0 -115
  67. data/.vbw-planning/milestones/default/STATE.md +0 -82
  68. data/.vbw-planning/milestones/default/phases/01-coverage-analysis-quick-wins/PLAN-01-SUMMARY.md +0 -56
  69. data/.vbw-planning/milestones/default/phases/01-coverage-analysis-quick-wins/PLAN-01.md +0 -187
  70. data/.vbw-planning/milestones/default/phases/01-coverage-analysis-quick-wins/PLAN-02-SUMMARY.md +0 -64
  71. data/.vbw-planning/milestones/default/phases/01-coverage-analysis-quick-wins/PLAN-02.md +0 -137
  72. data/.vbw-planning/milestones/default/phases/02-critical-path-test-coverage/PLAN-01-SUMMARY.md +0 -67
  73. data/.vbw-planning/milestones/default/phases/02-critical-path-test-coverage/PLAN-01.md +0 -142
  74. data/.vbw-planning/milestones/default/phases/02-critical-path-test-coverage/PLAN-02-SUMMARY.md +0 -64
  75. data/.vbw-planning/milestones/default/phases/02-critical-path-test-coverage/PLAN-02.md +0 -138
  76. data/.vbw-planning/milestones/default/phases/02-critical-path-test-coverage/PLAN-03-SUMMARY.md +0 -85
  77. data/.vbw-planning/milestones/default/phases/02-critical-path-test-coverage/PLAN-03.md +0 -147
  78. data/.vbw-planning/milestones/default/phases/02-critical-path-test-coverage/PLAN-04-SUMMARY.md +0 -63
  79. data/.vbw-planning/milestones/default/phases/02-critical-path-test-coverage/PLAN-04.md +0 -129
  80. data/.vbw-planning/milestones/default/phases/02-critical-path-test-coverage/PLAN-05-SUMMARY.md +0 -74
  81. data/.vbw-planning/milestones/default/phases/02-critical-path-test-coverage/PLAN-05.md +0 -154
  82. data/.vbw-planning/milestones/default/phases/03-large-file-refactoring/03-VERIFICATION-wave1.md +0 -303
  83. data/.vbw-planning/milestones/default/phases/03-large-file-refactoring/03-VERIFICATION.md +0 -510
  84. data/.vbw-planning/milestones/default/phases/03-large-file-refactoring/PLAN-01-SUMMARY.md +0 -61
  85. data/.vbw-planning/milestones/default/phases/03-large-file-refactoring/PLAN-01.md +0 -161
  86. data/.vbw-planning/milestones/default/phases/03-large-file-refactoring/PLAN-02-SUMMARY.md +0 -66
  87. data/.vbw-planning/milestones/default/phases/03-large-file-refactoring/PLAN-02.md +0 -132
  88. data/.vbw-planning/milestones/default/phases/03-large-file-refactoring/PLAN-03-SUMMARY.md +0 -59
  89. data/.vbw-planning/milestones/default/phases/03-large-file-refactoring/PLAN-03.md +0 -171
  90. data/.vbw-planning/milestones/default/phases/03-large-file-refactoring/PLAN-04-SUMMARY.md +0 -56
  91. data/.vbw-planning/milestones/default/phases/03-large-file-refactoring/PLAN-04.md +0 -152
  92. data/.vbw-planning/milestones/default/phases/04-code-quality-conventions-cleanup/04-CONTEXT.md +0 -33
  93. data/.vbw-planning/milestones/default/phases/04-code-quality-conventions-cleanup/PLAN-01-SUMMARY.md +0 -42
  94. data/.vbw-planning/milestones/default/phases/04-code-quality-conventions-cleanup/PLAN-01.md +0 -119
  95. data/.vbw-planning/milestones/default/phases/04-code-quality-conventions-cleanup/PLAN-02-SUMMARY.md +0 -52
  96. data/.vbw-planning/milestones/default/phases/04-code-quality-conventions-cleanup/PLAN-02.md +0 -195
  97. data/.vbw-planning/milestones/default/phases/04-code-quality-conventions-cleanup/PLAN-03-SUMMARY.md +0 -79
  98. data/.vbw-planning/milestones/default/phases/04-code-quality-conventions-cleanup/PLAN-03.md +0 -130
  99. data/.vbw-planning/milestones/generator-enhancements/REQUIREMENTS.md +0 -72
  100. data/.vbw-planning/milestones/generator-enhancements/ROADMAP.md +0 -125
  101. data/.vbw-planning/milestones/generator-enhancements/SHIPPED.md +0 -40
  102. data/.vbw-planning/milestones/generator-enhancements/STATE.md +0 -43
  103. data/.vbw-planning/milestones/generator-enhancements/phases/01-generator-steps/01-CONTEXT.md +0 -33
  104. data/.vbw-planning/milestones/generator-enhancements/phases/01-generator-steps/01-VERIFICATION.md +0 -86
  105. data/.vbw-planning/milestones/generator-enhancements/phases/01-generator-steps/PLAN-01-SUMMARY.md +0 -61
  106. data/.vbw-planning/milestones/generator-enhancements/phases/01-generator-steps/PLAN-01.md +0 -380
  107. data/.vbw-planning/milestones/generator-enhancements/phases/02-verification/02-VERIFICATION.md +0 -78
  108. data/.vbw-planning/milestones/generator-enhancements/phases/02-verification/PLAN-01-SUMMARY.md +0 -46
  109. data/.vbw-planning/milestones/generator-enhancements/phases/02-verification/PLAN-01.md +0 -500
  110. data/.vbw-planning/milestones/generator-enhancements/phases/03-docs-alignment/03-VERIFICATION.md +0 -89
  111. data/.vbw-planning/milestones/generator-enhancements/phases/03-docs-alignment/PLAN-01-SUMMARY.md +0 -48
  112. data/.vbw-planning/milestones/generator-enhancements/phases/03-docs-alignment/PLAN-01.md +0 -456
  113. data/.vbw-planning/milestones/generator-enhancements/phases/04-dashboard-ux/04-VERIFICATION.md +0 -129
  114. data/.vbw-planning/milestones/generator-enhancements/phases/04-dashboard-ux/PLAN-01-SUMMARY.md +0 -70
  115. data/.vbw-planning/milestones/generator-enhancements/phases/04-dashboard-ux/PLAN-01.md +0 -747
  116. data/.vbw-planning/milestones/generator-enhancements/phases/05-active-storage-images/05-VERIFICATION.md +0 -156
  117. data/.vbw-planning/milestones/generator-enhancements/phases/05-active-storage-images/PLAN-01-SUMMARY.md +0 -69
  118. data/.vbw-planning/milestones/generator-enhancements/phases/05-active-storage-images/PLAN-01.md +0 -455
  119. data/.vbw-planning/milestones/generator-enhancements/phases/05-active-storage-images/PLAN-02-SUMMARY.md +0 -39
  120. data/.vbw-planning/milestones/generator-enhancements/phases/05-active-storage-images/PLAN-02.md +0 -488
  121. data/.vbw-planning/milestones/generator-enhancements/phases/06-netflix-feed-fix/06-VERIFICATION.md +0 -100
  122. data/.vbw-planning/milestones/generator-enhancements/phases/06-netflix-feed-fix/PLAN-01-SUMMARY.md +0 -37
  123. data/.vbw-planning/milestones/generator-enhancements/phases/06-netflix-feed-fix/PLAN-01.md +0 -345
  124. data/.vbw-planning/milestones/upgrade-assurance/REQUIREMENTS.md +0 -80
  125. data/.vbw-planning/milestones/upgrade-assurance/ROADMAP.md +0 -75
  126. data/.vbw-planning/milestones/upgrade-assurance/STATE.md +0 -29
  127. data/.vbw-planning/milestones/upgrade-assurance/phases/01-upgrade-command/01-VERIFICATION.md +0 -144
  128. data/.vbw-planning/milestones/upgrade-assurance/phases/01-upgrade-command/PLAN-01-SUMMARY.md +0 -43
  129. data/.vbw-planning/milestones/upgrade-assurance/phases/01-upgrade-command/PLAN-01.md +0 -405
  130. data/.vbw-planning/milestones/upgrade-assurance/phases/02-config-deprecation/PLAN-01-SUMMARY.md +0 -27
  131. data/.vbw-planning/milestones/upgrade-assurance/phases/02-config-deprecation/PLAN-01.md +0 -303
  132. data/.vbw-planning/milestones/upgrade-assurance/phases/03-upgrade-skill-docs/03-VERIFICATION.md +0 -380
  133. data/.vbw-planning/milestones/upgrade-assurance/phases/03-upgrade-skill-docs/PLAN-01-SUMMARY.md +0 -36
  134. data/.vbw-planning/milestones/upgrade-assurance/phases/03-upgrade-skill-docs/PLAN-01.md +0 -652
  135. data/.vbw-planning/phases/01-aia-certificate-resolution/.context-dev.md +0 -17
  136. data/.vbw-planning/phases/01-aia-certificate-resolution/PLAN-01-SUMMARY.md +0 -26
  137. data/.vbw-planning/phases/01-aia-certificate-resolution/PLAN-01.md +0 -71
  138. data/.vbw-planning/phases/01-aia-certificate-resolution/PLAN-02-SUMMARY.md +0 -16
  139. data/.vbw-planning/phases/01-aia-certificate-resolution/PLAN-02.md +0 -56
  140. data/.vbw-planning/phases/01-aia-certificate-resolution/PLAN-03-SUMMARY.md +0 -17
  141. data/.vbw-planning/phases/01-aia-certificate-resolution/PLAN-03.md +0 -98
@@ -1,154 +0,0 @@
1
- # Testing
2
-
3
- ## Framework & Tools
4
-
5
- - **Test Framework**: Minitest (Rails default)
6
- - **System Tests**: Capybara + Selenium WebDriver (Chrome)
7
- - **HTTP Mocking**: WebMock (disables all external connections) + VCR (recorded cassettes)
8
- - **Coverage**: SimpleCov with branch coverage enabled
9
- - **Profiling**: test-prof (TagProf, EventProf) + StackProf
10
- - **Parallelization**: Built-in Rails parallel testing (configurable workers via `SOURCE_MONITOR_TEST_WORKERS`)
11
-
12
- ## Test Infrastructure
13
-
14
- ### Test Helper (`test/test_helper.rb`)
15
- - Loads SimpleCov in CI or when `COVERAGE` env is set
16
- - Configures Rails test environment pointing to dummy app
17
- - Sets migration paths to include both engine and dummy migrations
18
- - Uses `:test` ActiveJob queue adapter by default
19
- - Fixtures loaded from `test/fixtures/`
20
- - VCR cassettes stored in `test/vcr_cassettes/`
21
- - WebMock allows localhost only
22
- - Random test ordering enabled
23
- - Configuration reset in every test via `SourceMonitor.reset_configuration!`
24
-
25
- ### test-prof Integration (`test/test_prof.rb`)
26
- - `TestProf::BeforeAll::Minitest` for `before_all` blocks (shared expensive setup)
27
- - `SourceMonitor::TestProfSupport::SetupOnce` -- `setup_once` alias for `before_all`
28
- - `SourceMonitor::TestProfSupport::InlineJobs` -- `with_inline_jobs` helper
29
- - `TestProf::MinitestSample` -- SAMPLE/SAMPLE_GROUPS env var support for focused runs
30
-
31
- ### Shared Test Helpers
32
- - `create_source!(attributes = {})` -- factory method for creating test sources
33
- - `with_queue_adapter(adapter)` -- temporarily switch ActiveJob adapter
34
-
35
- ## Test Categories
36
-
37
- | Category | File Count | Path | Purpose |
38
- |----------|-----------|------|---------|
39
- | Unit (lib) | ~75 | `test/lib/source_monitor/` | Lib module tests |
40
- | Model | ~10 | `test/models/source_monitor/` | Model validation, scopes, behavior |
41
- | System | 6 | `test/system/` | Browser-driven end-to-end tests |
42
- | Integration | 4 | `test/integration/` | Engine mounting, navigation, packaging |
43
- | Example | 4 | `test/examples/` | Template and adapter examples |
44
- | Task | 2 | `test/tasks/` | Rake task tests |
45
- | Mailer | 1 | `test/mailers/` | Application mailer test |
46
- | Module | 1 | `test/source_monitor_test.rb` | Top-level module tests |
47
-
48
- **Total: ~124 test files**
49
-
50
- ## Test Structure
51
-
52
- Tests mirror the source directory structure:
53
-
54
- ```
55
- test/lib/source_monitor/
56
- configuration_test.rb
57
- feedjira_configuration_test.rb
58
- instrumentation_test.rb
59
- health/
60
- health_module_test.rb
61
- source_health_check_test.rb
62
- source_health_monitor_test.rb
63
- source_health_reset_test.rb
64
- pagination/
65
- paginator_test.rb
66
- scraping/
67
- bulk_result_presenter_test.rb
68
- bulk_source_scraper_test.rb
69
- enqueuer_test.rb
70
- item_scraper_test.rb
71
- item_scraper/
72
- adapter_resolver_test.rb
73
- persistence_test.rb
74
- scheduler_test.rb
75
- state_test.rb
76
- setup/
77
- bundle_installer_test.rb
78
- cli_test.rb
79
- dependency_checker_test.rb
80
- detectors_test.rb
81
- gemfile_editor_test.rb
82
- initializer_patcher_test.rb
83
- install_generator_test.rb
84
- migration_installer_test.rb
85
- node_installer_test.rb
86
- prompter_test.rb
87
- requirements_test.rb
88
- workflow_test.rb
89
- verification/
90
- action_cable_verifier_test.rb
91
- printer_test.rb
92
- runner_test.rb
93
- solid_queue_verifier_test.rb
94
- telemetry_logger_test.rb
95
- turbo_streams/
96
- stream_responder_test.rb
97
- release/
98
- runner_test.rb
99
- ```
100
-
101
- ## Dummy Application (`test/dummy/`)
102
-
103
- Full Rails application used as the host app for testing:
104
- - PostgreSQL database (`config/database.yml`)
105
- - Solid Queue configuration (`config/solid_queue.yml`, `config/queue.yml`)
106
- - Solid Cable configuration (`config/cable.yml`)
107
- - Mission Control integration
108
- - Custom STI model: `SourceMonitor::SponsoredSource` (tests model extensions)
109
- - Extension concern: `DummySourceMonitor::SourceExtensions`
110
- - `User` model for testing authentication
111
- - Source Monitor initializer exercising the full configuration API
112
-
113
- ## CI Pipeline
114
-
115
- ### Test Job
116
- 1. Sets up PostgreSQL 15 service container
117
- 2. Installs Ruby 3.4.4, Node 20
118
- 3. Builds frontend assets (`npm run build`)
119
- 4. Creates and migrates test database
120
- 5. Runs full test suite with coverage (`bin/test-coverage`)
121
- 6. Enforces diff coverage (`bin/check-diff-coverage`)
122
- 7. Uploads coverage artifact
123
- 8. Captures system test screenshots on failure
124
-
125
- ### Release Verification Job
126
- - Depends on lint, security, test jobs
127
- - Runs `test/integration/release_packaging_test.rb` specifically
128
- - Enforces diff coverage again
129
-
130
- ### Profiling Job (Nightly)
131
- - Runs on schedule (`cron: "30 6 * * *"`)
132
- - TagProf by type
133
- - EventProf on `sql.active_record`
134
- - StackProf on integration tests
135
- - Enforces profiling guardrails (`bin/check-test-prof-metrics`)
136
- - Uploads profiling artifacts
137
-
138
- ## Coverage
139
-
140
- - Branch coverage enabled
141
- - `refuse_coverage_drop :line` prevents regressions
142
- - Coverage baseline tracked in `config/coverage_baseline.json` (lists uncovered lines per file)
143
- - Diff coverage enforcement ensures new code is tested
144
- - `SOURCE_MONITOR_SKIP_COVERAGE` env var to disable coverage collection
145
- - `# :nocov:` annotations used for defensive/fallback code paths
146
-
147
- ## Notable Testing Patterns
148
-
149
- - **Configuration Reset**: Every test resets `SourceMonitor.reset_configuration!` in `setup`
150
- - **WebMock**: All external HTTP disabled; tests use stubs or VCR cassettes
151
- - **Job Testing**: Tests use `:test` adapter; `with_inline_jobs` for synchronous execution
152
- - **Parallel Safety**: Tests designed for parallel execution; use `SecureRandom.hex` for unique fixtures
153
- - **Factory Method**: `create_source!` with `save!(validate: false)` for flexible test data
154
- - **Setup Verification Tests**: `bin/check-setup-tests` ensures all setup files have corresponding tests
@@ -1,53 +0,0 @@
1
- {
2
- "effort": "thorough",
3
- "autonomy": "standard",
4
- "auto_commit": true,
5
- "planning_tracking": "manual",
6
- "auto_push": "never",
7
- "verification_tier": "standard",
8
- "skill_suggestions": true,
9
- "auto_install_skills": false,
10
- "discovery_questions": true,
11
- "context_compiler": true,
12
- "visual_format": "unicode",
13
- "max_tasks_per_plan": 5,
14
- "prefer_teams": "always",
15
- "branch_per_milestone": false,
16
- "plain_summary": true,
17
- "active_profile": "default",
18
- "custom_profiles": {},
19
- "model_profile": "quality",
20
- "model_overrides": {},
21
- "agent_max_turns": {
22
- "scout": 15,
23
- "qa": 25,
24
- "architect": 30,
25
- "debugger": 80,
26
- "lead": 50,
27
- "dev": 75
28
- },
29
- "qa_skip_agents": [
30
- "docs"
31
- ],
32
- "v3_delta_context": false,
33
- "v3_context_cache": false,
34
- "v3_plan_research_persist": false,
35
- "v3_metrics": false,
36
- "v3_contract_lite": false,
37
- "v3_lock_lite": false,
38
- "v3_validation_gates": false,
39
- "v3_smart_routing": false,
40
- "v3_event_log": false,
41
- "v3_schema_validation": false,
42
- "v3_snapshot_resume": false,
43
- "v3_lease_locks": false,
44
- "v3_event_recovery": false,
45
- "v3_monorepo_routing": false,
46
- "v2_hard_contracts": false,
47
- "v2_hard_gates": false,
48
- "v2_typed_protocol": false,
49
- "v2_role_isolation": false,
50
- "v2_two_phase_completion": false,
51
- "v2_token_budgets": false,
52
- "compaction_trigger": 130000
53
- }
@@ -1,26 +0,0 @@
1
- {
2
- "answered": [
3
- {
4
- "question": "What matters most in the conventions cleanup?",
5
- "answer": "All of the above: Model conventions, Controller patterns, Dead code removal",
6
- "category": "scope",
7
- "phase": "4",
8
- "date": "2026-02-10"
9
- },
10
- {
11
- "question": "How should we handle convention violations that would change public API behavior?",
12
- "answer": "Fix everything -- rename/restructure even if it changes method signatures or route patterns",
13
- "category": "api-policy",
14
- "phase": "4",
15
- "date": "2026-02-10"
16
- }
17
- ],
18
- "inferred": [
19
- "User wants comprehensive cleanup, not surface-level",
20
- "Public API changes are acceptable for convention alignment",
21
- "Tests should be updated to match any changes, not removed",
22
- "All layers: models, controllers, services, dead code",
23
- "Generator should be maximally helpful -- create files rather than just warn",
24
- "Target Rails 8 defaults (queue.yml) rather than supporting legacy naming"
25
- ]
26
- }
@@ -1,115 +0,0 @@
1
- <!-- VBW ROADMAP TEMPLATE (ARTF-07) -- Phase-based project roadmap -->
2
- <!-- Created by Architect agent during /vbw scope -->
3
-
4
- # SourceMonitor Roadmap
5
-
6
- ## Overview
7
-
8
- This roadmap focuses on stabilizing and improving the existing SourceMonitor codebase through test coverage improvements and refactoring for maintainability. 4 phases progressing from analysis to coverage to refactoring to cleanup.
9
-
10
- ## Phases
11
-
12
- - [x] Phase 1: Coverage Analysis & Quick Wins
13
- - [x] Phase 2: Critical Path Test Coverage
14
- - [x] Phase 3: Large File Refactoring
15
- - [x] Phase 4: Code Quality & Conventions Cleanup
16
-
17
- ## Phase Details
18
-
19
- ### Phase 1: Coverage Analysis & Quick Wins
20
-
21
- **Goal:** Analyze the coverage baseline, identify the highest-impact gaps, and close easy coverage wins (frozen_string_literal, small utility classes).
22
- **Depends on:** None
23
-
24
- **Requirements:**
25
- - REQ-13: Frozen string literal consistency
26
- - REQ-14: RuboCop audit
27
-
28
- **Success Criteria:**
29
- 1. All Ruby files have frozen_string_literal: true
30
- 2. Zero RuboCop violations against omakase ruleset
31
- 3. Coverage baseline shrinks by at least 10%
32
-
33
- **Plans:**
34
- - [x] Plan 01: frozen-string-literal-audit (5f02db8)
35
- - [x] Plan 02: rubocop-audit-and-fix (no changes needed)
36
-
37
- ### Phase 2: Critical Path Test Coverage
38
-
39
- **Goal:** Close the major test coverage gaps in the most critical business logic -- feed fetching, item creation, configuration, dashboard queries, and broadcasting.
40
- **Depends on:** Phase 1
41
-
42
- **Requirements:**
43
- - REQ-01: FeedFetcher coverage
44
- - REQ-02: ItemCreator coverage
45
- - REQ-03: Configuration coverage
46
- - REQ-04: Dashboard::Queries coverage
47
- - REQ-05: Broadcaster coverage
48
- - REQ-06: BulkSourceScraper coverage
49
- - REQ-07: SourcesIndexMetrics coverage
50
-
51
- **Success Criteria:**
52
- 1. Coverage baseline shrinks by at least 50% from original
53
- 2. All critical path files have branch coverage above 80%
54
- 3. CI pipeline passes with no regressions
55
-
56
- **Plans:**
57
- - [x] Plan 01: feed-fetcher-tests (8d4e8d3)
58
- - [x] Plan 02: item-creator-tests (ce8ede4)
59
- - [x] Plan 03: configuration-tests (66b8df2)
60
- - [x] Plan 04: dashboard-and-analytics-tests (a8f2611, 2e50580)
61
- - [x] Plan 05: scraping-and-broadcasting-tests (e497891, 66b8df2)
62
-
63
- ### Phase 3: Large File Refactoring
64
-
65
- **Goal:** Break down the three largest files (FeedFetcher, Configuration, ImportSessionsController) into focused, single-responsibility modules while maintaining all existing tests.
66
- **Depends on:** Phase 2
67
-
68
- **Requirements:**
69
- - REQ-08: Extract FeedFetcher
70
- - REQ-09: Extract Configuration
71
- - REQ-10: Extract ImportSessionsController
72
- - REQ-11: Fix LogEntry table name
73
- - REQ-12: Replace eager requires with autoloading
74
-
75
- **Success Criteria:**
76
- 1. No single file exceeds 300 lines
77
- 2. All existing tests pass without modification (or with minimal adapter changes)
78
- 3. Public API remains unchanged
79
-
80
- **Plans:**
81
- - [x] Plan 01: extract-feed-fetcher (2f00274)
82
- - [x] Plan 02: extract-configuration-settings (ab823a3)
83
- - [x] Plan 03: extract-import-sessions-controller (9dce996)
84
- - [x] Plan 04: fix-log-entry-and-autoloading (fb99d3d)
85
-
86
- ### Phase 4: Code Quality & Conventions Cleanup
87
-
88
- **Goal:** Final pass to ensure all code follows Rails best practices and conventions, clean up any remaining debt.
89
- **Depends on:** Phase 3
90
-
91
- **Requirements:**
92
- - REQ-15: Rails conventions audit
93
-
94
- **Success Criteria:**
95
- 1. All models, controllers, and service objects follow established conventions
96
- 2. No RuboCop violations
97
- 3. Coverage baseline is at least 60% smaller than original
98
- 4. CI pipeline fully green
99
-
100
- **Plans:**
101
- - [x] Plan 01: conventions-audit (44fe6b6, c30a503, f070ea6, 78600b5, ec67c65)
102
- - [x] Plan 02: item-creator-extraction (3d33a71)
103
- - [x] Plan 03: final-verification (cc2e538)
104
-
105
- ## Progress
106
-
107
- | Phase | Plans Complete | Status | Completed |
108
- |-------|---------------|--------|-----------|
109
- | 1 - Coverage Analysis & Quick Wins | 2/2 | complete | 2026-02-09 |
110
- | 2 - Critical Path Test Coverage | 5/5 | complete | 2026-02-09 |
111
- | 3 - Large File Refactoring | 4/4 | complete | 2026-02-10 |
112
- | 4 - Code Quality & Conventions Cleanup | 3/3 | complete | 2026-02-10 |
113
-
114
- ---
115
- *Last updated: 2026-02-10 after Phase 4 completion*
@@ -1,82 +0,0 @@
1
- <!-- VBW STATE TEMPLATE (ARTF-05) -- Session dashboard, auto-updated -->
2
- <!-- Updated after each plan completion and at checkpoints -->
3
-
4
- # Project State
5
-
6
- ## Project Reference
7
-
8
- See: .vbw-planning/PROJECT.md (updated 2026-02-09)
9
-
10
- **Core value:** Drop-in Rails engine for feed monitoring, content scraping, and operational dashboards.
11
- **Current focus:** All phases complete
12
-
13
- ## Current Position
14
-
15
- Phase: 4 of 4 (Code Quality & Conventions Cleanup)
16
- Plan: 3 of 3 in current phase
17
- Status: Built
18
- Last activity: 2026-02-10 -- Phase 4 complete (3/3 plans done)
19
-
20
- Progress: [##########] 100%
21
-
22
- ## Codebase Profile
23
-
24
- - **Total source files:** 535
25
- - **Primary language:** Ruby (330 files)
26
- - **Templates:** ERB (48 files)
27
- - **Tests:** 137 test files detected
28
- - **Test suite:** 841 runs, 2776 assertions, 0 failures (up from 473 runs in Phase 1)
29
- - **Coverage:** 86.97% line, 58.84% branch (510 uncovered lines, down from 2117)
30
- - **CI/CD:** GitHub Actions (1 workflow)
31
- - **Docker:** Yes (2 files)
32
- - **Monorepo:** No
33
- - **Stack:** Ruby on Rails 8 engine, Solid Queue, Hotwire, Tailwind CSS, PostgreSQL, Minitest, RuboCop, Brakeman
34
-
35
- ## Accumulated Context
36
-
37
- ### Decisions
38
-
39
- - [bootstrap]: Focus on coverage + refactoring before new features
40
- - [bootstrap]: Keep PostgreSQL-only for now
41
- - [bootstrap]: Keep host-app auth model
42
- - [phase-1]: Omakase RuboCop config only enables 45/775 cops; all Metrics cops disabled
43
- - [phase-1]: No .rubocop.yml exclusions needed for large files (Metrics cops off)
44
- - [phase-2]: PG parallel fork segfault when running single test files; use PARALLEL_WORKERS=1 or full suite
45
- - [phase-2]: Configuration tests (Plan 03) were committed under mislabeled "dev-plan05" commit; corrected in summaries
46
- - [phase-3]: FeedFetcher extraction (Plan 01) was committed under mislabeled "plan-04" commit (2f00274); corrected in summaries
47
- - [phase-3]: Ruby autoload used instead of Zeitwerk for lib/ modules -- safest drop-in replacement for eager requires
48
- - [phase-3]: 11 boot-critical requires kept explicit; 71 autoload declarations replace 66 eager requires
49
- - [phase-4]: ItemCreator extracted from 601 to 174 lines (EntryParser + ContentExtractor sub-modules)
50
- - [phase-4]: Fix-everything approach for public API convention violations
51
- - [phase-4]: 3 files slightly exceed 300 lines (entry_parser 390, queries 356, application_helper 346) -- all single-responsibility, cannot be split further
52
-
53
-
54
- None
55
-
56
- ### Blockers/Concerns
57
-
58
- None
59
-
60
- ### Skills
61
-
62
- **Installed:**
63
- - agent-browser (global)
64
- - flowdeck (global)
65
- - ralph-tui-create-json (global)
66
- - ralph-tui-prd (global)
67
- - vastai (global)
68
- - find-skills (global)
69
-
70
- **Suggested (not installed):**
71
- - dhh-rails-style (registry) -- DHH-style Rails conventions
72
- - ruby-rails (registry) -- Ruby on Rails development
73
- - github-actions (registry) -- GitHub Actions workflow
74
-
75
- **Stack detected:** Ruby on Rails 8 engine, Solid Queue, Hotwire (Turbo + Stimulus), Tailwind CSS, PostgreSQL, ESLint, GitHub Actions, Minitest, RuboCop, Brakeman
76
- **Registry available:** yes
77
-
78
- ## Session Continuity
79
-
80
- Last session: 2026-02-10
81
- Stopped at: All 4 phases complete
82
- Resume file: none
@@ -1,56 +0,0 @@
1
- # PLAN-01 Summary: frozen-string-literal-audit
2
-
3
- ## Status: COMPLETE
4
-
5
- ## Commit
6
-
7
- - **Hash:** `5f02db8`
8
- - **Message:** `style(frozen-string-literal): add pragma to all Ruby files`
9
- - **Files changed:** 113 files, 223 insertions
10
-
11
- ## Tasks Completed
12
-
13
- ### Task 1: Add frozen_string_literal to app/ and lib/ source files
14
- - Added pragma to all 29 app/ and lib/ `.rb` files
15
- - No shebang lines encountered in any files
16
-
17
- ### Task 2: Add frozen_string_literal to config and migration files
18
- - Added pragma to `config/routes.rb` and 4 migration files
19
-
20
- ### Task 3: Add frozen_string_literal to test files (excluding test/dummy and test/tmp)
21
- - Added pragma to all 43 test `.rb` files
22
- - `test/test_helper.rb` had no shebang, straightforward prepend
23
-
24
- ### Task 4: Add frozen_string_literal to test/dummy files
25
- - Added pragma to all 22 dummy app `.rb` files
26
-
27
- ### Task 5: Validate full codebase compliance and run tests
28
- - `git ls-files -- '*.rb' | ... | grep -cv 'frozen_string_literal: true'` returns **0**
29
- - `bin/rubocop --only Style/FrozenStringLiteralComment` exits **0** (341 files, no offenses)
30
- - `bin/rails test` passes: **473 runs, 1927 assertions, 0 failures, 0 errors**
31
-
32
- ## Deviations
33
-
34
- ### DEVN-02: Non-.rb Ruby files also needed the pragma (14 additional files)
35
-
36
- The plan scoped only `.rb` files, but the success criterion requires `bin/rubocop --only Style/FrozenStringLiteralComment` to pass. RuboCop also inspects non-`.rb` Ruby files: `Gemfile`, `Rakefile`, `source_monitor.gemspec`, 3 `.rake` files, `test/dummy/Gemfile`, `test/dummy/Rakefile`, 5 `test/dummy/bin/*` scripts, and `test/dummy/config.ru`. All 14 were given the pragma.
37
-
38
- ### DEVN-02: test/tmp/ excluded from RuboCop
39
-
40
- RuboCop was scanning 179 files under `test/tmp/` (untracked generated host app templates) which all lacked the pragma. Since these are not git-tracked and are generated artifacts, added `test/tmp/**/*` to `.rubocop.yml` AllCops Exclude list rather than modifying generated files.
41
-
42
- ### DEVN-01: Shebang handling for bin scripts
43
-
44
- Five `test/dummy/bin/*` files had shebang lines. The pragma was correctly inserted after the shebang on line 2. Two files (`bin/dev`, `bin/jobs`) had a blank line between the shebang and the first require, which would have created a double blank line; these were cleaned up to have a single blank line separator.
45
-
46
- ## Decisions
47
-
48
- 1. **Included non-.rb Ruby files** -- To satisfy the RuboCop success criterion, all Ruby-like files RuboCop inspects needed the pragma, not just `.rb` files.
49
- 2. **Excluded test/tmp/ from RuboCop** -- These are generated Rails app templates that are not git-tracked and should not be linted. This is a minimal `.rubocop.yml` change.
50
- 3. **Did not modify test/lib/tmp/install_generator/config/routes.rb** -- This file is not git-tracked (despite the path existing on disk from a previous test run), so it was left as-is.
51
-
52
- ## Success Criteria
53
-
54
- - [x] Every git-tracked `.rb` file has `# frozen_string_literal: true` (REQ-13)
55
- - [x] RuboCop `Style/FrozenStringLiteralComment` cop passes with zero offenses
56
- - [x] No test regressions introduced (473 tests, 0 failures)
@@ -1,187 +0,0 @@
1
- ---
2
- phase: 1
3
- plan: 1
4
- title: frozen-string-literal-audit
5
- wave: 1
6
- depends_on: []
7
- skills_used: []
8
- must_haves:
9
- truths:
10
- - "Every git-tracked `.rb` file begins with `# frozen_string_literal: true` as its first line (verified by `git ls-files -- '*.rb' | xargs head -1 | grep -cv 'frozen_string_literal: true'` returning 0)"
11
- - "`bin/rubocop --only Style/FrozenStringLiteralComment` exits 0 with zero offenses"
12
- - "All existing tests pass (`bin/rails test` exits 0)"
13
- artifacts:
14
- - "98 Ruby files modified to add the `# frozen_string_literal: true` pragma"
15
- key_links:
16
- - "REQ-13 fully satisfied by this plan"
17
- ---
18
-
19
- # Plan 01: frozen-string-literal-audit
20
-
21
- ## Objective
22
-
23
- Add the `# frozen_string_literal: true` magic comment to every git-tracked Ruby file that is currently missing it. This is a mechanical, low-risk change that brings the codebase into full compliance with REQ-13 and prepares for the RuboCop audit in Plan 02.
24
-
25
- ## Context
26
-
27
- <context>
28
- @.vbw-planning/REQUIREMENTS.md -- REQ-13: frozen_string_literal consistency
29
- @.vbw-planning/codebase/CONVENTIONS.md -- documents existing frozen_string_literal convention
30
- @.rubocop.yml -- RuboCop configuration (omakase base)
31
-
32
- **Decomposition rationale:** This plan is separated from the RuboCop audit because (a) frozen_string_literal changes touch nearly 100 files and are purely mechanical, making them ideal for a single focused commit, and (b) completing this first removes a large category of RuboCop violations, simplifying Plan 02's scope.
33
-
34
- **Current state:**
35
- - 325 git-tracked Ruby files total
36
- - 227 already have `# frozen_string_literal: true`
37
- - 98 are missing it
38
- - Missing files span: app/ (5), lib/ (24 including setup/, engine, version, assets), test/ (43 non-dummy test files), test/dummy/ (22), config/ (1), db/migrate/ (4)
39
- - The codebase convention (per CONVENTIONS.md) is to use frozen_string_literal consistently, but it has drifted in setup/, engine infrastructure, test files, and dummy app files
40
-
41
- **Constraints:**
42
- - Do NOT modify files under `test/tmp/` (generated artifacts, not tracked in git)
43
- - The `test/lib/tmp/install_generator/config/initializers/source_monitor.rb` already has the pragma (verified)
44
- - Migration files and config/routes.rb need the pragma too
45
- - Some files may have a shebang line (`#!/usr/bin/env ruby`) as line 1 -- the pragma must go AFTER the shebang
46
- - `test/dummy/db/schema.rb` is excluded from RuboCop in `.rubocop.yml` but should still get the pragma for consistency
47
- </context>
48
-
49
- ## Tasks
50
-
51
- ### Task 1: Add frozen_string_literal to app/ and lib/ source files
52
-
53
- - **name:** add-frozen-pragma-to-source-files
54
- - **files:**
55
- - `app/controllers/source_monitor/application_controller.rb`
56
- - `app/controllers/source_monitor/health_controller.rb`
57
- - `app/helpers/source_monitor/application_helper.rb`
58
- - `app/jobs/source_monitor/application_job.rb`
59
- - `app/models/source_monitor/application_record.rb`
60
- - `lib/source_monitor.rb`
61
- - `lib/source_monitor/assets.rb`
62
- - `lib/source_monitor/assets/bundler.rb`
63
- - `lib/source_monitor/engine.rb`
64
- - `lib/source_monitor/version.rb`
65
- - `lib/source_monitor/setup/initializer_patcher.rb`
66
- - `lib/source_monitor/setup/bundle_installer.rb`
67
- - `lib/source_monitor/setup/workflow.rb`
68
- - `lib/source_monitor/setup/gemfile_editor.rb`
69
- - `lib/source_monitor/setup/requirements.rb`
70
- - `lib/source_monitor/setup/detectors.rb`
71
- - `lib/source_monitor/setup/shell_runner.rb`
72
- - `lib/source_monitor/setup/cli.rb`
73
- - `lib/source_monitor/setup/verification/printer.rb`
74
- - `lib/source_monitor/setup/verification/telemetry_logger.rb`
75
- - `lib/source_monitor/setup/verification/solid_queue_verifier.rb`
76
- - `lib/source_monitor/setup/verification/result.rb`
77
- - `lib/source_monitor/setup/verification/action_cable_verifier.rb`
78
- - `lib/source_monitor/setup/verification/runner.rb`
79
- - `lib/source_monitor/setup/install_generator.rb`
80
- - `lib/source_monitor/setup/dependency_checker.rb`
81
- - `lib/source_monitor/setup/prompter.rb`
82
- - `lib/source_monitor/setup/migration_installer.rb`
83
- - `lib/source_monitor/setup/node_installer.rb`
84
- - **action:** Prepend `# frozen_string_literal: true\n\n` to each file listed above. If the file already begins with a shebang (`#!`), insert the pragma on line 2 (after the shebang) with a blank line separating them. For `lib/source_monitor.rb` specifically, note it starts with `require` statements -- the pragma goes before all requires.
85
- - **verify:** Run `grep -cL 'frozen_string_literal: true' app/**/*.rb lib/**/*.rb` returns no results (all files have the pragma). Additionally run `ruby -c lib/source_monitor.rb` to confirm syntax validity.
86
- - **done:** All 29 app/ and lib/ Ruby files have `# frozen_string_literal: true` as their first non-shebang line.
87
-
88
- ### Task 2: Add frozen_string_literal to config and migration files
89
-
90
- - **name:** add-frozen-pragma-to-config-and-migrations
91
- - **files:**
92
- - `config/routes.rb`
93
- - `db/migrate/20251009103000_add_feed_content_readability_to_sources.rb`
94
- - `db/migrate/20251014171659_add_performance_indexes.rb`
95
- - `db/migrate/20251014172525_add_fetch_status_check_constraint.rb`
96
- - `db/migrate/20251108120116_refresh_fetch_status_constraint.rb`
97
- - **action:** Prepend `# frozen_string_literal: true\n\n` to each file. These are small files (migration class definitions and route definitions).
98
- - **verify:** Run `head -1` on each file to confirm the pragma is present. Run `ruby -c config/routes.rb` to confirm syntax validity (it will fail since it references SourceMonitor::Engine, so instead just visually confirm the pragma is on line 1).
99
- - **done:** All 5 config/ and db/migrate/ files have the pragma.
100
-
101
- ### Task 3: Add frozen_string_literal to test files (excluding test/dummy and test/tmp)
102
-
103
- - **name:** add-frozen-pragma-to-test-files
104
- - **files:**
105
- - `test/test_helper.rb`
106
- - `test/source_monitor_test.rb`
107
- - `test/gemspec_test.rb`
108
- - `test/application_system_test_case.rb`
109
- - `test/system/dropdown_fallback_test.rb`
110
- - `test/integration/engine_mounting_test.rb`
111
- - `test/integration/navigation_test.rb`
112
- - `test/controllers/source_monitor/health_controller_test.rb`
113
- - `test/jobs/source_monitor/fetch_feed_job_test.rb`
114
- - `test/jobs/source_monitor/item_cleanup_job_test.rb`
115
- - `test/jobs/source_monitor/log_cleanup_job_test.rb`
116
- - All files under `test/lib/source_monitor/setup/` (12 files)
117
- - All files under `test/lib/source_monitor/setup/verification/` (5 files)
118
- - `test/lib/source_monitor/instrumentation_test.rb`
119
- - `test/lib/source_monitor/feedjira_configuration_test.rb`
120
- - `test/lib/source_monitor/metrics_test.rb`
121
- - `test/lib/source_monitor/scheduler_test.rb`
122
- - `test/lib/source_monitor/release/runner_test.rb`
123
- - `test/lib/source_monitor/release/changelog_test.rb`
124
- - `test/lib/source_monitor/items/item_creator_test.rb`
125
- - `test/lib/source_monitor/items/retention_pruner_test.rb`
126
- - `test/lib/source_monitor/events/event_system_test.rb`
127
- - `test/lib/source_monitor/assets/bundler_test.rb`
128
- - `test/lib/source_monitor/engine_assets_configuration_test.rb`
129
- - `test/lib/source_monitor/http_test.rb`
130
- - `test/lib/source_monitor/fetching/feed_fetcher_test.rb`
131
- - `test/lib/source_monitor/fetching/fetch_runner_test.rb`
132
- - **action:** Prepend `# frozen_string_literal: true\n\n` to each file. The `test/test_helper.rb` file may have a shebang or special first lines -- check and handle accordingly.
133
- - **verify:** Run `find test -name '*.rb' -not -path 'test/tmp/*' -not -path 'test/dummy/*' -exec head -1 {} \; | grep -cv 'frozen_string_literal'` returns 0.
134
- - **done:** All 43 test files (excluding dummy and tmp) have the pragma.
135
-
136
- ### Task 4: Add frozen_string_literal to test/dummy files
137
-
138
- - **name:** add-frozen-pragma-to-dummy-app
139
- - **files:**
140
- - `test/dummy/app/controllers/application_controller.rb`
141
- - `test/dummy/app/controllers/test_support_controller.rb`
142
- - `test/dummy/app/helpers/application_helper.rb`
143
- - `test/dummy/app/jobs/application_job.rb`
144
- - `test/dummy/app/mailers/application_mailer.rb`
145
- - `test/dummy/app/models/application_record.rb`
146
- - `test/dummy/app/models/user.rb`
147
- - `test/dummy/config/application.rb`
148
- - `test/dummy/config/boot.rb`
149
- - `test/dummy/config/environment.rb`
150
- - `test/dummy/config/environments/development.rb`
151
- - `test/dummy/config/environments/production.rb`
152
- - `test/dummy/config/environments/test.rb`
153
- - `test/dummy/config/importmap.rb`
154
- - `test/dummy/config/puma.rb`
155
- - `test/dummy/config/routes.rb`
156
- - `test/dummy/config/initializers/assets.rb`
157
- - `test/dummy/config/initializers/content_security_policy.rb`
158
- - `test/dummy/config/initializers/filter_parameter_logging.rb`
159
- - `test/dummy/config/initializers/inflections.rb`
160
- - `test/dummy/db/migrate/20251124080000_create_users.rb`
161
- - `test/dummy/db/schema.rb`
162
- - **action:** Prepend `# frozen_string_literal: true\n\n` to each file. The `test/dummy/db/schema.rb` may be auto-generated by Rails -- still add the pragma since it is git-tracked and part of the project.
163
- - **verify:** Run `find test/dummy -name '*.rb' -exec head -1 {} \; | grep -cv 'frozen_string_literal'` returns 0.
164
- - **done:** All 22 dummy app Ruby files have the pragma.
165
-
166
- ### Task 5: Validate full codebase compliance and run tests
167
-
168
- - **name:** validate-frozen-pragma-compliance
169
- - **files:** (no files modified -- validation only)
170
- - **action:** Run three verification commands: (1) Count git-tracked Ruby files without the pragma -- must be 0. (2) Run `bin/rubocop --only Style/FrozenStringLiteralComment` to confirm zero RuboCop offenses for this cop. (3) Run the test suite to confirm no regressions from adding the pragma.
171
- - **verify:**
172
- - `git ls-files -- '*.rb' | xargs head -1 | grep -cv 'frozen_string_literal: true'` outputs `0`
173
- - `bin/rubocop --only Style/FrozenStringLiteralComment` exits 0
174
- - `bin/rails test` exits 0 (or at minimum no new failures)
175
- - **done:** Full codebase compliance confirmed. REQ-13 is satisfied.
176
-
177
- ## Verification
178
-
179
- 1. `git ls-files -- '*.rb' | xargs head -1 | grep -cv 'frozen_string_literal: true'` returns `0`
180
- 2. `bin/rubocop --only Style/FrozenStringLiteralComment` exits 0 with zero offenses
181
- 3. Test suite passes with no regressions
182
-
183
- ## Success Criteria
184
-
185
- - [x] Every git-tracked Ruby file has `# frozen_string_literal: true` (REQ-13)
186
- - [x] RuboCop `Style/FrozenStringLiteralComment` cop passes with zero offenses
187
- - [x] No test regressions introduced