docs: Remove proposals (#1990)

Removes the proposals. Most of them are either implemented already, or
no longer relevant. The maintainers have not used in-repo proposals for
a number of years, so I don't think it will be a big loss to delete
these.
diff --git a/proposals/2018-10-25-selecting-between-python-2-and-3.md b/proposals/2018-10-25-selecting-between-python-2-and-3.md
deleted file mode 100644
index e731f97..0000000
--- a/proposals/2018-10-25-selecting-between-python-2-and-3.md
+++ /dev/null
@@ -1,136 +0,0 @@
----
-title: Selecting Between Python 2 and 3
-status: Accepted
-created: 2018-10-25
-updated: 2019-01-11
-authors:
-  - [brandjon@](https://github.com/brandjon)
-reviewers:
-  - [mrovner@](https://github.com/mrovner)
-discussion thread: [bazel #6583](https://github.com/bazelbuild/bazel/issues/6583)
----
-
-# Selecting Between Python 2 and 3
-
-## Abstract
-
-The "Python mode" configuration value controls whether Python 2 or Python 3 is used to run Python targets built by Bazel. This design document reviews the existing mechanisms for setting the Python mode (the "tri-state model") and describes a simplified mechanism that should replace it (the "boolean model").
-
-Links to Github issues are given where applicable. See also [bazel #6444](https://github.com/bazelbuild/bazel/issues/6444) for a tracking list of Python mode issues.
-
-Throughout, when we say `py_binary`, we also mean to include `py_test`.
-
-## Background
-
-The Python mode controls whether a Python 2 or 3 interpreter is used to run a `py_binary` that is built by Bazel.
-
-* When no `py_runtime` is supplied (via `--python_top`), the mode should control whether the command `python2` or `python3` is embedded into the generated wrapper script ([bazel #4815](https://github.com/bazelbuild/bazel/issues/4815)).
-
-* In a future design for a "`py_toolchain`"-type rule, a pair of interpreter targets will be bundled together as a toolchain, and the mode will control which one gets their full path embedded into this script.
-
-The Python mode is also used to help validate that Python source code annotated with `srcs_version` is used appropriately: If a Python target has the `srcs_version` attribute set to `PY2` or `PY3` rather than to `PY2AND3` (the default), it can only be depended on by targets built in Python 2 or Python 3 mode respectively.
-
-Whenever the same Bazel target can be built in multiple configurations within a single build, it is necessary to write the output artifacts of different versions of the target to different paths. Otherwise the build fails with an "action conflict" error -- Bazel's way of avoiding a correctness bug. For Python targets, and more broadly for targets that may transitively depend on Python targets, this means that different output path roots must be used for different Python modes.
-
-## Out-of-scope generalizations
-
-It is possible to imagine extending the Python mode and `srcs_version` so that it can check for compatibility with minor releases (ex: "Python 3.7"), patch releases ("Python 3.7.1"), alternative interpreters ("CPython" or "PyPy"), and exclude known bad releases. We decline to do so because this treads into generalized constraint checking, which may be better handled in the future by the [platforms and toolchain framework](https://docs.bazel.build/versions/master/toolchains.html).
-
-Compared to these other kinds of version checks, Python 2 vs. 3 is a more compelling use case to support with dedicated machinery. The incompatibilities between these versions are more severe. In many code bases there is an ongoing effort to migrate from 2 to 3, while in others there exists Python 2 code that will never be migrated and must be supported indefinitely.
-
-## Tri-state model
-
-Under the existing tri-state model, the Python mode can take on three values: `PY2`, `PY3`, and `null`. The first two modes can be triggered by the `--force_python` flag on the command line or by the `default_python_version` attribute on `py_binary` rules. The `null` mode is the default state when neither the flag nor `default_python_version` is specified. `select()` expressions can distinguish between these states by using `config_setting`s that test the value of `force_python` (where `null` is matched by `//conditions:default`).
-
-The Python mode is "sticky"; once it is set to `PY2` or `PY3`, it stays that way for all subsequent targets. For a `py_binary` target, this means that all transitive dependencies of the target are built with the same mode as the target itself. For the `--force_python` flag, this means that if the flag is given, it applies universally to the entire build invocation, regardless of the `default_python_version` attributes of any Python targets (hence the "default" in the attribute's name).
-
-### Data dependencies
-
-In principle the Python mode needs to propagate to any `py_library` targets that are transitively in the `deps` attribute. Conceptually, this corresponds to enforcing that a Python binary cannot `import` a module written for a different version of Python than the currently running interpreter. But there is no need to propagate the mode across the `data` attribute, which often corresponds to one Python binary calling another as a separate process.
-
-In order to facilitate `PY3` binaries that depend on `PY2` ones and vice versa, the tri-state model needs to be modified so that the mode is reset to `null` for `data` attributes ([bazel #6441](https://github.com/bazelbuild/bazel/issues/6441)). But it's not clear exactly which attributes should trigger a reset. For example, suppose a Python source file is generated by a `genrule`: Then the `genrule` shouldn't propagate any Python mode to any of its attributes, even though it appears in the transitive closure of a `py_binary`'s `deps`. One could imagine resetting the mode across every attribute except those in a small whitelist (`deps` of `py_binary`, `py_test`, and `py_library`), but this would require new functionality in Bazel and possibly interact poorly with Starlark-defined rules.
-
-### Output roots
-
-Since targets that are built for Python 3 produce different results than those built for Python 2, the outputs for these two configurations must be kept separate in order to avoid action conflicts. Therefore, targets built in `PY3` mode get placed under an output root that includes the string "`-py3`".
-
-Currently, targets that are built in the `null` mode default to using Python 2. Counterintuitively, there is a subtle distinction between building a target in `null` mode and `PY2` mode: Even though the same interpreter is used for the top-level target, the target's transitive dependencies may behave differently, for instance if a `select()` on `force_python` is used. This means that using both `PY2` and `null` for the same target can result in action conflicts ([bazel #6501](https://github.com/bazelbuild/bazel/issues/6501)). However, due to a bug it is not yet possible to have both `PY2` and `null` modes within the same build invocation.
-
-Under the tri-state model, the most straightforward solution for these action conflicts is to use a separate "`-py2`" root for `PY2` mode. This would mean that the same target could be built in not two but three different configurations, corresponding to the three different modes, even though there are only two distinct Python versions. A more complicated alternative would be to prohibit `select()` from being able to distinguish `null` from `PY2`, in order to help ensure that building an arbitrary target in both of these modes does not succeed with different results.
-
-### Libraries at the top level
-
-Currently the mode is only changed by `--force_python` and by `py_binary`. This means that when you build a `py_library` at the top level (that is, specifying it directly on the build command line) without a `--force_python` flag, the library gets the `null` mode, which means Python 2 by default. This causes an error if the library has `srcs_python` set to `PY3`. This in turn means you cannot run a flagless build command on a wildcard pattern, such as `bazel build :all` or `bazel build ...`, if any of the targets in the package(s) contains a Python 3-only library target. Worse, if there are both a Python 2-only library and a Python 3-only library, even specifying `--force_python` can't make the wildcard build work.
-
-In the tri-state model, this can be addressed by allowing `py_library` to change the mode from `null` to either `PY2` or `PY3` based on whichever version is compatible with its `srcs_version` attribute. This was a proposed fix for [bazel #1446](https://github.com/bazelbuild/bazel/issues/1446).
-
-## Boolean model
-
-Under the boolean model, `null` is eliminated as a valid value for the Python mode. Instead, the mode will immediately default to either `PY2` or `PY3`. The mode is no longer sticky, but changes as needed whenever a new `py_binary` target is reached.
-
-Since there is no longer a third value corresponding to "uncommitted", a target can no longer tell whether it was set to `PY2` mode explicitly (by a flag or a `py_binary`), or if it was set by default because no mode was specified. The current version will be inspectable using `config_setting` to read a setting whose value is always one of `"PY2"` or `"PY3"`.
-
-### Data dependencies
-
-Since `py_binary` will now change the mode as needed, there is no need to explicitly reset the mode to a particular value (`null`) when crossing `data` attributes. Python 3 targets can freely depend on Python 2 targets and vice versa, so long as the dependency is not via the `deps` attribute in a way that violates `srcs_version` validation (see below).
-
-### Output roots
-
-Since there are only two modes, there need only be two output roots. This avoids action conflicts without resorting to creating a redundant third output root, or trying to coerce two similar-but-distinct modes to map onto the same output root.
-
-Since the mode is not being reset across data dependencies, it is possible that compared to the tri-state model, the boolean model causes some data dependencies to be built in two configurations instead of just one. This is considered to be an acceptable tradeoff of the boolean model. Note that there exist other cases where redundant rebuilding occurs regardless of which model we use.
-
-### Libraries at the top level
-
-We want to be able to build a `py_library` at the top level without having to specify the correct mode. At the same time, we still want `srcs_version` to validate that a `py_binary` only depends on `py_library`s that are compatible with its mode. The way to achieve this is to move validation from within the `py_library` rule up to the `py_binary` rule.
-
-We add two new boolean fields to a provider returned by `py_library`. This bools correspond to whether or not there are any Python 2-only and Python 3-only sources (respectively) in the library's transitive closure. It is easy to compute these bits as boolean ORs as the providers are merged. `py_binary` simply checks these bits against its own Python mode.
-
-It is important that when `py_binary` detects a version conflict, the user is given the label of one or more transitive dependencies that introduced the constraint. There are several ways to implement this, such as:
-
-- additional provider fields to propagate context to the error message
-- an aspect that traverses the dependencies of the `py_binary`
-- emitting warning messages at conflicting `py_library` targets
-
-The choice of which approach to use is outside the scope of this proposal.
-
-It is possible that a library is only ever used by Python 3 binaries, but when the library is built as part of a `bazel build :all` command it gets the Python 2 mode by default. This happens even if the library is annotated with `srcs_version` set to `PY3`. Generally this should cause no harm aside from some repeated build work. In the future we can add the same version attribute that `py_binary` has to `py_library`, so the target definition can be made unambiguous.
-
-Aside from failures due to validation, there is currently a bug whereby building a `PY2` library in `PY3` mode can invoke a stub wrapper that fails ([bazel #1393](https://github.com/bazelbuild/bazel/issues/1393)). We will remove the stub and the behavior that attempted to call it.
-
-## API changes
-
-The attribute `default_python_version` of `py_binary` is renamed to `python_version`. The flag `--force_python` is renamed to `--python_version`. (An alternative naming scheme would have been to use "python_major_version", but this is more verbose and inconsistent with `srcs_version`.)
-
-The Python mode becomes "non-sticky" and `srcs_version` validation becomes less strict. Building a `py_library` target directly will not trigger validation. Building a `py_binary` that depends on a `py_library` having an incompatible version will only fail if the dependency occurs via transitive `deps`, and not when it occurs via other paths such as a `data` dep or a `genrule` that produces a source file.
-
-The `"py"` provider of Python rules gains two new boolean fields, `has_py2_only_sources` and `has_py3_only_sources`. Existing Python rules are updated to set these fields. Dependencies of Python rules that do not have the `"py"` provider, or those fields on that provider, are treated as if the value of the fields is `False`.
-
-A new `select()`-able target is created at `@bazel_tools//tools/python:python_version` to return the current Python mode. It can be used in the `flag_values` attribute of `config_setting` and always equals either `"PY2"` or `"PY3"`. (In the future this flag may be moved out of `@bazel_tools` and into `bazelbuild/rules_python`. It may also be made into a `build_setting` so that it can replace the native `--python_version` flag.) It is disallowed to use `"python_version"` in a `config_setting`.
-
-The flag `--host_force_python` is unaffected by this doc, except that it becomes illegal to use it in a `config_setting`.
-
-## Migration and compatibility
-
-The rollout and migration of the new features are split into two groups, syntactic and semantic.
-
-For syntax, the new `--python_version` flag and `python_version` attribute are available immediately, and behave exactly the same as the old flag and attribute. When both the new and old flags are present on the command line, or both the new and old attributes are present on the same target, the new one takes precedence and the old is ignored. The `@bazel_tools//tools/python:python_version` target is also available unconditionally.
-
-A migration flag `--incompatible_remove_old_python_version_api` makes unavailable the `--force_python` flag and `default_python_version` attribute, and disallows `select()`-ing on `"force_python"` and `"host_force_python"`.
-
-For semantics, a flag `--incompatible_allow_python_version_transitions` makes Bazel use the new non-sticky version transitions and the deferred `srcs_version` validation. This applies regardless of whether the new or old API is used to specify the Python version. The new `"py"` provider fields are created regardless of which flags are given.
-
-Migrating for `--incompatible_remove_old_python_version_api` guarantees that the Python version only ever has two possible values. Migrating for `--incompatible_allow_python_version_transitions` enables data dependencies across different versions of Python. It is recommended to do the API migration first in order to avoid action conflicts.
-
-Strictly speaking, Python 3 support is currently marked "experimental" in documentation, so in theory we may be able to make these changes without introducing new incompatible and experimental flags. However these changes will likely affect many users of the Python rules, so flags would be more user-friendly. Bazel is also transitioning to a policy wherein all experimental APIs must be flag-guarded, regardless of any disclaimers in their documentation.
-
-## Changelog
-
-Date         | Change
------------- | ------
-2018-10-25   | Initial version
-2018-11-02   | Refine migration path
-2018-12-17   | Refine plan for `select()`
-2018-12-19   | Refine plan for `select()` again
-2019-01-10   | Refine migration path
-2019-01-11   | Formal approval and update provider fields
diff --git a/proposals/2018-11-08-customizing-the-python-stub-template.md b/proposals/2018-11-08-customizing-the-python-stub-template.md
deleted file mode 100644
index 5b9d878..0000000
--- a/proposals/2018-11-08-customizing-the-python-stub-template.md
+++ /dev/null
@@ -1,47 +0,0 @@
----
-title: Customizing the Python Stub Template
-status: Draft, not yet ready for review
-created: 2018-11-08
-updated: 2018-11-09
-authors:
-  - [brandjon@](https://github.com/brandjon)
-reviewers:
-  - [gpshead@](https://github.com/gpshead)
-discussion thread: [bazel #137](https://github.com/bazelbuild/bazel/issues/137)
----
-
-# Customizing the Python Stub Template
-
-## Abstract
-
-This design document proposes a way to use a different Python stub template, so that users can control how the Python interpreter gets invoked to run their targets.
-
-**Open questions:** It is not currently clear whether the use cases warrant this kind of expressivity, or whether users can get by with smaller, more narrowly focused ways of parameterizing the existing stub template. The exact stub API is also to be determined.
-
-## Background
-
-The usual executable artifact of a `py_binary` rule is a Python stub script. This script manipulates the Python environment to set up the module import path and make the runfiles available, before passing control to the underlying user Python program. The stub script is generated from a [stub template](https://github.com/bazelbuild/bazel/blob/ef0024b831a71521390dcb837b24b86485e5998d/src/main/java/com/google/devtools/build/lib/bazel/rules/python/python_stub_template.txt) by [instantiating some placeholders](https://github.com/bazelbuild/bazel/blob/ef0024b831a71521390dcb837b24b86485e5998d/src/main/java/com/google/devtools/build/lib/bazel/rules/python/BazelPythonSemantics.java#L152-L159).
-
-Generally the Python stub and user program is executed using the system Python interpreter of the target platform. Although this is non-hermetic, the details of the interpreter can be reified by a [`py_runtime`](https://docs.bazel.build/versions/master/be/python.html#py_runtime) target. In the future this will allow for platform-aware selection of an appropriate Python interpreter using the [toolchain](https://docs.bazel.build/versions/master/toolchains.html) framework.
-
-## Proposal
-
-A new `Label`-valued attribute, `stub_template`, is added to `py_runtime`. This label points to a file; by default it is `//tools/python:python_stub_template.txt`, which is the renamed location of the existing template. The `py_runtime` rule will resolve this label to an `Artifact` and propagate it in a new field of [`BazelPyRuntimeProvider`](https://github.com/bazelbuild/bazel/blob/1f684e1b87cd8881a0a4b33e86ba66743e32d674/src/main/java/com/google/devtools/build/lib/bazel/rules/python/BazelPyRuntimeProvider.java). [`BazelPythonSemantics#createExecutable`](https://github.com/bazelbuild/bazel/blob/ef0024b831a71521390dcb837b24b86485e5998d/src/main/java/com/google/devtools/build/lib/bazel/rules/python/BazelPythonSemantics.java#L130) will refer to this `Artifact` instead of retrieving the template as a Java resource file.
-
-It is not yet decided which template placeholders are specified, or whether the placeholders will remain an experimental API for the moment.
-
-## Original approach
-
-An earlier proposed approach (suggested on the discussion thread, and implemented by [fahhem@](https://github.com/fahhem)) was to add the `stub_template` attribute to `py_binary` rather than to `py_runtime`.
-
-This would make it trivial to customize the stub for an individual Python target without affecting the other targets in the build. This could be useful if there were a one-off target that had special requirements.
-
-However, the author believes that the stub is more naturally tied to the Python interpreter than to an individual target. Putting the attribute on `py_runtime` makes it easy to affect all Python targets that use the same interpreter. It also allows the same Python target to use different stubs depending on which interpreter it is built for -- for instance, the same target can have different stubs on different platforms.
-
-If it is necessary to use a custom stub for a particular target, that could still be achieved by making that one target use a different `py_runtime`. This isn't possible at the moment but will be when a `py_toolchain` rule is added.
-
-## Changelog
-
-Date         | Change
------------- | ------
-2018-11-08   | Initial version
diff --git a/proposals/2019-02-12-design-for-a-python-toolchain.md b/proposals/2019-02-12-design-for-a-python-toolchain.md
deleted file mode 100644
index 0d45866..0000000
--- a/proposals/2019-02-12-design-for-a-python-toolchain.md
+++ /dev/null
@@ -1,247 +0,0 @@
----
-title: Design for a Python Toolchain
-status: Accepted
-created: 2019-02-12
-updated: 2019-02-21
-authors:
-  - [brandjon@](https://github.com/brandjon)
-reviewers:
-  - [katre@](https://github.com/katre), [mrovner@](https://github.com/mrovner), [nlopezgi@](https://github.com/nlopezgi)
-discussion thread: [bazel #7375](https://github.com/bazelbuild/bazel/issues/7375)
----
-
-# Design for a Python Toolchain
-
-## Abstract
-
-This doc outlines the design of a Python toolchain rule and its associated machinery. Essentially a new `py_runtime_pair` toolchain rule is created to wrap two `py_runtime` targets (one for Python 2 and one for Python 3), thereby making runtimes discoverable via [toolchain resolution](https://docs.bazel.build/versions/master/toolchains.html). This replaces the previous mechanism of explicitly specifying a global runtime via `--python_top` or `--python_path`; those flags are now deprecated.
-
-The new toolchain-related definitions are implemented in Starlark. A byproduct of this is that the provider type for `py_runtime` is exposed to Starlark. We also add to `py_runtime` an attribute for declaring whether it represents a Python 2 or Python 3 runtime.
-
-## Motivation
-
-The goal is to make the native Python rules use the toolchain framework to resolve the Python runtime. Advantages include:
-
-* allowing each `py_binary` to use a runtime suitable for its target platform
-
-* allowing Python 2 and Python 3 targets to run in the same build without [hacks](https://github.com/bazelbuild/bazel/issues/4815#issuecomment-460777113)
-
-* making it easier to run Python-related builds under remote execution
-
-* adding support for autodetection of available system Python runtimes, without requiring ad hoc rule logic
-
-* removing `--python_top` and `--python_path`
-
-* bringing Python in line with other rule sets and Bazel's best practices
-
-**Non-goal:** This work does not allow individual `py_binary`s to directly name a Python runtime to use. Instead, this information should be worked into either the configuration or a future toolchain constraint system. See the FAQ, below.
-
-## Design
-
-### New definitions
-
-A new [toolchain type](https://docs.bazel.build/versions/master/toolchains.html#writing-rules-that-use-toolchains) is created at `@bazel_tools//tools/python:toolchain_type`. This is the type for toolchains that provide a way to run Python code.
-
-Toolchain rules of this type are expected to return a [`ToolchainInfo`](https://docs.bazel.build/versions/master/skylark/lib/ToolchainInfo.html) with two fields, `py2_runtime` and `py3_runtime`, each of type `PyRuntimeInfo`. They are used for `PY2` and `PY3` binaries respectively.
-
-```python
-def _some_python_toolchain_impl(ctx):
-    ...
-    return [platform_common.ToolchainInfo(
-        py2_runtime = PyRuntimeInfo(...),
-        py3_runtime = PyRuntimeInfo(...))]
-```
-
-If either Python 2 or Python 3 is not provided by the toolchain, the corresponding field may be set to `None`. This is strongly discouraged, as it will prevent any target relying on that toolchain from using that version of Python. Toolchains that do use `None` here should be registered with lower priority than other toolchains, so that they are chosen only as a fallback.
-
-`PyRuntimeInfo` is the newly-exposed Starlark name of the native provider returned by the [`py_runtime`](https://docs.bazel.build/versions/master/be/python.html#py_runtime) rule. Like `PyInfo`, it is a top-level built-in name. Also like `PyInfo` and the native Python rules, it will eventually be migrated to Starlark and moved out of the Bazel repository.
-
-A `PyRuntimeInfo` describes either a *platform runtime* or an *in-build runtime*. A platform runtime accesses a system-installed interpreter at a known path, whereas an in-build runtime points to a build target that acts as the interpreter. In both cases, an "interpreter" is really any executable binary or wrapper script that is capable of running a Python script passed on the command line, following the same conventions as the standard CPython interpreter. Note that any platform runtime imposes a requirement on the target platform. Therefore, any toolchain returning such a `PyRuntimeInfo` should include a corresponding target platform constraint, to ensure it cannot be selected for a platform that does not have the interpreter at that path. Even an in-build runtime can require platform constraints, for instance in the case of a wrapper script that invokes the system interpreter.
-
-We provide two [`constraint_setting`](https://docs.bazel.build/versions/master/be/platform.html#constraint_setting)s to act as a standardized namespace for this kind of platform constraint: `@bazel_tools//tools/python:py2_interpreter_path` and `@bazel_tools//tools/python:py3_interpreter_path`. This doc does not mandate any particular structure for the names of [`constraint_value`](https://docs.bazel.build/versions/master/be/platform.html#constraint_value)s associated with these settings. If a platform does not provide a Python 2 runtime, it should have no constraint value associated with `py2_interpreter_path`, and similarly for Python 3.
-
-`PyRuntimeInfo` has the following fields, each of which corresponds to an attribute on `py_runtime`. (The last one, `python_version`, is newly added in this doc.)
-
-* `interpreter_path`: If this is a platform runtime, this field is the absolute filesystem path to the interpreter on the target platform. Otherwise, this is `None`.
-
-* `interpreter`: If this is an in-build runtime, this field is a `File` representing the interpreter. Otherwise, this is `None`.
-
-* `files`: If this is an in-build runtime, this field is a depset of `File`s that need to be added to the runfiles of an executable target that uses this toolchain. The value of `interpreter` need not be included in this field. If this is a platform runtime then this field is `None`.
-
-* `python_version`: Either the string `"PY2"` or `"PY3"`, indicating which version of Python the interpreter referenced by `interpreter_path` or `interpreter` is.
-
-The constructor of `PyRuntimeInfo` takes each of these fields as keyword arguments. The constructor enforces the invariants about which combinations of fields may be `None`. Fields that are not meaningful may be omitted; e.g. when `interpreter_path` is given, `interpreter` and `files` may be omitted instead of passing `None`.
-
-It is not possible to directly specify a system command (e.g. `"python"`) in `interpreter_path`. However, this can be done indirectly by creating a wrapper script that invokes the system command, and referencing that script from the `interpreter` field.
-
-Finally, we define a standard Python toolchain rule implementing the new toolchain type. The rule's name is `py_runtime_pair` and it can be loaded from `@bazel_tools//tools/python:toolchain.bzl`. It has two label-valued attributes, `py2_runtime` and `py3_runtime`, that refer to `py_runtime` targets.
-
-### Changes to the native Python rules
-
-The executable Python rules [`py_binary`](https://docs.bazel.build/versions/master/be/python.html#py_binary) and [`py_test`](https://docs.bazel.build/versions/master/be/python.html#py_test) are modified to require the new toolchain type. The Python runtime information is obtained by retrieving a `PyRuntimeInfo` from either the `py2_runtime` or `py3_runtime` field of the toolchain, rather than from `--python_top`. The `python_version` field of the `PyRuntimeInfo` is also checked to ensure that a `py_runtime` didn't accidentally end up in the wrong place.
-
-Since `--python_top` is no longer read, it is deprecated. Since `--python_path` was only read when no runtime information is available, but the toolchain must always be present, it too is deprecated.
-
-Implementation wise, the native `PyRuntimeProvider` is turned into the user-visible `PyRuntimeInfo` by adding Starlark API annotations in the usual way (`@SkylarkCallable`, etc.). A previous version of this proposal suggested defining `PyRuntimeInfo` in Starlark underneath `@bazel_tools` and accessing it from the native rules, but this is technically difficult to implement.
-
-A `python_version` attribute is added to `py_runtime`. It is mandatory and accepts values `"PY2"` and `"PY3"` only.
-
-As a drive-by cleanup (and non-breaking change), the `files` attribute of `py_runtime` is made optional. For the non-hermetic case, specifying `files` is nonsensical and it is even an error to give it a non-empty value. For the hermetic case, `files` can be useful but is by no means necessary if the interpreter requires no additional in-repo inputs (such as when the "interpreter" is just a wrapper script that dispatches to the platform's system interpreter).
-
-### Default toolchain
-
-For convenience, we supply a predefined [toolchain](https://docs.bazel.build/versions/master/be/platform.html#toolchain) of last resort, `@bazel_tools//tools/python:autodetecting_python_toolchain`. This toolchain is registered with lower priority than any user-registered Python toolchain. It simply dispatches to a wrapper script that tries to locate a suitable interpreter from `PATH` at runtime, on a best-effort basis. It has no platform constraints.
-
-## Example
-
-Here is a minimal example that defines a platform whose Python interpreters are located under a non-standard path. The example also defines a Python toolchain to accompany this platform.
-
-```python
-# //platform_defs:BUILD
-
-load("@bazel_tools//tools/python:toolchain.bzl", "py_runtime_pair")
-
-# Constraint values that represent that the system's "python2" and "python3"
-# executables are located under /usr/weirdpath.
-
-constraint_value(
-    name = "usr_weirdpath_python2",
-    constraint_setting = "@bazel_tools//tools/python:py2_interpreter_path",
-)
-
-constraint_value(
-    name = "usr_weirdpath_python3",
-    constraint_setting = "@bazel_tools//tools/python:py3_interpreter_path",
-)
-
-# A definition of a platform whose Python interpreters are under these paths.
-
-platform(
-    name = "my_platform",
-    constraint_values = [
-        ":usr_weirdpath_python2",
-        ":usr_weirdpath_python3",
-    ],
-)
-
-# Python runtime definitions that reify these system paths as BUILD targets.
-
-py_runtime(
-    name = "my_platform_py2_runtime",
-    interpreter_path = "/usr/weirdpath/python2",
-)
-
-py_runtime(
-    name = "my_platform_py3_runtime",
-    interpreter_path = "/usr/weirdpath/python3",
-)
-
-py_runtime_pair(
-    name = "my_platform_runtimes",
-    py2_runtime = ":my_platform_py2_runtime",
-    py3_runtime = ":my_platform_py3_runtime",
-)
-
-# A toolchain definition to expose these runtimes to toolchain resolution.
-
-toolchain(
-    name = "my_platform_python_toolchain",
-    # Since the Python interpreter is invoked at runtime on the target
-    # platform, there's no need to specify execution platform constraints here.
-    target_compatible_with = [
-        # Make sure this toolchain is only selected for a target platform that
-        # advertises that it has interpreters available under /usr/weirdpath.
-        ":usr_weirdpath_python2",
-        ":usr_weirdpath_python3",
-    ],
-    toolchain = ":my_platform_runtimes",
-    toolchain_type = "@bazel_tools//tools/python:toolchain_type",
-)
-```
-
-```python
-# //pkg:BUILD
-
-# An ordinary Python target to build.
-py_binary(
-    name = "my_pybin",
-    srcs = ["my_pybin.py"],
-    python_version = "PY3",
-)
-```
-
-```python
-# WORKSPACE
-
-# Register the custom Python toolchain so it can be chosen for my_platform.
-register_toolchains(
-    "//platform_defs:my_platform_python_toolchain",
-)
-```
-
-We can then build with
-
-```
-bazel build //pkg:my_pybin --platforms=//platform_defs:my_platform
-```
-
-and thanks to toolchain resolution, the resulting executable will automatically know to use the interpreter located at `/usr/weirdpath/python3`.
-
-If we had not defined a custom toolchain, then we'd be stuck with `autodetecting_python_toolchain`, which would fail at execution time if `/usr/weirdpath` were not on `PATH`. (It would also be slightly slower since it requires an extra invocation of the interpreter at execution time to confirm its version.)
-
-## Backward compatibility
-
-The new `@bazel_tools` definitions and the `PyRuntimeInfo` provider are made available immediately. A new flag, `--incompatible_use_python_toolchains`, is created to assist migration. When the flag is enabled, `py_binary` and `py_test` will use the `PyRuntimeInfo` obtained from the toolchain, instead of the one obtained from `--python_top` or the default information in `--python_path`. In addition, when `--incompatible_use_python_toolchains` is enabled it is an error to set the following flags: `--python_top`, `--python_path`, `--python2_path`, `--python3_path`. (The latter two were already deprecated.) These flags will be deleted when the incompatible flag is removed.
-
-Because of how the toolchain framework is implemented, it is not possible to gate whether a rule requires a toolchain type based on a flag. Therefore `py_binary` and `py_test` are made to require `@bazel_tools//tools/python:toolchain_type` immediately and unconditionally. This may impact how toolchain resolution determines the toolchains and execution platforms for a given build, but should not otherwise cause problems so long as the build uses constraints correctly.
-
-The new `python_version` attribute is added to `py_runtime` immediately. Its default value is the same as the `python_version` attribute for `py_binary`, i.e. `PY3` if `--incompatible_py3_is_default` is true and `PY2` otherwise. When `--incompatible_use_python_toolchains` is enabled this attribute becomes mandatory.
-
-## FAQ
-
-#### How can I force a `py_binary` to use a given runtime, say for a particular minor version of Python?
-
-This is not directly addressed by this doc. Note that such a system could be used not just for controlling the minor version of the interpreter, but also to choose between different Python implementations (CPython vs PyPy), compilation modes (optimized, debug), an interpreter linked with a pre-selected set of extensions, etc.
-
-There are two possible designs.
-
-The first design is to put this information in the configuration, and have the toolchain read the configuration to decide which `PyRuntimeInfo` to return. We'd use Starlark Build Configurations to define a flag to represent the Python minor version, and transition the `py_binary` target's configuration to use this version. This configuration would be inherited by the resolved toolchain just like any other dependency inherits its parents configuration. The toolchain could then use a `select()` on the minor version flag to choose which `py_runtime` to depend on.
-
-There's one problem: Currently all toolchains are analyzed in the host configuration. It is expected that this will be addressed soon.
-
-We could even migrate the Python major version to use this approach. Instead of having two different `ToolchainInfo` fields, `py2_runtime` and `py3_runtime`, we'd have a single `py_runtime` field that would be populated with one or the other based on the configuration. (It's still a good idea to keep them as separate attributes in the user-facing toolchain rule, i.e. `py_runtime_pair`, because it's a very common use case to require both major versions of Python in a build. But note that this causes both runtimes to be analyzed as dependencies, even if the whole build uses only one or the other.)
-
-The second design for controlling what runtime is chosen is to introduce additional constraints on the toolchain, and let toolchain resolution solve the problem. However, currently toolchains only support constraints on the target and execution platforms, and this is not a platform-related constraint. What would be needed is a per-target semantic-level constraint system.
-
-The second approach has the advantage of allowing individual runtimes to be registered independently, without having to combine them into a massive `select()`. But the first approach is much more feasible to implement in the short-term.
-
-#### Why `py_runtime_pair` as opposed to some other way of organizing multiple Python runtimes?
-
-Alternatives might include a dictionary mapping from version identifiers to runtimes, or a list of runtimes paired with additional metadata.
-
-The `PY2`/`PY3` dichotomy is already baked into the Python rule set and indeed the Python ecosystem at large. Keeping this concept in the toolchain rule serves to complement, rather than complicate, Bazel's existing Python support.
-
-It will always be possible to add new toolchains, first by extending the schema of the `ToolchainInfo` accepted by the Python rules, and then by defining new user-facing toolchain rules that serve as front-ends for this provider.
-
-#### Why not split Python 2 and Python 3 into two separate toolchain types?
-
-The general pattern for rule sets seems to be to have a single toolchain type representing all of a language's concerns. Case in point: The naming convention for toolchain types is to literally name the target "toolchain_type", and let the package path distinguish its label.
-
-If the way of categorizing Python runtimes changes in the future, it will probably be easier to migrate rules to use a new provider schema than to use a new set of toolchain types.
-
-#### How does the introduction of new symbols to `@bazel_tools` affect the eventual plan to migrate the Python rules to `bazelbuild/rules_python`?
-
-The new `PyRuntimeInfo` provider and `py_runtime_pair` rule would have forwarding aliases set up, so they could be accessed both from `@bazel_tools` and `rules_python` during a future migration window.
-
-Forwarding aliases would also be defined for the toolchain type and the two `constraint_setting`s. Note that aliasing `toolchain_type`s is currently broken ([#7404](https://github.com/bazelbuild/bazel/issues/7404)).
-
-In the initial implementation of this proposal, the predefined `autodetecting_python_toolchain` will be automatically registered in the user's workspace by Bazel. This follows precedent for other languages with built-in support in Bazel. Once the rules are migrated to `rules_python`, registration will not be automatic; the user will have to explicitly call a configuration helper defined in `rules_python` from their own `WORKSPACE` file.
-
-## Changelog
-
-Date         | Change
------------- | ------
-2019-02-12   | Initial version
-2019-02-14   | Make `PyRuntimeInfo` natively defined
-2019-02-15   | Clarify platform runtime vs in-build runtime
-2019-02-21   | Formal approval
diff --git a/proposals/README.md b/proposals/README.md
deleted file mode 100644
index 36a8a0b..0000000
--- a/proposals/README.md
+++ /dev/null
@@ -1,11 +0,0 @@
-# Python Rules Proposals
-
-This is an index of all design documents and proposals for Python rules, both in native code (the Bazel binary) and in Starlark (the rules_python repository). Some of these proposals are also hosted in this directory.
-
-Proposals that impact native code are also indexed by [bazelbuild/proposals](https://github.com/bazelbuild/proposals), and subject to the [Bazel design process](https://bazel.build/designs/index.html).
-
-Last updated | Status        | Title | Author(s)
------------- | ------------- | ------| ---------
-2019-02-21   | Accepted      | [Design for a Python Toolchain](https://github.com/bazelbuild/rules_python/blob/master/proposals/2019-02-12-design-for-a-python-toolchain.md) | [brandjon@](https://github.com/brandjon)
-2018-11-09   | Draft         | [Customizing the Python Stub Template](https://github.com/bazelbuild/rules_python/blob/master/proposals/2018-11-08-customizing-the-python-stub-template.md) | [brandjon@](https://github.com/brandjon)
-2019-01-11   | Accepted      | [Selecting Between Python 2 and 3](https://github.com/bazelbuild/rules_python/blob/master/proposals/2018-10-25-selecting-between-python-2-and-3.md) | [brandjon@](https://github.com/brandjon)