# Changelog

All notable changes to this project are documented in this file.

The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
and this project follows [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [Unreleased]

### Added
- `GET /` root index returning a JSON pointer to demo, health, docs, and agent-discovery endpoints (previously the bare base URL returned a 404, which looked broken to agents and registries landing on it).

### Changed
- Agent descriptor (`/.well-known/agent.json`) and `/llms.txt` tagline: replaced "autonomous proposal operations" with "governed proposal operations" to match the HITL/human-review model the runtime actually enforces.
- FastAPI app `description`: replaced "Enterprise-grade grant proposal automation" with "Agent-native API for governed grant-proposal workflows" (the former overclaims; it is surfaced in `/openapi.json` and `/docs`).

## [2.4.0] - 2026-05-19

### Added
- Critic: `TOC_ASSUMPTIONS_RISKS_DISTINCT` check — flags when assumptions and risks fields are identical text (medium severity flaw).
- Critic: `CORPUS_RETRIEVAL_ZERO_HITS` check — fires when RAG is enabled but no corpus hits were retrieved (medium severity flaw); explains confidence ceiling to operators.
- Critic: `CORPUS_LOW_RETRIEVAL_CONFIDENCE` check — fires when RAG hits exist but avg confidence < 0.65 (low severity flaw).
- Agent discovery: `GET /demo/run` now returns `x-agent-sandbox`, `x-auth-required`, and `x-grantflow-version` headers.
- Agent discovery: `GET /.well-known/agent-capabilities.json` now includes `sandbox` and `mcp` blocks documenting both stdio and streamable-http transport options.
- MCP: `fastmcp_server.py` startup failure now prints actionable Option A / Option B recovery instructions.
- Word export: professional document theme — Calibri font, navy/blue headings, cover page, section rules.

### Fixed
- Deterministic ToC template: `assumptions` and `risks` fields now generate distinct content (previously both used identical boilerplate, triggering the new critic check).
- `black` formatting applied to `critic_rules.py`, `word_builder.py`.
- Unused variable `llm_mode` and mypy type error removed from `critic_rules.py`.
- Eval baseline snapshot refreshed to reflect improved EU, WorldBank, GIZ, State Dept, and UN Agencies scores (9.25 from 8.75 for several donors) after template fix.

### Changed
- BL-01 (billing metering) formally closed as out-of-scope for v2.x. Hard-block quotas available via `GRANTFLOW_TENANT_QUOTA_HARD_BLOCK=true`; `GET /tenants/{tenant_id}/usage` is the billing integration point.
- Contributor docs updated: role-based Start Here table, `feat(scope):` commit format, unified `make qa-fast` test path.
- `BACKLOG.md` updated: last open P1 (BL-01) resolved; only BL-06 (in-app RBAC, P3) remains.

## [2.3.3] - 2026-05-13

### Fixed
- Conformance smoke suite now passes 7/7 checks against a live server.
- `unsupported_donor` error on `POST /generate/preflight` was returning a plain string; converted to structured `raise_agent_error()`.
- `POST /ingest/text` conformance check fixed: `chunks_ingested` is nested under `result.result`, not at the top level.
- HITL flow conformance fixed: `POST /resume/{job_id}` must be called after `POST /hitl/approve` to dispatch job continuation.
- Conformance deadline bug: post-approval polling window now resets to a full `timeout_seconds`, not leftover from pre-approval phase.
- `AGENTS.md` updated to document the explicit `POST /resume/{job_id}` step after HITL approval.
- `error-contract.md` updated with `finding_status_conflict` and `service_not_ready` codes.
- Two remaining plain-string `HTTPException` errors in `presets_service.py` converted to `raise_agent_error()`.

## [2.3.2] - 2026-05-13

### Fixed
- `finding_status_conflict` 409 responses in `review_mutations.py` (single and bulk) converted from raw `HTTPException` to `raise_agent_error()` with `retryable=True` and `next_action`.
- Remaining plain-string `HTTPException` errors in `system.py` (`/demo/run`, `/ready`, `/decision/bid-no-bid`) converted to `raise_agent_error()`.
- `finding_status_conflict` added to `docs/agents/error-contract.md`.
- `black` formatting applied to 8 files; pre-commit style drift resolved.
- mypy fix: `cast(dict, initial_state)` in demo route resolves `GrantFlowState` vs `dict` type mismatch.

## [2.3.1] - 2026-05-13

### Added
- `conformance-smoke` job added to CI: starts uvicorn, waits for `/health`, runs `python -m grantflow.agents.conformance`.

### Fixed
- All remaining 73 plain-string 400/403/409/503 `HTTPException` errors converted to `raise_agent_error()` across 13 files. New machine-readable codes: `unsupported_filter`, `unsupported_status`, `unsupported_format`, `missing_selector`, `missing_preset_key`, `invalid_parameter`, `missing_required_field`, `version_not_found`, `linked_finding_not_found`, `section_mismatch`, `invalid_job_state`, `checkpoint_missing`, `checkpoint_pending`, `checkpoint_not_decided`, `checkpoint_stage_mismatch`, `checkpoint_conflict`, `job_queue_full`, `tenant_id_required`, `tenant_id_not_allowed`, `tenant_access_denied`.
- `docs/agents/error-contract.md` updated with all new error codes from 2.3.0 and 2.3.1; legacy plain-string note removed.

## [2.3.0] - 2026-05-13

### Added
- Contract tests for `/status/{job_id}/metrics`, `/status/{job_id}/critic`, `/status/{job_id}/quality`, `/status/{job_id}/events`, and `/status/{job_id}/export-payload`: 404 agent error format, auth guard, response shape, count/list consistency.
- Tenant contract tests: auth guards for all three tenant endpoints, job status counting, quota floor, allowed_donors round-trip, 404 agent error format.

### Changed
- `requires-python` raised to `<3.15` to allow Python 3.14 (all deps are pure-Python wheels).
- Lock files regenerated after `langchain-core` bump.

### Fixed
- `langchain-core` pinned to `1.3.3` conflicted with `langgraph==1.2.0` and `langchain==1.3.0`, both of which require `>=1.4.0`; bumped to `1.4.0`.
- All agent-facing 404s now use `raise_job_not_found(job_id)` from `grantflow.api.errors`; 54 inline `HTTPException(404, "Job not found")` and verbose inline equivalents replaced across `jobs.py`, `review.py`, `exports.py`, and `review_mutations.py`.
- Operations runbook and deployment checklist updated to reflect Python 3.11–3.14 support range and correct `uv pip compile` lock-regen commands.
- Node.js runtime fix applied to remaining GitHub Actions workflow (`synthetic-alert-delivery-check.yml`).

## [2.2.0] - 2026-05-13

### Added
- Tenant provisioning and usage metering: `POST /tenants`, `GET /tenants`, `GET /tenants/{tenant_id}`, `GET /tenants/{tenant_id}/usage` with daily job/ingest quotas (advisory, not hard-blocking).
- Four new MCP tools: `grantflow_ingest_text`, `grantflow_hitl_approve`, `grantflow_hitl_list_pending`, `grantflow_get_export_payload`; agent tool manifest updated.
- Self-serve OAuth bearer onboarding via `POST /agents/onboarding` with `auth_type=oauth_client_credentials`.
- Credential lifecycle endpoints: `POST /agents/credentials/rotate`, `POST /agents/credentials/revoke`.
- Credential introspection contract: `POST /agents/introspect`.
- Runtime session management: `POST /agents/session`.
- Agent discovery descriptor and conformance smoke expanded with full e2e webhook verification.
- Buyer-facing `trust_summary` block in quality payload.
- Demo endpoint, `llms.txt`, and README agent-native landing section.
- Redis-backed idempotency for write endpoints and rate limiting.
- Regression test to prevent reintroducing mypy quarantine (`grantflow/tests/test_mypy_policy.py`).

### Changed
- Removed temporary mypy `ignore_errors` quarantine overrides; full-package type gating restored in CI.
- Hardened import stability around API routers with explicit package markers and import-contract coverage.
- `guard_agent_write` wired into preflight; idempotency replay check corrected.
- Revocation scope bounded to in-process JTI denylist; `revocation_scope` and `restart_safe` fields added to revoke responses.
- Bumped: langgraph 1.2.0, langgraph-checkpoint 4.1.0, langchain 1.3.0, mypy 2.1.0, fastapi 0.136.1, pydantic 2.13.4, chromadb 1.5.9, pymupdf 1.27.2.3, redis 7.4.0, pytest 9.0.3, ruff 0.15.12.

### Fixed
- CVE patches: python-multipart bumped to patched version; langchain-core bumped to patched line.
- Removed unused imports flagged by ruff across API modules.

## [2.1.2] - 2026-03-13

### Added
- Buyer-facing packaging helper targets: `buyer-facing-pack-refresh` and `buyer-facing-artifacts-index`.
- Generated buyer-facing artifact index output at `build/buyer-facing-artifacts-index.md` to quickly review pilot/customer-ready deliverables.

### Changed
- Review workflow public payload now includes concise reviewer UX signals:
  - finding-level `triage_priority_label`, `reviewer_next_actions`, `reviewer_next_action_short`
  - summary-level `summary.triage_summary.next_priority_label`, `summary.triage_summary.next_action_brief`

### Fixed
- Added integration regression coverage to ensure default DOCX exports remain client-ready (diagnostic sections excluded unless `include_diagnostics=true`).

## [2.1.1] - 2026-03-03

### Changed
- Dependency management moved to `pyproject.toml` as the canonical source of truth (`[project]` + `[project.optional-dependencies]`).
- CI, Docker, and docs install flows updated to `pip install .` / `pip install ".[dev]"`.
- Legacy `requirements` files kept as compatibility shims pointing to the project metadata.
- State contract now exposes canonical helpers for strategy and iteration access; core swarm nodes (`discovery`, `architect`, `mel`, `critic`) now consume those helpers instead of ad-hoc alias reads.
- Critic findings hardened as stable entities: deterministic `finding_id` generation for legacy/unstructured payloads and stricter LLM `fatal_flaws` coercion to object lists.
- Release governance now validates Keep-a-Changelog heading format (`## [X.Y.Z] - YYYY-MM-DD`) for current/tagged versions.
- CI now enforces Conventional Commit PR titles via `scripts/pr_title_guard.py`.
- Added CI-driven tag cutting workflow (`Release Cut`) with manual approval gate through environment `release`.
- Added Release Drafter automation (`.github/release-drafter.yml` + workflow) for continuously updated draft release notes.

## [2.1.0] - 2026-03-03

### Added
- Grounded smoke CI lane that boots API, ingests seed corpus, and validates donor readiness/benchmark status.
- Pilot run artifacts for grounded deterministic and LLM benchmark tracks under `docs/pilot_runs/2026-03-03-grounded-llm-p2/`.

### Changed
- Architect and MEL citation confidence calibration tuned for more stable scoring behavior.
- CI mypy baseline updated for stricter type safety in API preflight and public review SLA payload shaping.
- Eval baseline snapshot aligned with clean no-corpus environment to prevent false CI regressions.

## [2.0.1] - 2026-02-27

### Added
- Graph-level HITL pause/resume gates with checkpoint-driven continuation.
- Donor-specific export templates/sheets for USAID, EU, and World Bank.
- RAG traceability enrichment: `doc_id`, retrieval rank/confidence, and stronger namespace normalization.
- Golden contract tests for donor resolution, public redaction, versioning/citation behavior, and non-LLM lane coverage.
- Readiness endpoint (`/ready`) and ingest inventory/export endpoints for RAG operations.
- GitHub release workflow (`.github/workflows/release.yml`) that extracts versioned notes from `CHANGELOG.md` and publishes releases for `v*.*.*` tags.
- Grounding Gate policy (`off|warn|strict`) with strict-mode finalization/export blocking on weak grounding signals.
- Graph-native HITL checkpoint creation with optional stage selection (`hitl_checkpoints`) in `/generate`.
- Expanded donor-specific exporters for specialized strategies (`usaid`, `eu`, `worldbank`, `giz`, `state_department`).
- Fixture-driven golden snapshots for contract-critical behaviors (donor resolution, citations/versioning, export payload redaction).
- `scripts/release_guard.py` for SemVer/tag/changelog/governance validation.

### Changed
- README expanded with execution modes, grounding caveats, sample artifacts, and quality/readiness guidance.
- Critic findings normalized into typed entities with lifecycle status (`open`, `acknowledged`, `resolved`).
- Tooling baseline formalized with `black`, `ruff`, `isort`, `mypy`, and pre-commit hooks.
- Runtime API version now uses `grantflow/core/version.py` as source of truth.
- CI and release workflows now run release governance checks before merge/release.

## [2.0.0] - 2026-02-24

### Added
- FastAPI + LangGraph proposal drafting backend with donor strategy routing.
- HITL checkpoint API, async job lifecycle, and export package generation.
- Chroma-backed RAG ingestion and retrieval paths with in-memory fallback.
