{
  "schema_version": "1.2.0",
  "canonical": "https://approximated.app/guides/examples/rails--v8.1.json",
  "example": {
    "id": "rails--v8.1",
    "framework": "Ruby on Rails",
    "edition": "v8.1",
    "edition_status": "current",
    "guide": "https://approximated.app/guides/ruby-on-rails-custom-domains-guide/",
    "version_url": "https://approximated.app/guides/ruby-on-rails-custom-domains-guide/v8.1/",
    "source_file": "src/guides/ruby-on-rails-custom-domains-guide/index.html",
    "edition_source": "src/_partials/guide-editions/rails/v8.1.html",
    "upstream_repository": "https://github.com/Approximated-Inc/rails-custom-domains-example",
    "upstream_exists": true,
    "published": null,
    "prepared_at": "2026-09-09",
    "publication_status": "local_draft",
    "last_reviewed": "2026-09-09",
    "review_scope": "26 tests and 105 assertions passed on Ruby 4.0.6/Rails 8.1.3.1. The suite covers two-tenant routing, session-derived authorization, Rails CSRF rejection, normalization and global uniqueness, control-host parsing, nullable provider status, apx_hit plus TLS routing readiness, unconfirmed-identity fail-closed behavior, provider-ID refresh/removal, mismatched refresh disablement, stale refresh and delayed-404 races, and the actual Faraday transport through a loopback HTTP stub. Zeitwerk eager loading and production asset precompilation passed. Brakeman reported zero warnings. Local smoke returned 200 for each seeded tenant, 404 for an unknown host, and 302 for the protected control host. September 9 provider-mode follow-up: 33 tests and 146 assertions passed in the pinned Ruby/Rails container. Zeitwerk, scoped RuboCop, and production assets passed. Forced-mock Puma smoke returned tenant 200/200, unknown 404, and protected control 302.",
    "runtime_test_status": "passed_local",
    "upstream_revision": "7e5444cf0f916efd337ef7111f26e94c347b8a05",
    "tested_versions": {
      "ruby": "4.0.6",
      "ruby_container": "ruby:4.0@sha256:8dc3950712ad2078bdd275b890419ba2fd3aab5a0653b291a7325f0d8a24ca05",
      "ruby_build_base": "ruby:4.0.6-slim@sha256:58479f164d5947f852da27a4436c89bb986a811f959c40552bc7f6ccaabcc9c9",
      "rails": "8.1.3.1",
      "bundler": "4.0.16",
      "sqlite3_gem": "2.9.6",
      "puma": "8.0.2",
      "faraday": "2.14.3",
      "public_suffix": "7.0.5",
      "simpleidn": "0.3.0",
      "json": "2.21.2"
    },
    "test_commands": [
      "docker run --rm --network none --user \"$(id -u):$(id -g)\" -e BUNDLE_PATH=/workspace/vendor/bundle -e RAILS_ENV=test -e APPROXIMATED_API_KEY=test-key -e APP_ORIGIN_HOST=origin.test -e CONTROL_HOST=control.test -e DEMO_LOGIN_PASSWORD=demo-only -v \"$PWD:/workspace\" -w /workspace ruby:4.0 bundle exec bin/rails test",
      "docker run --rm --network none --user \"$(id -u):$(id -g)\" -e BUNDLE_PATH=/workspace/vendor/bundle -e APPROXIMATED_API_KEY=placeholder -e APP_ORIGIN_HOST=origin.test -e CONTROL_HOST=control.test -v \"$PWD:/workspace\" -w /workspace ruby:4.0 bundle exec bin/rails zeitwerk:check",
      "docker run --rm --network none --user \"$(id -u):$(id -g)\" -e BUNDLE_PATH=/workspace/vendor/bundle -e RAILS_ENV=production -e SECRET_KEY_BASE_DUMMY=1 -e APPROXIMATED_API_KEY=placeholder -e APP_ORIGIN_HOST=origin.test -e CONTROL_HOST=control.test -v \"$PWD:/workspace\" -w /workspace ruby:4.0 bundle exec bin/rails assets:precompile",
      "docker run --rm --network none --user \"$(id -u):$(id -g)\" -e BUNDLE_PATH=/workspace/vendor/bundle -v \"$PWD:/workspace\" -w /workspace ruby:4.0 bundle exec brakeman --no-pager",
      "PORT=3086 scripts/smoke.sh",
      "docker compose config",
      "docker build -t rails-custom-domains-example:local ."
    ],
    "api_contract_revision": "99f0de6b74f4a88a7c5674d86c852036f22dcd13",
    "api_paths": [
      "/api/vhosts",
      "/api/vhosts/{id}"
    ],
    "not_tested": [
      "No live Approximated API credentials or service requests were used.",
      "No public DNS records, certificate issuance, HTTPS endpoint, or asynchronous live deletion convergence was exercised.",
      "No deployment, production database, external reverse proxy, or multi-process write load was exercised; Compose configuration was checked locally.",
      "The development fixture login is not production authentication.",
      "The provider-independent walkthrough snippets are illustrative; companion runtime results do not verify every guide snippet."
    ],
    "direct_resource": "https://approximated.app/guides/examples/rails--v8.1.json",
    "snippet_count": 13,
    "snippets": [
      {
        "id": "rails--v8.1--snippet-1-ruby",
        "language": "ruby",
        "sha256": "e156b8ce0892f72135ce9eb53bae2a48aa676eb5794be17eee6ece17d3a68cd5"
      },
      {
        "id": "rails--v8.1--snippet-2-html",
        "language": "html",
        "sha256": "8947df844fdec9436788abc9b9e5db888ad76094015ae4746ee8ee13fd6ed84e"
      },
      {
        "id": "rails--v8.1--snippet-3-ruby",
        "language": "ruby",
        "sha256": "057c90a88019ae3af8d0b04df192d9e57784b0a00910daa5cc492ca3ab7e7176"
      },
      {
        "id": "rails--v8.1--snippet-4-bash",
        "language": "bash",
        "sha256": "17ccd7da0bc481cfd51f76f7c25d59befe4cef4ee34d8b19d1ef24e245de163f"
      },
      {
        "id": "rails--v8.1--snippet-5-bash",
        "language": "bash",
        "sha256": "104ad1312aa2e98ddfaa01bf11436e97736cdb08802c16ca2b0f2f583e3566b7"
      },
      {
        "id": "rails--v8.1--snippet-6-ruby",
        "language": "ruby",
        "sha256": "168cf891c34c21e136198aba38014610bb13eeda8b5f694461cdb2edc64365b7"
      },
      {
        "id": "rails--v8.1--snippet-7-bash",
        "language": "bash",
        "sha256": "b575ebf89c5d2e0ab93e02f10d21bb60d5d0f098ac4ec73b25d5fea91e568939"
      },
      {
        "id": "rails--v8.1--snippet-8-ruby",
        "language": "ruby",
        "sha256": "2e14c6397f7bf2195b24d2627e1835c7b5831ae01b9d37d0f4d591b620d3148f"
      },
      {
        "id": "rails--v8.1--snippet-9-ruby",
        "language": "ruby",
        "sha256": "3940bef11564084e931077635f07a7fe0fde988cea379c6d6b9d63f8072b1c50"
      },
      {
        "id": "rails--v8.1--snippet-10-ruby",
        "language": "ruby",
        "sha256": "515a283a8e62d70cf933c939c4e08bc7c0655c9002c5c9022b5441547d03c74a"
      },
      {
        "id": "rails--v8.1--snippet-11-ruby",
        "language": "ruby",
        "sha256": "0283cb73465ef7e93c16a5dadc64fc71a0c0b6a01a11f5129f1e659cc5ff0d9a"
      },
      {
        "id": "rails--v8.1--snippet-12-ruby",
        "language": "ruby",
        "sha256": "f3e2c71415934e574a03a7034e4a32d41166c215e01af1892a607e715489a4c7"
      },
      {
        "id": "rails--v8.1--snippet-13-bash",
        "language": "bash",
        "sha256": "28b2b3d4a1f374add097c818ce5aade3f6fd0b860e1eb614e86a9c572fb5db23"
      }
    ],
    "sources": [
      {
        "url": "https://www.rubyonrails.org/releases",
        "title": "Official Rails releases"
      },
      {
        "url": "https://rubyonrails.org/2026/3/24/Rails-Versions-8-0-5-and-8-1-3-have-been-released",
        "title": "Rails 8.1.3 release announcement"
      },
      {
        "url": "https://rubygems.org/gems/rails/versions/8.1.3.1",
        "title": "Rails 8.1.3.1 on RubyGems"
      },
      {
        "url": "https://www.ruby-lang.org/en/news/2026/07/14/ruby-4-0-6-released/",
        "title": "Ruby 4.0.6 release announcement"
      },
      {
        "url": "https://guides.rubyonrails.org/security.html#cross-site-request-forgery-csrf",
        "title": "Rails CSRF guidance"
      },
      {
        "url": "https://approximated.app/openapi.yaml",
        "title": "Approximated public OpenAPI contract"
      },
      {
        "url": "https://docs.aws.amazon.com/Route53/latest/DeveloperGuide/ResourceRecordTypes.html",
        "title": "A, AAAA, and CNAME records and apex restrictions"
      },
      {
        "url": "https://developers.cloudflare.com/dns/cname-flattening/",
        "title": "Provider-specific CNAME flattening at the apex"
      },
      {
        "url": "https://approximated.app/docs/#how-approximated-works",
        "title": "Approximated routing, certificates, and dedicated IPv4"
      },
      {
        "url": "https://approximated.app/docs/#edge-verify",
        "title": "Form bot protection with Edge Verify"
      },
      {
        "url": "https://approximated.app/docs/#edge-sequences",
        "title": "Request rules and rate limiting with Edge Sequences"
      },
      {
        "url": "https://approximated.app/docs/#dns-widget",
        "title": "DNS onboarding widget and provider-specific support"
      },
      {
        "url": "https://approximated.app/docs/#webhook-events-virtual-host-monitor-updated",
        "title": "Domain monitoring status webhooks"
      }
    ],
    "walkthrough": {
      "provider_independent": true,
      "optional_integration_anchor": "bonus-approximated",
      "code_scope": "Main walkthrough snippets illustrate adding custom domains to an existing app. They are not a complete standalone application or a copy of the companion implementation.",
      "runtime_verification_scope": "Recorded runtime versions, commands, and results apply to the companion repository implementation. They do not imply that every illustrative guide snippet was executed.",
      "domain_connection_policy": {
        "txt_challenge_required": false,
        "dns_check_in_main": "A brief recommendation to check that DNS points directly or indirectly to the app or its receiving service.",
        "automated_dns_checks": "Explained in the optional Approximated bonus, alongside HTTPS readiness."
      }
    },
    "companion_provider_mode": {
      "default": "auto",
      "api_key_environment_variable": "APPROXIMATED_API_KEY",
      "without_key": "local mock",
      "with_key": "real Approximated API at https://cloud.approximated.app",
      "explicit_mock_override": "APPROXIMATED_MODE=mock",
      "verification": {
        "date": "2026-09-09",
        "summary": "33 tests and 146 assertions passed in the pinned Ruby/Rails container. Zeitwerk, scoped RuboCop, and production assets passed. Forced-mock Puma smoke returned tenant 200/200, unknown 404, and protected control 302.",
        "live_api_used": false
      }
    },
    "publication_evidence": {
      "type": "public_companion_git_tag",
      "published_at": "2026-09-09",
      "repository": "https://github.com/Approximated-Inc/rails-custom-domains-example",
      "revision": "7e5444cf0f916efd337ef7111f26e94c347b8a05",
      "tag": "guide-rails8.1-r1",
      "tag_url": "https://github.com/Approximated-Inc/rails-custom-domains-example/tree/guide-rails8.1-r1",
      "anonymous_clone_verified_at": "2026-09-09",
      "scope": "Companion source publication and anonymous HTTPS clone verified. This does not establish guide deployment or live API, DNS, or HTTPS acceptance.",
      "previous_edition_tag": "guide-legacy-2026-09"
    }
  }
}
