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 |
|
yes, under drafts |
Accepted |
Agreed by the maintainers; waiting to be picked up |
|
yes |
In progress |
Being implemented; at least one phase has started |
|
yes |
Final |
Implemented on every backend, tested and documented |
|
no |
Deferred |
Not pursued for now; may return to Draft |
|
no |
Rejected |
Decided against; the reasons are recorded in the SEP |
|
no |
Withdrawn |
Abandoned by its author |
|
no |
Superseded |
Replaced by a later SEP, named in the header |
|
no |
Active |
A Process SEP in force |
|
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)orModel 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#
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.Fill in the header and Part I: the Author, any Drafting agent, status
Draft, review statusNot reviewedand Reviewers—. Leave Part II empty and start Part III with the date drafted.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.
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:
implemented under the rules of §7, native code in
native/with the Python backends;checked with the fast checks and the directly affected tests of
AGENTS.mdonly;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_cpuand 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 onnumba_cpu; then on the native CPU build innative/. 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, asAGENTS.mdrequires; 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.mdhold: 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 ( |
How the functionality works and how to use it, as it is now |
Design pages ( |
How the code is built, as it is now |
Open work: accepted and draft SEPs, then ideas and known issues not fully covered by one |
|
|
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 innative/, no longer a separate repository.