Skip to content

Latest commit

 

History

History
165 lines (113 loc) · 8.75 KB

File metadata and controls

165 lines (113 loc) · 8.75 KB

AGENTS.md

This file provides guidance to AI coding agents when working with code in this repository.

Keep in sync: CLAUDE.md, AGENTS.md, and .github/copilot-instructions.md must contain identical guidance (except for the first heading). When updating one, update all three.

Overview

Shared library repository for Down Syndrome Education International (DSE) research projects. The primary artifact is dse-research-utils, a Python utility package (src/python/). A .NET utilities area (src/dotnet/) is a future placeholder.

AI tool attribution

When you draft or author any of the following, you must prefix it with a callout that identifies the AI tool used. Place the callout as the first lines of the body:

  • document drafts
  • pull request descriptions
  • issue descriptions
  • comments on pull requests
  • comments on issues

Substitute the actual tool and model you are running as (for example, GitHub Copilot or Claude Code/Opus 4.8). This requirement applies to every drafted artifact so that human reviewers can readily distinguish AI-generated content.

Use the callout syntax that matches where the text will render:

GitHub surfaces — pull request descriptions, issues, and their comments — use GitHub alert syntax:

> [!NOTE]
> Drafted by a LLM-based AI tool (Claude Code/Opus 4.8).

Quarto documents (.qmd) — GitHub alert syntax does not render in Quarto, so use a Quarto callout block instead:

::: {.callout-note appearance="simple"}
Drafted by a LLM-based AI tool (Claude Code/Opus 4.8).
:::

Quarto supports five callout types (note, tip, warning, caution, important); use note for attribution. Drop appearance="simple" for the default boxed style, or add collapse="true" to make it collapsible.

Markdown authoring

When drafting Markdown — repository documents, pull request descriptions, issue descriptions, or comments on either — write each paragraph as a single unwrapped line and avoid superfluous line breaks. Do not hard-wrap prose at a fixed column or scatter extra blank lines; let the renderer wrap the text. Prettier runs with proseWrap: "preserve", so any manual wrapping is kept verbatim and produces noisy diffs.

Commit messages

Follow Conventional Commits for every commit — this applies to agents and humans alike.

  • Subject line: <type>[optional scope]: <description> (for example feat(plot): add credible-interval helper or fix: guard against zero variance).
  • Common types: feat, fix, docs, refactor, perf, test, build, ci, chore, revert.
  • Keep the description in the imperative mood and concise, with no trailing period.
  • Flag breaking changes with a ! before the colon (for example feat!:) or a BREAKING CHANGE: footer.
  • Add a body separated from the subject by a blank line when the change needs explanation.

Repositories using these libraries

Current projects using these libraries include:

To support developing across these repositories simultaneously, we typically check these out relative to this project as follows:

  • ../language-reading-predictors
  • ../vocabulary-growth
  • ../../dspopulations/us-birth-certificates

Commands

Spellcheck

npm ci
npm run spellcheck      # runs cspell over all *.md files

Markdown format

npm run format          # rewrites Markdown files in place
npm run format:check    # checks Markdown formatting without rewriting

Uses Prettier with proseWrap: "preserve" so existing prose line breaks are kept.

Python — environment

conda env create -f environment.yml   # create (Python 3.14, conda required — not pip/venv)
conda activate dse-research

Python — build

cd src/python
python -m build         # builds wheel via hatchling

Python — lint and format

cd src/python
ruff check .            # lint
ruff check . --fix      # lint with auto-fix
ruff format .           # format

Python — tests

pytest                                           # full suite
pytest path/to/test_file.py                      # single file
pytest path/to/test_file.py::test_function_name  # single test

Architecture

src/python/src/dse_research_utils/ is structured by domain:

  • environment/ — system info, execution context; init_workbook() / init_script() for notebook/script setup
  • math/ — constants (EPSILON, etc.)
  • metadata/ — package version introspection
  • ml/ — ML utilities (placeholder)
  • plot/ — matplotlib/ArviZ plotting helpers; constants follow FIGSIZE_XS, COLOUR_BLUE, DPI_NOTEBOOK naming
  • report/ — report data-access helpers (ReportData, show_or_pending) that read a fitted model's artefacts and degrade to a visible "pending fit" placeholder before a fit exists
  • statistics/ — descriptive stats; credible/confidence intervals (intervals.hdi_1d / eti_1d / eti_bands); the shared evidence ladder (evidence.py: evidence_label / odds_string / favoured_direction); the ROPE report card (rope.py: rope_card); the MCMC convergence gate, banner, and styled diagnostics table (diagnostics.py); and PyMC models and sampling presets

All __init__.py files are empty — no re-exports. Use fully-qualified absolute imports everywhere (e.g. from dse_research_utils.math.constants import EPSILON).

statistics/models/reporting.ReportingConfiguration carries the reporting ci_prob (credible-interval coverage) and interval_kind ("eti" equal-tailed or "hdi" highest-density); reports read both back so tables, plots, and the diagnostics summary agree on the interval convention. Credible-interval coverage defaults to 0.89 across the shared helpers (hdi_1d, eti_1d, rope_card, ReportingConfiguration.ci_prob, …), matching ArviZ's rcParams["stats.ci_prob"]; a report that wants a different width passes it explicitly (e.g. vocabulary-growth uses 0.90, language-reading-predictors uses 0.95).

Bayesian sampling presets in statistics/models/sampling.py, selected via get_sampling_configuration(config):

  • dev / development — 2 chains × 500 draws, target_accept=0.85 (fast iteration)
  • test / testing — 4 chains × 2000 draws, target_accept=0.90
  • rep-lite / reporting-lite / rep_lite — 4 chains × 4000 draws, target_accept=0.95
  • reporting / report / rep — 6 chains × 6000 draws, target_accept=0.95

Python Conventions

License header — every source file starts with:

# Copyright (c) 2026 Down Syndrome Education International and contributors
# SPDX-License-Identifier: AGPL-3.0-or-later
  • Naming: snake_case for files/functions/variables; UPPER_CASE for constants grouped by domain (e.g. FIGSIZE_XS, COLOUR_BLUE, DPI_NOTEBOOK)
  • Type hints: always on function signatures
  • Type unions: X | Y syntax (not Union[X, Y])
  • Docstrings: NumPy-style (Parameters, Returns, --- separators); dataclass fields use attribute docstrings (bare string literals after the field declaration)
  • print: import from rich import print to override built-in
  • Imports: fully-qualified absolute imports only — no relative imports, no __init__.py re-exports. The package root __init__.py is the one exception: it stores __version__ for Hatch.
  • Dataclasses: stdlib @dataclass; use __post_init__ for validation
  • Plot functions: create figure → render → optionally save to output_dir as .png (300 DPI) and .svgreturn plt.gcf()
  • Notebooks: call init_workbook() at top (prints environment info); scripts call init_script() (silent setup); both apply the default matplotlib style via set_matplotlib_default_style()

Ruff config (in src/python/pyproject.toml): line-length 120, target Python 3.14, rules: F, E, W, I, UP, B, SIM, RUF, ANN (source only; tests ignore annotation rules).

.NET

SDK pinned to 10.0.200 (rollForward: latestMinor) via global.json. Test runner is Microsoft.Testing.Platform. NuGet sources: nuget.org (all packages) and dseinternational (https://nuget.pkg.github.com/dseinternational/index.json, DSE.* packages only) — package source mapping enforced with <clear />. No projects exist yet.