diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml new file mode 100644 index 0000000..5836cc5 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -0,0 +1,12 @@ +# SPDX-FileCopyrightText: 2026 John C. Travers and contributors +# +# SPDX-License-Identifier: MIT + +blank_issues_enabled: true +contact_links: + - name: How to write an issue + url: https://github.com/LupoLab/optmat/blob/main/CONTRIBUTING.md#writing-an-issue + about: What to check first, the sections and the labels. + - name: A problem with a propagation run + url: https://github.com/LupoLab/solprop/issues + about: The right values giving a wrong propagation belong with solprop. diff --git a/.github/ISSUE_TEMPLATE/oep_tracking.md b/.github/ISSUE_TEMPLATE/oep_tracking.md new file mode 100644 index 0000000..94585a2 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/oep_tracking.md @@ -0,0 +1,37 @@ +--- +name: OEP tracking issue +about: For an OEP's author. One per OEP, except a Process OEP (OEP 0). +title: "OEP N: " +labels: oep, enhancement +--- + + + +Tracks [OEP N: Title](link to the OEP on `main`). + + + +### Where it stands + +- **Status:** … **Review:** … **Implementation:** … +- **Requires:** … + +### What comes next + +- [ ] … + +### To resolve first + + + +### Related + + + +### Done when + +The OEP reaches `Final`, `Rejected`, `Withdrawn` or `Superseded`, and this issue closes with it. A `Deferred` OEP keeps it open. diff --git a/.github/ISSUE_TEMPLATE/offer_a_source.yml b/.github/ISSUE_TEMPLATE/offer_a_source.yml new file mode 100644 index 0000000..8e83f20 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/offer_a_source.yml @@ -0,0 +1,31 @@ +# SPDX-FileCopyrightText: 2026 John C. Travers and contributors +# +# SPDX-License-Identifier: MIT + +name: Offer a paper or data +description: A measurement or calculation that optmat lacks, or better data than it holds. +labels: [data] +body: + - type: markdown + attributes: + value: | + Please search the [issues](https://github.com/LupoLab/optmat/issues?q=is%3Aissue) and the [curated sources](https://optmat.readthedocs.io/en/latest/the-data/sources.html) first. Cite the paper; do not attach its PDF or paste its tables, since the publishers' copyright applies. + - type: textarea + id: citation + attributes: + label: The source + description: The citation and DOI, or the data service or repository. + validations: + required: true + - type: textarea + id: content + attributes: + label: What it holds + description: The quantity, the materials, and the range of wavelength, temperature or density. Whether the values are printed in tables, in a supplement or only in figures, and the stated uncertainty if you know it. + validations: + required: true + - type: textarea + id: improves + attributes: + label: What it would improve + description: The model or the value it would change or check, and a page or register entry (`TC-n`) that bears on it, if you know one. diff --git a/.github/ISSUE_TEMPLATE/planned_work.md b/.github/ISSUE_TEMPLATE/planned_work.md new file mode 100644 index 0000000..5db4e1b --- /dev/null +++ b/.github/ISSUE_TEMPLATE/planned_work.md @@ -0,0 +1,49 @@ +--- +name: Planned work +about: A bug, a data gap, a feature or a clean-up that someone can pick up from this text alone. +--- + + + +### What happens + + + +### Why it matters + + + +### Reproduction + + + +### Context + + + +### To do + + + +- [ ] … + +### Done when + + diff --git a/.github/ISSUE_TEMPLATE/report_a_value.yml b/.github/ISSUE_TEMPLATE/report_a_value.yml new file mode 100644 index 0000000..997f46d --- /dev/null +++ b/.github/ISSUE_TEMPLATE/report_a_value.yml @@ -0,0 +1,41 @@ +# SPDX-FileCopyrightText: 2026 John C. Travers and contributors +# +# SPDX-License-Identifier: MIT + +name: Report a problem with a value +description: A wrong value or model, a failure, or a suspected misprint in a paper. The maintainers fill in the rest. +body: + - type: markdown + attributes: + value: | + Please [search the issues](https://github.com/LupoLab/optmat/issues?q=is%3Aissue) first. The [review register](https://optmat.readthedocs.io/en/latest/register.html) may already record the disagreement or the doubt. + - type: textarea + id: value + attributes: + label: Which value or model + description: The material, the wavelength and conditions, and the function you called. A short script is ideal. For a misprint, the paper and where in it. + render: python + validations: + required: true + - type: textarea + id: expected + attributes: + label: What you expected + description: What you compared against (a paper with its table or page, an independent calculation, an instrument), and at what conditions. Cite a paper rather than pasting its tables. + validations: + required: true + - type: textarea + id: got + attributes: + label: What optmat gives + description: The value, or the output or the traceback. + validations: + required: true + - type: textarea + id: version + attributes: + label: Version + description: The output of `python -c "import optmat; print(optmat.__version__)"`. + render: text + validations: + required: true diff --git a/AGENTS.md b/AGENTS.md index fc6cd7b..0cb5760 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -9,7 +9,8 @@ The coding standards are conventional; **the data rules and the review register not negotiable.** **Read first:** -- [`CONTRIBUTING.md`](CONTRIBUTING.md): the short guide. +- [`CONTRIBUTING.md`](CONTRIBUTING.md): the short guide, and the standard for issues and + pull requests. - The manual pages *The curated data* (`docs/data.md`) and *The review register* (`docs/register.md`): the long form of the data format and of the register. - [OEP 0](docs/oeps/oep-0000-process.md), when the work is a major change: the @@ -32,6 +33,8 @@ concerns physics or the reading of a paper rather than style, ask rather than gu | Data | `src/optmat/data/`: `sources/` (one record per paper), `values///` (extracted values), `external/` (third-party files), `materials.toml` (the material registry), `gas/` and `solid/` (model configurations and stored fits) | | Register | [`REGISTER.md`](REGISTER.md): the review register, cited as `TC-n` | | Enhancement proposals | `docs/oeps/`: OEPs for major changes; the process is OEP 0 (`oep-0000-process.md`), the form `template.md` | +| Planned work | [GitHub issues](https://github.com/LupoLab/optmat/issues): open work goes in an issue, not on the roadmap, which lists only OEPs. [`CONTRIBUTING.md`](CONTRIBUTING.md) says how to write an issue and how to label an issue or a pull request | +| Downstream | [solprop](https://github.com/LupoLab/solprop), the pulse-propagation code, depends on optmat from PyPI and builds on the interface of the manual page *Using optmat from a propagation code* ([its issues](https://github.com/LupoLab/solprop/issues), [its SEPs](https://solprop.readthedocs.io/en/latest/dev/seps/index.html)). optmat never depends on solprop | | Python | 3.12 or later (`requires-python`); development, the lock and the gate on 3.14 | | Licences | Code, source records and fits MIT; prose and figures CC-BY-4.0; published data (`data/values/`, `data/external/`) remain the publishers', shipped under the third-party data notice (`REUSE.toml`, `LICENSES/LicenseRef-optmat-third-party.txt`) | | CI | [`.github/workflows/ci.yml`](.github/workflows/ci.yml): the gate below on Linux and macOS, the tests on Windows, and the tests on Python 3.12 with the lowest supported dependencies | @@ -129,15 +132,49 @@ Functionality built from an enhancement proposal is also not done until its phas is appended to the OEP (below). In your summary, say what you verified against a primary source and what you could not. -**Proposal-only changes.** A change that only adds or edits OEPs, their index or their -roadmap entries does not need the full gate. Run instead: +**Documentation-only changes**, including adding or editing OEPs, their index or their +roadmap entries, do not need the full gate. Run instead: - `git diff --check`; - `uv run codespell` on the changed files, and `uv run poe reuse` if files were added; -- `uv run pytest tests/test_proposals.py tests/test_register.py`; +- `uv run pytest tests/test_proposals.py tests/test_register.py`, and the tests that read + a page you changed (the `tests/test_*_page.py` of an accuracy page, the snippets' tests, + `tests/test_counts.py` for a front page); - `uv run poe docs`. +The exception is based on content, not on a file's location. A change to code, tests, +data, fixtures, a gallery script, dependencies, build configuration or tooling takes the +full gate, and so does a mixed change. Report the checks actually run. + --- +## Working agreement + +- **Agree the plan for large changes.** A major change starts from an accepted OEP (below). + Any other change that touches more than a couple of files or alters a public signature + starts from an issue or a short agreed plan; a focused fix, a new source or a + documentation update does not need one. +- **Stay in scope.** No refactoring, renaming or reformatting unrelated to the task. +- **Open an issue for what you find.** Whatever you notice while working and do not fix + in the change in hand (a bug, a wrong statement, a missing test, a slow path) gets an + issue straight away, so that it outlives the work in hand and the branch. Do not wait to + be asked, and write it as [`CONTRIBUTING.md`](CONTRIBUTING.md) says, searching first. If + you plan to fix it yourself, open it all the same and keep it in your own plan too. A + doubt about data or a model also gets its `open` register entry. +- **Connect a fix to its issue.** When you fix something you noticed, search the issues + for it, and solprop's if it consumes the result. If the change closes one of optmat's, + say `Closes #N` in the pull request; if it only goes part of the way or bears on one, + comment there on what changed and what is left, and do not close it. `Closes` acts only + on a pull request based on `main` in the same repository: after a stacked pull request + or a local merge reaches `main`, or for an issue in solprop, close or update it by hand, + naming the commit. +- **Report failure honestly.** A check that fails, a test you could not make pass, an + assumption you had to invent: say it plainly. Silent partial completion is worse than an + admitted gap. +- **The public tree stands alone.** No local paths, host names, private notes or links to + them, and no development identifiers, in code, tests, data, docs, the changelog, issues + or pull requests. Register numbers (`TC-n`) are public and are cited freely; the paper + library's contents are not, so cite a paper rather than pasting its text or tables. + ## The review register [`REGISTER.md`](REGISTER.md) is the public record of how the data were checked, and it @@ -208,9 +245,12 @@ The long form is [OEP 0](docs/oeps/oep-0000-process.md); the index is - Copy `docs/oeps/template.md` to `oep-NNNN-short-slug.md`, with the next free number. - Add it to the index, and to the roadmap's draft section (after the accepted proposals). - - Merge it early as `Draft`, from a `docs/oep-NNNN-…` branch. - - Remove an informal roadmap item only if the OEP covers it fully. Otherwise link the - OEP, state the partial coverage and keep the remaining work. + - List in its *Context* the open issues it will fix or that must be resolved first + (search them, and solprop's if it consumes the result). + - Open its tracking issue (OEP 0), and merge it early as `Draft`, from a + `docs/oep-NNNN-…` branch. + - Close an issue the OEP covers fully only when the OEP is `Final`. Otherwise link the + OEP from the issue and state what it leaves. - Reconcile these entries whenever the scope or status changes. - **An OEP stands alone.** It may cite: - optmat's and solprop's own docs, code, tests and proposals, and commits on their @@ -260,7 +300,8 @@ The long form is [OEP 0](docs/oeps/oep-0000-process.md); the index is Report failures and gaps plainly. - **Finishing.** At `Final`: - each manual page the OEP produced ends with a link to it; - - its open questions move to the roadmap, to issues or to `open` register entries; + - its open questions move to issues or to `open` register entries; + - its tracking issue closes; - the `CHANGELOG.md` line cites it. A final OEP is history: the manual describes current behaviour. @@ -399,6 +440,10 @@ The manual's conventions pages are the long form. copyright, and its `PROVENANCE.md` states the publisher's terms, or that it states none. **The package is self-contained:** it never downloads data at run time; what a model needs is shipped with it. +- **Frozen fixtures:** `tests/data/solprop_*.json` record what solprop held before it + moved to optmat, and are neither edited nor regenerated: solprop now takes these values + from optmat, so re-running `tools/solprop_*.py` would compare optmat with itself. A + change to a model does not touch them. - **Generated files are never hand-edited;** re-run what writes them: - `uv.lock` (uv); - the docs build: `docs/_build/`, `docs/auto_gallery/`, `docs/api/generated/`, @@ -409,8 +454,7 @@ The manual's conventions pages are the long form. `data/gas/` and `data/solid/` (`tools/fit/`); - test fixtures: `tests/data/public_api.json` (`tools/public_api.py`), `golden_models.json` and `golden_raman_identities.json` (`tools/golden_models.py`), - `solprop_*.json` (`tools/solprop_*.py`), `luna_master.json` - (`tools/luna_reference.jl`); + `luna_master.json` (`tools/luna_reference.jl`); - the manual's tables written by `--update-docs` (`tools/fit/nonlinear_support.py`, `tools/two_photon_tables.py`). @@ -418,13 +462,16 @@ The manual's conventions pages are the long form. - **Branches and worktrees:** all development happens on a topic branch in its own worktree. Create them without asking: name the branch for its topic (`data/`, - `fit/`, `fix/...`, `feature/...`, `docs/...`; `docs/oep-NNNN-…` for an OEP draft - and `feature/oep-NNNN-…` for each of its phases) and put the worktree under + `fit/`, `fix/...`, `feature/...`, `docs/...`, `chore/...`; `docs/oep-NNNN-…` for + an OEP draft and `feature/oep-NNNN-…` for each of its phases) and put the worktree under `.claude/worktrees/` (ignored), or where your tool puts its worktrees. Continue in an existing branch/worktree when asked to. **The main checkout stays on `main`, clean:** other local projects build against it, so never edit files, switch branches or leave - work in it; its one use is to merge a finished branch. Changes reach GitHub as pull - requests, which CI checks. + work in it; its one use is to merge a finished branch. Changes reach `main` as pull + requests with green CI, or by a local merge when the maintainers ask for one. +- **Before opening an issue or a pull request,** read [`CONTRIBUTING.md`](CONTRIBUTING.md): + search the issues, the pull requests and the OEPs, link what is related, and follow its + sections and labels. - **Review:** a pull request that changes data or models is reviewed for: - its register entries, and its errata with their evidence; - its extraction reproducing the files; @@ -439,12 +486,11 @@ The manual's conventions pages are the long form. - **Versions:** never tag, release or change a version by hand; versions come from git tags. - **Coding agents:** - - never push; + - merge, push, tag or release only when asked or authorised, and do not ask again for + an already authorised action; - never run a destructive or history-rewriting command (`git reset --hard`, `git checkout .`, `git restore` over uncommitted changes, `git clean`, `git stash drop`, `git branch -D`, `git worktree remove --force`, `git commit --amend`, `git rebase`, a force push): these can destroy work that is not yours; - - create branches and worktrees freely (above); `fetch`, `pull` and `merge` into - `main` only when asked or authorised, and do not ask again for an already - authorised action. + - create branches and worktrees freely (above). diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index cd1c2ac..7b07ca9 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -5,16 +5,125 @@ materials, better models and documentation fixes are all welcome. Because optmat is the trustworthiness of its data, a contribution that touches data or models comes with its evidence; this guide says what that means. +## Check what already exists + +Before opening an issue or a pull request, and before starting work on either, look for +what already covers it or touches it: + +- the [issues](https://github.com/LupoLab/optmat/issues) and + [pull requests](https://github.com/LupoLab/optmat/pulls), open and recently closed; +- the [OEPs](docs/oeps/index.md), since one may already propose the change or be about to + alter the code; +- for a question about a value, the [review register](REGISTER.md) and the source record: + the disagreement or the doubt may already be on record; +- for a change that the propagation code [solprop](https://github.com/LupoLab/solprop) + consumes, its [issues](https://github.com/LupoLab/solprop/issues) and its + [SEPs](https://solprop.readthedocs.io/en/latest/dev/seps/index.html), since it may be + waiting for the change or may be broken by it. + +```sh +gh issue list --state all --search "line mixing" +gh pr list --state all --search "line mixing" +git grep -il "line mixing" docs/oeps REGISTER.md +gh issue list --repo LupoLab/solprop --state all --search "line mixing" +``` + +If one already covers your work, add to it rather than opening another. If one only +touches it, such as an open pull request that changes the same files, link it from what +you open, even if you need nothing from it: GitHub shows the reference on both sides, and +the next reader then knows the two are connected. Link across the repositories as +`LupoLab/solprop#285`. For a report of a wrong value, a quick search of the issues is +enough. + ## Reporting a problem with a value -Open an issue saying: +Use the [report form](https://github.com/LupoLab/optmat/issues/new?template=report_a_value.yml), +which asks for: - which value or model (the gas, the wavelength, the function you called, the version: `python -c "import optmat; print(optmat.__version__)"`); - what you expected and what optmat gives; - what you compared against (a paper with its table or page, an independent calculation, an instrument), at what conditions. -A suspected misprint in a paper is just as welcome: say where, and why you think so. +A suspected misprint in a paper is just as welcome: say where, and why you think so. If +you have a paper or data that optmat lacks, the +[source form](https://github.com/LupoLab/optmat/issues/new?template=offer_a_source.yml) +is for that. + +A wrong value belongs here. A propagation that goes wrong with the right values belongs +with [solprop](https://github.com/LupoLab/solprop/issues); if you cannot tell which it +is, open it in either and it will be moved. + +That is all a report needs. The maintainers fill in the rest. + +## Writing an issue + +Planned work lives in [GitHub issues](https://github.com/LupoLab/optmat/issues). So an +issue for planned work, written by a person or an agent, has to let someone pick up the +task from its text alone. [#6](https://github.com/LupoLab/optmat/issues/6) is an example. + +[Check what already exists](#check-what-already-exists) first, and link what you find. +Write one issue per coherent piece of work, not one per finding or per file. A major +change starts as an OEP, which has a tracking issue of its own +([OEP 0](docs/oeps/oep-0000-process.md), +[template](.github/ISSUE_TEMPLATE/oep_tracking.md)). + +Use these sections, which the [planned work template](.github/ISSUE_TEMPLATE/planned_work.md) +lays out, leaving out any that do not apply: + +- **What happens**, or what is missing, so that someone new to this code can follow it. +- **Why it matters:** what a user or a developer gets wrong or pays for today. +- **Reproduction.** For a bug, the smallest script that shows it, which you have run, + with its output. For a performance issue, the numbers, the machine, the build and the + command. +- **Context:** links to what a reader needs, namely the code, the manual, OEPs, source + records, register entries (`TC-n`), pull requests and other issues. Link code as a + permalink to a commit (press `y` on a file's page on GitHub), and say which commit you + checked against. +- **To do:** checkboxes that are actions, not restated symptoms. Name what must not change + or break. Check that a suggested fix would work before writing it down. +- **Done when:** what someone can check to know it is finished, with a tolerance and a + machine for a measurement. A criterion should cover every box, and one that no pull + request can show should say what stands in for it. + +Be exact about what you know: + +- Say what you ran and what you only read ("read, not run"), and label a suspicion as one. +- Give a measurement its machine, width and date, and a count its scope ("259 errata + in the 762 source records of 0.9.0"). +- Mark a choice that is not the contributor's with **Needs a decision:**, saying who + decides and what you recommend. A physics judgement, the reading of a paper, a + recommended value or a changed default, and a changed public signature are the + maintainers' ([`AGENTS.md`](AGENTS.md)). +- Name a value's source: the source record and the table or page, and the register entry + that bears on it. A value in an issue follows the same rule as a value in the data: + nothing from memory. +- Issues are public, so leave out local paths, private notes and nicknames for machines. + Name hardware by its model. Cite a paper rather than pasting its text or its tables, and + do not attach its PDF: the publishers' copyright applies. + +An issue records work to be done; the register records what has been checked. A finding +about data or a model still gets its register entry when the change is made, and an open +scientific question its `open` entry. + +### Labels + +Issues are filtered by [label](https://github.com/LupoLab/optmat/labels), so an issue +carries: + +- one **type**, or two if it really is both: `bug` (wrong behaviour or a wrong result), + `data` (a source record, an extraction, an erratum or a curated value), `performance` + (slower or larger than it should be, with no wrong result), `enhancement` (a new + feature or a request), `documentation`, `refactor` (no change in behaviour) or `testing` + (tests, test lanes and CI coverage); +- one **priority**: `priority: high` (wrong values, wrong public statements or a user's + first contact), `priority: medium` (real work that should not wait long) or + `priority: low` (worth doing, no hurry); +- an **area** where one fits, such as `area: raman` or `area: solids`; +- `oep` on an OEP's tracking issue, `solprop` if it was found through solprop or solprop + needs it, and `good first issue` if it needs no physics judgement and no paper library. + +If you cannot set labels, suggest them in the text and the maintainers will. ## Setting up @@ -82,29 +191,40 @@ motivated it in the register. ## Making a change -1. Work on a branch named for its topic (`data/`, `fit/`, `fix/...`, - `feature/...`, `docs/...`). A major change starts as an enhancement proposal (OEP): +1. [Check what already exists](#check-what-already-exists), so that you neither repeat + nor collide with work in hand. Look especially for open pull requests that change the + same files and for OEPs that would change the same behaviour. +2. Work on a branch named for its topic (`data/`, `fit/`, `fix/...`, + `feature/...`, `docs/...`, `chore/...`). A major change starts as an enhancement + proposal (OEP): see [OEP 0](docs/oeps/oep-0000-process.md) and the [template](docs/oeps/template.md). That means a new medium, a new family of properties or models, a new kind of curated value, a changed default or convention, or a redesigned interface. For anything else larger than a focused fix, open an issue first so the approach can be agreed. -2. Read [`AGENTS.md`](AGENTS.md): the data rules, the register, and the coding +3. Read [`AGENTS.md`](AGENTS.md): the data rules, the register, and the coding standards (for people and coding agents alike). -3. Keep the change to the task. Add tests with the code, document new functionality in +4. Keep the change to the task. Add tests with the code, document new functionality in the manual as well as in docstrings, add register entries for data and model changes, and add a line to `CHANGELOG.md` under `Unreleased`. -4. Run `uv run poe check`; with data or fit changes also `poe test-library` (if you - have the library) and `poe test-fits`. A change that only adds or edits OEPs runs - the shorter checks listed in [`AGENTS.md`](AGENTS.md), *Definition of done*. -5. Open a pull request saying what changed, why, and how it was verified, and what you - assumed, skipped or could not check. +5. Run `uv run poe check`; with data or fit changes also `poe test-library` (if you + have the library) and `poe test-fits`. A change to the documentation alone, including + a new or edited OEP, runs the shorter checks listed in [`AGENTS.md`](AGENTS.md), + *Definition of done*. +6. Open a pull request saying what changed, why, and how it was verified, and what you + assumed, skipped or could not check. Search again first, since work may have appeared + while you were busy. Link the issue it closes (`Closes #N`) and any issue, pull request + or OEP it overlaps with or depends on, here or in solprop, and give it a label or two: + its type and, where one fits, its area, as for an issue. If you cannot set labels, the + maintainers will. ## Review checklist A pull request is ready to merge when: -- `uv run poe check` passes, and `poe test-fits` where a fit or its data changed; +- it links the issues, pull requests and OEPs it closes, overlaps with or depends on; +- the applicable checks pass: the documentation checks for a documentation-only change; + otherwise `uv run poe check`, and `poe test-fits` where a fit or its data changed; - every new or changed value has its source record, its register entry, and, for a correction, its erratum with evidence; - no value was typed from memory or a secondary source where the primary one was diff --git a/docs/contributing.md b/docs/contributing.md index 6569305..ec96ea7 100644 --- a/docs/contributing.md +++ b/docs/contributing.md @@ -9,9 +9,16 @@ documentation fixes are all welcome. Choose the workflow for your change: -- **Report a problem with a value** by opening an issue: which value, what you expected, - and what you compared against (a paper with its table or page, an independent - calculation), at what conditions. A suspected misprint in a paper is just as welcome. +- **Report a problem with a value** with the + [report form](https://github.com/LupoLab/optmat/issues/new?template=report_a_value.yml): + which value, what you expected, and what you compared against (a paper with its table or + page, an independent calculation), at what conditions. A suspected misprint in a paper is + just as welcome. A propagation that goes wrong with the right values belongs with + [solprop](https://github.com/LupoLab/solprop/issues). +- **Offer a paper or data** that optmat lacks with the + [source form](https://github.com/LupoLab/optmat/issues/new?template=offer_a_source.yml). +- **Plan work** in an [issue](https://github.com/LupoLab/optmat/issues). `CONTRIBUTING.md` + says what to check first, the sections to use and the labels. - **Add or correct data** through a source record, an extraction script that writes the values exactly as printed, errata with their evidence for any misprint, and an entry in the review register ({doc}`register`). The format is on {doc}`data`; the workflow is in {doc}`/developers/data`. @@ -33,9 +40,9 @@ Every change passes the full gate, `uv run poe check`: lint, format, types, docs spelling, copyright and licence (`reuse lint`), the tests with 100 % statement and branch coverage of the package, and this manual's build. The coverage scope and additional verification lanes are described on -{doc}`/developers/testing`. Proposal-only changes use the shorter gate specified +{doc}`/developers/testing`. Documentation-only changes use the shorter gate specified in the working rules. -Prefer topic branches and separate worktrees; agents confirm their creation or switching -with the maintainer. Concurrent register entries are reconciled before integration as +Work on a topic branch in its own worktree; agents create both without asking. Concurrent +register entries are reconciled before integration as described on {doc}`/developers/register`. Contributions are licensed under the project's MIT licence. diff --git a/docs/developers/testing.md b/docs/developers/testing.md index 39e16a4..7e1c495 100644 --- a/docs/developers/testing.md +++ b/docs/developers/testing.md @@ -22,12 +22,13 @@ The commands and requirements in | Extracted data | `PAPER_LIBRARY= uv run poe test-library` | | Fits, fitting code or data used by a fit | Refit, regenerate robustness and derived records as described in {doc}`fitting`, then `uv run poe test-fits` | | Packaging, data layout or public interfaces | `uv run poe test-release` | -| Documentation | `uv run poe docs`, relevant snippet and generated-table tests, and the full gate | +| Documentation alone | The shorter checks below | -A proposal-only change uses the shorter gate specified in the working rules -(`AGENTS.md`): diff whitespace, spelling, -proposal and register tests, and the documentation build. This exception does not -apply when implementation changes accompany a proposal. +A documentation-only change, including a new or edited OEP, uses the shorter gate +specified in the working rules (`AGENTS.md`): diff whitespace, spelling, the proposal and +register tests, the tests that read the pages it changes, and the documentation build. +The exception is based on content: it does not apply when a change also touches code, +tests, data, a gallery script or tooling. Tests run in parallel in the gate and must be independent of order and share no writable output. Use `tmp_path` for test output. A focused invocation such as diff --git a/docs/oeps/oep-0000-process.md b/docs/oeps/oep-0000-process.md index fa4319b..d36a78d 100644 --- a/docs/oeps/oep-0000-process.md +++ b/docs/oeps/oep-0000-process.md @@ -154,20 +154,23 @@ the header. `tests/test_proposals.py` checks this. Leave Part II empty, and start Part III with the date drafted. 3. Add the OEP to the index table, the index's toctree and the *Draft enhancement proposals* section of the {doc}`roadmap <../roadmap>`, after the accepted proposals. - Review the informal roadmap items in the same change: - - remove an item only when the OEP covers it in full; - - for partial coverage, link the OEP, state what it covers and keep the remaining - work. - - Discussion of a possible future extension does not count as coverage. -4. Open a pull request on a branch named `docs/oep-NNNN-short-slug`. A draft merges +4. Search the open [issues](https://github.com/LupoLab/optmat/issues) for anything the + OEP touches, and solprop's where it consumes the result, and list what you find in its + *Context* section: the issues it will fix, and those that must be resolved first. An + issue stays open until the OEP that covers it is `Final`; for partial coverage, link + the OEP from the issue and state what it leaves. Discussion of a possible future + extension does not count as coverage. +5. Open the OEP's tracking issue, titled `OEP N: ` and labelled `oep` with a type, + a priority and any area that fits. It links the OEP and the issues found, and says + where the OEP stands and what comes next. Name the issue in the OEP's Part III. +6. Open a pull request on a branch named `docs/oep-NNNN-short-slug`. A draft merges early, once it is coherent rather than once it is agreed, so that it appears in the manual 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. Whenever its scope changes, update its roadmap -summary and the informal items, and restore work that the revised scope no longer -covers. +summary and its tracking issue, and open an issue for work that the revised scope no +longer covers. ### Review @@ -222,9 +225,10 @@ The maintainers accept an OEP in a pull request that: the roadmap. A rejection or deferral records the reasons in the OEP, removes its proposal listing from -the roadmap and restores any still-relevant informal work that it had replaced. The same -roadmap update applies on withdrawal. For supersession, reconcile the work with the -replacement OEP's scope. +the roadmap and opens an issue for any still-relevant work that it had covered. The same +update applies on withdrawal. For supersession, reconcile the work with the replacement +OEP's scope. The tracking issue closes on rejection, withdrawal or supersession; a +deferred OEP keeps it open. 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 @@ -260,8 +264,8 @@ An OEP becomes `Final` when: - every phase is merged and reported; - the manual documents it, and each manual page it produced ends with a link to the OEP; - its data and models have their register entries; -- the open questions left are moved to the roadmap, to issues or to `open` register - entries, and named in the last report. +- the open questions left are moved to issues or to `open` register entries, and named + in the last report. In the pull request that sets `Final`: - fill in **Manual pages**; @@ -269,6 +273,7 @@ In the pull request that sets `Final`: - move its index row to the archived table, and its toctree entry to the archive index; - fix the relative links the move breaks; - remove its roadmap link; +- close its tracking issue; - cite the OEP in the `CHANGELOG.md` line. A Final OEP is a historical record. It is not updated to follow later changes to the @@ -322,8 +327,9 @@ checked against the paper before acceptance, never written from memory. comment. The manual's tables are tested against the stored fits where they quote them. - **Fits.** A phase that changes a fit, or the data a fit uses, re-runs the fits, robustness records and fit tests as `AGENTS.md` requires, and says what changed. -- **Downstream.** A change that solprop consumes updates the solprop parity fixtures - under `tests/data/`, and its report says so. +- **Downstream.** A change that solprop consumes says so in its report and links the + solprop issue or SEP that bears on it, or opens an issue there. The solprop fixtures + under `tests/data/` are frozen history and are not updated. - **Documentation.** Comments on the physics and the sources, docstrings with units and ranges on every public name, and a manual page with the background and a worked example. Where it helps, a gallery example. @@ -348,7 +354,7 @@ the finished code is kept. Each report states: their primary source, and which could not be. - **Limitations:** cases refused, and ranges or materials not qualified. - **Open questions**, numbered Q1, Q2, … through the whole OEP, each with its owner or - destination: the next phase, the roadmap, an issue or a register entry. + destination: the next phase, an issue or a register entry. - **Handoff:** what the next phase needs to know. A report is written honestly. A check that failed, a test left weaker than planned, or @@ -361,7 +367,8 @@ an assumption that had to be invented is said plainly. | OEP | The proposal, and the history of how it was implemented and verified | | Register (`REGISTER.md`) | The facts about data and models: sources, errata, fit decisions, findings and open questions, cited as TC-n | | Manual (`docs/`) | How the functionality works and how to use it, as it is now | -| {doc}`Roadmap <../roadmap>` | Open work: accepted and draft OEPs, then ideas and known gaps not fully covered by one | +| {doc}`Roadmap <../roadmap>` | The status lists of accepted and draft OEPs | +| [Issues](https://github.com/LupoLab/optmat/issues) | Planned work: ideas and known gaps, and each OEP's tracking issue | | `CHANGELOG.md` | What changed in each release, citing the OEP | The theory of an OEP moves into the manual when it is implemented. The manual page @@ -377,3 +384,11 @@ pull request that edits this document and adds a line to its history. - 2026-09-29: Drafted and adopted. Modelled on solprop's SEP 0, with the parts that concern a data library: primary sources, the register, fits and validators. +- 2026-11-04: Planned work goes in GitHub issues, not on the roadmap, whose informal items + move to issues, and work an OEP gives back goes in an issue. Each OEP has a tracking + issue, and a draft lists the open issues it touches. This follows solprop's SEP 0 and + was decided by the maintainers as a change to this document, without a Process OEP + (§2, §10). +- 2026-11-04: The solprop fixtures under `tests/data/` are frozen history, since solprop + takes these values from optmat; the *Downstream* rule now links the solprop issue or + SEP instead. diff --git a/docs/oeps/template.md b/docs/oeps/template.md index ed19706..d6086bd 100644 --- a/docs/oeps/template.md +++ b/docs/oeps/template.md @@ -6,9 +6,9 @@ index, and replace every placeholder. Keep the headings: the parts and their ord the same in every OEP. Delete the italic guidance as you write each section. The process is OEP 0 (oep-0000-process.md); read it first. Add the draft to the OEP index and its toctree, and to the roadmap's Draft enhancement -proposals section after the accepted proposals. Remove informal roadmap items only when -fully covered by this proposal; for partial coverage, link the OEP and retain the -uncovered work explicitly. Keep these entries current when the scope or status changes. +proposals section after the accepted proposals. Search the open issues for what it touches +and open its tracking issue (OEP 0, section 6). Keep these entries current when the scope +or status changes. --> | | | @@ -50,7 +50,7 @@ what is not, including tempting adjacent work.* *What optmat does today in this area:* - *links to the manual pages and the modules involved;* - *the register entries that bear on it, cited by number;* -- *the roadmap item this answers, if any;* +- *the open issues it will fix or that must be resolved first, here and in solprop;* - *the prior OEPs it builds on.* ### 4. Theory @@ -105,7 +105,7 @@ plan. Cover as applicable:* - *reproductions of printed values;* - *sum rules and invariants;* - *independent measurements or calculations held out as validators;* -- *parity with solprop where it consumes the result.* +- *how solprop's qualification is affected where it consumes the result.* *For each, the quantity compared and what will set the tolerance.* @@ -120,7 +120,7 @@ belongs.* - *changed recommended values or defaults, and the size of the change;* - *stored fits that must be re-run;* - *breaking changes to the public interface;* -- *the solprop parity fixtures;* +- *what solprop consumes, and the solprop issue or SEP that bears on it;* - *register entries that are superseded.* ### 11. Alternatives considered