Developer Guide#
Installation From Source (Development)#
Clone the repository and install in editable mode with the dev dependency group (which provides pytest, pre-commit, and ipython):
pip install -e . --group dev
Project Layout#
historia/
├── src/historia/ # Main package source
│ ├── _cli.py # CLI entry points
│ └── data/
│ └── github/ # GitHub data fetch/dump/update APIs
├── tests/ # Pytest test suite
├── docs/ # Sphinx documentation source
├── AGENTS.md # Agent/AI contributor instructions
├── CHANGELOG.md # Release changelog
└── pyproject.toml # Project metadata and tool configuration
Testing#
This project uses pytest for its test suite.
python -m pytest
Assertion Style#
Always place the actual (observed) value on the left and the expected value on the right:
# Correct
assert actual_value == expected_value
# Incorrect
assert expected_value == actual_value
AI-Generated Tests#
Tests written or substantially assisted by AI must be marked with the ai_generated marker:
import pytest
@pytest.mark.ai_generated
def test_something():
...
Use pytest.mark.parametrize wherever appropriate to reduce test duplication.
Code Quality (Pre-commit Hooks)#
This project uses pre-commit to enforce code quality automatically before each commit.
The configured hooks are:
black — code formatting
ruff — linting and import sorting (with auto-fix)
codespell — spell checking
mypy — static type checking
Install the hooks once after cloning:
pre-commit install
Run all hooks manually against all files (recommended before opening a PR):
pre-commit run --all-files
Pre-commit will auto-fix most formatting and lint issues. Re-run the command afterward to confirm everything passes.
CLI#
The Historia package exposes a single entry point:
historia— primary entrypoint
Commands are organized into sub-groups:
historia update— data managementhistoria update github— fetch raw GitHub activity data for a user
historia project— GitHub Project managementhistoria project create— create a new GitHub Project pagehistoria project populate— populate a project from fetched datahistoria project update dates— update item date fields in a projecthistoria project transition— transition project items between statuses
Since every command requires at least one option, running any command or sub-group without arguments automatically prints its help text:
historia
historia update
historia project
Changelog#
Add a short description of any user-facing change to the ## Upcoming section of CHANGELOG.md under the appropriate subsection:
### 🚀 Enhancement— new features### 🐛 Bug Fix— bug fixes### 📝 Documentation— documentation-only changes### 🏠 Internal— refactors, tooling, CI, and test infrastructure### 🔩 Dependency Updates— dependency-only changes
Include the GitHub PR link at the end of each entry:
- Brief description of the change. ([#N](https://github.com/CodyCBakerPhD/historia/pull/N))
Building Documentation#
Building Locally#
Install the docs dependencies:
pip install -e . --group docs
Build the HTML output:
python -m sphinx -b html docs docs/_build/html
Open docs/_build/html/index.html in your browser to preview the result.
AI Usage Addendum#
Materials across repositories in this organization have been prepared with the assistance of agentic AI coding tools and large language models (LLMs), alongside direct human authoring and supervision.
Our working practice is: 👤 Human review and accountability. We strive to have final versions of all work — prose, code, figures, and specifications — to be reviewed and/or edited by human authors, who remain accountable for the content. 🪪 Transparent annotation. Where AI tools materially contributed to a commit, we strive to annotate that commit adequately and trustworthily (for example, via a Co-Authored-By trailer identifying the tool and model version), so that the provenance of individual changes can be inspected in the git history. 🔍 Inspectable provenance. Because all work is developed in public git repositories with pull-request review, readers can trace portions of the materials which involved AI assistance.
AI tools are used as assistive instruments; they do not substitute for the scientific judgment, domain expertise, or editorial responsibility of the human authors.
Agent / AI Contributor Instructions#
Agent instructions#
Always run
pre-commitbefore committing and pushing changesTo the best of your ability, ensure tests are passing
Follow assertion style (actual on left, expected on right)
Always mark AI-generated tests with
ai_generatedPytest markerAttempt to utilize
pytest.mark.parametrizewherever appropriate to reduce duplication in test casesFor tests, avoid importing private-marked API functions (those with leading underscores) and always favor importing what is publicly exposed through
__init__.pyfilesBump the version in
pyproject.tomlonce per pull request when either any file undersrc/changes (excludingtests/anddocs/), orpyproject.tomlitself changes.; do NOT bump for changes that are purely CI/workflow, documentation, or configuration (e.g., GitHub Actions workflows,AGENTS.md,README.mdbadges)For API signatures, require keyword arguments for multi-input functions using
(*, ...). For any function with exactly one caller-supplied parameter (excludingselfandcls), require positional-only usage with the/designatorLeave a short description of the change or addition in the top
## Upcomingsection of theCHANGELOG.mdunder the appropriate subsection (### 🚀 Enhancement,### 🐛 Bug Fix,### 📝 Documentation,### 🔩 Dependency Updates, or### 🏠 Internal) as a new item (line starts with-); create the subsection if it does not yet exist; include the GitHub PR link at the end of each entry in the format([#N](https://github.com/stamped-principles/stamped-checklist/pull/N)PR titles should be human-readable and in the past tense; they should NOT use conventional commit style
Always add new imports to the top of the file rather than locally scoped inside a function; the only exception is if it is needed to avoid a circular dependency
Never include code other than imports,
__all__, simple import errors, or magic__dir__overrides in any__init__.pyfileFor external dependencies, always avoid specific import style (e.g., using
import abc from xyzkeyword) in favor of the generic full import (e.g.,import xyz; xyz.abc)For internal imports, always use the relative import style (e.g.,
from .foo import bar); when monkeypatching such imports in tests, target the importing module’s binding, not the original definition module (e.g.,foo.baz, instead offoo._bar.baz)Every commit you author MUST include a
Co-Authored-Bytrailer identifying both your tool name + version and your underlying model + version. Format (replace all<…>placeholders with actual values): `Co-Authored-By:/ <noreply@ > Avoid using excessive em-dashes, colons, and semi-colons in written text such as documentation. Prefer breaking into separate, shorter sentences instead
Prefer assigning return values to named locals before
returnwhen this improves readability and debugger breakpoint placementNever expose private names (those with a leading underscore) in any module’s
__all__Do not add compatibility aliases when renaming functions. Update all call sites to the canonical name instead
Favor defining one-word names for CLI flags, then map those onto longer more explicit keyword arguments at the API level