SEP 0 — Purpose and process#

SEP

0

Title

Purpose and process

Author

John Travers

Drafting agent

GPT-6 Astra

Status

Active

Review status

Not reviewed

Reviewers

—

Type

Process

Created

2026-09-26

Resolution

Adopted with ADR-035, 2026-09-26

Requires

—

Supersedes

—

Superseded-by

—

Implementation

—

Manual pages

—

1. What a SEP is#

A solprop Enhancement Proposal (SEP) is a design document for one major change to solprop: a new physical model, route or numerical scheme, a changed default or convention, a redesigned public interface. It states what is proposed and why, sets out the theory with its references, discusses how the change could be implemented, and says how it will be shown to work. Once accepted it is implemented on branches, in phases, and each phase appends a report to the same document. When the work is complete the SEP is archived and the manual pages it produced link to it, so that every major feature carries the record of how it was specified, built and verified.

The process follows established practice in the scientific Python community: Python’s PEPs (PEP 1, the process, and PEP 12, the template) and NumPy’s NEPs (NEP 0 and the NEP template). It differs from them in one respect: a SEP is also the record of its own implementation, because in a numerical code the decisions made while building and qualifying a feature — a tolerance, a refused case, a measured cost — matter as much as the proposal.

solprop was developed from the start from written specifications, each implemented, verified against independent references and reviewed before it merged (ADR-024). SEPs formalise that practice for an open project. They apply to new work from the adoption of this document; no SEP is written retrospectively for functionality that already exists.

2. When a SEP is needed#

A SEP is required for:

  • a new physical model or response (a nonlinearity, an ionisation rate, a material model);

  • a new propagation route, geometry, spatial decomposition or mode family;

  • a new numerical scheme: a stepper, a transform, a quadrature, a coupled flow;

  • a change to a physics default or to a convention of conventions.md;

  • a redesign of a public interface, or a change that breaks many users’ scripts;

  • a substantive change to the kernel contract (kernel-contract.md) or a new backend;

  • a change to how solprop is developed (a Process SEP, like this one).

A SEP is not needed for bug fixes, documentation, tests, refactoring, tooling and continuous integration, dependency updates, small additions to the public interface (a keyword, a helper, a statistic), or optimisations that leave results unchanged (they still need a benchmark ledger entry, benchmarks.md). Those follow the working agreement of AGENTS.md: an issue or a short agreed plan, then a pull request.

When it is unclear whether a change needs a SEP, the maintainers decide; they may ask for one on an issue or a pull request that turns out to be larger than it looked.

3. Types#

Type

For

Feature

New functionality: a model, a route, a scheme, a tool

Change

A change to existing behaviour: a default, a convention, an interface, the seam

Process

How solprop is developed, reviewed or released

4. Statuses#

Draft ──► Accepted ──► In progress ──► Final
  │           │             │
  ├──► Deferred ◄───────────┤
  ├──► Withdrawn            └──► (back to Draft for a substantial revision)
  └──► Rejected
Any status ──► Superseded (by a later SEP)

Status

Meaning

Lives in

On the roadmap

Draft

Written and under discussion; may change freely

seps/

yes, under drafts

Accepted

Agreed by the maintainers; waiting to be picked up

seps/

yes

In progress

Being implemented; at least one phase has started

seps/

yes

Final

Implemented on every backend, tested and documented

seps/archive/

no

Deferred

Not pursued for now; may return to Draft

seps/

no

Rejected

Decided against; the reasons are recorded in the SEP

seps/archive/

no

Withdrawn

Abandoned by its author

seps/archive/

no

Superseded

Replaced by a later SEP, named in the header

seps/archive/

no

Active

A Process SEP in force

seps/

no

The folder, the index and the roadmap are kept consistent with the status in the header; tests/test_seps.py checks it.

5. Roles#

  • The author is the person among the maintainers who initiated the SEP and manages it through drafting and acceptance, named in the Author field. The author is always a person.

  • Drafting agents are the AI agents, if any, that helped draft or revise the proposal. They are named with their model and version in the Drafting agent field. An agent that joins at a later revision is added with the date of that revision. A drafting agent is never the author.

  • Implementers carry out its phases. They may be the author or not, and may be people or coding agents; a phase can be picked up by a different implementer from the one before, from the SEP and its reports alone.

  • Reviewers review the proposal before acceptance and its implementation pull request. Each review of the proposal is recorded in the Reviewers field as Name (human) or Model version (AI), and the Review status field summarises them (§6, Review). The author may be one of the human reviewers.

  • The maintainers accept, reject or defer a SEP, and approve the Final status.

6. The lifecycle#

Drafting#

  1. Copy the template to docs/dev/seps/sep-NNNN-short-slug.md, taking the next free number from the index. Numbers are never reused, even for a withdrawn or rejected SEP.

  2. Fill in the header and Part I: the Author, any Drafting agent, status Draft, review status Not reviewed and Reviewers —. Leave Part II empty and start Part III with the date drafted.

  3. Add the SEP to the index table, the index’s toctree and the Draft enhancement proposals section of the roadmap, after the accepted proposals. Review the informal roadmap items in the same change: remove an item only when the SEP covers it in full; for partial coverage, link the SEP, state what it covers and retain the remaining work. Discussion of a possible future extension does not count as coverage by the proposal’s implementation scope.

  4. Open a pull request on a branch named docs/sep-NNNN-short-slug. A draft merges early — once it is coherent, not once it is agreed — so it appears in the developer documentation and can be discussed.

Revising a draft is free: edit it in place in further pull requests and add a line to Part III for each substantial revision. Update its roadmap summary and the informal items whenever its scope changes; restore work that the revised scope no longer covers.

Review#

A proposal is reviewed while it is a draft. A review is a reading of the whole of Part I against the acceptance criteria below. When a review is complete, the reviewer is added to Reviewers as Name (human) or Model version (AI), and a line goes into Part III. The AI entry names the model and version, for example Opus 5.5 (AI). Review status is one of:

Review status

Meaning

Not reviewed

No review is recorded

In review

At least one review is recorded, but not yet one human and one AI review

Reviewed

At least one human and at least one frontier AI model have reviewed it

Review in place, revise separately. A reviewer, human or AI, records findings in the SEP without rewriting Part I. The findings go in a dated subsection under Part III (for example ### AI review — 2026-10-18), as numbered points (R1, R2, …). Each point names the sections it concerns, the problem, its priority and a recommended change, with any evidence, probe or counterexample behind it. A maintainer’s decision on a point is recorded beside it. The drafting agent then answers every point in a Response to review subsection, saying what changed and where, or why a recommendation was not taken, and makes the revisions to Part I itself. This keeps the author’s text and the reviewer’s reasoning separately readable, and makes each change traceable to the point that caused it. A reviewer edits Part I directly only for trivial corrections (typos, broken links), and says so in the review.

Every SEP must be reviewed by at least one human and one frontier AI model before it is accepted. tests/test_seps.py checks that an accepted, in-progress or final SEP has review status Reviewed, and that the status agrees with the recorded reviewers.

Acceptance#

A SEP is ready to accept when:

  • the motivation names a concrete use case;

  • the theory is complete: every equation derived or cited, its approximations and range of validity stated, in the conventions of conventions.md;

  • the implementation options have been compared and one is recommended, with its place in the layers (architecture.md) and its effect on the kernel contract;

  • the verification plan names analytic solutions, limits, invariants or independent references, and says what will set each tolerance;

  • the documentation plan names the manual page, and a tutorial or worked example where appropriate;

  • the phases are defined, each independently qualified and reported;

  • the open questions are resolved, or explicitly deferred to a named phase;

  • its review status is Reviewed: at least one human and one frontier AI model have reviewed it (Review, above).

The maintainers accept a SEP in a pull request that sets the status to Accepted, fills in Resolution (the date and the pull request or discussion where it was decided), adds a line to Part III and moves the SEP from Draft enhancement proposals to Accepted enhancement proposals on the roadmap. A rejection or deferral records the reasons in the SEP, removes its proposal listing from the roadmap and restores any still-relevant informal work that it had replaced. Apply the same roadmap update on withdrawal; for supersession, reconcile the work with the replacement SEP’s scope.

From acceptance, Part I is frozen. A deviation found during implementation is recorded in the phase report (§8), not edited into the proposal. A change large enough to invalidate the proposal sends the SEP back to Draft for re-acceptance, or is made in a new SEP that supersedes it. A return to Draft moves its roadmap listing back to the draft section.

Implementation#

An implementer picks up an accepted SEP with a commit that sets the status to In progress and records, in the Implementation field, who is implementing it and the branch. Every phase is made on that one branch, feature/sep-NNNN-short-slug, which may start on top of an open pull request’s branch when pull requests are stacked behind CI. Each phase is:

  1. implemented under the rules of §7, native code in native/ with the Python backends;

  2. checked with the fast checks and the directly affected tests of AGENTS.md only;

  3. reported: the phase report (§8) is appended to Part II, and the Implementation field and Part III updated, in commits on the branch.

The SEP reaches main in one pull request, opened when its last commit sets Final (Completion). CI runs the full gate, slow and coverage lanes on it; failures are fixed by further commits on the branch. Reviewers review that pull request, and merging it is the maintainers’ approval. Phases may be taken by different implementers, one after another on the branch.

Completion#

A SEP becomes Final when:

  • every phase is merged and reported;

  • the functionality runs on every backend (numpy_ref, numba_cpu and the native CPU build), with parity tests — or the accepted SEP records a justified exception, which then has a roadmap item;

  • the manual documents it, and each manual page it produced ends with a link to the SEP;

  • the open questions left are moved to the roadmap or to issues, and named in the last report.

The SEP’s implementation pull request sets Final in its last commit, so that merging it, which is the maintainers’ approval, completes the SEP. A separate pull request sets Final only when the evidence for it can exist only after the merge (a run of the published artefacts, for example); being documentation alone, it runs only the documentation checks in CI. The commit that sets Final fills in Manual pages, moves the file with git mv to docs/dev/seps/archive/, moves its index row to the archived table and its toctree entry to the archive index, fixes the relative links the move breaks, removes its roadmap link, and cites the SEP in the CHANGELOG.md line.

A Final SEP is a historical record. It is not updated to follow later changes to the code; the manual and the design pages describe current behaviour. Only errata and a “Superseded-by” note are added afterwards.

7. Writing and implementing a SEP#

A SEP stands alone#

A SEP is written so that a contributor, or a coding agent, who has never seen the discussion behind it could implement it from the SEP and solprop’s own documentation and code. It may refer to:

  • solprop and its native backend, solprop-native: their documentation pages, modules, tests and ADRs;

  • optmat, solprop’s companion optical-materials package: its documentation, modules and data files, cited by module or page name;

  • the scientific literature, with DOIs where they exist;

  • public reports, standards and data sources.

Apart from optmat, it does not refer to any other code’s source; nor does it refer to local files, machines or paths, or to private notes. A proposal may well be informed by another implementation; the SEP then re-derives what it takes, chooses deliberately and cites the literature, as AGENTS.md asks of all code (“re-derive, do not transcribe”). A deliberate difference from Luna.jl’s behaviour is still recorded on the differences from Luna page when it is implemented.

Theory is written in SI units and in the conventions of conventions.md, with maths in MyST dollar notation; a departure from a convention is stated where it occurs. The implementation section proposes strategies and compares options; it is not a line-by-line plan, which belongs to the implementer.

Implementation rules#

  • Backends in order. A feature is implemented first on numpy_ref, the oracle, with its tests and its manual page; then on numba_cpu; then on the native CPU build in native/. Device (GPU) qualification follows the standing policy of backends.md, later and in one pass.

  • Parity, eventually. Until a backend implements the feature it refuses the problem by name, with an error saying which backend does support it; it never falls back silently. A SEP is Final only when all backends agree within tolerances derived from summation bounds, as for every other feature (testing.md).

  • The seam. A change to the kernel problem, the stage bundles or the protected driver surface bumps SCHEMA_VERSION, as AGENTS.md requires; the SEP says in which phase.

  • Tests. Unit, invariant, convergence and parity tests as testing.md sets out, against the analytic and independent references the SEP names; every tolerance justified in a comment.

  • Documentation. Comments on the physics and numerics, docstrings on every public name, a manual page with the background and a worked example, and, where it helps, a tutorial or a worked example in the galleries.

  • Qualification scope. The limits of AGENTS.md hold: ten steps or a very short fibre in tests and timings; full-length problems only in the galleries.

8. The implementation record#

Part II of a SEP holds one report per phase, appended when the phase is complete. The reports are how a SEP can be continued by someone else, and how the reasoning behind the finished code is kept. Each report states:

  • Scope: the phase, the date, the implementer, the branch and the phase’s commits.

  • Delivered: the modules, tests and pages added or changed, as paths.

  • Deviations from the proposal, and why each was necessary.

  • Decisions: choices made during implementation that the proposal left open. A decision of lasting architectural weight is also recorded as an ADR in decisions.md, and the report cites its number.

  • Verification: the gate and lanes run, on which tree; the references, measured errors, convergence orders and benchmarks, with the windows measured; what was not run.

  • Sources checked: which constants, coefficients and citations were checked against their primary source, and which could not be.

  • Limitations: cases refused, ranges not qualified, backends still missing.

  • Open questions, numbered Q1, Q2, … through the whole SEP, each with its owner or destination (the next phase, the roadmap, an issue).

  • Handoff: what the next phase needs to know.

A report is written honestly: a check that failed, a test left weaker than planned, an assumption that had to be invented are all said plainly.

9. Relation to the other records#

Record

Holds

SEP

The proposal, and the history of how it was implemented and verified

ADR (decisions.md)

A durable decision and its reasons; code comments cite ADRs

Manual (docs/)

How the functionality works and how to use it, as it is now

Design pages (docs/dev/)

How the code is built, as it is now

Roadmap

Open work: accepted and draft SEPs, then ideas and known issues not fully covered by one

CHANGELOG.md

What changed in each release, citing the SEP

The theory of a SEP moves into the manual when it is implemented: the manual page carries the derivation in its current form, and the SEP remains the record of the proposal.

10. Changing this process#

This process is changed by a Process SEP, or for small clarifications by a pull request that edits this document and adds a line to its history.

History#

  • 2026-09-26: Drafted and adopted (ADR-035).

  • 2026-09-27: List draft SEPs on the roadmap after accepted proposals and reconcile informal items against each proposal’s full or partial scope throughout its lifecycle.

  • 2026-09-29: The header’s Authors became Author, always the person among the maintainers who initiated and manages the SEP. Added Drafting agent, Review status and Reviewers, and the rule that every SEP is reviewed by at least one human and one frontier AI model before acceptance. Existing SEPs were given the new fields.

  • 2026-10-18: Reviews are recorded in place as numbered points under Part III, without rewriting Part I; the drafting agent responds point by point and revises the proposal (maintainer’s preferred practice, first used for SEP 26).

  • 2026-10-24: One branch and one pull request per SEP implementation, opened when the SEP is set Final; phases are reported in commits on that branch, may start on top of stacked pull requests, run only targeted checks locally, and leave the full gate, slow and coverage lanes to CI on the pull request (maintainer’s decision, first used for SEP 21). Native work is in native/, no longer a separate repository.