> ## Documentation Index
> Fetch the complete documentation index at: https://docs.reasonos.com/llms.txt
> Use this file to discover all available pages before exploring further.

# The RBS Language

> The Python-like .rbs build language — file types, load(), predeclared symbols, labels, environments, and the gotchas that matter

Every rbs build file is written in **the RBS language**, a deterministic,
Python-like configuration language. Files use the `.rbs` extension. This page
is the language reference for anyone writing build files; see
[Custom Rules](/reference/custom-rules) for the rule-authoring API and
[External Rule Packages](/reference/ext-packages) for `ext.rbs`.

## File types

| File            | Where                | Purpose                                                                                                                      |
| --------------- | -------------------- | ---------------------------------------------------------------------------------------------------------------------------- |
| `WORKSPACE.rbs` | workspace root       | Workspace identity and toolchain setup. Executed first.                                                                      |
| `BUILD.rbs`     | any directory        | Declares the targets of that **package** (the directory containing it).                                                      |
| `*.rbs` modules | anywhere             | Helper modules brought in with `load()` — rule definitions, shared constants, macros.                                        |
| `.env.schema`   | root and/or packages | An `.rbs`-language file declaring environments and environment variables (see [Environments](#environments-the-env-module)). |
| `ext.rbs`       | workspace root       | Manifest of external rule packages. Only `ext()` is available there — see [External Rule Packages](/reference/ext-packages). |

## The language in .rbs files

If you know Python, you already know most of the RBS language:

```python theme={null}
# Values: None, True/False, int, float, string, list, tuple, dict
SRC_DIRS = ["src", "lib"]
CONFIG = {"debug": False, "opt": 2}

def sources(dirs):
    """Functions, default args, keyword args all work."""
    return [d + "/**/*.go" for d in dirs]  # comprehensions too

go_binary(
    name = "server",
    srcs = glob(sources(SRC_DIRS)),
)
```

The dialect rbs evaluates is deliberately restricted so build files stay
analyzable and terminate:

* **No `while` loops and no recursion.** Iterate with `for` over finite
  collections.
* **`if` and `for` statements only inside functions.** At the top level of a
  file you may assign names, define functions, call rules, and `load()`.
  (Conditional *expressions* like `x = a if cond else b` are fine anywhere.)
* **Top-level names are assigned once** — no reassigning a global.
* **No implicit string concatenation.** Adjacent string literals are a parse
  error; see [Gotchas](#gotchas).
* `print()` writes to the build output; `fail()` aborts the build.

## Build file structure

A directory with a `BUILD.rbs` is a package. A build file loads the rules it
needs, then declares targets by calling them:

```python theme={null}
load("@rbs//go/rules.rbs", "go_binary", "go_library")

go_library(
    name = "greeter",
    srcs = ["greeter.go"],
)

go_binary(
    name = "hello",
    srcs = ["main.go", "greeter.go"],
    deps = [":greeter"],
)
```

```bash theme={null}
rbs build //examples/go-hello:hello
rbs run examples/go-hello:hello
rbs query //...
```

## load()

```python theme={null}
load("module_path", "symbol", local_name = "exported_name")
```

`load()` executes another `.rbs` file (once — modules are cached) and binds
selected top-level names from it into the **current file**.

| Path form                     | Resolves to                                                          |
| ----------------------------- | -------------------------------------------------------------------- |
| `@rbs//go/rules.rbs`          | The embedded ruleset shipped inside the rbs binary.                  |
| `@<namespace>//jvm/rules.rbs` | An external rule package declared in `ext.rbs` under that namespace. |
| `//tools/defs.rbs`            | Workspace-root-relative path.                                        |
| `helpers.rbs`                 | Relative to the directory of the loading file.                       |

If the path has no extension, rbs tries `.rbs` and then `.rbi`. Load cycles
are detected and reported as errors.

```python theme={null}
load("@rbs//python/rules.rbs", "py_binary")          # embedded rules
load("//rules/env/go_service.rbs", "GO_SERVICE_ENV")  # workspace module
load("@java//jvm/rules.rbs", "java_binary")           # external package
```

<Warning>
  `load()` bindings are **file-local — they are not re-exported**. A module
  that loads a symbol does not make it loadable from itself. An aggregator
  module must rebind explicitly:

  ```python theme={null}
  # prelude.rbs — WRONG: consumers of prelude.rbs will NOT see `y`
  load("x.rbs", "y")

  # prelude.rbs — RIGHT: rebind to a module-level name
  load("x.rbs", _y = "y")
  y = _y
  ```
</Warning>

## Predeclared symbols

Every build file executes with these names already defined — no `load()`
needed for any of them:

| Symbol                                        | Kind     | Available in                                                                   |
| --------------------------------------------- | -------- | ------------------------------------------------------------------------------ |
| [`glob()`](#glob)                             | function | all `.rbs` files                                                               |
| [`fail()`](#fail)                             | function | all `.rbs` files                                                               |
| [`platform`](#platform)                       | struct   | all `.rbs` files                                                               |
| [`output_path`](#output-path)                 | struct   | all `.rbs` files                                                               |
| [`config_setting()`](#config-setting)         | function | all `.rbs` files                                                               |
| [`register_toolchain()`](#register-toolchain) | function | all `.rbs` files                                                               |
| [`native`](#the-native-module)                | module   | all `.rbs` files                                                               |
| `attr`                                        | module   | all `.rbs` files — see [Custom Rules](/reference/custom-rules#the-attr-module) |
| [`env`](#environments-the-env-module)         | module   | all `.rbs` files                                                               |
| [`infra`](#infrastructure-the-infra-module)   | module   | all `.rbs` files                                                               |
| `workspace()`                                 | function | `WORKSPACE.rbs` only                                                           |
| `struct()`                                    | function | loaded modules only (not directly in `BUILD.rbs`/`WORKSPACE.rbs`)              |

In addition, **every registered rule is predeclared by its bare name** —
built-in rules like `genrule`, `task`, and `filegroup` can be called without
the `native.` prefix, and a rule defined with `native.define_rule` in a
loaded module is callable wherever it is loaded.

<Note>
  `env` and `infra` are predeclared in every `.rbs` file. There is no
  `@rbs//env/...` or similar module to load — writing such a `load()` is an
  error.
</Note>

### platform

A struct describing the platform being built for:

```python theme={null}
platform.os      # "linux", "darwin", "windows"
platform.arch    # "amd64", "arm64"
platform.name    # full name, e.g. "darwin-arm64"
platform.host    # the machine running the build (for build-time tools)
platform.target  # the platform being built for (differs when cross-compiling)
```

Supported platform names: `linux-amd64`, `linux-arm64`, `darwin-amd64`,
`darwin-arm64`, `windows-amd64`.

### output\_path

A struct of workspace output directories (all live under `.rbs/`):

```python theme={null}
output_path.out            # generic action outputs
output_path.bin            # built binaries and runfiles
output_path.testlogs       # test logs
output_path.toolchains     # installed toolchains
output_path.external_deps  # resolved external packages
```

### glob()

```python theme={null}
glob(include, exclude = [], exclude_directories = False)
```

Returns a sorted list of files matching the patterns, as paths relative to
the current package directory.

| Parameter             | Type           | Description                                                                                                              |
| --------------------- | -------------- | ------------------------------------------------------------------------------------------------------------------------ |
| `include`             | `list[string]` | Glob patterns to match. Required.                                                                                        |
| `exclude`             | `list[string]` | Patterns to remove from the result. Matched against the basename and against the full relative path (with `**` support). |
| `exclude_directories` | `bool`         | When `True`, directories matched by simple patterns are filtered out. Patterns containing `**` only ever match files.    |

Pattern syntax: `*` (any characters except `/`), `?` (one character),
`[...]` (character class), `**` (any files and directories, recursively).

```python theme={null}
glob(["*.py"])                                    # Python files in this package
glob(["**/*.go"], exclude = ["**/*_test.go"])     # all Go files, minus tests
glob(["src/**/*.ts", "lib/**/*.ts"])              # multiple roots
```

### fail()

```python theme={null}
fail(msg)
```

Stops evaluation and fails the build with the message (exit code 1).

```python theme={null}
if not ctx.file.exists(go_mod):
    fail("go.mod is required for hermetic module builds")
```

### config\_setting()

```python theme={null}
config_setting(key, value)
```

Stores a global configuration value under `key`. `value` may be any plain
value — a bool, number, string, list, or dict.

```python theme={null}
config_setting(key = "build.strict", value = True)
```

### register\_toolchain()

```python theme={null}
register_toolchain(name, kind = ..., **attributes)
```

Registers a toolchain by name with arbitrary attributes (`kind` or
`toolchain_type` classifies it). Rules reference a registered toolchain via
their `toolchain =` parameter, and rule implementations read its attributes
through `ctx.toolchain`. In practice most workspaces use a language
toolchain rule instead of calling this directly:

```python theme={null}
# WORKSPACE.rbs
load("@rbs//go/toolchain.rbs", "go_toolchain")

go_toolchain(
    name = "go",
    version = "1.24.3",   # rbs downloads it; no system Go needed
)
```

### workspace()

```python theme={null}
workspace(name)
```

`WORKSPACE.rbs` only. Declares the workspace's identity. The name must be
letters, digits, `.`, `-` or `_`, starting with a letter or digit, and may
only be declared once.

```python theme={null}
workspace(name = "my-service")
```

## Attributes every rule accepts

Beyond each rule's own attributes, these work on **every** target:

| Attribute                | Type                   | Description                                                                                                                                                                            |
| ------------------------ | ---------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `name`                   | `string`               | Required. The target's name within its package.                                                                                                                                        |
| `env`                    | `dict[string, string]` | Environment variables for the target's actions. Accepted by every rule — including ones whose definition never declared it — and usually produced by `env.vars([...])` or `env.all()`. |
| `target_compatible_with` | `list[string]`         | Platform names the target builds for, e.g. `["linux-amd64", "darwin-arm64"]`. Empty means all platforms.                                                                               |

```python theme={null}
go_binary(
    name = "worker",
    srcs = ["main.go"],
    env = env.vars(["DATABASE_URL"], override = {"GOMAXPROCS": "4"}),
    target_compatible_with = ["linux-amd64", "linux-arm64"],
)
```

## Labels

Targets are addressed by label:

| Label                             | Meaning                                                                                                                                                       |
| --------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `:greeter`                        | Target in the same package.                                                                                                                                   |
| `//services/api:server`           | Absolute: package path from the workspace root, then target name.                                                                                             |
| `//services/api`                  | Shorthand for `//services/api:api` on the command line.                                                                                                       |
| `//...`                           | All targets in the workspace (command line, e.g. `rbs query //...`).                                                                                          |
| `@external://<package>:<version>` | An external ecosystem dependency (npm, pip, ...) in a rule's `deps`, e.g. `@external://react:19.0.0`. Resolved by the language rules, not a build-graph edge. |

`@rbs//...` and `@<namespace>//...` are **load paths** for rule modules, not
target labels.

## Environments: the `env` module

Environment handling is schema-driven. A `.env.schema` file (written in the
same build language) declares environments and variables; plain dotenv files supply the values
(`.env` base, `.env.<name>` per-environment overlay, `.env.local` personal,
gitignored); targets bind an allow-list with `env.vars()`. The environment
is selected with `-e <name>` / `RBS_ENV`, and an undeclared name is a hard
error. Validation happens at analysis time — a missing required variable
fails the build, not the process at runtime.

### env.var()

```python theme={null}
env.var(type = "string", default = None, required = False, secret = False,
        values = [], doc = "", source = None)
```

Declares one variable. Returns a value usable in `env.schema(vars = {...})`.

| Parameter  | Type           | Description                                                                                            |
| ---------- | -------------- | ------------------------------------------------------------------------------------------------------ |
| `type`     | `string`       | `"string"` (default), `"int"`, `"bool"`, `"url"`, or `"enum"`.                                         |
| `default`  | `string`       | Default value. All env values are strings — quote numbers. `None` (no default) and `""` are different. |
| `required` | `bool`         | May be computed, e.g. `required = env.name() == "prod"`.                                               |
| `secret`   | `bool`         | Marks the value secret: redacted in output, digest-cached instead of stored in plaintext.              |
| `values`   | `list[string]` | Allowed values for `type = "enum"`.                                                                    |
| `doc`      | `string`       | Documentation string.                                                                                  |
| `source`   | `env.source`   | Where the value comes from, instead of the env files — see [Value sources](#value-sources).            |

### env.schema()

```python theme={null}
env.schema(vars = {}, extends = [])
```

Composes variables into a schema. Called from a `.env.schema` file it
registers as that package's schema; assigned to a name in a shared module
it becomes a reusable standard. Calling `env.schema()` twice in one
`.env.schema` is an error — compose with `extends` instead. Conflicting
declarations of the same variable across `extends` are an error unless the
extending schema restates the variable explicitly.

```python theme={null}
# rules/env/go_service.rbs — a shared standard
GO_SERVICE_ENV = env.schema(
    vars = {
        "PORT":         env.var(type = "int", default = "8080"),
        "LOG_LEVEL":    env.var(type = "enum",
                                values = ["debug", "info", "warn", "error"],
                                default = "info"),
        "DATABASE_URL": env.var(type = "url", required = True, secret = True),
    },
)
```

```python theme={null}
# services/controlplane/.env.schema — inherit and extend
load("//rules/env/go_service.rbs", "GO_SERVICE_ENV")

env.schema(
    extends = [GO_SERVICE_ENV],
    vars = {
        "WORKOS_API_KEY": env.var(secret = True, required = env.name() == "prod"),
    },
)
```

### env.environment() and env.files()

```python theme={null}
env.environment(name, extends = "", infra = "")
env.files(pattern)
```

The root `.env.schema` declares which environments exist — rbs hardcodes
none. `extends` layers another environment's overlay file underneath;
`infra` links the environment to an `infra.environment()`. `env.files()`
overrides the overlay filename pattern (default `.env.{env}`); the pattern
must contain `{env}`, and one workspace has one pattern.

```python theme={null}
# .env.schema (workspace root)
env.environment("dev")
env.environment("staging", extends = "dev")
env.environment("prod")

env.files(pattern = ".env.{env}")   # the default
```

### env.vars() and env.all()

```python theme={null}
env.vars(names, override = {})   # allow-list — the documented default
env.all(override = {})           # every declared variable — escape hatch
```

Both return a plain `dict[string, string]` for a target's `env` attribute.
`env.vars()` binds exactly the named, schema-declared variables — only
those reach the process and only those enter its cache key. A name not
declared in any reachable schema is an analysis-time error listing the
declared names. `override` layers literal values on top (they win over
files). `env.all()` injects every declared variable, at the cost of a wider
cache key.

```python theme={null}
go_binary(
    name = "controlplane",
    srcs = glob(["*.go"]),
    env = env.vars(["DATABASE_URL", "PORT"]),
)
```

### env.name()

```python theme={null}
env.name()
```

Returns the selected environment name (`-e` / `RBS_ENV`), so schemas can
make declarations conditional.

### Value sources

A variable's value normally comes from the env files. `source =` points it
elsewhere:

| Source                         | Signature                        | Value comes from                                                                                                                 |
| ------------------------------ | -------------------------------- | -------------------------------------------------------------------------------------------------------------------------------- |
| `env.infra(ref)`               | `ref` is `"<resource>.<output>"` | An applied infra resource output, e.g. `env.infra("maindb.connection_string")`.                                                  |
| `env.host(name = "")`          | optional host variable name      | The host process environment — the **only** passthrough; the value is hashed into the cache key.                                 |
| `env.command(argv)`            | non-empty `list[string]`         | Stdout of a command, e.g. `env.command(["git", "rev-parse", "HEAD"])`.                                                           |
| `env.managed(name = "")`       | optional name                    | A value the platform delivers to the node. Unlike other sources it is a fallback: an env file the developer writes wins over it. |
| `env.source(resolver, **args)` | resolver name + string kwargs    | A custom resolver registered with `env.define_source()`.                                                                         |

```python theme={null}
env.define_source(name, impl)
```

registers a custom resolver (Vault, cloud secret managers, ...) at module
top level.

```python theme={null}
"BUILD_SHA": env.var(source = env.command(["git", "rev-parse", "HEAD"])),
"DB_PASS":   env.var(secret = True, source = env.source("vault", key = "prod/db")),
```

## Infrastructure: the `infra` module

`infra` is predeclared everywhere and is the surface for
infrastructure-as-code definitions. Its members, grouped:

| Group               | Members                                                                                                                                             |
| ------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------- |
| Providers           | `infra.register_provider`, `infra.provider_config`, `infra.register_native_provider`, `infra.define_provider_adapter`                               |
| Resource types      | `infra.define_resource_type`, `infra.define_native_resource`, `infra.define_native_data_source`, `infra.attribute`, `infra.block`                   |
| Declarations        | `infra.resource`, `infra.component`, `infra.module`, `infra.workspace`, `infra.environment`, `infra.var`                                            |
| Policy & mapping    | `infra.define_policy`, `infra.define_equivalence`, `infra.resolve`, `infra.define_value_map`, `infra.map_value`                                     |
| Data & outputs      | `infra.data`, `infra.lookup`, `infra.output`, `infra.get_output`, `infra.apply`, `infra.all`, `infra.secret`, `infra.is_unknown`, `infra.is_secret` |
| Values & references | `infra.format`, `infra.join`, `infra.depends`, `infra.ref`                                                                                          |
| HTTP helpers        | `infra.http_get`, `infra.http_post`, `infra.http_put`, `infra.http_delete`                                                                          |
| Utility             | `infra.generate_id`                                                                                                                                 |

See the infrastructure guides for end-to-end usage; this page only records
that the module exists in every file with these members.

## The `native` module

`native` exposes every built-in rule and SDK function. All of them are
*also* predeclared by bare name, so `genrule(...)` and
`native.genrule(...)` are the same call.

### Built-in target rules

| Rule                                                                                      | Declares                                                                                                 |
| ----------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------- |
| [`genrule`](#genrule)                                                                     | A shell command (or build-language function) producing declared outputs.                                 |
| [`run_tool`](#run-tool)                                                                   | A registered tool invocation producing declared outputs.                                                 |
| [`task`](#task)                                                                           | A runnable command target (no cached outputs required).                                                  |
| [`filegroup`](#filegroup)                                                                 | A named collection of files.                                                                             |
| `http_file(name, url, sha256 = "", executable = False, output_name = "")`                 | Downloads a single file into the toolchain area.                                                         |
| `http_archive(name, url, sha256 = "", strip_prefix = "", build_file = "", platform = "")` | Downloads and extracts an archive.                                                                       |
| `tool_binary(...)`                                                                        | Declares a downloadable tool binary.                                                                     |
| `oci_image(...)`                                                                          | Builds an OCI container image.                                                                           |
| `external_dep(name, ecosystem, package, version, resolver = "", host = False)`            | Resolves an external ecosystem package (and its transitive deps); referenced as `@external://<package>`. |
| `scaffolding(...)`                                                                        | Code-generation template target.                                                                         |
| `lsp_provider(...)`                                                                       | Declares an LSP server for a language.                                                                   |
| `lint(...)`                                                                               | Lint target using a defined linter.                                                                      |
| `ai_task(...)`                                                                            | AI-driven task/test target.                                                                              |
| `migration_database(...)`                                                                 | Database migration target.                                                                               |

#### genrule

```python theme={null}
genrule(name, outs, cmd = "", action_fn = None, srcs = [], tools = [],
        deps = [], env = {}, message = "", executable = False,
        local = False, visibility = [], testonly = False)
```

| Parameter                | Type           | Description                                                             |
| ------------------------ | -------------- | ----------------------------------------------------------------------- |
| `name`                   | `string`       | Target name. Required.                                                  |
| `outs`                   | `list[string]` | Declared outputs. Required.                                             |
| `cmd`                    | `string`       | Shell command to run. Exactly one of `cmd` / `action_fn` must be given. |
| `action_fn`              | `callable`     | Build-language function executed instead of a shell command.            |
| `srcs`                   | `list[string]` | Input files.                                                            |
| `tools`                  | `list[string]` | Tools the command needs.                                                |
| `deps`                   | `list[string]` | Target dependencies.                                                    |
| `env`                    | `dict`         | Environment for the action (pairs with `env.vars()`).                   |
| `message`                | `string`       | Progress message.                                                       |
| `executable`             | `bool`         | Mark the output executable.                                             |
| `local`                  | `bool`         | Run locally (never remotely).                                           |
| `visibility`, `testonly` |                | Standard metadata.                                                      |

```python theme={null}
genrule(
    name = "version_file",
    outs = ["version.txt"],
    cmd = "git rev-parse HEAD > version.txt",
)
```

#### run\_tool

```python theme={null}
run_tool(name, tool, outs, args = [], srcs = [], deps = [], env = {},
         message = "", local = False, visibility = [], testonly = False)
```

Like `genrule`, but invokes a registered tool by name with an argument list
instead of a shell string.

#### task

```python theme={null}
task(name, command, deps = [], outputs = [], description = "",
     working_dir = "", toolchain = "")
```

A runnable command. `command` is a `list[string]` argv. Run it with
`rbs run //pkg:name`.

```python theme={null}
task(
    name = "dev",
    command = ["npm", "run", "dev"],
    description = "Start the dev server",
)
```

#### filegroup

```python theme={null}
filegroup(name, srcs = [], deps = [], data = [], visibility = [],
          testonly = False, executable = False, output_group = None)
```

Groups files under one label, typically fed by `glob()`:

```python theme={null}
filegroup(
    name = "testdata",
    srcs = glob(["testdata/**"]),
)
```

### Rule and SDK definition functions

These register capabilities rather than declaring targets. Most run at
module top level in rule packages; auto-registration at top level is the
mechanism — the module executes, the definition registers.

| Function                                                     | Registers                                                       |
| ------------------------------------------------------------ | --------------------------------------------------------------- |
| `native.define_rule(...)`                                    | A new build rule — see [Custom Rules](/reference/custom-rules). |
| `native.define_external_dep_resolver(...)`                   | A package-ecosystem resolver (npm, pip, ...).                   |
| `native.define_linter(...)`                                  | A linter for a language.                                        |
| `native.define_completion_language(...)`                     | Tab-completion support for a language.                          |
| `native.define_coverage_converter(...)`                      | A coverage-format converter.                                    |
| `native.define_language_constraints(...)`                    | Per-language do's/don'ts surfaced to agents.                    |
| `native.define_setup_template(...)`                          | A per-language setup guide.                                     |
| `native.define_atlas_extractor(...)`                         | How a language maps into the Atlas knowledge graph.             |
| `native.define_agent_tool(...)` / `define_agent_prompt(...)` | Agent tools and prompts.                                        |
| `native.define_subagent(...)` / `define_teammate_role(...)`  | Agent specialists and roles.                                    |
| `native.define_skill(...)`                                   | A slash-command skill.                                          |
| `native.define_mcp_server(...)`                              | An external MCP tool server.                                    |
| `native.register_fragment_config(name, config)`              | A configuration fragment (read via `ctx.fragments`).            |
| `native.register_language_config(language, config)`          | Language configuration.                                         |
| `native.create_launcher(...)`                                | Generates a language-agnostic launcher script.                  |

Companion `list_*` functions (`list_skills`, `list_subagents`,
`list_mcp_servers`, ...) enumerate what is registered, and
`get_toolchain_attribute(toolchain, attribute)` / `toolchain_path(...)`
read toolchain metadata.

### Utility functions

The file, directory, JSON, archive, HTTP, and tool helpers
(`native.file_read`, `native.dir_create`, `native.json_parse`,
`native.archive_extract`, `native.http_download`, `native.tool_run`, ...)
are the same operations exposed on `ctx` inside rule implementations, where
they are documented: see
[Custom Rules → the ctx API](/reference/custom-rules#the-ctx-api).

## Gotchas

**No implicit string concatenation.** Unlike Python, adjacent string
literals do not concatenate — it is a parse error. Use `+` or `join`:

```python theme={null}
# WRONG — parse error
cmd = "echo hello " "world"

# RIGHT
cmd = "echo hello " + "world"
script = "\n".join(["set -e", "make build"])
```

**`load()` does not re-export.** See [load()](#load) — aggregator modules
must rebind (`load("x.rbs", _y = "y")` then `y = _y`).

**`env` and `infra` are predeclared.** Never write a `load()` for them.

**`env = ...` works on every rule** — even rules whose definition never
declared an `env` attribute, including rules you define yourself.

**Control flow lives in functions.** A top-level `if` or `for` *statement*
is a parse error; wrap logic in a `def` and call it.

**`struct()` is only predeclared in loaded modules.** Build a struct in a
helper module and load it, rather than calling `struct()` directly in a
`BUILD.rbs`.
