Supporting reference · Working design and evidence, not a promise of complete support.

On this page

Rails Core composition

Status: Implemented for the pinned Rails Core and the bounded Capabilities and Domain the Compiler emits.

Every generated Rails application starts from one pinned Foundation Rails Core archive. The Compiler loads that archive as values, adds renderer output for the selected Capabilities and Domain, and checks path ownership before anything is written. Core paths are immutable unless an explicit registry transfers one path to one named renderer. A dependency plan projects one complete Gemfile and Gemfile.lock from a qualified universe without network access. The Compiler also writes the application's README, AGENTS, and UI documents, substitutes the application identity into Core's configuration, and verifies that no reusable-Core identity token remains. The Rails target profile states the Core, Capabilities, and Domain concept, and the Compiler owner owns rendering and packaging.

On this page

Core pin

The prototype bundles the current Rails Core pin (repository-only) as a deterministic compressed Git archive. The only released tag, v0.1.0, predates material fixes, so this is recorded as an exact revision rather than a release. In pre-alpha mode, a Core repin may repair the current target profile's constant, route, and inflection census in place only after complete local re-extraction and review of the active-pin surfaces. The machine reference (repository-only) names that profile. Cross-platform hosted reproduction on both profile platforms is the landing gate. The dangerous-attribute registry was re-extracted from Core 9181b05043977f95fb1ead1012a2b1478363eb67 for the September 16 naming correction and reproduced locally and in hosted CI. No retained-Project migration or coexistence machinery is added; a profile repair starts a new Project or an explicit fork. A later package update should move the same loading boundary to a verified Core release asset.

Moving the pin is an explicit maintenance operation. It verifies the archive digest, embedded revision, root, regular-file count, uncompressed bytes, and lockfile digest; regenerates the maximal dependency universe when Core inputs change; refreshes exact output characterizations; and reruns current-pin profile compatibility and generated-app qualification. Review changed Core commands, dependencies, and UI APIs against the complete application README, AGENTS, and UI templates so their operating guidance stays accurate. Reconcile relevant facts; those templates need not copy Core's contributor prose. A repin removes the superseded archive and dependency pairs unless code, tests, or a frozen profile name them; Git history keeps their bytes. User compilations remain network-free. The loader verifies the compressed-byte SHA-256 and Git revision in the global PAX header before it exposes file values. It accepts regular files and directories, rejects links and special entries, strips one required root, reduces Git's executable bit to 0644 or 0755, and passes the complete file set through OutputManifest.

The profile workflow automatically compares every changed active archive with the frozen compatible surfaces on arm64 Darwin and x86-64 Linux through script/verify_rails_target_profile_compatibility. The default Actions token cannot read the private sibling Core repository, so script/release check reads Core main through gh on the release operator's machine instead. When the pin lags, it warns and lists the missing commits. Merging a Core pull request approves adopting it in the next Compiler release unless the pull request is labeled for separate approval; see owner sign-off (repository-only).

Dev Container

The generated Dev Container selects PostgreSQL client 18 to match its PostgreSQL 18 service. It omits the unused Active Storage media feature; applications adding image variants or previews choose and install their processor. The Dev Container adoption (repository-only) records the exact package and qualification boundary. That adoption changed the Compiler release while retaining its Plan, API, Analyzer, and target profile.

Path ownership

All Core paths are immutable by default. CorePathRegistry contains only explicit path-to-renderer ownership transfers. A registered replacement is required from that exact renderer owner; an absent replacement, a different claimant, or any undeclared collision fails. The default registry transfers nine paths. Five concrete renderers own config/application.rb, config/database.yml, config/locales/en.yml, render.yaml, and README.md; application-document renderers own AGENTS.md and UI.md; the schema renderer owns db/schema.rb; and the application-global renderer owns app/controllers/application_controller.rb. The active application plan adds the Domain-routes and main-navigation Web transfers that Web files and routes describes, plus unconditional Gemfile and Gemfile.lock transfers to their separate generic renderers. Account qualification changes dependency-plan and ApplicationController content without changing global file ownership. It also changes the generic Domain-routes and main-navigation outputs through shared semantic evidence. The Account-self renderer owns only app/controllers/accounts_controller.rb, app/views/accounts/show.html.erb, and its locale. The Web families do not claim Core's application layout. Core retains the layout and responsive navigation. The task plan preflights every selected task-backed transfer, and CoreComposer enforces the planned owner during composition.

Dependency projection

RailsDependencyPlan receives the complete sealed Project, exact compilation input, and base rendering context. Each selected contributor supplies one internal immutable identifier, direct-requirement set, complete Gemfile block, prerequisite list, and source identities. Policy requires Account. The planner orders contributors, rejects duplicate or conflicting claims, coalesces shared identical requirements, and checks every contributor against its digest-gated universe entry, including its prerequisite list. Every contributed requirement must also be a direct dependency of the maximal lock, not merely a reachable specification. Account, Normalization, Policy, and State Machine are the current entries. Normalization contributes pinned strip_attributes only when an emitted Field requests trim. This is a linear contributor registry, not a table of contributor combinations.

The empty selection returns Core's exact Gemfile and Gemfile.lock without starting the projector. A nonempty selection inserts the qualified blocks once into the exact Core Gemfile. It starts one isolated service-Ruby 4.0.6 subprocess with only the checked-in Bundler 4.0.10 package, an empty Bundler configuration, fixed locale and time, private home and temporary directories, and an explicit environment allowlist. Bundler runs lock --local --print; Compilation inherits no proxy, Bundler, Ruby, credential, or ambient gem paths and has no resolution route to the network.

The lock verifier parses Core, the maximal universe, and the candidate. It requires exact direct dependencies, remote, platforms, Bundler version, reachable specifications, and checksums. ApplicationTaskPlan retains the one result in its derived rendering context. The two dependency renderers only emit that retained pair. Six baseline snapshots retain the previous lockfile bytes and compose Gemfiles against the selected Core. A focused regression projects the six additional normalization-bearing selections and verifies that only strip_attributes is added. The standalone qualifier checks seven pairs, including the maximal universe, twice under hostile parent settings. Production selection consults no overlay contract or bytes.

The maximal universe is an upper bound for the current contributor registry, not a permanent gem census. Adding Money, Position, or Counter contributors under Issue #418 requires regenerating and requalifying the universe. The same dependency advance must requalify Issue #570's target namespace facts. Optional library methods must remain qualified by the selected dependency rather than restrict apps that do not load it. Package provenance, qualification, and runtime installation live in the vendor owner (repository-only) and packaging decision (repository-only).

Application documents

The Compiler writes complete application-facing README, AGENTS, and UI documents. The README starts with the application display name and a small replaceable product-description paragraph. Operational instructions derive from the selected emitted clients and retained Rails source, and concrete test-coverage omissions remain visible. It does not turn Plan subjects or gaps into a feature catalogue. The user's agent can replace the paragraph from retained design context after inspecting the emitted source and gaps; no narrative Plan field is required. Setup, runtime, preview helpers, and application tests work independently of removable .firstdraft/ context.

Core's changelog, contributor guide, and root composition document are omitted; they describe Core maintenance rather than the application's history or operation. The Core path registry rejects replacement claims for these paths. Useful UUID generator, Dev Container, and Codespaces guidance belongs in the application README; UI retains reusable component and native geometry guidance; DEPLOY keeps its existing Account-sensitive operational guidance. License-required third-party notices remain. The minimal CLAUDE.md adapter stays @AGENTS.md; removing it would require separate first-session agent-discovery qualification.

Identity and configuration

The identity renderers derive the Rails module, database prefix, display name, and Render service name from Project#application_key and Project#name. README is a full-file renderer: its title is escaped, single-line application display text; its iPhone and Android preview links use the same selected-client projections as the emitted clients and guides. Requested but ungenerated clients receive no preview instructions. README preserves the private Codespaces port default and routes temporary remote-preview exceptions and cleanup to the selected guide. It no longer relies on exact Core prose markers or carries a historical forwarded-host receipt as instruction.

Other identity renderers read verified Core files through RenderingContext and return complete replacements. The module name uses the declared target's camelization rather than mutable Designer inflections. Identity derivation rejects a Project with another target/profile. CoreTemplate validates exact marker counts before one atomic in-memory substitution and verifies replacement counts; JSON quoting and YAML-printable filtering keep valid display text valid in nested Ruby/YAML source. Files retain Core modes. No renderer patches a materialized file or consumes another renderer's output.

The application-configuration renderer substitutes the application namespace in Core's ordinary Rails configuration. The CSP baseline (repository-only) retains Rails' commented initializer and standard layout helper without custom middleware or nonce wiring.

The composition identity test (repository-only) requires complete Rails output to contain no bare reusable-Core identity token. README and AGENTS carry application guidance; historical Core provenance sentences are no longer exceptions. Replacement values preserve the original file modes, and required third-party notices remain.

References marked “repository-only” name implementation or internal material outside this public guide. They are intentionally not links. Publishing a design does not prove its implementation.