FLATPAK-METADATA(5)
FLATPAK METADATA(5) β flatpak metadata π
okay bestie, buckle up, this is the flatpak-metadata page and it's lowkey a whole vibe. it's section 5 of the flatpak manual, and it's all about the little .ini files that tell Flatpak what an app or runtime even is. β¨
πΈ NAME πΈ
flatpak-metadata β all the tea about an application or runtime π«
π DESCRIPTION π
so. Flatpak uses metadata files to describe applications and runtimes. iconic behavior honestly. the metadata file for a deployed application or runtime lives in the toplevel deploy directory. for example, the metadata for the locally installed application org.gnome.Calculator is chilling at:
~/.local/share/flatpak/app/org.gnome.Calculator/current/active/metadata
most aspects of the metadata configuration can be overridden when launching applications, either:
- temporarily, via options of the
flatpak runcommand, or - permanently, with the
flatpak overridecommand. π
a metadata file describing the effective configuration is available inside the running sandbox at /.flatpak-info. and for compatibility with older Flatpak versions, /run/user/$UID/flatpak-info is a symbolic link to that same file. no cap, it's the same file. π
π¦ FILE FORMAT π¦
the metadata file uses the same .ini file format as systemd unit files or application .desktop files. you already know this format, bestie, you've got this. πͺ
π [Application] or [Runtime] π
metadata for applications starts with an [Application] group, and metadata for runtimes starts with a [Runtime] group. pick your fighter. π₯
the following keys can be present in these groups:
name(string) β the name of the application or runtime. this key is mandatory, fr fr.runtime(string) β the fully qualified name of the runtime that the application uses. this key is mandatory for applications.sdk(string) β the fully qualified name of the sdk that matches the runtime. available since0.1.command(string) β the command to run. only relevant for applications. available since0.1.required-flatpak(string list) β the required version of Flatpak to run this application or runtime. for applications, this was available since0.8.0. for runtimes, this was available since0.9.1, and backported to0.8.3for the0.8.xbranch. Flatpak after version1.4.3and1.2.5support multiple versions here. this is useful if you need to support features that got backported to a previous stable series. for example, if you wanna use a feature added in1.6.0that was also backported to1.4.4, you'd write1.6.0;1.4.4;. note that older versions of flatpak will just use the first element in the list, so make that one the largest version. π (iykyk)tags(string list) β tags to include in AppStream XML. typical values in use on Flathub includebeta,stable,proprietaryandupstream-maintained. available since0.4.12. π·οΈ
π [Context] π
this group determines the various system resources that may be shared with the application when it's run in a flatpak sandbox. it's giving "what are we letting the app touch" energy.
β¨ Conditional Permissions β¨
some permissions (such as sockets and devices) support conditional grants, where access is only provided when specific runtime conditions are met. this lets applications adapt to different system capabilities and session types. available since 1.17. π
conditional permissions use the syntax if:PERMISSION:CONDITION in the metadata file. for example, if:wayland:has-wayland grants Wayland socket access only when running in a Wayland session.
the following conditions are supported:
trueβ always evaluates to true. βfalseβ always evaluates to false. βhas-input-deviceβ true if this version of Flatpak supports the input device permission. this is always true in Flatpak1.15.6and later, and can be used to provide fallback behavior for older Flatpak versions.has-waylandβ true if the current desktop session supports Wayland.has-usb-deviceβ true if this version of Flatpak supports the usb device permission. this is always true in Flatpak1.16.0and later, and can be used to provide fallback behavior for older Flatpak versions.has-usb-portalβ true if the current desktop session supports the USB Portal.
conditions can be negated by prefixing with !. for example, if:x11:!has-wayland grants X11 socket access only when NOT running in a Wayland session. π
multiple conditional permissions can be specified for the same resource. if any condition matches, the permission is granted (OR logic). for example:
sockets=wayland;if:x11:!has-wayland;if:x11:false
for backward compatibility with older Flatpak versions, conditional permissions can be combined with unconditional grants:
sockets=x11;if:x11:!has-wayland;
older Flatpak versions will grant X11 access unconditionally (seeing only x11), while newer versions recognize the conditional syntax and grant X11 access only when not in Wayland sessions. bestie, it's a whole time-travel trick. β³
to explicitly deny a permission that might be granted at a lower layer (such as from the runtime or a global override), prefix the permission name with !:
sockets=!x11;
this denial can be combined with conditional grants to remove unconditional access while allowing conditional access:
sockets=!x11;x11;if:x11:!has-wayland;
this denies unconditional X11 access, but allows X11 access conditionally when not running in a Wayland session. the seemingly contradictory !x11 and x11 ensures backward compatibility: older Flatpak versions see the final x11 grant, while newer versions understand the conditional logic. π€―
all keys in this group (and the group itself) are optional. breathe easy. π«Ά
the keys supported in this group are:
shared(list) β list of subsystems to share with the host system. possible subsystems:network,ipc. available since0.3. this option supports conditional permissions. see Conditional Permissions for details on how to share subsystem access conditionally based on runtime conditions.sockets(list) β list of well-known sockets to make available in the sandbox. possible sockets:x11,wayland,fallback-x11,pulseaudio,session-bus,system-bus,ssh-auth,pcsc,cups,gpg-agent,inherit-wayland-socket. when making a socket available, flatpak also sets well-known environment variables likeDISPLAYorDBUS_SYSTEM_BUS_ADDRESSso the application can find sockets that aren't in a fixed location. available since0.3. this option supports conditional permissions. see Conditional Permissions for details on how to grant socket access conditionally based on runtime conditions.devices(list) β list of devices to make available in the sandbox. this just exposes the device nodes, it doesn't grant any permission that the user doesn't already have. possible values:driβ GPU graphics and compute (/dev/dri), including vendor specific render and compute devices. available since0.3.inputβ input devices (/dev/input). available since1.15.6.usbβ USB device bus (all device nodes below/dev/bus/usb). available since1.15.11.kvmβ virtualization (/dev/kvm). available since0.6.12.allβ all device nodes in/dev, but not/dev/shm(which is separately specified). available since0.6.6.shmβ access to the host/dev/shm(/dev/shm). available since1.6.1. this option supports conditional permissions. see Conditional Permissions for details on how to grant device access conditionally based on runtime conditions.
filesystems(list) β list of filesystem subsets to make available to the application. possible values:homeβ the entire home directory. available since0.3.home/pathβ alias for~/path. available since1.10. for better compatibility with older Flatpak versions, prefer to write this as~/path. πhostβ the entire host file system, except for directories that are handled specially by Flatpak. in particular, this shares/home,/media,/opt,/run/mediaand/srvif they exist./devis not shared: usedevices=all;instead. parts of/sysare always shared. this option does not make additional files in/sysavailable. additionally, this keyword provides all of the same directories in/run/hostas thehost-osandhost-etckeywords. if this keyword is used in conjunction with one of thehost-keywords, whichever access level is higher (more permissive) will be used for the directories in/run/host: for example,host:rw;host-os:ro;is equivalent tohost:rw;. these other reserved directories are currently excluded:/app,/bin,/boot,/efi,/etc,/lib,/lib32,/lib64,/proc,/root,/run,/sbin,/tmp,/usr,/var. available since0.3.host-osβ the host operating system's libraries, executables and static data from/usrand the related directories/bin,/lib,/lib32,/lib64,/sbin. additionally, this keyword provides access to a subset of/etcthat is associated with packaged libraries and executables, even if thehost-etckeyword was not used:/etc/ld.so.cache, (used by the dynamic linker) and/etc/alternatives(on operating systems that use it, such as Debian). to avoid conflicting with the Flatpak runtime, these are mounted in the sandbox at/run/host/usr,/run/host/etc/ld.so.cacheand so on. available since1.7.host-etcβ the host operating system's configuration from/etc. to avoid conflicting with the Flatpak runtime, this is mounted in the sandbox at/run/host/etc. available since1.7.host-rootβ the complete host operating system. to avoid conflicting with the Flatpak runtime, this is mounted in the sandbox at/run/host/root.
this permission is only intended to be used as a last resort when there is no possible alternative with other filesystem permissions for applications that need the entire root filesystem of the host. β οΈ
please note that following symlinks under /run/host/root naively will result in a wrong path. for example, using realpath() is wrong. instead, applications will have to implement some way of following symlinks in a way that behaves as if it were chroot'd into /run/host/root. π no shortcuts bestie, sorry.
There are a few ways to do this. Modern kernels support the openat2()[1] call with RESOLVE_IN_ROOT. For a more portable solution with support for older kernels, see the implementation from the steam-runtime-tools[2] as an example.
Available since 1.17.
xdg-desktop,xdg-documents,xdg-download,xdg-music,xdg-pictures,xdg-public-share,xdg-videos,xdg-templatesβ the freedesktop.org special directories[3]. Available since 0.3.xdg-desktop/path,xdg-documents/path, etc. β subdirectories inside those freedesktop.org special directories. Available since 0.4.13.xdg-cache,xdg-config,xdg-dataβ the directories defined by the freedesktop.org Base Directory Specification[4]. Available since 0.6.14.xdg-cache/path,xdg-config/path,xdg-data/pathβ subdirectories of the directories defined by the freedesktop.org Base Directory Specification. Available since 0.6.14.xdg-run/pathβ subdirectories of theXDG_RUNTIME_DIRdefined by the freedesktop.org Base Directory Specification. Heads up tho:xdg-runall on its own is not supported, bestie. Available since 0.4.13./pathβ any absolute path you want, just raw like that. Available since 0.3.~/pathβ any path relative to the home directory. Available since 0.3.~β same thing ashome. Available since 1.10. For better compatibility with older Flatpak versions, prefer to write this ashome.- one of the above, followed by
:roβ makes that directory available read-only. - one of the above, followed by
:rwβ makes that directory available read/write. This is the default, so if you say nothing, this is what you get. - one of the above, followed by
:createβ makes that directory available read/write, and creates it if it doesn't already exist.
persistent(list) β a list of homedir-relative paths to make available at the corresponding path in the per-application home directory, so those spots can be used for persistent data when the app doesn't have access to the real homedir. Like, say you make".myapp"persistent β then"~/.myapp"inside the sandbox becomes a bind mount to"~/.var/app/org.my.App/.myapp", which means an unmodified application can save its data in the per-application location. Available since 0.3.features(list) β a list of features that are available or unavailable to the application, currently from this list right here:develβ allows the system calls used by development-oriented tools likeperf,straceandgdb. Available since 0.6.10.multiarchβ allows running multilib/multiarch binaries, for example i386 binaries in an x86_64 environment. Available since 0.6.12.bluetoothβ allows the application to use bluetooth (AF_BLUETOOTH) sockets. Note tho: for bluetooth to fully work you also gotta have network access. Available since 0.11.8.canbusβ allows the application to use canbus (AF_CAN) sockets. Note that for this to work you also gotta have network access. Available since 1.0.3.per-app-dev-shmβ shares a single instance of/dev/shmbetween all instances of this application run by the same user ID, including sub-sandboxes. If the application has theshmdevice permission in its devices list, then this feature flag is just ignored. Available since 1.12.0.
A feature can be prefixed with ! to indicate the absence of that feature β for example !devel if development and debugging are not allowed. Iconic negation moment.
This option supports conditional permissions. See Conditional Permissions for the deets on how to allow features conditionally, based on runtime conditions.
unset-environment(list) β a list of names of environment variables to unset. Note that environment variables you want to set to a value (even an empty one) live over in the[Environment]group instead. Different group, different job.
π«Ά [Instance] π«Ά
This group only shows up in /.flatpak-info for a running app, and not in the metadata files written by application authors. Flatpak itself fills it in. It's like the app's little ID card, no cap.
instance-id(string) β the ID of the running instance. This number is used as the name of the directory inXDG_RUNTIME_DIR/.flatpakwhere Flatpak stores information about this instance.instance-path(string) β the absolute path on the host system of the app's persistent storage area in$HOME/.var.app-path(string) β the absolute path on the host system of the app's app files, as mounted at/appinside the container. Available since 0.6.10.
Since 1.12.0, if flatpak run was run with the --app-path option, this key gives the absolute path of whatever files were mounted on /app, even if that differs from the app's normal app files.
If flatpak run was run with --app-path= (which results in an empty directory being mounted on /app), the value is set to the empty string. Yes, empty. On purpose.
original-app-path(string) β ifflatpak runwas run with the--app-pathoption, this key gives the absolute path of the app's original files, as mounted at/run/parent/appinside the container. Available since 1.12.0.
If this key is missing, the app files are given by app-path.
app-commit(string) β the commit ID of the application that is running. The filename of a deployment of this commit can be found inoriginal-app-pathif present, orapp-pathotherwise.app-extensions(list of strings) β a list of app extensions that are mounted into the running instance. The format for each list item isEXTENSION_ID=COMMIT. Iforiginal-app-pathis present, the extensions are mounted below/run/parent/app; otherwise, they are mounted below/app.branch(string) β the branch of the app, for examplestable. Available since 0.6.10.arch(string) β the architecture of the running instance.flatpak-version(string) β the version number of the Flatpak version that ran this app. Available since 0.6.11.runtime-path(string) β the absolute path on the host system of the app's runtime files, as mounted at/usrinside the container. Available since 0.6.10.
Since 1.12.0, if flatpak run was run with the --usr-path option, this key gives the absolute path of whatever files were mounted on /usr, even if that differs from the app's normal runtime files.
original-runtime-path(string) β ifflatpak runwas run with the--runtime-pathoption, this key gives the absolute path of the app's original runtime, as mounted at/run/parent/usrinside the container. Available since 1.12.0.
If this key is missing, the runtime files are given by runtime-path.
runtime-commit(string) β the commit ID of the runtime that is used. The filename of a deployment of this commit can be found inoriginal-runtime-pathif present, orruntime-pathotherwise.runtime-extensions(list of strings) β a list of runtime extensions that are mounted into the running instance. The format for each list item isEXTENSION_ID=COMMIT. Iforiginal-app-pathis present, the extensions are mounted below/run/parent/usr; otherwise, they are mounted below/usr.extra-args(string) β extra arguments that were passed toflatpak run.sandbox(boolean) β whether the--sandboxoption was passed toflatpak run.build(boolean) β whether this instance was created byflatpak build.session-bus-proxy(boolean) βtrueif this app cannot access the D-Bus session bus directly (either it goes via a proxy, or it can't access the session bus at all). Available since 0.8.0.system-bus-proxy(boolean) βtrueif this app cannot access the D-Bus system bus directly (either it goes via a proxy, or it can't access the system bus at all). Available since 0.8.0.
π [Session Bus Policy] π
If the sockets key is not allowing full access to the D-Bus session bus, then flatpak provides filtered access instead. It's giving bouncer energy, honestly.
The default policy for the session bus only lets the application own its own application ID, its subnames, and its own application ID as a subname of org.mpris.MediaPlayer2. So for instance, if the app is called org.my.App, it can only own org.my.App, org.my.App.* and org.mpris.MediaPlayer2.org.my.App. It's only allowed to talk to names matching those patterns, plus the bus itself (org.freedesktop.DBus) and the portal APIs (bus names of the form org.freedesktop.portal.*).
Additionally, the app is always allowed to reply to messages sent to it, and emit broadcast signals (but these will not reach other sandboxed apps unless they are allowed to talk to your app.
If the [Session Bus Policy] group is present, it provides policy for session bus access.
Each key in this group has the form of a D-Bus bus name or a prefix thereof, for example org.gnome.SessionManager or org.freedesktop.portal.*.
The possible values for an entry are the following, in increasing order of access. Each value implies all the access from any lower values β so it stacks, bestie:
noneβ the bus name is invisible to the application. Available since 0.2.seeβ the bus name can be enumerated by the application. Available since 0.2.talkβ the application can send messages to, and receive replies and signals from, the bus name. Available since 0.2.ownβ the application can own the bus name. Available since 0.2.
π¦ [System Bus Policy] π¦
If the sockets key is not allowing full access to the D-Bus system bus, then flatpak does not make the system bus available unless the [System Bus Policy] group is present and provides a policy for filtered access. Available since 0.2.
Entries in this group have the same form as for the [Session Bus Policy] group. However, the app has no permissions by default. Starting from zero, literally.
π [Environment] π
The [Environment] group specifies environment variables to set when running the application. Available since 0.3.
Entries in this group have the form VAR=VALUE where VAR is the name of an environment variable to set.
Note that environment variables can also be unset (removed from the environment) by listing them in the unset-environment entry of the [Context] group. Two ways to handle env vars, pick your fighter.
[Extension NAME] π«Άβ¨
Okay bestie, listen. Runtimes and apps can define extension points. These let optional extra runtimes get mounted at a specific spot inside the sandbox when they're actually present on the system. Think translations for apps, or debuginfo for sdks. The extension point name lives right in the group heading. Since 0.11.4, the NAME can optionally have a tag using the name@tag ref syntax β that's for when you want different configurations (like versions) of the same extension at the same time. The "tag" is basically ignored, but it's necessary so you can specify the same extension name more than once. π
directory(string) β The relative path where the extension gets mounted in the sandbox. If the extension point is for an app, the path is relative to/app; otherwise it's relative to/usr. This key is mandatory. Available since0.1. πversion(string) β The branch to use when looking for the extension. If you don't specify it, it defaults to the branch of the app or runtime that the extension point is for. Available since0.4.1. πΈversions(string) β The branches to use when looking for the extension. If not specified, defaults to the branch of the app or runtime the extension point is for. Available since0.9.1, and backported to the0.8.xbranch in0.8.4. πadd-ld-path(string) β A path relative to the extension point directory that gets appended toLD_LIBRARY_PATH. Available since0.9.1, and backported to the0.8.xbranch in0.8.3. β¨merge-dirs(string) β A list of relative paths of directories below the extension point directory that will be merged. Available since0.9.1, and backported to the0.8.xbranch in0.8.3. π¦download-if(string) β A condition that must be true for the extension to be auto-downloaded. As of1.1.1, this supports multiple conditions separated by semi-colons. π
These are the supported conditions:
active-gl-driverβ True if the name of the active GL driver matches the extension point basename. Available since0.9.1, and backported to the0.8.xbranch in0.8.3. π₯active-gtk-themeβ True if the name of the current GTK theme (viaorg.gnome.desktop.interfaceGSetting) matches the extension point basename. Added0.10.1. π¨have-intel-gpuβ True if thei915kernel module is loaded. Added0.10.1. π»have-kernel-module-*β True if the suffix (case-sensitive) is found in/proc/modules. For examplehave-kernel-module-nvidia. Added1.13.1. π§on-xdg-desktop-*β True if the suffix (case-insensitively) is in theXDG_CURRENT_DESKTOPenv var. For exampleon-xdg-desktop-GNOME-classic. Added1.1.1. π
autoprune-unless(string) β A condition that must be false for the extension to be considered unused when pruning. For example,flatpak uninstall --unusedandflatpak updateuse this info. The only currently recognized value isactive-gl-driver, which is true if the name of the active GL driver matches the extension point basename. Available since0.11.8. π§Ήenable-if(string) β A condition that must be true for the extension to be enabled. As of1.1.1, this supports multiple conditions separated by semi-colons. Seedownload-iffor available conditions. βsubdirectory-suffix(string) β A suffix that gets appended to the directory name. Very useful when the extension point naming scheme is "reversed". For example, an extension point for GTK+ themes would be/usr/share/themes/$NAME/gtk-3.0, which you could achieve usingsubdirectory-suffix=gtk-3.0. Available since0.9.1, and backported to the0.8.xbranch in0.8.3. πsubdirectories(boolean) β If set totrue, flatpak will look for extensions whose name is a prefix of the extension point name, and mount them at the corresponding name below the subdirectory. Available since0.1. π³no-autodownload(boolean) β Whether to automatically download extensions matching this extension point when updating or installing a 'related' application or runtime. Available since0.6.7. π«locale-subset(boolean) β If set, the extensions are partially downloaded by default, based on the currently configured locales. That means the extension contents should be a set of directories with the language code as name. Available since0.9.13(and0.6.6for any extensions called*.Locale). πautodelete(boolean) β Whether to automatically delete extensions matching this extension point when deleting a 'related' application or runtime. Available since0.6.7. ποΈcollection-id(string) β The ID of the collection that this extension point belongs to. If unspecified, it defaults to the collection ID of the app or runtime the extension point is for. Currently, extension points must be in the same collection as the app or runtime they're for. Available since0.99.1. π
[ExtensionOf] π«
This optional group may be present if the runtime is an extension.
ref(string) β The ref of the runtime or application that this extension belongs to. Available since0.9.1. πruntime(string) β The runtime this extension will be inside of. If it's an app extension, this is the app's runtime; otherwise, this is identical toref, without theruntime/prefix. Available since1.5.0. πpriority(integer) β The priority to give this extension when looking for the best match. Default is0. Available since0.9.1, and backported to the0.8.xbranch in0.8.3. βtag(string) β The tag name to use when searching for this extension's mount point in the parent flatpak. Available since0.11.4. π·οΈ
[Extra Data] π¦
This optional group may be present if the runtime or application uses extra data that gets downloaded separately. The data in this group gets merged into the repository summary, with the xa.extra-data-sources key.
If multiple extra data sources are present, their uri, size and checksum keys are grouped together by using the same suffix. If only one extra data source is present, the suffix can be omitted.
NoRuntime(boolean) β Whether to mount the runtime while running the/app/bin/apply_extrascript. Defaults totrue, i.e. not mounting the runtime. Available since0.9.1, and backported to the0.8.xbranch in0.8.4. π οΈuriX(string) β The uri for extra data source X. The only supported uri schemes arehttpandhttps. Available since0.6.13. πsizeX(integer) β The size for extra data source X. Available since0.6.13. πchecksumX(string) β The sha256 sum for extra data source X. Available since0.6.13. π
[Policy SUBSYSTEM] ποΈ
Subsystems can define their own policies to be placed in a group whose name has this form. Their values are treated as lists, in which items can have their meaning negated by prepending ! to the value. They are not otherwise parsed by Flatpak. Available since 0.6.13. β¨
[USB Devices] π
USB devices can be enumerable or hidden by the USB portal as specified by the keys in this group. The vendor and product ids are validated by Flatpak, but aren't otherwise used or parsed. This merely grants the permission to enumerate USB device for use by the portal. This does give access to the devices. Available since 1.15.11. β οΈ
enumerable-devices(string list) β List of enumerable USB devices. Each element is the same syntax the arguments to--usb. Available since1.15.11. πhidden-devices(string list) β List of hidden USB devices, i.e. to remove the enumerable devices list. Each element is the same syntax the arguments to--nousb. Hidden devices take precedence over enumerable devices. Available since1.15.11. π
EXAMPLE π
[Application]
name=org.gnome.Calculator
runtime=org.gnome.Platform/x86_64/3.20
sdk=org.gnome.Sdk/x86_64/3.20
command=gnome-calculator
[Context]
shared=network;ipc;
sockets=x11;wayland;
filesystems=xdg-run/dconf;~/.config/dconf:ro;
[Session Bus Policy]
ca.desrt.dconf=talk
[Environment]
DCONF_USER_CONFIG_DIR=.config/dconf
[USB Devices]
enumerable-devices=0fd9:*;
hidden-devices=0fd9:0063;
[Extension org.gnome.Calculator.Locale]
directory=share/runtime/locale
subdirectories=true
[Extension org.gnome.Calculator.Debug]
directory=lib/debug
Example using conditional permissions to support fallback from Wayland to X11:
[Application]
name=org.example.App
runtime=org.gnome.Platform/x86_64/3.20
sdk=org.gnome.Sdk/x86_64/3.20
[Context]
shared=network;ipc;
sockets=wayland;x11;if:x11:!has-wayland;
In this example, the application will always have access to the Wayland socket if the app runs in a Wayland session. The X11 socket only is available if the app does not run in a wayland session (!has-wayland). πͺ
SEE ALSO π
NOTES π
openat2()β https://man7.org/linux/man-pages/man2/openat2.2.htmlsteam-runtime-toolsβ https://gitlab.steamos.cloud/steamrt/steam-runtime-tools/-/blob/65adfdd5fc812aeb5f33986755f6ff72c9612afa/steam-runtime-tools/resolve-in-sysroot.c- freedesktop.org special directories β https://www.freedesktop.org/wiki/Software/xdg-user-dirs/
- freedesktop.org Base Directory Specification β https://specifications.freedesktop.org/basedir-spec/basedir-spec-latest.html
Source/version: flatpak; section: FLATPAK METADATA(5); date: the manpage date, bestie. That's the whole vibe. Bye! ππ«Άβ¨
π¦ where this page comes from
- fedora 44: flatpak 1.18.4-1.fc44 Β· LGPL-2.1-or-later
- fedora 44: flatpak 1.18.4-1.fc44 Β· LGPL-2.1-or-later
- nixpkgs unstable: flatpak 1.18.4
- ubuntu stonking: flatpak 1.18.4-1
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms