.. _NXEP0:

============================
NXEP 0 — Purpose and Process
============================

:Author: Jarrod Millman <millman@berkeley.edu>
:Status: Draft
:Type: Process
:Created: 2020-06-25


What is a NXEP?
---------------


NXEP stands for NetworkX Enhancement Proposal.  NXEPs are the primary
mechanisms for proposing major new features, for collecting community input on
an issue, and for documenting the design decisions that have gone into
NetworkX.  A NXEP should provide a concise technical specification of the
feature and a rationale for the feature.  The NXEP author is responsible for
building consensus within the community and documenting dissenting opinions.

Because the NXEPs are maintained as text files in a versioned
repository, their revision history is the historical record of the
feature proposal [1]_.


Types
^^^^^

There are three kinds of NXEPs:

1. A **Standards Track** NXEP describes a new feature or implementation
   for NetworkX.

2. An **Informational** NXEP describes a NetworkX design issue, or provides
   general guidelines or information to the Python community, but does not
   propose a new feature. Informational NXEPs do not necessarily represent a
   NetworkX community consensus or recommendation, so users and implementers are
   free to ignore Informational NXEPs or follow their advice.

3. A **Process** NXEP describes a process surrounding NetworkX, or
   proposes a change to (or an event in) a process.  Process NXEPs are
   like Standards Track NXEPs but apply to areas other than the NetworkX
   language itself.  They may propose an implementation, but not to
   NetworkX's codebase; they require community consensus.  Examples include
   procedures, guidelines, changes to the decision-making process, and
   changes to the tools or environment used in NetworkX development.
   Any meta-NXEP is also considered a Process NXEP.


NXEP Workflow
-------------

The NXEP process begins with a new idea for NetworkX.  It is highly
recommended that a single NXEP contain a single key proposal or new
idea. Small enhancements or patches often don't need
a NXEP and can be injected into the NetworkX development workflow with a
pull request to the NetworkX `repo`_. The more focused the
NXEP, the more successful it tends to be.
If in doubt, split your NXEP into several well-focused ones.

Each NXEP must have a champion---someone who writes the NXEP using the style
and format described below, shepherds the discussions in the appropriate
forums, and attempts to build community consensus around the idea.  The NXEP
champion (a.k.a. Author) should first attempt to ascertain whether the idea is
suitable for a NXEP. Posting to the networkx-discussion `mailing list`_ is the best
way to go about doing this.

The proposal should be submitted as a draft NXEP via a `GitHub pull
request`_ to the ``doc/nxeps`` directory with the name ``nxep-<n>.rst``
where ``<n>`` is an appropriately assigned four-digit number (e.g.,
``nxep-0000.rst``). The draft must use the :doc:`nxep-template` file.

Once the PR for the NXEP is in place, a post should be made to the
mailing list containing the sections up to "Backward compatibility",
with the purpose of limiting discussion there to usage and impact.
Discussion on the pull request will have a broader scope, also including
details of implementation.

At the earliest convenience, the PR should be merged (regardless of
whether it is accepted during discussion).  Additional PRs may be made
by the Author to update or expand the NXEP, or by maintainers to set
its status, discussion URL, etc.

Standards Track NXEPs consist of two parts, a design document and a
reference implementation.  It is generally recommended that at least a
prototype implementation be co-developed with the NXEP, as ideas that sound
good in principle sometimes turn out to be impractical when subjected to the
test of implementation.  Often it makes sense for the prototype implementation
to be made available as PR to the NetworkX repo (making sure to appropriately
mark the PR as a WIP).


Review and Resolution
^^^^^^^^^^^^^^^^^^^^^

NXEPs are discussed on the mailing list.  The possible paths of the
status of NXEPs are as follows:

.. image:: _static/nxep-0000.png

All NXEPs should be created with the ``Draft`` status.

Eventually, after discussion, there may be a consensus that the NXEP
should be accepted – see the next section for details. At this point
the status becomes ``Accepted``.

Once a NXEP has been ``Accepted``, the reference implementation must be
completed.  When the reference implementation is complete and incorporated
into the main source code repository, the status will be changed to ``Final``.

To allow gathering of additional design and interface feedback before
committing to long term stability for a language feature or standard library
API, a NXEP may also be marked as "Provisional". This is short for
"Provisionally Accepted", and indicates that the proposal has been accepted for
inclusion in the reference implementation, but additional user feedback is
needed before the full design can be considered "Final". Unlike regular
accepted NXEPs, provisionally accepted NXEPs may still be Rejected or Withdrawn
even after the related changes have been included in a Python release.

Wherever possible, it is considered preferable to reduce the scope of a
proposal to avoid the need to rely on the "Provisional" status (e.g. by
deferring some features to later NXEPs), as this status can lead to version
compatibility challenges in the wider NetworkX ecosystem.

A NXEP can also be assigned status ``Deferred``.  The NXEP author or a
core developer can assign the NXEP this status when no progress is being made
on the NXEP.

A NXEP can also be ``Rejected``.  Perhaps after all is said and done it
was not a good idea.  It is still important to have a record of this
fact. The ``Withdrawn`` status is similar---it means that the NXEP author
themselves has decided that the NXEP is actually a bad idea, or has
accepted that a competing proposal is a better alternative.

When a NXEP is ``Accepted``, ``Rejected``, or ``Withdrawn``, the NXEP should be
updated accordingly. In addition to updating the status field, at the very
least the ``Resolution`` header should be added with a link to the relevant
thread in the mailing list archives.

NXEPs can also be ``Superseded`` by a different NXEP, rendering the
original obsolete.  The ``Replaced-By`` and ``Replaces`` headers
should be added to the original and new NXEPs respectively.

Process NXEPs may also have a status of ``Active`` if they are never
meant to be completed, e.g. NXEP 0 (this NXEP).


How a NXEP becomes Accepted
^^^^^^^^^^^^^^^^^^^^^^^^^^^

A NXEP is ``Accepted`` by consensus of all interested contributors. We
need a concrete way to tell whether consensus has been reached. When
you think a NXEP is ready to accept, send an email to the
networkx-discussion mailing list with a subject like:

  Proposal to accept NXEP #<number>: <title>

In the body of your email, you should:

* link to the latest version of the NXEP,

* briefly describe any major points of contention and how they were
  resolved,

* include a sentence like: "If there are no substantive objections
  within 7 days from this email, then the NXEP will be accepted; see
  NXEP 0 for more details."

For an example, see: https://mail.python.org/pipermail/networkx-discussion/2018-June/078345.html

After you send the email, you should make sure to link to the email
thread from the ``Discussion`` section of the NXEP, so that people can
find it later.

Generally the NXEP author will be the one to send this email, but
anyone can do it – the important thing is to make sure that everyone
knows when a NXEP is on the verge of acceptance, and give them a final
chance to respond. If there's some special reason to extend this final
comment period beyond 7 days, then that's fine, just say so in the
email. You shouldn't do less than 7 days, because sometimes people are
travelling or similar and need some time to respond.

In general, the goal is to make sure that the community has consensus,
not provide a rigid policy for people to try to game. When in doubt,
err on the side of asking for more feedback and looking for
opportunities to compromise.

If the final comment period passes without any substantive objections,
then the NXEP can officially be marked ``Accepted``. You should send a
followup email notifying the list (celebratory emoji optional but
encouraged 🎉✨), and then update the NXEP by setting its ``:Status:``
to ``Accepted``, and its ``:Resolution:`` header to a link to your
followup email.

If there *are* substantive objections, then the NXEP remains in
``Draft`` state, discussion continues as normal, and it can be
proposed for acceptance again later once the objections are resolved.

In unusual cases, disagreements about the direction or approach may
require escalation to the NetworkX :ref:`steering_council` who
then decide whether a controversial NXEP is ``Accepted``.


Maintenance
^^^^^^^^^^^

In general, Standards track NXEPs are no longer modified after they have
reached the Final state as the code and project documentation are considered
the ultimate reference for the implemented feature.
However, finalized Standards track NXEPs may be updated as needed.

Process NXEPs may be updated over time to reflect changes
to development practices and other details. The precise process followed in
these cases will depend on the nature and purpose of the NXEP being updated.


Format and Template
-------------------

NXEPs are UTF-8 encoded text files using the reStructuredText_ format.  Please
see the :doc:`nxep-template` file and the reStructuredTextPrimer_ for more
information.  We use Sphinx_ to convert NXEPs to HTML for viewing on the web
[2]_.


Header Preamble
^^^^^^^^^^^^^^^

Each NXEP must begin with a header preamble.  The headers
must appear in the following order.  Headers marked with ``*`` are
optional.  All other headers are required. ::

    :Author: <list of authors' real names and optionally, email addresses>
    :Status: <Draft | Active | Accepted | Deferred | Rejected |
             Withdrawn | Final | Superseded>
    :Type: <Standards Track | Process>
    :Created: <date created on, in dd-mmm-yyyy format>
  * :Requires: <nxep numbers>
  * :NetworkX-Version: <version number>
  * :Replaces: <nxep number>
  * :Replaced-By: <nxep number>
  * :Resolution: <url>

The Author header lists the names, and optionally the email addresses
of all the authors of the NXEP.  The format of the Author header
value must be

    Random J. User <address@dom.ain>

if the email address is included, and just

    Random J. User

if the address is not given.  If there are multiple authors, each should be on
a separate line.


References and Footnotes
------------------------

.. [1] This historical record is available by the normal git commands
   for retrieving older revisions, and can also be browsed on
   `GitHub <https://github.com/networkx/networkx/tree/main/doc/developer/nxeps>`_.

.. [2] The URL for viewing NXEPs on the web is
   https://networkx.org/documentation/latest/developer/nxeps/index.html

.. _repo: https://github.com/networkx/networkx

.. _mailing list: https://groups.google.com/group/networkx-discuss/

.. _issue tracker: https://github.com/networkx/networkx/issues

.. _`GitHub pull request`: https://github.com/networkx/networkx/pulls

.. _reStructuredText: http://docutils.sourceforge.net/rst.html

.. _reStructuredTextPrimer: http://www.sphinx-doc.org/en/stable/rest.html

.. _Sphinx: http://www.sphinx-doc.org/en/stable/
