Skip to content

feat(rails): replace Rails rules with per-layer MVC conventions - #15

Merged
tms-anhnguyen1 merged 1 commit into
TOMOSIA-VIETNAM:mainfrom
tms-minhtang1:feat/rails-conventions
Oct 28, 2026
Merged

tms-anhnguyen1 merged 1 commit into
TOMOSIA-VIETNAM:mainfrom
tms-minhtang1:feat/rails-conventions

Conversation

@tms-minhtang1

@tms-minhtang1 tms-minhtang1 commented Oct 9, 2026 •

Copy link
Copy Markdown
Contributor

Purpose

The three generic Rails rules gave advice our Rails projects don't follow. This PR replaces them with 29 rules, one per layer or gem, and four procedure-only skills, so Claude writes code the way the team does: thin controllers, service objects, form objects, Hotwire on the front end. Markdown only; tests/pipeline.test.ts uses the new rule ids.

What changes

Always loaded rails-structure: where each kind of code goes, the call flow, read a layer's rule before writing it, ask the user via AskUserQuestion
Server controllers, services, validations, authorization, errors, models, queries, search, migrations, jobs, json, views, i18n, config, lib
Cross-cutting security, performance, specs, style, comments
Front end hotwire (Turbo, Stimulus), javascript-packages (importmap or jsbundling)
Gem rules, each "applies only when the project includes it" decorators, view-components, enumerize, soft-delete, tailwind, bootstrap
Skills rails-feature, rails-migration, rails-debug-n-plus-one (procedure only, conventions stay in the rules), rails-doctor (typed only: fills AGENTS.md, reports rules that don't fit the project)

Cost

Every rule except rails-structure has paths: and loads once per session, when Claude first touches a matching file.

Tokens
Session start +1,640
First file of a layer +1.5k to +9k (the 2 to 9 rules matching it)
Another file of the same layer +0
All 29 rules ~19k

Result

Rules generated into fresh Rails 8.1 apps; each task ran in a clean claude -p session and its diff was graded against the rules by a separate session.

Server (20 tasks) Front end (Tailwind and Bootstrap apps)
Team conventions held ¹ ✅ 10/10 ✅ 7/7
Specs pass, also in random order ✅ ✅
RuboCop clean, no new Brakeman warning ✅ ✅
Right skill invoked ✅ ⚠️ 2/3 ²
Same tasks Without these rules With these rules
Convention breaks per task 22 5
Cost per task (claude-opus-5-5) $0.47 $0.92
  1. Server: no model validation or callback, ApplicationService, form objects, specs split by model and endpoint, scoped shared_context, locales split by scope, Rails-named indexes, frozen_string_literal, helpers by topic, a concurrent spec for a limited shared resource.
  2. Front end: no DOM query outside the controller, listeners through data-action, broadcasts from the service, no interpolated or !important classes, a base ApplicationController, dom_id(Model, :list) for collection frames, browser-formatted text through Intl.
  3. The miss was a display-only change; the layer rules load from the files Claude touches, not from the skill, and that task met every convention.

Not exercised: jsbundling and the tailwindcss-rails gem path (both front-end apps use importmap, and Tailwind from npm).

Verification

npm run check: typecheck, 120/120 tests, bundle. dist/ unchanged. npm run try -- --framework rails emits 29 Rails rules and 4 Rails skills.

@tms-minhtang1
tms-minhtang1 force-pushed the feat/rails-conventions branch from ecaca7f to 38d4059 Compare October 9, 2026 16:39
@tms-minhtang1 tms-minhtang1 changed the title feat: ship Rails HMVC conventions with enforcing cops feat(rails): replace Rails rules with per-layer MVC conventions Oct 9, 2026
@tms-anhnguyen1
tms-anhnguyen1 marked this pull request as draft October 19, 2026 07:04

@tms-minhtang1 tms-minhtang1 left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤖【AI REVIEW】Overview

Cảm ơn bạn 🙏 Toàn bộ thay đổi của PR đã được review tại commit 2929571. Bạn trả lời ngay trong thread của từng finding nếu đồng ý hoặc không đồng ý.

🔵 SUGGESTION

🔵 Hai tài liệu ngoài diff vẫn mô tả bộ rule Rails cũ.

  • knowledge/README.md:144: bảng agent-stack catalog vẫn ghi dòng rails là 3 rule, 29 skill; sau PR này là 25 rule, 30 skill (26 global + 4).
  • README.md:183-192: ví dụ checklist liệt kê rails-activerecord, rails-conventions, rails-ruby (cả ba bị xoá ở PR này) dưới Rules (3).

Cách sửa — chạy agent-stack catalog và npm run try -- --framework rails, chép số thật vào hai chỗ trên, và đổi ví dụ checklist sang id đang có (ví dụ rails-models, rails-structure, rails-style).

Comment thread knowledge/rules/framework/rails/lib.md Resolved

@tms-minhtang1 tms-minhtang1 left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤖【AI REVIEW】Overview

Cảm ơn 🙏 Toàn bộ thay đổi của PR đã được review tại commit 40657c8. Bạn trả lời ngay trong từng comment nếu không đồng ý hoặc đã sửa.

tms-minhtang1 added a commit to tms-minhtang1/agent-stack that referenced this pull request Oct 26, 2026
- validations: forms use custom validators for existence and uniqueness;
  uniqueness: is Active Record only. The 422 error carries the form.
- controllers: HTML create/update re-render new/edit from the error's form.
- lib: the core_ext initializer declares CoreExt namespaces before require.
- models, structure: models never enqueue jobs; the service does after commit.
- authorization: skip_authorization / skip_authorization_check for actions
  whose permission is the lookup or authentication alone.
- migrations, models, validations: SQLite bounds strings by check constraint.
- errors: a message is for the log and tracker, never rendered.
- security: concurrent tests turn transactions off for their group only.
- queries, performance: loading rules live once, in queries.
- enumerize: configs read with fetch. rails-doctor checklist: Gemfile.
- README, knowledge/README: current Rails rule ids and counts.
@tms-minhtang1

Copy link
Copy Markdown
Contributor Author

Về finding knowledge/README.md:144 và README.md:183-192 (tài liệu còn mô tả bộ rule Rails cũ): đã sửa. Bảng agent-stack catalog ghi rails 25 rule, 30 skill; ví dụ checklist dùng id đang có (rails-authorization, rails-comments, rails-style). Cảm ơn!

@tms-minhtang1 tms-minhtang1 left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM 🌟 (commit d28f574)

@tms-minhtang1 tms-minhtang1 left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤖【AI REVIEW】Overview

Cảm ơn bạn 🙏 Toàn bộ thay đổi của PR đã được review tại commit deb28e4. Bạn trả lời ngay trong thread của từng finding nếu đã sửa hoặc không đồng ý.

tms-minhtang1 added a commit to tms-minhtang1/agent-stack that referenced this pull request Oct 27, 2026
- security, services: a constraint-guarded insert runs in a savepoint,
  tries the next slot and raises sold-out when none is left; the lock
  bullet accepts a constraint. The concurrent spec releases its threads
  through a gate, with records created before.
- specs: system specs typed by location, no hand-written type:.
- tailwind: entry file for both install paths; app/assets/builds/ is
  build output.
- rails-doctor checklist: gems count from the Gemfile, never the lock.

@tms-minhtang1 tms-minhtang1 left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM 🌟 (commit ed539d6)

Rails projects got no conventions from agent-stack beyond the imported
global layer. This adds 29 rules under knowledge/rules/framework/rails/
(structure, server layers, cross-cutting concerns, Hotwire, JS packages,
and gem-gated rules for decorators, view components, enumerize, soft
delete, Tailwind and Bootstrap) and four skills: rails-feature,
rails-migration, rails-debug-n-plus-one and rails-doctor, which fills a
project's AGENTS.md from its own code and reports rules that conflict
with it.

Every rule but structure is path-scoped, so it loads only when Claude
touches a matching file and adds nothing to session start.
@tms-minhtang1
tms-minhtang1 force-pushed the feat/rails-conventions branch from ed539d6 to eeb4a7d Compare October 27, 2026 08:13
@tms-minhtang1
tms-minhtang1 marked this pull request as ready for review October 27, 2026 08:14
@tms-anhnguyen1
tms-anhnguyen1 merged commit 8c6e793 into TOMOSIA-VIETNAM:main Oct 28, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants