diff --git a/CLAUDE.md b/CLAUDE.md index dd6b763..7e6eaa1 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -23,7 +23,8 @@ scripting engine for game authors. | Read | For | |---|---| | [`MAINTENANCE.md`](MAINTENANCE.md) | Everything above. Start here | -| [`TODO.md`](TODO.md) | Outstanding defects, with file, line and consequence. §0.1 first — it retires the byte-for-byte fidelity constraint several later sections were written on | +| [the issue tracker](https://source.starfort.tech/andrew/akbasic/issues) | **Outstanding defects and gaps.** Labelled by kind and blast radius; `status::grooming` means the scope is not settled yet | +| [`TODO.md`](TODO.md) | The record: settled design decisions, the deviation register, defects already fixed, and the reasoning behind the measurements. §0.1 first — it retires the byte-for-byte fidelity constraint several later sections were written on | | [`README.md`](README.md) | What the project is and why, for somebody who has not seen it | | [`docs/`](docs/README.md) | The language itself: eighteen chapters, verb and function reference. [Chapter 14](docs/14-architecture.md) is the interpreter's architecture — the step loop, the pools, the two kinds of error, and how to debug it. [Chapter 15](docs/15-error-codes.md) is the error-code appendix. [Chapters 17](docs/17-tutorial-breakout.md) and [18](docs/18-tutorial-breakout-artwork.md) are tutorials that build the games in `examples/breakout/` | | `deps/libakerror/AGENTS.md` | The `ATTEMPT`/`CLEANUP`/`PROCESS`/`HANDLE`/`FINISH` protocol, authoritatively | @@ -44,19 +45,26 @@ repeating where you will see them: - **Add tests in the same commit as the behaviour change**, and assert the *correct* contract even where the code is currently wrong. A known-failing test goes in - `AKBASIC_KNOWN_FAILING_TESTS` with a `TODO.md` entry; it does not get pinned to the buggy + `AKBASIC_KNOWN_FAILING_TESTS` with an open issue; it does not get pinned to the buggy behaviour, because that turns the eventual fix into a test failure. -- **Never work around a missing dependency capability here.** File it in that repository's - `TODO.md` — what the BASIC verb requires, what the entry point should look like, what tests - would cover it. `MAINTENANCE.md` explains why, and names the four gaps this closed upstream. +- **Never work around a missing dependency capability here.** Open an issue in that + repository's tracker on — what the BASIC verb requires, what + the entry point should look like, what tests would cover it. `MAINTENANCE.md` explains why, + and names the four gaps this closed upstream. **Recording it here instead is not filing it**: + two `akgl_ui` gaps sat in `TODO.md` for a release because changing a submodule is that + repository's decision — which is true of changing it and not of reporting it. - **Never edit generated output** — `build/` trees, the generated `akerror.h`, `akgl.pc`, `include/akgl/SDL_GameControllerDB.h`. Change the template or the generator script. - **Do not reformat code you are not otherwise changing.** Several files mix tabs and spaces and there is no repo-wide formatter; style conversions get their own commit. - **Do not edit `tests/reference/`.** Those expectations came from the Go implementation and - are never edited to suit this interpreter. A deliberate divergence goes in `TODO.md` and - `docs/13-differences.md`. -- **Update `TODO.md` when you learn something about a defect**, including that it is worse or - better than recorded. Publishing a problem you cannot fix yet is a contribution. + are never edited to suit this interpreter. A deliberate divergence goes in + `tests/reference/README.md`'s divergence table and `docs/13-differences.md`. +- **Open an issue for outstanding work; do not add it to `TODO.md`.** + , or `tea issues create --repo + andrew/akbasic`. Name the file and line, the functional consequence, and what closing it would + touch. Publishing a problem you cannot fix yet is a contribution — and **when you learn + something about an open issue, say so in the issue**, including that it is worse than + recorded, already fixed, or resting on a premise that has expired. - **Add yourself — program, model and version — as a commit co-author.** `libakgl`'s `AGENTS.md` requires it and this repository follows the same rule. diff --git a/MAINTENANCE.md b/MAINTENANCE.md index a2812a3..b632f54 100644 --- a/MAINTENANCE.md +++ b/MAINTENANCE.md @@ -38,8 +38,8 @@ the idiom of the `ak*` C libraries it builds on. 2. **Finish the language.** The full Dartmouth BASIC and Commodore 128 BASIC 7.0 verb and function set. `deps/basicinterpret/README.md` ends with the original's list of what was - unimplemented, and that list was the work queue. What remains is in `TODO.md` and is - summarised for a BASIC programmer in `docs/13-differences.md`. A few entries are + unimplemented, and that list was the work queue. Every group of it is done; what remains is + in the issue tracker and is summarised for a BASIC programmer in `docs/13-differences.md`. A few entries are deliberately out of scope on a modern PC — `BANK`, `FAST`, `MONITOR`, and `SPRDEF`, which is an interactive editor rather than a programmable verb. Keep that reasoning rather than reviving them. @@ -60,9 +60,12 @@ the idiom of the `ak*` C libraries it builds on. ### Missing capabilities get filed upstream, not worked around **When `libakgl` — or `libakstdlib` — cannot supply something a verb needs, do not work -around it here.** Add a numbered item to that repository's `TODO.md` describing the missing -API: what the BASIC verb requires, what the `akgl_*` or `aksl_*` entry point should look -like, and what tests would cover it. Follow the prose-paragraph style of the entries already +around it here.** Open an issue in that repository's tracker on + describing the missing API: what the BASIC verb requires, what +the `akgl_*` or `aksl_*` entry point should look like, and what tests would cover it. +**Recording it in this repository instead is not filing it** — two `akgl_ui` gaps sat in +`TODO.md` for a release on the reasoning that changing a submodule is that repository's +decision, which is true of *changing* it and not of *reporting* it. Follow the prose-paragraph style of the entries already there. Growing the dependency to serve the interpreter is a wanted outcome, not a detour. It works. Four gaps were filed this way — text measurement, immediate-mode drawing, audio, @@ -324,7 +327,7 @@ parameters but not all of them fails the run. Every public declaration under `CMakeLists.txt` declares `AKBASIC_TESTS`, `AKBASIC_WILL_FAIL_TESTS` and `AKBASIC_KNOWN_FAILING_TESTS`. The first must exit 0. The second aborts by design. The -third **asserts the correct contract for a defect that is documented in `TODO.md`** and is +third **asserts the correct contract for a defect that has an open issue** and is expected to fail. A green `ctest` therefore does not mean defect-free. When a known-failing test starts @@ -336,7 +339,7 @@ there when it is next needed. The dependencies use the same split under their own prefixes: `AKSL_TESTS` / `AKSL_WILL_FAIL_TESTS` / `AKSL_KNOWN_FAILING_TESTS`, and `AKERR_TESTS` / -`AKERR_WILL_FAIL_TESTS`. `libakstdlib` 0.2.0 fixed all six defects its `TODO.md` §2.1 listed +`AKERR_WILL_FAIL_TESTS`. `libakstdlib` 0.2.0 fixed all six defects it had confirmed and left `AKSL_KNOWN_FAILING_TESTS` empty. ### Test target names @@ -351,7 +354,8 @@ name. That is not cosmetic: `add_executable` creates a dependency's targets even `tests/reference/` is the Go implementation's own acceptance suite, byte-compared. **Nothing in it is ever edited to suit this interpreter.** If a case fails, either this interpreter is wrong or the divergence is deliberate — and a deliberate one goes in -`TODO.md` and `docs/13-differences.md`, not into the expectation file. `tests/reference/README.md` +`tests/reference/README.md`'s divergence table and `docs/13-differences.md`, not into the +expectation file. `tests/reference/README.md` says the same thing at more length. `tests/language/` is ours and may be changed freely. A new language feature needs a @@ -463,7 +467,8 @@ is there so the question "between them *where*" has an answer. Breakout reaches the high end of that bracket for a reason worth knowing: two of its eight sprites *are the screen*, a captured HUD strip and a captured play field, so the field's box covers everything and the bounding-box reject can never throw those pairs out. That is -`TODO.md` §9 item 9, and fixing it would take this row down as a side effect. +the sprite-slot cost recorded in `TODO.md` §9 item 9, and fixing it — issue #23 — would take +this row down as a side effect. **Read a benchmark as a gap between two rows of the same run, not as an absolute.** libakgl's `PERFORMANCE.md` records a whole laptop reading 15% high on a later run, including rows nothing @@ -553,7 +558,7 @@ stale: | `__AKERR_ERROR_NAMES` | `akerr_name_for_status()`; the table is private to the library now | | `AKERR_STATUS_RANGE_OK` / `AKERR_STATUS_NAME_OK` | success is a `NULL` `akerr_ErrorContext *`, like everything else | -`libakerror`'s own `TODO.md` §2 says the limit plainly: ownership enforcement covers *naming*, +`libakerror`'s own tracker says the limit plainly (its issue #4): ownership enforcement covers *naming*, which is the part the library mediates. It cannot detect two components compiling the same integer into a `HANDLE` `case` label without ever registering a name — that never reaches the registry. §3 adds that there is no way to ask who owns a status or to enumerate reservations,