Skip to content
Draft
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
15 changes: 15 additions & 0 deletions .github/copilot-instructions.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# Copilot Instructions

Follow the repository's canonical engineering skills under
`docs/engineering/skills/`.

For API v2 migration contract, route-group metadata, generated migration docs,
or migration guard changes, read
`docs/engineering/skills/migration_contracts.md`.

For tests, read `docs/engineering/skills/testing.md` before adding, moving, or
reviewing test files.

For pull requests, read `docs/engineering/skills/github-prs.md` before opening,
replacing, or sharing a PR.

12 changes: 12 additions & 0 deletions .github/workflows/pr.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,18 @@ jobs:
run: pip install ruff>=0.9.0
- name: Format check with ruff
run: ruff format --check .
quality-guards:
name: Quality guards
runs-on: ubuntu-latest
steps:
- name: Checkout repo
uses: actions/checkout@v4
- name: Setup Python
uses: actions/setup-python@v5
with:
python-version: "3.12"
- name: Run quality guards
run: python scripts/run_quality_guards.py
check-changelog:
name: Check changelog fragment
runs-on: ubuntu-latest
Expand Down
29 changes: 29 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
# Agent Instructions

These instructions apply repository-wide.

## Skills System

Canonical AI-facing engineering skills live under `docs/engineering/skills/`.
Use those files as the source of truth across Codex, Claude, Copilot, and other
AI tools.

When changing API v2 migration contracts, route-group migration metadata, PR
cutover plans, generated migration docs, or migration guard scripts, read
`docs/engineering/skills/migration_contracts.md`.

When adding, moving, or reviewing tests, read
`docs/engineering/skills/testing.md`.

## GitHub PRs

Read `docs/engineering/skills/github-prs.md` before opening, replacing, or
sharing any pull request.

Before creating or sharing a migration PR, run the focused migration guards:

```bash
python scripts/run_quality_guards.py
python scripts/export_migration_contracts.py
```

31 changes: 31 additions & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# Claude Instructions

These instructions apply repository-wide.

## Canonical Guidance

Repository-wide AI-facing engineering guidance lives in `AGENTS.md`.
Canonical skills live under `docs/engineering/skills/`.

Use those files as the source of truth. This file is a Claude adapter and should
stay thin; do not duplicate detailed testing, CI, formatting, or architecture
rules here.

## Required Skill Lookup

Before opening, replacing, or sharing a PR, read
`docs/engineering/skills/github-prs.md`.

When changing API v2 migration contracts, route-group migration metadata,
generated migration docs, or migration guard scripts, read
`docs/engineering/skills/migration_contracts.md`.

When adding, moving, or reviewing tests, read
`docs/engineering/skills/testing.md`.

## Safety Boundaries

Do not claim a route, database table, compute path, or deployment surface has
migrated unless the relevant contract tests, migration flags, and generated
migration docs identify that state.

7 changes: 5 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,11 @@ test-env-vars:
pytest tests/env_variables

test:
MAX_HOUSEHOLDS=1000 coverage run -a --branch -m pytest tests/to_refactor tests/unit tests/integration/test_budget_window_in_flight_dedupe.py --disable-pytest-warnings
coverage xml -i
MAX_HOUSEHOLDS=1000 python -m coverage run -a --branch -m pytest tests/to_refactor tests/unit tests/contract tests/integration/test_budget_window_in_flight_dedupe.py --disable-pytest-warnings
python -m coverage xml -i

quality-guards:
python scripts/run_quality_guards.py

debug-test:
MAX_HOUSEHOLDS=1000 FLASK_DEBUG=1 pytest -vv --durations=0 tests
Expand Down
1 change: 1 addition & 0 deletions changelog.d/migration-pr1-contract-harness.added.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Added migration contract tests, typed migration registries, no-op source flags, migration-context logging, baseline capture tooling, and model-agnostic AI harness docs for the API v2 migration.
100 changes: 100 additions & 0 deletions docs/engineering/migration-contracts.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
# Migration Contracts

Generated from `policyengine_api/migration_registry.py` and `tests/contract/registry.py`.

## Summary

| Metric | Count |
| --- | ---: |
| route group count | 10 |
| workflow count | 7 |
| request count | 14 |
| db entity count | 6 |
| sim flow count | 3 |

## Route Groups

| Route group | Path segments | DB entity | Simulation flow |
| --- | --- | --- | --- |
| `metadata` | `metadata` | `metadata` | `none` |
| `policy` | `policy`, `policies`, `user-policy` | `policy` | `none` |
| `household` | `household`, `calculate`, `calculate-full` | `household` | `household` |
| `economy` | `economy` | `simulation` | `economy` |
| `simulation` | `simulation`, `simulations` | `simulation` | `economy` |
| `report` | `report` | `report` | `report` |
| `user_profile` | `user-profile` | `user` | `none` |
| `simulation_analysis` | `simulation-analysis` | `none` | `none` |
| `tracer_analysis` | `tracer-analysis` | `none` | `none` |
| `ai` | `ai-prompts` | `none` | `none` |

## App V2 Workflow Contracts

### `policy_save_search`

- Current contract: `api_v1_compatible`
- Future owner: PR 10: Policy Migration

| Method | Path | Status | Route group | Stable response fields |
| --- | --- | ---: | --- | --- |
| `POST` | `/us/policy` | 201 | `policy` | `status`, `message`, `result.policy_id` |
| `GET` | `/us/policy/{policy_id}` | 200 | `policy` | `status`, `message`, `result` |
| `GET` | `/us/policies` | 200 | `policy` | `result` |

### `household_save_edit_read`

- Current contract: `api_v1_compatible`
- Future owner: PR 11: Household Migration

| Method | Path | Status | Route group | Stable response fields |
| --- | --- | ---: | --- | --- |
| `POST` | `/us/household` | 201 | `household` | `status`, `message`, `result.household_id` |
| `PUT` | `/us/household/{household_id}` | 200 | `household` | `status`, `message`, `result.household_id` |
| `GET` | `/us/household/{household_id}` | 200 | `household` | `status`, `message`, `result` |

### `household_calculate`

- Current contract: `api_v1_compatible`
- Future owner: PR 13: Household Calculation Compute Cutover

| Method | Path | Status | Route group | Stable response fields |
| --- | --- | ---: | --- | --- |
| `POST` | `/us/calculate` | 200 | `household` | `status`, `message`, `result` |

### `region_selection`

- Current contract: `api_v1_compatible`
- Future owner: PR 9: v2 Metadata, Regions, Datasets, Parameters, and Variables

| Method | Path | Status | Route group | Stable response fields |
| --- | --- | ---: | --- | --- |
| `GET` | `/us/metadata` | 200 | `metadata` | `status`, `result.current_law_id`, `result.economy_options.region`, `result.economy_options.time_period` |
| `GET` | `/uk/metadata` | 200 | `metadata` | `status`, `result.current_law_id`, `result.economy_options.region`, `result.economy_options.time_period` |

### `simulation_submit_poll`

- Current contract: `api_v1_compatible`
- Future owner: PR 13: Household Calculation Compute Cutover

| Method | Path | Status | Route group | Stable response fields |
| --- | --- | ---: | --- | --- |
| `POST` | `/us/simulation` | 201 | `simulation` | `status`, `message`, `result.id`, `result.status` |
| `GET` | `/us/simulation/{simulation_id}` | 200 | `simulation` | `status`, `message`, `result` |

### `report_create_poll`

- Current contract: `api_v1_compatible`
- Future owner: PR 14: Economy Simulation and Economic Impact Compute Cutover

| Method | Path | Status | Route group | Stable response fields |
| --- | --- | ---: | --- | --- |
| `POST` | `/us/report` | 201 | `report` | `status`, `message`, `result.id`, `result.status` |
| `GET` | `/us/report/{report_id}` | 200 | `report` | `status`, `message`, `result` |

### `budget_window_submit_poll`

- Current contract: `api_v1_compatible`
- Future owner: PR 15: Budget-Window and Remaining Simulation API Migration

| Method | Path | Status | Route group | Stable response fields |
| --- | --- | ---: | --- | --- |
| `GET` | `/us/economy/{policy_id}/over/{baseline_policy_id}/budget-window?region=us&start_year=2026&window_size=1` | 200 | `economy` | `status`, `result.kind`, `progress`, `completed_years`, `computing_years`, `queued_years`, `error` |
17 changes: 17 additions & 0 deletions docs/engineering/skills/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# Engineering Skills

This directory is the canonical source for AI-facing engineering rules.

Tool-specific instruction files such as `AGENTS.md`, `CLAUDE.md`, and
`.github/copilot-instructions.md` should point here instead of duplicating
implementation-specific guidance. When a rule changes, update the skill here
first, then keep adapters thin.

Current skills:

- `github-prs.md`: PR workflow and migration PR handoff expectations.
- `migration_contracts.md`: API v2 migration route contracts, route-group
metadata, generated migration artifacts, and quality guards.
- `testing.md`: focused test commands and dependency boundaries for migration
work.

27 changes: 27 additions & 0 deletions docs/engineering/skills/github-prs.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# GitHub PRs

Use this skill before opening, replacing, or sharing a pull request.

## Migration PRs

Migration PRs should keep the user experience stable unless the PR explicitly
declares an API contract change. If a PR changes migration route contracts,
route-group metadata, generated migration artifacts, or the cutover guardrails,
it should:

1. Include a changelog fragment.
2. Refresh generated migration artifacts with
`python scripts/export_migration_contracts.py`.
3. Run `python scripts/run_quality_guards.py`.
4. Run the focused contract or unit tests that cover the changed surface.

## PR Descriptions

For migration work, identify:

- which route groups or workflows are covered;
- what remains on the Flask/API v1 path;
- what is newly prepared for FastAPI, SQLAlchemy/Alembic, Supabase, Cloud Run,
or Modal migration;
- which user-visible API contract changes are intentionally introduced.

47 changes: 47 additions & 0 deletions docs/engineering/skills/migration_contracts.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
# Migration Contracts

Use this skill when changing API v2 migration contracts, route-group migration
metadata, generated migration docs, or guard scripts.

## Sources Of Truth

- `policyengine_api/migration_registry.py` defines route groups, path segments,
database entities, and simulation flows used by migration flags and request
logging.
- `tests/contract/registry.py` defines app-v2 user workflows and stable route
response fields that must be preserved while the migration is staged.
- `scripts/export_migration_contracts.py` merges those sources into:
- `docs/generated/migration_contracts.json`
- `docs/engineering/migration-contracts.md`

Generated migration artifacts are checked-in review material. If a PR changes a
route group, workflow contract, stable response field, or future owner PR, run
the exporter and commit the regenerated files in the same PR.

## Update Workflow

```bash
python scripts/export_migration_contracts.py
python scripts/run_quality_guards.py
python -m pytest tests/contract tests/unit/test_migration_contract_artifacts.py -q
```

The migration-contracts guard checks that workflow names and route requests are
unique, every contract route group is declared in the migration registry, stable
response fields are present, and generated artifacts match the current
registry.

## Annotation Rules

Keep contract metadata explicit and durable:

- Use stable route-group names that match the migration flag environment
surface.
- Record the current user-facing contract, not an aspirational target.
- Keep `future_owner_pr` at the granularity of the migration plan so reviewers
can tell which later PR owns each workflow.
- Add only response fields that are meaningful user-facing compatibility
anchors.
- If a route intentionally changes its API contract, update the generated docs
and call that out in the PR description.

27 changes: 27 additions & 0 deletions docs/engineering/skills/testing.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# Testing Skill

Use this skill whenever adding, moving, or reviewing tests.

## Migration Test Layout

- Put API migration compatibility tests under `tests/contract/`.
- Put focused unit tests for migration flags, generated artifacts, guard
scripts, or baseline tools under `tests/unit/`.
- Keep contract tests isolated from live Cloud SQL, Modal, external AI APIs, and
network credentials unless the test is explicitly marked as a live integration
probe.

## Focused Commands

For PR 1 migration harness changes, prefer these focused checks before running
the full suite:

```bash
python scripts/run_quality_guards.py
python scripts/export_migration_contracts.py
python -m pytest tests/contract tests/unit/test_migration_flags.py tests/unit/test_migration_contract_artifacts.py tests/unit/test_capture_migration_baseline.py tests/unit/routes/test_migration_context_logging.py -q
```

Run `ruff format --check` and `ruff check` on changed Python files before
handoff.

Loading
Loading