From 58dfcdc14e88a37290b106077c447477247cb17d Mon Sep 17 00:00:00 2001 From: Hampton Lintorn-Catlin Date: Fri, 27 Feb 2026 14:14:50 -0600 Subject: [PATCH] Document engine vs host app architecture in AGENTS.md - Add Architecture section explaining that core logic lives in the engine - Detail what belongs in engine/ vs the top-level host app - Add MySQL JSON column default warning to prevent migration errors Amp-Thread-ID: https://ampcode.com/threads/T-019c9ba5-621e-7769-81b4-99b46ff27501 Co-authored-by: Amp --- AGENTS.md | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/AGENTS.md b/AGENTS.md index 46cdc559..c81978f8 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -4,13 +4,36 @@ A Rails app for engineering design doc review, purpose-built for AI-assisted planning. Plans get better through collaboration — domain experts leave inline feedback, AI agents respond to that feedback and apply edits automatically, and every change is versioned with full provenance. Humans comment, AI agents edit. Local agents interact via the REST API using skills (see `coplan` skill) and future CLIs. +## Architecture: Engine vs Host App + +Most of the application logic lives in the **CoPlan Rails engine** (`engine/`), packaged as the `coplan` gem (path-based, in `Gemfile`). The top-level Rails app is a **thin host** that provides deployment configuration, ActiveAdmin, and app-specific glue. + +### Engine (`engine/`) — where the code lives +- **Models** — all domain models live in `engine/app/models/coplan/` (Plan, PlanVersion, User, Comment, CommentThread, EditLease, EditSession, ApiToken, AutomatedPlanReviewer, PlanCollaborator) +- **Controllers** — web UI and API controllers in `engine/app/controllers/coplan/`, including `api/v1/` for the REST API +- **Services** — all service objects in `engine/app/services/coplan/` (Plans::Create, Plans::ApplyOperations, AI providers, etc.) +- **Policies** — authorization policies in `engine/app/policies/coplan/` +- **Jobs** — background jobs in `engine/app/jobs/coplan/` +- **Views, helpers, assets, JS** — all Hotwire views and Stimulus controllers +- **Migrations** — engine-owned tables go in `engine/db/migrate/` +- **Routes** — engine routes in `engine/config/routes.rb`, mounted by the host + +### Host app (top-level) — thin deployment shell +- **ActiveAdmin** — admin registrations in `app/admin/` +- **Auth** — `SessionsController`, `User` model (legacy, being migrated to `CoPlan::User`) +- **App-specific integrations** — `SlackClient`, `SlackNotificationJob` +- **Migrations** — only for data migrations, FK rewiring, or host-specific tables in `db/migrate/` (the engine owns schema for `coplan_*` tables) +- **Config** — database, deployment, environment, seeds + +**When adding new features, put them in the engine** unless they are deployment- or host-specific (admin UI, external integrations, auth). + ## Tech Stack & Philosophy - **Rails** with importmaps — no Node, no bundler, no Webpack, no esbuild - **Hotwire** — Turbo Drive, Turbo Frames, Turbo Streams, Stimulus - **Plain CSS** — no Tailwind, no preprocessors - **Plain JavaScript** — via importmaps and Stimulus controllers only -- **MySQL 8** — but schema must stay portable (no PG-only or MySQL-only features) +- **MySQL 8** — but schema must stay portable (no PG-only or MySQL-only features); **no `default:` on JSON columns** (use `after_initialize` in the model instead) - **SolidQueue** for background jobs, **SolidCable** for ActionCable - **ActiveAdmin 4 beta** + `activeadmin_assets` for admin UI — no node/tailwind needed - **No Devise, no OmniAuth** — auth is hand-rolled (stub OIDC in dev, real OIDC later)