Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .github/CODEOWNERS
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# Every change needs an approving review from an author who did not write it.
* @max578 @aidanmoller
7 changes: 7 additions & 0 deletions .github/pull_request_template.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,12 @@ Link the issue this closes, so that merging closes it:
<!-- One or two sentences. The why matters more than the what, which the diff
already shows. -->

## Plan

<!-- The plan.md this change implements (dev/work/<date>-<slug>/plan.md), and
any departure from it, recorded in the same commit as the change. A
change to the numerical core without a plan is a review finding. -->

## How it was checked

<!-- Which of these ran, and what they said. A change to the numerical core
Expand All @@ -21,6 +27,7 @@ Link the issue this closes, so that merging closes it:
- [ ] `R CMD check --as-cran`
- [ ] `Rscript tools/oracle/check_fixture_provenance.R`, if any fixture changed
- [ ] `NEWS.md` entry, for anything a user would notice
- [ ] Any test, fixture or tolerance changed is listed here

## Anything left open

Expand Down
35 changes: 35 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
# Contributing

`acir` is developed by its two authors under the process in `dev/PROCESS.md`.
Contributions from outside are welcome and pass through the same stages.

## Proposing a change

Open an issue, or write an `intent.md` from `dev/work/_template/` in a new
directory `dev/work/<date>-<slug>/` and open a pull request containing only
it. An accepted intent is one whose pull request merges.

## Building a change

Write `plan.md` before code: the files that change, the order of work, the
risks, and the proof that the change works. Commit it. Then make the change,
and if the implementation departs from the plan, update the plan in the same
commit.

## Before opening a pull request

Run the four gates in `dev/PROCESS.md` and quote their output in the pull
request under *How it was checked*. A change to the numerical core needs the
oracle tests, not only a green suite, because those are graded against a
source this repository did not author.

## Review

Every pull request is reviewed under `REVIEW.md` and needs one approving
review from an author who did not write it. Branch protection on
`acir-package` and `main` enforces this and the required checks.

## Reporting

Bugs and numerical disagreements have issue templates under
`.github/ISSUE_TEMPLATE/`. Security reports go through `SECURITY.md`.
31 changes: 31 additions & 0 deletions REVIEW.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# Review policy

This applies to every pull request into `acir-package` and `main`, and to
every reviewer, human or automated. A review is a list of findings ranked by
severity. Approval is a separate act, by an author who did not write the
change, and branch protection requires it before a merge.

## Three passes

1. **Numbers.** Does any graded quantity move? Check the evidence register
(`acir/inst/evidence/register.csv`), the fixtures it names and their
tolerance classes. A test, fixture or tolerance that changed is a finding
whether or not the pull request declares it.
2. **Code.** Logic errors and edge cases: short records, one-dimensional
against multi-dimensional states, the freeze paths, the generic-model
route against the library route. The provenance of any ported kernel.
3. **Compliance.** Does the change match its `plan.md`, with departures
recorded in the same commit? Is there a `NEWS.md` entry for anything a
user would notice, and a register row for any new export?

## Blocking against nit

Blocking: a number outside its tolerance; a test weakened or removed; a gate
bypassed; a fixture changed without provenance; a change to the numerical
core without a plan. Everything about style, naming or wording is a nit.
Report at most five nits and give the rest as a count.

## Not reported

Anything CI already enforces (lint, check, coverage, bench), generated files
(`man/`, `NAMESPACE`), and the parents' code at the tag `parents-final`.
97 changes: 97 additions & 0 deletions dev/PROCESS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
# How `acir` is developed

This document describes the development process of the repository: the
stages a change passes through, the artefact each stage commits, the gate
that closes it, and who decides. It follows the stage-and-artefact discipline
of the AI-native software development lifecycle playbook (Claxton, 2026),
adapted to a two-author scientific package whose deliverable is a numerical
result graded against the method authors' reference implementation.

Development uses AI coding assistance. The process below is what makes that
assistance auditable: what was asked is committed before what was built, what
was built is graded against a source its author did not write, and every
change is approved by an author who did not make it. `dev/acir-process-rationale.md`
records how the package was assembled before this process was written down;
this process applies from 2026-09-02.

## The stages

| Stage | Artefact | Where it lives | Gate | Who decides |
|:---|:---|:---|:---|:---|
| Plan | `intent.md`: problem, proposed outcome, affected code, constraints, open questions | `dev/work/<date>-<slug>/intent.md` | accepted by the other author when its pull request merges | the authors |
| Design | `spec.md`: requirements, design, flagged concerns | same directory; the package-level specification is `dev/specification.md` | flagged concerns resolved before engineering starts; the other author signs off | the authors |
| Build | `plan.md`: files that change, order of work, risks, proof | same directory, committed before code; a departure is recorded in the same commit as the change that causes it | a reader unfamiliar with the change could implement it from the plan alone | the author of the change |
| Test | the diff, its tests, the evidence register | `acir/tests/`, `acir/inst/evidence/register.csv`, `.github/workflows/` | the four gates below, locally before the pull request and again in CI | CI, deterministically |
| Deploy | review findings ranked by severity | the pull-request thread, under `REVIEW.md` | one approving review from an author who did not write the change; branch protection enforces it | the reviewing author |
| Maintain | incident record | a new `intent.md` | a bench breach or a numerical disagreement re-enters at Plan | the authors |

## The four gates

Every pull request into `acir-package` carries these, and CI runs them again.

1. **Numbers.** Every fixture in `acir/inst/evidence/register.csv` at its
tolerance class, and the package's stored outputs on the reference records
within 1e-12 of their values before the change. A change that moves a
number beyond round-off is a change of method and is reviewed as one.
2. **Time.** The Section 8 stages timed against the committed baseline
(`tools/bench/baseline.csv`) on the CI runner, relative to the runner
(`.github/workflows/bench.yaml`).
3. **Hygiene.** `R CMD check --as-cran` at zero errors and zero warnings on
six platforms, lint clean, coverage not below the floor, fixture
provenance verified (`tools/oracle/check_fixture_provenance.R`).
4. **Provenance.** Every ported kernel names its source file and function and
the tag it was taken from, in the roxygen and in `acir/NEWS.md`.

## Verifying a change before opening a pull request

Run from the repository root, with the package installed from source. Each
command exits non-zero on failure, and its output is quoted in the pull
request under *How it was checked*.

```sh
Rscript -e 'devtools::test("acir")'
Rscript -e 'lintr::lint_package("acir")'
R CMD build acir && R CMD check --as-cran acir_*.tar.gz
Rscript tools/oracle/check_fixture_provenance.R
```

If a test fails, the fix is to the code. A change to a test, to a fixture or
to a tolerance is a change to the evidence, is listed in the pull request,
and is a review finding in its own right.

## Correspondence to the playbook

| Play in the playbook | Practice here | Status |
|:---|:---|:---|
| Capture as `intent.md` | `dev/work/<date>-<slug>/intent.md` | in use |
| Requirements and design as `spec.md` | `dev/work/<date>-<slug>/spec.md`; package-level `dev/specification.md` | in use |
| Plan before code, `plan.md` | `dev/work/<date>-<slug>/plan.md`, committed before the change | in use |
| Institutional knowledge as agent configuration (`CLAUDE.md`, skills, hooks) | not part of this repository; each author's tooling configuration stays with that author | not used in the repository |
| Parallel sessions in worktrees | one branch per work package, one writer per branch | in use |
| Feedback loop before reporting done | the four gates, run locally and in CI | in use |
| Continuous evaluation of agent configuration | not applicable to the repository | not used |
| Review loop under a written policy | `REVIEW.md`; approval by a human author is required | in use |
| Hooks as approval gates | branch protection on `acir-package` and `main`: pull request required, one approving review, nine required checks, no force push | in use, enforced by the host |
| An agent inside CI/CD | not used; CI is deterministic | not used |
| Control bands in maintenance | `bench.yaml` compares every run with `baseline.csv`; a breach is triaged by the authors and re-enters as an intent | in use, with a manual response |
| Recurring security scans | not used; the package opens no network connection (`SECURITY.md`) | not used |
| On-call automation | not applicable | not used |

## What is measured

Read from the pull-request history when needed, not automated: the share of
pull requests whose checks pass on the first run, the time from a pull request
opening to its first review, and whether the merged diff matches the committed
plan. The bench workflow records the timing of every run as an artefact.

## First recorded instance

`dev/work/2026-09-01-performance/` is the performance work package: the
intent and specification were recorded inside its plan at the time and are
separated here, and the plan is the version approved on 2026-09-01 after
review. Later work packages start from `dev/work/_template/`.

## Reference

Claxton, L. (2026, August 21). *The AI-native SDLC playbook*. Anthropic.
https://claude.com/blog/the-ai-native-sdlc-playbook
Loading
Loading