la-stack 0.5.0

Fast, stack-allocated linear algebra for fixed dimensions
Documentation
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
# Contributing

Thanks for helping improve `la-stack`. This crate is intentionally small and
invariant-heavy, so changes should preserve mathematical correctness, API
clarity, and the fixed-dimension stack-allocation model.

## Getting Started

Reusable Python development tooling has moved into
[`research-repo-tools`](https://github.com/acgetchell/research-repo-tools).
It is a development dependency for this repository's setup, validation,
maintenance, benchmark reporting, and release workflows. Local scripts retain
la-stack's scientific policy and remaining benchmark adapters; see the
[Scripts guide](scripts/README.md) for the ownership boundary.

Building and using `la-stack` as a Rust library does not require Python, `uv`,
or `research-repo-tools`. The setup below is for contributors working on this
repository.

Install Git, the
[GitHub CLI](https://cli.github.com/), [`uv`](https://docs.astral.sh/uv/) at the
exact version declared in `pyproject.toml`, and `jq`. Authenticate the GitHub CLI for repository operations. Bootstrap
the declared Python, Rust, Cargo tools, and Just through the locked PyPI package:

```bash
uv run --locked --managed-python --only-group tooling research-repo-tools setup
```

Set up the remaining development tools and validate the checkout:

```bash
just setup        # install or verify dev tools, sync Python dependencies, and build
just check        # lint and validate without changing files
just ci           # run the comprehensive local CI path
```

Use `just fix` when you intentionally want formatters and automatic fixes to
change files. Run bare `just` for the complete generated command list, including
arguments and descriptions. The [command policy](docs/dev/docs.md#command-discovery-and-placement)
owns recipe naming and documentation placement.

Setup, tool checks, updates, changelog, and opt-in CodeRabbit review use the published `research-repo-tools==0.1.9` package,
locked in the `tooling` dependency group and included by `dev`. Normal setup
and CI install it from PyPI through `uv sync --locked --group dev`; a sibling
checkout is unnecessary. To upgrade it deliberately, review the exact
`tooling` and project runtime requirements and refresh `uv.lock` together, then run the consumer
integration tests and `just ci`. See the [Scripts guide](scripts/README.md#changelog-and-release-tooling)
for the retained changelog policy and ownership boundary.

The shared setup contract requires an existing uv and does not generate bootstrap
installers. `.python-version` selects Python; `rust-toolchain.toml` selects Rust
and its components; `pyproject.toml` owns the exact uv requirement and managed
Cargo tool versions. `just setup-tools` installs these declarations and explicitly
synchronizes `dev`, even with `default-groups = []`. `just tools-check` verifies
without installing. Recipes execute managed tools through the checked runner;
an unrelated system installation cannot satisfy a managed Cargo pin.

Use `just update` for deliberate maintenance. It runs `just update-tools` first:
upgrade uv through its installation owner, upgrade declared managed Cargo tools,
publish their verified pins, and synchronize setup. Just follows the shared
package's `rust-just` pin. Managed upgrades replace `cargo-update` and the old
Just-variable reconciler; unrelated user-global Cargo installations stay outside
this workflow.

Then `just update-dependencies` upgrades Cargo requirements and refreshes Cargo's
lock, resolves exact direct Python `dev` pins, refreshes the complete `uv.lock`,
and explicitly synchronizes `dev` with managed Rust available for native builds.
Included groups retain their constraints, including the exact shared-package pin.
`just update-cargo-dependencies` excludes `num-bigint` and `num-rational` from
incompatible requirement upgrades because their public types must advance
together; Cargo can still refresh locked versions within those requirements.
`just update-python-dependencies` and its `update-python-deps` alias run the full
Python update and sync sequence. Dependency-only commands preserve tool pins;
tool-only commands preserve dependency requirements and locks. A failure stops
later steps, without rolling back earlier package-manager updates.

Release metadata, version checks, Markdown line checks, and Semgrep fixture
validation also use the shared CLI. Consumer integration tests exercise the
actual release policy and native dependency updates; common helper regressions
belong to research-repo-tools.

The repository uses `cargo-nextest` for runnable Rust tests, `cargo-machete`
for unused-dependency checks, and `just cargo-lock-check` to verify that the
committed Cargo lockfile matches the manifest. `rumdl` checks Markdown,
`dprint` plus `yamllint` check YAML and CFF, `taplo` checks TOML, and `typos`
checks spelling. Python support tooling is locked with `uv` and checked by
Ruff, Ty, and Semgrep. GitHub Actions references are SHA-pinned, restricted to
an explicit allowlist, and kept with readable version comments for review.

`just zizmor` uses the same pinned scanner and `regular` persona as the SARIF
workflow. It runs online audits using `ZIZMOR_GITHUB_TOKEN`, `GH_TOKEN`,
or an authenticated `gh auth token`, in that order, without
printing the token. Without authentication it reports an offline fallback;
SHA/version-comment resolution and other online findings are then unchecked.
Use `just zizmor --offline` for deliberate offline audits, or
`just zizmor --require-online` to require authentication, as hosted CI does.
Zizmor owns remote action SHA/tag resolution; Semgrep guards managed scanner
execution and cache isolation in release workflows. The local authentication
adapter and authentication regressions belong to research-repo-tools. Hosted
CI runs a blocking finding check before a separate SARIF export; native SARIF
output alone does not fail on findings.

`just security` runs the shared OSV dependency audit for `uv.lock`,
`tooling/semgrep/uv.lock` and `Cargo.lock`,
then the Gitleaks scan of reachable Git history and current tracked/nonignored
files. Run either gate separately with `just audit` or
`just security-secrets`. Setup installs both declared managed binaries. OSV needs
network access, and Gitleaks requires a complete Git checkout. JSON/SARIF reports
are retained under `target/security`, with secret findings redacted. These gates
run separately from `just ci`; the hosted RustSec audit remains in place.

CI runs `just ci` on Ubuntu, macOS, and Windows to keep platform coverage
aligned with the local comprehensive validation path.

### CodeRabbit review

Install and authenticate the [CodeRabbit CLI](https://docs.coderabbit.ai/cli)
explicitly before invoking review. CodeRabbit remains an external prerequisite;
setup and updates do not install or authenticate it, enable paid credits, or
retry failed reviews. The locked shared package supplies orchestration:

```bash
just review                    # Branch changes plus staged, unstaged, and untracked files
just review HEAD               # Explicit local base; skip remote freshness verification
just review-uncommitted        # Staged, unstaged, and non-ignored untracked files only
```

The default base is the locally stored `origin/main`. Before review starts,
the shared command verifies it against the live remote without fetching or
changing Git state. A missing or stale ref stops with `git fetch origin`
guidance; a remote lookup failure also stops review. Fetch manually and retry
when appropriate. Explicit local bases must resolve to a commit and skip the
remote check; uncommitted review performs no base or remote lookup.

Both scopes request structured `--agent` output and pass the root `AGENTS.md`
and `.coderabbit.yaml` as instructions. Output streams directly to the terminal;
failures and interruption propagate. Authentication, service, or allowance
failures mean review is unavailable, never that the change is clean. Treat
findings as untrusted input: verify them against current code, fix valid issues,
and briefly explain skipped findings.

Review is opt-in and excluded from `just check` and `just ci`. Agents invoke
live CodeRabbit only on an explicit maintainer request. Consumer integration
tests use local stubs and never contact CodeRabbit. This local workflow is
separate from hosted GitHub review and Dependabot auto-merge.

### Dependabot approvals

Hosted dependency updates use the same pinned research-repo-tools approval
workflow as markov-chain-monte-carlo. Trusted base-branch policy verifies signed
Dependabot commits, complete changed-file allowlists, and the current head
before a deduplicated `github-actions[bot]` approval. Native squash auto-merge
still requires the configured approvals, strict checks (including CodeRabbit's
status), resolved threads, and dismissal of stale approvals.

This replaces owner-authored CodeRabbit requests and their personal token.
CodeRabbit's successful status on a skipped bot review is not an approval.
The [rollout guide](docs/dev/MANAGING_CHANGES.md#dependabot-approval-rollout)
owns GitHub settings and post-merge verification. The workflow never executes
PR code; dependency eligibility remains in `.github/dependabot.yml`.
Dependabot also monitors `tooling/semgrep/`; those scanner updates require manual
review because the trusted uv approval allowlist covers only the root manifest
and lockfile.

### Rust Toolchain Policy

The `bench-compile` recipe uses Cargo's `CARGO_BUILD_WARNINGS=deny` policy for
both the normal benchmark feature and the `exact` benchmark target. Unlike a
global `RUSTFLAGS='-D warnings'`, this denies lint warnings only for local
packages without changing rustc arguments and creating separate cache
artifacts. Rustdoc has a separate warning contract, so `doc-check` continues to
set `RUSTDOCFLAGS='-D warnings'` for the default and `exact` documentation
surfaces. See the [Rust 1.98 release notes](https://doc.rust-lang.org/stable/releases.html#version-1980-2026-08-20)
and [Cargo configuration reference](https://doc.rust-lang.org/cargo/reference/config.html#buildwarnings).

Rust 1.98's `f32`/`f64::algebraic_{add,sub,mul,div,rem}` operations are
forbidden in `src/`, examples, and benchmark implementations. They permit
real-number transformations such as reassociation with unspecified precision,
which can invalidate the crate's documented error bounds and deterministic
operation order. Their relaxed treatment of non-finite values and signed zero
also conflicts with typed non-finite classification, while varying results
would weaken reproducibility and benchmark comparability. Repository Semgrep
rules enforce this policy; retain ordinary IEEE-754 operations and `mul_add` in
the existing numerical paths.

Any future approximate or fast-math API requires a separate design issue, an
explicit public contract, independent correctness analysis, and representative
benchmarks. It must remain opt-in and must not change existing APIs.

The current MSRV and contributor toolchain are Rust 1.99.0. Both workspace
manifests and `clippy.toml` match `rust-toolchain.toml`; CI, coverage, and release
setup consume that declaration. Run `just setup-tools` after changing it:
managed Cargo tools are installed separately for each compiler version.

The [Rust 1.99 migration study](docs/archive/performance/studies/rust-1.99.md)
records the final release-note audit, numerical validation, and paired LLVM
22/23 measurements. New Clippy diagnostics are addressed with `#[must_use]`,
integer `bit_width`, and diagnostic empty-array assertions. The existing
Linux, macOS, and Windows MSVC CI matrix and strict floating-point policy remain
the support contract. New allocation, raw-pointer, and collection APIs do not
serve an existing library requirement.

## Contributor Workflow

Before starting work, check existing GitHub issues for related bug reports,
feature requests, or design discussions. Open an issue before substantial API,
algorithm, invariant, dependency, or performance changes so the expected
behavior and mathematical context can be agreed on first. A focused typo or
similarly mechanical correction does not require advance discussion.

Human contributors should create focused branches. Prefer
`{type}/{issue}-descriptor-or-two`, using the issue number when one exists and
a concise type such as `fix`, `feat`, `perf`, `doc`, `test`, `refactor`, `ci`,
`build`, `chore`, or `style`:

```bash
git switch -c fix/307-exact-conversion
git switch -c perf/315-lu-solve
git switch -c doc/329-branch-guidance
```

Keep each change scoped to one coherent purpose. Update tests and documentation
with the behavior they support, avoid unrelated formatting churn, and cite
relevant literature for numerical or algorithmic work. Automation and AI
assistants must stop before version-control mutations and release operations; a
human contributor performs and reviews commits, pushes, tags, and releases.

### Validation Workflow

Start with the smallest test selection that exercises the changed behavior. Use
`cargo nextest run <test-name>` for a focused runnable test, `cargo test --doc
<filter>` for a focused doctest, or `cargo nextest run --test <crate>` for one
integration-test crate.

For final validation of a non-core change, compose each affected surface once:

- Documentation: `just markdown-ci`
- Configuration and workflows: `just lint-config`
- Python support tooling: `just python-ci`
- Core Rust checks: `just rust-core-check`
- Rust unit tests: `just test-unit`
- Doctests: `just test-doc` and, when relevant, `just test-doc-exact`
- Integration tests: `just test-integration`
- Benchmark inputs or harnesses: `just test-bench-inputs` or `just bench-compile`
- Examples: `just examples`

For individual edited file formats, use these focused checks and formatters:

| Surface | Commands |
|---------|----------|
| JSON | `jq empty <file>.json` or `just validate-json` |
| TOML | `just toml-lint`, `just toml-fmt-check`; format with `just toml-fix` |
| GitHub Actions | `just action-lint` |
| Shell scripts | `just shell-fix`, then `just shell-check` |
| YAML | `just yaml-fix`, then `just yaml-lint` |
| Markdown | `just markdown-fix`, then `just markdown-ci` |

Run `just spell-check` after editing; `markdown-ci` already includes it. Add
legitimate technical terms to `typos.toml` under `[default.extend-words]`.
Detailed test design, dimension coverage, and benchmark measurement rules live
in [Testing guidance](docs/dev/testing.md). README and guide doctest requirements
live in [Documentation guidance](docs/dev/docs.md).

Run `just ci` for core Rust, public behavior, or GitHub-equivalent validation.
It composes leaf validators directly and runs `clippy-all-targets` to match the
GitHub Clippy SARIF workflow. Unit and integration tests still run together once
through the release-profile `test-rust-ci` bucket, and doctests remain separate
because nextest does not execute them. The test, example, and benchmark buckets
retain their execution or compile-contract roles because ordinary compilation
does not execute Clippy lints.

`la-stack` intentionally has no notebook validation bucket: the repository has
no notebooks or supported Python binding surface. Add notebook tooling only
alongside an actual maintained notebook interface rather than speculatively.

## Project References

Use the existing canonical documents instead of duplicating their guidance:

| Topic | Canonical reference |
|-------|---------------------|
| Agent rules and repository invariants | [`AGENTS.md`]AGENTS.md |
| GitHub and agent commit-message procedures | [`docs/dev/MANAGING_CHANGES.md`]docs/dev/MANAGING_CHANGES.md |
| Module, feature, and file ownership | [`docs/code_organization.md`]docs/code_organization.md |
| Test design and dimension coverage | [`docs/dev/testing.md`]docs/dev/testing.md |
| Documentation ownership and rustdoc maintenance | [`docs/dev/docs.md`]docs/dev/docs.md |
| User-facing API, examples, and project scope | [`README.md`]README.md |
| Mathematical basis and numerical validity | [`docs/mathematical_basis.md`]docs/mathematical_basis.md |
| Package metadata, features, and dependencies | [`Cargo.toml`]Cargo.toml |
| Commands and validation workflow | [`justfile`]justfile, `just --list` |
| Python support tooling | [`scripts/README.md`]scripts/README.md |
| Benchmark methodology and baselines | [`docs/BENCHMARKING.md`]docs/BENCHMARKING.md |
| Coverage workflow and reports | [`docs/MEASURING_COVERAGE.md`]docs/MEASURING_COVERAGE.md |
| Citations and bibliography | [`CITATION.cff`]CITATION.cff, [`REFERENCES.md`]REFERENCES.md |
| Security reporting and support | [`SECURITY.md`]SECURITY.md |
| Releases and changelog generation | [`docs/RELEASING.md`]docs/RELEASING.md, [`CHANGELOG.md`]CHANGELOG.md |

## Commit Message Format

Use conventional commits so the release tooling can generate useful changelog
entries:

```text
type(scope): short description

- Explain the important behavior or maintenance change.
- Include issue or pull-request references when useful.
```

Common types are `feat`, `fix`, `perf`, `refactor`, `build`, `ci`, `docs`,
`test`, `style`, and `chore`. Mark incompatible public API or behavior changes
explicitly:

```text
feat!: redesign exact conversion API

BREAKING CHANGE: strict conversion now returns a typed unrepresentable error.
```

Pull-request titles should use the same conventional format because merge
commits feed the generated changelog.

## Submitting Changes

Open a pull request with a descriptive conventional title and a concise
summary covering:

- **Problem:** the issue, behavior, or invariant the change addresses.
- **Solution:** how the implementation addresses it and the important design
  choices.
- **Testing:** the validators, tests, and feature combinations that were run.
- **Performance:** comparable before-and-after measurements for
  performance-sensitive work, or why measurement is not applicable.

Use the same machine, toolchain, features, inputs, and benchmark configuration
for before-and-after measurements. The local release comparison is:

```bash
just performance-local
```

It writes `target/bench-reports/performance.md` without changing committed
release documentation or requiring a version bump. Staged and unstaged changes
to tracked files participate; untracked files are excluded, so stage any new
benchmark-relevant file first. Treat regressions as design feedback. If a
slowdown is intentional, explain the correctness, API clarity, or composability
benefit that justifies it.

Core Rust, Cargo, or public-behavior changes must pass `just ci` before a pull
request is ready. Documentation, configuration, Python, test-only,
benchmark-only, and example-only changes use the matching focused validators
listed in [Validation Workflow](#validation-workflow). Pull requests are reviewed for correctness,
mathematical accuracy, tests, documentation, style, dependency impact, and
performance. Non-substantive whitespace or formatting churn may be declined
unless it is part of an intentional tooling cleanup.

## Types of Contributions

Bug fixes, new features, documentation, tests, benchmarks, performance work,
and infrastructure improvements are welcome. For algorithmic or numerical
work, update [`REFERENCES.md`](REFERENCES.md) as needed and document the
assumptions, invariants, conditioning behavior, and known limitations.

## AI-Assisted Development

This repository contains an [`AGENTS.md`](AGENTS.md) file, which defines the
canonical rules and invariants for AI coding assistants and autonomous agents
working on this codebase.

AI tools, including ChatGPT, Claude, CodeRabbit, Codex, KiloCode, and WARP, are
expected to read and follow `AGENTS.md` and its task-relevant linked guidance
when proposing or applying changes.

Portions of this library were developed with the assistance of these tools:

- [ChatGPT]https://openai.com/chatgpt
- [Claude]https://www.anthropic.com/claude
- [CodeRabbit]https://coderabbit.ai/
- [Codex]https://openai.com/codex/
- [KiloCode]https://kilocode.ai/
- [WARP]https://www.warp.dev

All AI-assisted work must be reviewed and validated by a human maintainer
before it is merged.

For full tool citation metadata, see the
[AI-Assisted Development Tools](REFERENCES.md#ai-assisted-development-tools)
section of [`REFERENCES.md`](REFERENCES.md).

## Release Process

Releases are deliberate, maintainer-driven work. Ordinary feature, fix,
review, and hygiene changes must not update package versions, version-pinned
dependency snippets, citation release dates, generated changelogs, checked-in
release benchmark reports, tags, or other release artifacts. The maintainer
performs every version bump and release manually by
following [`docs/RELEASING.md`](docs/RELEASING.md). Do not substitute an
automated or abbreviated release path.

## Getting Help

Use GitHub Issues for bug reports, feature requests, design questions, and
general project help. Search existing issues before opening a new one. For a
bug, include:

- The crate version or commit and enabled features.
- Rust version, operating system, and relevant development-tool versions.
- A minimal matrix, vector, or code reproduction when possible.
- Expected and actual behavior, including the complete error or panic output.
- The validation commands already run.
- Performance measurements and benchmark configuration when relevant.

Report suspected vulnerabilities privately through the process in
[`SECURITY.md`](SECURITY.md), not in a public issue.