{
  "id": "rails-app",
  "type": "loadout",
  "title": "Rails app rules",
  "summary": "Rails 8 rules for agents: reversible migrations with real constraints, params.expect, N+1 checks with assert_queries_count, and rubocop and brakeman as the gate.",
  "description": "Agents write Rails code that runs, then leave the database to the model layer: validations with no constraint behind them, migrations that only go up, an each loop that fires a query per row, permit! to make a form work. This loadout gives your agent the Rails 8 conventions from the official guides, with the commands that prove a change is done, and a model-change skill whose migration, models and tests the verifier runs on Active Record 8.1 and SQLite. The N+1 test is checked both ways: it passes with includes and fails without it.\n",
  "highlights": [
    "Every schema change is a reversible migration, checked by rolling back and migrating again",
    "Database constraints behind validations: null false, foreign keys, unique indexes",
    "params.expect, scoped record lookups and no html_safe on user content",
    "assert_queries_count guards against N+1 queries",
    "bin/rails test, bin/rubocop and bin/brakeman as the done-gate"
  ],
  "version": "1.0.0",
  "license": "MIT",
  "author": {
    "name": "Agent Loadout",
    "url": "https://loadout.jnw-it.com"
  },
  "credits": [
    {
      "title": "Rails Guides: Active Record migrations",
      "url": "https://guides.rubyonrails.org/active_record_migrations.html"
    },
    {
      "title": "Rails Guides: testing Rails applications (assert_queries_count)",
      "url": "https://guides.rubyonrails.org/testing.html"
    },
    {
      "title": "Rails Guides: Action Controller overview (params.expect)",
      "url": "https://guides.rubyonrails.org/action_controller_overview.html"
    },
    {
      "title": "Rails Guides: securing Rails applications",
      "url": "https://guides.rubyonrails.org/security.html"
    },
    {
      "title": "rubocop-rails-omakase",
      "url": "https://github.com/rails/rubocop-rails-omakase"
    },
    {
      "title": "strong_migrations by Andrew Kane",
      "url": "https://github.com/ankane/strong_migrations"
    }
  ],
  "categories": [
    "web-app"
  ],
  "stacks": [
    "ruby",
    "rails"
  ],
  "files": [
    {
      "path": "AGENTS.md",
      "role": "instructions",
      "description": "Rails rules for migrations, models, controllers, secrets and gems.",
      "skill": null,
      "agent": null,
      "install_to": {
        "claude-code": "AGENTS.md",
        "codex": "AGENTS.md",
        "cursor": "AGENTS.md",
        "gemini-cli": "AGENTS.md",
        "antigravity-cli": "AGENTS.md",
        "copilot": "AGENTS.md"
      },
      "raw_url": "https://loadout.jnw-it.com/raw/rails-app/1.0.0/AGENTS.md",
      "raw_latest_url": "https://loadout.jnw-it.com/raw/rails-app/latest/AGENTS.md",
      "bytes": 2247,
      "lang": "markdown",
      "content": "# AGENTS.md: Rails app\n\nRuby on Rails app. Check `Gemfile.lock` for the Rails version before using newer APIs; these rules assume Rails 8.\n\n## Commands\n- Tests: `bin/rails test` (and `bin/rails test:system` if system tests exist). Single file:\n  `bin/rails test test/models/order_test.rb`.\n- Lint: `bin/rubocop` (rubocop-rails-omakase in new apps). Security: `bin/brakeman --no-pager`.\n- Migrations: `bin/rails db:migrate`, then confirm `bin/rails db:rollback` and migrate again work.\n- Done means: tests green, rubocop clean, brakeman shows no new warnings, `db/schema.rb` changed only by migrations.\n\n## Models and the database\n- Every schema change is a migration generated with `bin/rails generate migration`. Never edit `db/schema.rb` by hand.\n- Migrations are reversible (`change` with reversible operations, or `up` and `down`). No data backfills in schema\n  migrations on large tables; write a separate task or job.\n- Constraints in the database as well as the model: `null: false`, foreign keys, unique indexes behind\n  `validates ... uniqueness`.\n- If `strong_migrations` is in the Gemfile, follow its advice instead of silencing it.\n- Avoid N+1 queries: `includes` or `preload` for associations used in loops. Prove it with `assert_queries_count`.\n- Money in integer minor units or `decimal`, never `float`.\n- New model or column: use the `rails-model-change` skill.\n\n## Controllers and views\n- Strong parameters with `params.expect(order: [:title, :quantity])` (Rails 8) or `require`/`permit`. Never\n  `permit!`.\n- Keep controllers to the seven REST actions where possible; add a new controller rather than custom actions.\n- Escape output: no `html_safe` or `raw` on user content. Use `sanitize` with an allow-list if HTML is required.\n- Authorise every record lookup through the current user (`current_user.orders.find(params[:id])`).\n\n## Secrets and config\n- Credentials live in `config/credentials.yml.enc`, edited with `bin/rails credentials:edit`. Never commit\n  `config/master.key` or print credentials.\n- Do not run commands against production (`RAILS_ENV=production`, `kamal`, `cap`) unless the user asks.\n\n## Dependencies\n- Ask before adding a gem. Add it with `bundle add <gem> --version \"~> x.y\"` and commit `Gemfile.lock`.\n"
    },
    {
      "path": "CLAUDE.md",
      "role": "adapter",
      "description": "Imports AGENTS.md for Claude Code.",
      "skill": null,
      "agent": "claude-code",
      "install_to": {
        "claude-code": "CLAUDE.md",
        "codex": null,
        "cursor": null,
        "gemini-cli": null,
        "antigravity-cli": null,
        "copilot": null
      },
      "raw_url": "https://loadout.jnw-it.com/raw/rails-app/1.0.0/CLAUDE.md",
      "raw_latest_url": "https://loadout.jnw-it.com/raw/rails-app/latest/CLAUDE.md",
      "bytes": 363,
      "lang": "markdown",
      "content": "# CLAUDE.md\n\n@AGENTS.md\n\n## Claude Code notes\n- Skills from this loadout live in `.claude/skills/`: `rails-model-change`. Use them when their description matches the task.\n- Follow AGENTS.md above; where this file and AGENTS.md disagree, AGENTS.md wins.\n\n<!-- From the Agent Loadout \"Rails app rules\" v1.0.0 — https://loadout.jnw-it.com/loadouts/rails-app/ -->\n"
    },
    {
      "path": "GEMINI.md",
      "role": "adapter",
      "description": "Imports AGENTS.md for Gemini CLI.",
      "skill": null,
      "agent": "gemini-cli",
      "install_to": {
        "claude-code": null,
        "codex": null,
        "cursor": null,
        "gemini-cli": "GEMINI.md",
        "antigravity-cli": null,
        "copilot": null
      },
      "raw_url": "https://loadout.jnw-it.com/raw/rails-app/1.0.0/GEMINI.md",
      "raw_latest_url": "https://loadout.jnw-it.com/raw/rails-app/latest/GEMINI.md",
      "bytes": 364,
      "lang": "markdown",
      "content": "# GEMINI.md\n\n@./AGENTS.md\n\n## Gemini CLI notes\n- Skills from this loadout live in `.agents/skills/`: `rails-model-change`. Use them when their description matches the task.\n- Follow AGENTS.md above; where this file and AGENTS.md disagree, AGENTS.md wins.\n\n<!-- From the Agent Loadout \"Rails app rules\" v1.0.0 — https://loadout.jnw-it.com/loadouts/rails-app/ -->\n"
    },
    {
      "path": "skills/rails-model-change/SKILL.md",
      "role": "skill",
      "description": "Add or change a model with a reversible migration and tests.",
      "skill": "rails-model-change",
      "agent": null,
      "install_to": {
        "claude-code": ".claude/skills/rails-model-change/SKILL.md",
        "codex": ".agents/skills/rails-model-change/SKILL.md",
        "cursor": ".agents/skills/rails-model-change/SKILL.md",
        "gemini-cli": ".agents/skills/rails-model-change/SKILL.md",
        "antigravity-cli": ".agents/skills/rails-model-change/SKILL.md",
        "copilot": ".agents/skills/rails-model-change/SKILL.md"
      },
      "raw_url": "https://loadout.jnw-it.com/raw/rails-app/1.0.0/skills/rails-model-change/SKILL.md",
      "raw_latest_url": "https://loadout.jnw-it.com/raw/rails-app/latest/skills/rails-model-change/SKILL.md",
      "bytes": 1345,
      "lang": "markdown",
      "content": "---\nname: rails-model-change\ndescription: Add or change a Rails model with a reversible migration, database constraints, validations, an N+1-safe query scope and a model test. Use for new tables, new columns and new associations.\n---\n\n# Rails model change\n\nExamples: `references/20261017120000_create_orders.rb`, `references/order.rb`, `references/order_test.rb`.\n\n1. Generate, do not hand-write the file name: `bin/rails generate migration CreateOrders` (or `AddXToY`).\n2. In the migration:\n   - `null: false` on required columns, with a default where it makes sense.\n   - `t.references ... foreign_key: true` for associations.\n   - A unique index for anything validated as unique.\n   - Money as integer pence (`price_pence`) or `decimal` with precision and scale.\n3. Run `bin/rails db:migrate`, then `bin/rails db:rollback` and `bin/rails db:migrate` again. Both directions must work.\n   Commit the `db/schema.rb` change the migration produced.\n4. Model: validations that mirror the constraints, associations with `dependent:` chosen on purpose, and scopes that\n   preload what callers will use.\n5. Test in `test/models/`: one test per validation, one for each scope, and an `assert_queries_count` test for any\n   scope that should avoid N+1 queries.\n6. Run `bin/rails test test/models/<model>_test.rb`, then the full suite and `bin/rubocop`.\n"
    },
    {
      "path": "skills/rails-model-change/references/20261017120000_create_orders.rb",
      "role": "reference",
      "description": "Migration with constraints, foreign key and unique indexes.",
      "skill": "rails-model-change",
      "agent": null,
      "install_to": {
        "claude-code": ".claude/skills/rails-model-change/references/20261017120000_create_orders.rb",
        "codex": ".agents/skills/rails-model-change/references/20261017120000_create_orders.rb",
        "cursor": ".agents/skills/rails-model-change/references/20261017120000_create_orders.rb",
        "gemini-cli": ".agents/skills/rails-model-change/references/20261017120000_create_orders.rb",
        "antigravity-cli": ".agents/skills/rails-model-change/references/20261017120000_create_orders.rb",
        "copilot": ".agents/skills/rails-model-change/references/20261017120000_create_orders.rb"
      },
      "raw_url": "https://loadout.jnw-it.com/raw/rails-app/1.0.0/skills/rails-model-change/references/20261017120000_create_orders.rb",
      "raw_latest_url": "https://loadout.jnw-it.com/raw/rails-app/latest/skills/rails-model-change/references/20261017120000_create_orders.rb",
      "bytes": 535,
      "lang": "markdown",
      "content": "class CreateOrders < ActiveRecord::Migration[8.1]\n  def change\n    create_table :customers do |t|\n      t.string :email, null: false\n      t.timestamps\n    end\n    add_index :customers, :email, unique: true\n\n    create_table :orders do |t|\n      t.references :customer, null: false, foreign_key: true\n      t.string :reference, null: false\n      t.integer :total_pence, null: false, default: 0\n      t.string :status, null: false, default: \"pending\"\n      t.timestamps\n    end\n    add_index :orders, :reference, unique: true\n  end\nend\n"
    },
    {
      "path": "skills/rails-model-change/references/order.rb",
      "role": "reference",
      "description": "Models with validations, normalizes and preloading scopes.",
      "skill": "rails-model-change",
      "agent": null,
      "install_to": {
        "claude-code": ".claude/skills/rails-model-change/references/order.rb",
        "codex": ".agents/skills/rails-model-change/references/order.rb",
        "cursor": ".agents/skills/rails-model-change/references/order.rb",
        "gemini-cli": ".agents/skills/rails-model-change/references/order.rb",
        "antigravity-cli": ".agents/skills/rails-model-change/references/order.rb",
        "copilot": ".agents/skills/rails-model-change/references/order.rb"
      },
      "raw_url": "https://loadout.jnw-it.com/raw/rails-app/1.0.0/skills/rails-model-change/references/order.rb",
      "raw_latest_url": "https://loadout.jnw-it.com/raw/rails-app/latest/skills/rails-model-change/references/order.rb",
      "bytes": 705,
      "lang": "markdown",
      "content": "class Customer < ApplicationRecord\n  has_many :orders, dependent: :restrict_with_error\n\n  normalizes :email, with: ->(email) { email.strip.downcase }\n  validates :email, presence: true, uniqueness: true\nend\n\nclass Order < ApplicationRecord\n  STATUSES = %w[pending paid refunded].freeze\n\n  belongs_to :customer\n\n  validates :reference, presence: true, uniqueness: true, format: { with: /\\AORD-\\d{6}\\z/ }\n  validates :total_pence, numericality: { only_integer: true, greater_than_or_equal_to: 0 }\n  validates :status, inclusion: { in: STATUSES }\n\n  scope :paid, -> { where(status: \"paid\") }\n  scope :with_customer, -> { includes(:customer) }\n\n  def total\n    format(\"£%.2f\", total_pence / 100.0)\n  end\nend\n"
    },
    {
      "path": "skills/rails-model-change/references/order_test.rb",
      "role": "reference",
      "description": "Model tests including an N+1 guard.",
      "skill": "rails-model-change",
      "agent": null,
      "install_to": {
        "claude-code": ".claude/skills/rails-model-change/references/order_test.rb",
        "codex": ".agents/skills/rails-model-change/references/order_test.rb",
        "cursor": ".agents/skills/rails-model-change/references/order_test.rb",
        "gemini-cli": ".agents/skills/rails-model-change/references/order_test.rb",
        "antigravity-cli": ".agents/skills/rails-model-change/references/order_test.rb",
        "copilot": ".agents/skills/rails-model-change/references/order_test.rb"
      },
      "raw_url": "https://loadout.jnw-it.com/raw/rails-app/1.0.0/skills/rails-model-change/references/order_test.rb",
      "raw_latest_url": "https://loadout.jnw-it.com/raw/rails-app/latest/skills/rails-model-change/references/order_test.rb",
      "bytes": 1544,
      "lang": "markdown",
      "content": "require \"test_helper\"\n\nclass OrderTest < ActiveSupport::TestCase\n  setup do\n    @customer = Customer.create!(email: \"  Ada@Example.com \")\n  end\n\n  test \"normalises customer email\" do\n    assert_equal \"ada@example.com\", @customer.email\n  end\n\n  test \"requires a well-formed, unique reference\" do\n    Order.create!(customer: @customer, reference: \"ORD-000001\", total_pence: 1250)\n    duplicate = Order.new(customer: @customer, reference: \"ORD-000001\")\n    assert_not duplicate.valid?\n    assert_includes duplicate.errors[:reference], \"has already been taken\"\n    assert_not Order.new(customer: @customer, reference: \"123\").valid?\n  end\n\n  test \"rejects negative totals and unknown statuses\" do\n    order = Order.new(customer: @customer, reference: \"ORD-000002\", total_pence: -1, status: \"lost\")\n    assert_not order.valid?\n    assert order.errors.key?(:total_pence)\n    assert order.errors.key?(:status)\n  end\n\n  test \"formats the total in pounds\" do\n    assert_equal \"£12.50\", Order.new(total_pence: 1250).total\n  end\n\n  test \"paid scope filters by status\" do\n    paid = Order.create!(customer: @customer, reference: \"ORD-000003\", status: \"paid\")\n    Order.create!(customer: @customer, reference: \"ORD-000004\")\n    assert_equal [ paid ], Order.paid.to_a\n  end\n\n  test \"with_customer avoids N+1 queries\" do\n    3.times { |i| Order.create!(customer: Customer.create!(email: \"c#{i}@example.com\"), reference: format(\"ORD-1%05d\", i)) }\n    assert_queries_count(2) do\n      Order.with_customer.each { |order| order.customer.email }\n    end\n  end\nend\n"
    }
  ],
  "requires": {
    "tools": [
      "ruby",
      "bundler"
    ],
    "env": [],
    "mcp": []
  },
  "tested": {
    "status": "untested",
    "last_run": null,
    "fixture": null,
    "per_agent": {
      "claude-code": "untested",
      "codex": "untested",
      "cursor": "untested",
      "gemini-cli": "untested",
      "antigravity-cli": "untested",
      "copilot": "untested"
    }
  },
  "security": {
    "scanned": true,
    "scanner": "intake-precheck/1",
    "verdict": "clean",
    "network": true,
    "scripts": [],
    "notes": "bundle add and bundle install download gems from rubygems.org. The rules forbid committing config/master.key and running commands against production unless asked."
  },
  "featured": false,
  "deprecated": false,
  "last_checked": "2026-10-17",
  "published": "2026-10-17",
  "updated": "2026-10-17",
  "compatibility": {
    "claude-code": "native",
    "codex": "native",
    "cursor": "native",
    "gemini-cli": "native",
    "antigravity-cli": "native",
    "copilot": "native"
  },
  "counts": {
    "rules": 1,
    "skills": 1,
    "mcp": 0
  },
  "url": "https://loadout.jnw-it.com/loadouts/rails-app/",
  "api_url": "https://loadout.jnw-it.com/api/loadouts/rails-app.json",
  "verification": {
    "level": "verified-install",
    "status": "verified",
    "label": "Verified install",
    "verified": true,
    "checked_at": "2026-10-17T09:35:26Z",
    "commit": "021470d33f1f82ab91e12f0c64c43ad15bac6118",
    "content_current": true,
    "agent_tests": "not-run",
    "counts": {
      "pass": 9,
      "fail": 0,
      "skip": 0,
      "not_applicable": 1
    },
    "meaning": "Level 1: automated checks on the files (parse, install paths, MCP config, safety scan, references, size, licence, starter build). No AI agent was run.",
    "checks": [
      {
        "id": "listing",
        "name": "Listing",
        "status": "pass",
        "summary": "Schema valid; 7 files declared, none missing or extra",
        "details": [
          "tested.status: untested (agent tests are separate from Level 1)"
        ]
      },
      {
        "id": "parse",
        "name": "Files parse",
        "status": "pass",
        "summary": "All 7 files parse; front matter valid",
        "details": []
      },
      {
        "id": "adapters",
        "name": "Adapters",
        "status": "pass",
        "summary": "CLAUDE.md and GEMINI.md import AGENTS.md and are up to date",
        "details": [
          "CLAUDE.md: matches the generator",
          "GEMINI.md: matches the generator"
        ]
      },
      {
        "id": "install-paths",
        "name": "Install paths",
        "status": "pass",
        "summary": "Correct paths for all 6 agents; layouts re-discovered",
        "details": [
          "Claude Code: 6 files, 1 skill in .claude/skills/",
          "Codex CLI: 5 files, 1 skill in .agents/skills/",
          "Cursor: 5 files, 1 skill in .agents/skills/",
          "Gemini CLI: 6 files, 1 skill in .agents/skills/",
          "Antigravity CLI: 5 files, 1 skill in .agents/skills/",
          "GitHub Copilot: 5 files, 1 skill in .agents/skills/"
        ]
      },
      {
        "id": "mcp",
        "name": "MCP config",
        "status": "n/a",
        "summary": "No MCP servers in this loadout",
        "details": []
      },
      {
        "id": "safety",
        "name": "Safety scan",
        "status": "pass",
        "summary": "Clean: no credentials, risky shell or hidden text",
        "details": [
          "Scanner intake-precheck/1: verdict clean; network no (listing says yes)"
        ]
      },
      {
        "id": "references",
        "name": "References",
        "status": "pass",
        "summary": "1 reference between files resolves for every agent",
        "details": []
      },
      {
        "id": "size",
        "name": "Size limits",
        "status": "pass",
        "summary": "7 files, 6.9 KB total; largest AGENTS.md 2.2 KB",
        "details": [
          "Limits: 30 files, 32 KB per file, 128 KB total, 500 lines per skill or rule"
        ]
      },
      {
        "id": "licence",
        "name": "Licence",
        "status": "pass",
        "summary": "MIT, by Agent Loadout; text in the repository LICENSE",
        "details": []
      },
      {
        "id": "starter-build",
        "name": "Starter build",
        "status": "pass",
        "summary": "The rails-model-change skill's migration, models and test run on Active Record 8.1 with SQLite: the migration reverses cleanly, all six model tests pass (including an assert_queries_count N+1 guard), rubocop-rails-omakase is clean, and dropping the includes fails the N+1 test",
        "details": [
          "Applied 11 loadout files at every agent's paths",
          "✓ place the examples: bash -c mkdir -p db/migrate app/models test/models && R=.agents/skills/rails-model-change/references && cp $R/20261017120000_create_orders.rb db/migrate/ && cp $R/order.rb app/models/ && cp $R/order_test.rb test/models/ && echo placed",
          "✓ bundle install (pinned gems): bash -c export BUNDLE_PATH=\"${BUNDLE_PATH:-$HOME/.cache/agent-loadout-verify/bundle}\"; bundle install --quiet && echo bundled",
          "✓ migration is reversible: bash -c export BUNDLE_PATH=\"${BUNDLE_PATH:-$HOME/.cache/agent-loadout-verify/bundle}\"; bundle exec ruby reversible.rb",
          "✓ model tests: bash -c export BUNDLE_PATH=\"${BUNDLE_PATH:-$HOME/.cache/agent-loadout-verify/bundle}\"; bundle exec ruby -I. test/models/order_test.rb",
          "✓ rubocop-rails-omakase: bash -c export BUNDLE_PATH=\"${BUNDLE_PATH:-$HOME/.cache/agent-loadout-verify/bundle}\"; bundle exec rubocop db app test",
          "✓ N+1 guard catches a missing includes: bash -c export BUNDLE_PATH=\"${BUNDLE_PATH:-$HOME/.cache/agent-loadout-verify/bundle}\"; sed -i 's/includes(:customer)/all/' app/models/order.rb && bundle exec ruby -I. test/models/order_test.rb -n /avoids_N/; test $? -ne 0 && echo caught",
          "Covers: Reversible migration with null: false, a foreign key and unique indexes",
          "Covers: Validations mirroring the constraints; normalizes on email",
          "Covers: assert_queries_count proves includes avoids N+1, and fails without it",
          "Covers: rubocop-rails-omakase clean, as in a new Rails 8 app"
        ]
      }
    ]
  },
  "install": {
    "claude-code": {
      "files": [
        {
          "path": "AGENTS.md",
          "target": "AGENTS.md",
          "raw_url": "https://loadout.jnw-it.com/raw/rails-app/1.0.0/AGENTS.md",
          "role": "instructions"
        },
        {
          "path": "CLAUDE.md",
          "target": "CLAUDE.md",
          "raw_url": "https://loadout.jnw-it.com/raw/rails-app/1.0.0/CLAUDE.md",
          "role": "adapter"
        },
        {
          "path": "skills/rails-model-change/SKILL.md",
          "target": ".claude/skills/rails-model-change/SKILL.md",
          "raw_url": "https://loadout.jnw-it.com/raw/rails-app/1.0.0/skills/rails-model-change/SKILL.md",
          "role": "skill"
        },
        {
          "path": "skills/rails-model-change/references/20261017120000_create_orders.rb",
          "target": ".claude/skills/rails-model-change/references/20261017120000_create_orders.rb",
          "raw_url": "https://loadout.jnw-it.com/raw/rails-app/1.0.0/skills/rails-model-change/references/20261017120000_create_orders.rb",
          "role": "reference"
        },
        {
          "path": "skills/rails-model-change/references/order.rb",
          "target": ".claude/skills/rails-model-change/references/order.rb",
          "raw_url": "https://loadout.jnw-it.com/raw/rails-app/1.0.0/skills/rails-model-change/references/order.rb",
          "role": "reference"
        },
        {
          "path": "skills/rails-model-change/references/order_test.rb",
          "target": ".claude/skills/rails-model-change/references/order_test.rb",
          "raw_url": "https://loadout.jnw-it.com/raw/rails-app/1.0.0/skills/rails-model-change/references/order_test.rb",
          "role": "reference"
        }
      ],
      "manual_steps": [],
      "zip_url": "https://loadout.jnw-it.com/download/rails-app/claude-code.zip"
    },
    "codex": {
      "files": [
        {
          "path": "AGENTS.md",
          "target": "AGENTS.md",
          "raw_url": "https://loadout.jnw-it.com/raw/rails-app/1.0.0/AGENTS.md",
          "role": "instructions"
        },
        {
          "path": "skills/rails-model-change/SKILL.md",
          "target": ".agents/skills/rails-model-change/SKILL.md",
          "raw_url": "https://loadout.jnw-it.com/raw/rails-app/1.0.0/skills/rails-model-change/SKILL.md",
          "role": "skill"
        },
        {
          "path": "skills/rails-model-change/references/20261017120000_create_orders.rb",
          "target": ".agents/skills/rails-model-change/references/20261017120000_create_orders.rb",
          "raw_url": "https://loadout.jnw-it.com/raw/rails-app/1.0.0/skills/rails-model-change/references/20261017120000_create_orders.rb",
          "role": "reference"
        },
        {
          "path": "skills/rails-model-change/references/order.rb",
          "target": ".agents/skills/rails-model-change/references/order.rb",
          "raw_url": "https://loadout.jnw-it.com/raw/rails-app/1.0.0/skills/rails-model-change/references/order.rb",
          "role": "reference"
        },
        {
          "path": "skills/rails-model-change/references/order_test.rb",
          "target": ".agents/skills/rails-model-change/references/order_test.rb",
          "raw_url": "https://loadout.jnw-it.com/raw/rails-app/1.0.0/skills/rails-model-change/references/order_test.rb",
          "role": "reference"
        }
      ],
      "manual_steps": [],
      "zip_url": "https://loadout.jnw-it.com/download/rails-app/codex.zip"
    },
    "cursor": {
      "files": [
        {
          "path": "AGENTS.md",
          "target": "AGENTS.md",
          "raw_url": "https://loadout.jnw-it.com/raw/rails-app/1.0.0/AGENTS.md",
          "role": "instructions"
        },
        {
          "path": "skills/rails-model-change/SKILL.md",
          "target": ".agents/skills/rails-model-change/SKILL.md",
          "raw_url": "https://loadout.jnw-it.com/raw/rails-app/1.0.0/skills/rails-model-change/SKILL.md",
          "role": "skill"
        },
        {
          "path": "skills/rails-model-change/references/20261017120000_create_orders.rb",
          "target": ".agents/skills/rails-model-change/references/20261017120000_create_orders.rb",
          "raw_url": "https://loadout.jnw-it.com/raw/rails-app/1.0.0/skills/rails-model-change/references/20261017120000_create_orders.rb",
          "role": "reference"
        },
        {
          "path": "skills/rails-model-change/references/order.rb",
          "target": ".agents/skills/rails-model-change/references/order.rb",
          "raw_url": "https://loadout.jnw-it.com/raw/rails-app/1.0.0/skills/rails-model-change/references/order.rb",
          "role": "reference"
        },
        {
          "path": "skills/rails-model-change/references/order_test.rb",
          "target": ".agents/skills/rails-model-change/references/order_test.rb",
          "raw_url": "https://loadout.jnw-it.com/raw/rails-app/1.0.0/skills/rails-model-change/references/order_test.rb",
          "role": "reference"
        }
      ],
      "manual_steps": [],
      "zip_url": "https://loadout.jnw-it.com/download/rails-app/cursor.zip"
    },
    "gemini-cli": {
      "files": [
        {
          "path": "AGENTS.md",
          "target": "AGENTS.md",
          "raw_url": "https://loadout.jnw-it.com/raw/rails-app/1.0.0/AGENTS.md",
          "role": "instructions"
        },
        {
          "path": "GEMINI.md",
          "target": "GEMINI.md",
          "raw_url": "https://loadout.jnw-it.com/raw/rails-app/1.0.0/GEMINI.md",
          "role": "adapter"
        },
        {
          "path": "skills/rails-model-change/SKILL.md",
          "target": ".agents/skills/rails-model-change/SKILL.md",
          "raw_url": "https://loadout.jnw-it.com/raw/rails-app/1.0.0/skills/rails-model-change/SKILL.md",
          "role": "skill"
        },
        {
          "path": "skills/rails-model-change/references/20261017120000_create_orders.rb",
          "target": ".agents/skills/rails-model-change/references/20261017120000_create_orders.rb",
          "raw_url": "https://loadout.jnw-it.com/raw/rails-app/1.0.0/skills/rails-model-change/references/20261017120000_create_orders.rb",
          "role": "reference"
        },
        {
          "path": "skills/rails-model-change/references/order.rb",
          "target": ".agents/skills/rails-model-change/references/order.rb",
          "raw_url": "https://loadout.jnw-it.com/raw/rails-app/1.0.0/skills/rails-model-change/references/order.rb",
          "role": "reference"
        },
        {
          "path": "skills/rails-model-change/references/order_test.rb",
          "target": ".agents/skills/rails-model-change/references/order_test.rb",
          "raw_url": "https://loadout.jnw-it.com/raw/rails-app/1.0.0/skills/rails-model-change/references/order_test.rb",
          "role": "reference"
        }
      ],
      "manual_steps": [],
      "zip_url": "https://loadout.jnw-it.com/download/rails-app/gemini-cli.zip"
    },
    "antigravity-cli": {
      "files": [
        {
          "path": "AGENTS.md",
          "target": "AGENTS.md",
          "raw_url": "https://loadout.jnw-it.com/raw/rails-app/1.0.0/AGENTS.md",
          "role": "instructions"
        },
        {
          "path": "skills/rails-model-change/SKILL.md",
          "target": ".agents/skills/rails-model-change/SKILL.md",
          "raw_url": "https://loadout.jnw-it.com/raw/rails-app/1.0.0/skills/rails-model-change/SKILL.md",
          "role": "skill"
        },
        {
          "path": "skills/rails-model-change/references/20261017120000_create_orders.rb",
          "target": ".agents/skills/rails-model-change/references/20261017120000_create_orders.rb",
          "raw_url": "https://loadout.jnw-it.com/raw/rails-app/1.0.0/skills/rails-model-change/references/20261017120000_create_orders.rb",
          "role": "reference"
        },
        {
          "path": "skills/rails-model-change/references/order.rb",
          "target": ".agents/skills/rails-model-change/references/order.rb",
          "raw_url": "https://loadout.jnw-it.com/raw/rails-app/1.0.0/skills/rails-model-change/references/order.rb",
          "role": "reference"
        },
        {
          "path": "skills/rails-model-change/references/order_test.rb",
          "target": ".agents/skills/rails-model-change/references/order_test.rb",
          "raw_url": "https://loadout.jnw-it.com/raw/rails-app/1.0.0/skills/rails-model-change/references/order_test.rb",
          "role": "reference"
        }
      ],
      "manual_steps": [],
      "zip_url": "https://loadout.jnw-it.com/download/rails-app/antigravity-cli.zip"
    },
    "copilot": {
      "files": [
        {
          "path": "AGENTS.md",
          "target": "AGENTS.md",
          "raw_url": "https://loadout.jnw-it.com/raw/rails-app/1.0.0/AGENTS.md",
          "role": "instructions"
        },
        {
          "path": "skills/rails-model-change/SKILL.md",
          "target": ".agents/skills/rails-model-change/SKILL.md",
          "raw_url": "https://loadout.jnw-it.com/raw/rails-app/1.0.0/skills/rails-model-change/SKILL.md",
          "role": "skill"
        },
        {
          "path": "skills/rails-model-change/references/20261017120000_create_orders.rb",
          "target": ".agents/skills/rails-model-change/references/20261017120000_create_orders.rb",
          "raw_url": "https://loadout.jnw-it.com/raw/rails-app/1.0.0/skills/rails-model-change/references/20261017120000_create_orders.rb",
          "role": "reference"
        },
        {
          "path": "skills/rails-model-change/references/order.rb",
          "target": ".agents/skills/rails-model-change/references/order.rb",
          "raw_url": "https://loadout.jnw-it.com/raw/rails-app/1.0.0/skills/rails-model-change/references/order.rb",
          "role": "reference"
        },
        {
          "path": "skills/rails-model-change/references/order_test.rb",
          "target": ".agents/skills/rails-model-change/references/order_test.rb",
          "raw_url": "https://loadout.jnw-it.com/raw/rails-app/1.0.0/skills/rails-model-change/references/order_test.rb",
          "role": "reference"
        }
      ],
      "manual_steps": [],
      "zip_url": "https://loadout.jnw-it.com/download/rails-app/copilot.zip"
    }
  },
  "source_zip_url": "https://loadout.jnw-it.com/download/rails-app/source.zip"
}