feat: implement dcy-007 contract governance and ci gates

This commit is contained in:
Jarca
2026-06-30 20:06:39 +09:00
parent 26b815d723
commit 7fd1b45bd5
20 changed files with 1038 additions and 22 deletions
@@ -0,0 +1,50 @@
# BAT-007 Design
## Contract versioning design
- Active MCP success response contract version: `1.0`.
- Version format: `major.minor`.
- Runtime exposure: unexposed. MCP success payloads are not modified to add a common `contract_version` field.
- Source of truth: `docs/interface-contract.md`.
- Snapshot metadata: `tests/contract_snapshots/response_contract_v1_0.json`.
## Change classification
- Breaking / major: required key removal, required key type change, nested object/list shape change that breaks existing consumers.
- Additive / minor: optional field additions and documentation/test metadata additions that preserve existing response semantics.
- Every response-shape-changing REQ/BAT must record contract impact: none, additive minor, or breaking major.
## Contract regression design
Representative first-wave scopes:
- health/status: `service.health_check`, `service.get_ledger_db_status`
- list: `service.list_ledger_accounts`
- report: `service.get_monthly_cashflow_report`
- mutation success envelope: `service.create_ledger_account`
The pytest contract checker validates required keys and required types only. Additional keys are allowed, matching the additive policy.
Synthetic fixture policy:
- Test DB paths are created under pytest `tmp_path`.
- Fixture data uses synthetic names and amounts only.
- No operating DB path, source financial filename, password, raw payload, or real account identifier is used.
## CI design
Required-check contract job names:
- `pytest-regression`
- `dashboard-app-test`
- `dashboard-http-smoke`
- `db-safety-smoke`
- `contract-regression`
- `lint`
`.github/workflows/ci.yml` adds:
- `contract-regression`: `uv run pytest tests/test_contract_regression.py`
- `lint`: `uv run ruff check .`
Actual branch protection toggles remain external GitHub repository settings.
@@ -0,0 +1,115 @@
# BAT-007 Implementation
## Changed files
- `.github/workflows/ci.yml`
- Added stable required-check candidate jobs: `contract-regression`, `lint`.
- `pyproject.toml`, `uv.lock`
- Added `ruff` to dev dependencies and conservative `E9`/`F` initial lint config.
- `tests/test_contract_regression.py`
- Added representative MCP response contract regression tests.
- `tests/contract_snapshots/response_contract_v1_0.json`
- Added contract `1.0` metadata and required-subset schemas for health/status, list, report, and mutation success envelope scopes.
- `docs/interface-contract.md`
- Added MCP response contract `1.0` governance, breaking/additive classification, runtime exposure policy, version log, and CI required-check contract.
- `docs/project-structure.md`, `docs/runtime-flows.md`
- Updated baseline structure/flow docs for contract snapshots/tests, `contract-regression`, `lint`, branch-protection boundary, and synthetic-only invariant.
- `docs/batches/index.md`
- Registered BAT-007.
- `docs/batches/bat-007_20260630_mcp-response-contract-ci-versioning/{index,planning,design,implementation,verification}.md`
- Added standard batch delivery docs.
- `docs/srs/Interface/req-007_mcp-response-contract-versioning-governance.md`
- `docs/srs/Testing/req-008_ci-contract-regression-and-lint-required-checks.md`
- `docs/srs/index.md`
- Updated REQ state to Implemented after verification evidence.
## Implementation notes
- Runtime MCP success payloads were not changed.
- Contract version `1.0` is documented in `docs/interface-contract.md` and mirrored in `tests/contract_snapshots/response_contract_v1_0.json`.
- Contract regression is representative, not exhaustive.
- Lint gate uses conservative `ruff` rules: `E9`, `F`.
- All new test data uses pytest temp DBs and synthetic names/amounts only.
## Verification command log
Executed from `/root/projects/jarca-ledger-mcp`.
1. `uv sync --extra dev --extra dashboard`
Result:
```text
Resolved 72 packages in 1.37s
Building jarca-ledger-mcp @ file:///root/projects/jarca-ledger-mcp
Downloading ruff (11.0MiB)
Downloaded ruff
Built jarca-ledger-mcp @ file:///root/projects/jarca-ledger-mcp
Prepared 3 packages in 2.94s
Uninstalled 2 packages in 18ms
Installed 3 packages in 338ms
~ jarca-ledger-mcp==0.1.0 (from file:///root/projects/jarca-ledger-mcp)
- pytest==9.1.0
+ pytest==9.1.1
+ ruff==0.15.20
```
2. `uv run pytest tests/test_contract_regression.py`
Result:
```text
... [100%]
3 passed in 0.99s
```
3. `uv run ruff check .`
Result:
```text
All checks passed!
```
4. `uv run pytest --ignore=tests/test_dashboard_app.py`
Result:
```text
...............ss...............ss... [100%]
33 passed, 4 skipped in 29.37s
```
5. `uv run python scripts/ci_db_safety_smoke.py --timeout 45`
Result:
```json
{
"success": true,
"gate": "db-safety-smoke",
"fixture": "synthetic",
"fixture_integrity": "ok",
"restore_smoke_exit_code": 0,
"restored_exists": true,
"restored_integrity": "ok",
"health_success": true,
"operating_db_used": false
}
```
6. `uv run python scripts/ci_dashboard_http_smoke.py --host 127.0.0.1 --port 18501 --timeout 45`
Result:
```json
{
"success": true,
"gate": "dashboard-http-smoke",
"fixture": "synthetic",
"fixture_integrity": "ok",
"http_status": 200,
"attempts": 4,
"cleanup": "terminated"
}
```
@@ -0,0 +1,32 @@
# BAT-007 MCP response contract / CI contract versioning
- Profile: standard
- Status: release-candidate
- Included REQ: REQ-007, REQ-008
- Discovery: dcy-007
- Owner: 렛저장인
- Date (KST): 2026-06-30
## 목표
REQ-007/REQ-008에 따라 MCP 성공 응답 contract version `1.0` governance를 확정하고, representative contract regression과 `ruff` lint를 CI required-check 계약에 추가한다. 런타임 성공 응답 shape는 보존하며 `contract_version` 필드는 노출하지 않는다.
## 산출물
- `docs/interface-contract.md`의 versioning governance, change classification, version log, required-check contract
- `docs/project-structure.md`, `docs/runtime-flows.md` baseline gap 해소 및 CI/branch-protection/synthetic-only 경계 반영
- `tests/test_contract_regression.py`와 `tests/contract_snapshots/response_contract_v1_0.json`
- `.github/workflows/ci.yml`의 `contract-regression`, `lint` stable job 추가
- `pyproject.toml`의 `ruff` dev dependency 및 보수적 초기 lint rule set
- BAT-007 planning/design/implementation/verification 문서
## 범위 제한
모든 MCP 도구 100% snapshot 커버리지, 런타임 `contract_version` 노출, breaking response migration, 실제 GitHub branch protection setting 토글, browser visual regression CI gate는 포함하지 않는다.
## 문서
- `planning.md`: delivery plan, dependencies, risks
- `design.md`: contract governance and CI gate design
- `implementation.md`: changed files and actual execution evidence
- `verification.md`: AC별 검증 결과와 REQ state 판단
@@ -0,0 +1,29 @@
# BAT-007 Planning
## Scope
- Implement REQ-007: MCP response contract versioning governance.
- Implement REQ-008: representative contract regression and lint required checks.
- Preserve existing success response shapes; runtime `contract_version` remains unexposed.
- Use synthetic/temp data only for tests and evidence.
## Dependencies
- dcy-007 confirmed Discovery and approved REQ-007/REQ-008.
- Existing BAT-006 CI workflow and synthetic fixture policy.
- Existing service-layer functions that accept `db_path` for temp fixture tests.
## Work plan
1. Add BAT-007 standard batch docs and index entry.
2. Add contract version `1.0` governance and CI required-check contract to baseline docs.
3. Add representative contract snapshot metadata and pytest regression for health/status, list, report, and mutation success envelope scopes.
4. Add `ruff` dev dependency/config and CI `lint`/`contract-regression` jobs while preserving existing job names.
5. Run narrow local verification: contract pytest, ruff, targeted regression that includes the new test, then full pytest if narrow gates pass.
6. If evidence satisfies ACs, move REQ-007 and REQ-008 to Implemented.
## Risks and mitigations
- Over-strict snapshot failures: mitigate by required-subset/type checks so optional additive fields pass.
- Existing code lint churn: mitigate by conservative initial `ruff` rule set (`E9`, `F`).
- Branch protection cannot be toggled from code: document as external operator setting and keep stable job names.
@@ -0,0 +1,48 @@
# BAT-007 Verification
## Verification summary
Status: PASS
REQ-007 and REQ-008 have sufficient repository evidence to move from Approved to Implemented.
Evidence commands executed from `/root/projects/jarca-ledger-mcp`:
| Command | Result |
| --- | --- |
| `uv sync --extra dev --extra dashboard` | PASS; `ruff==0.15.20` installed and lockfile updated. |
| `uv run pytest tests/test_contract_regression.py` | PASS; `3 passed in 0.99s`. |
| `uv run ruff check .` | PASS; `All checks passed!`. |
| `uv run pytest --ignore=tests/test_dashboard_app.py` | PASS; `33 passed, 4 skipped in 29.37s`. |
| `uv run python scripts/ci_db_safety_smoke.py --timeout 45` | PASS; JSON `success: true`, `fixture: synthetic`, `operating_db_used: false`. |
| `uv run python scripts/ci_dashboard_http_smoke.py --host 127.0.0.1 --port 18501 --timeout 45` | PASS; JSON `success: true`, `fixture: synthetic`, `http_status: 200`. |
## Acceptance criteria mapping
### REQ-007
- AC-1: PASS. `docs/interface-contract.md` defines `major.minor` and initial `1.0` contract version.
- AC-2: PASS. Breaking vs additive rules cover key removal, type changes, nested structure changes, and optional field additions.
- AC-3: PASS. `docs/interface-contract.md` contains source-of-truth rules and a version log linking dcy-007/REQ-007/BAT-007.
- AC-4: PASS. Runtime `contract_version` exposure is explicitly unexposed for `1.0`.
- AC-5: PASS. Response-shape-changing REQ/BAT work must state contract impact: none, additive minor, or breaking major.
- AC-6: PASS. Runtime success payloads were not changed; contract tests assert existing representative shapes.
### REQ-008
- AC-1: PASS. `tests/test_contract_regression.py` covers health/status, list, report, and mutation success envelope representative scopes.
- AC-2: PASS. The checker fails on missing required keys, required type changes, and required nested structure changes; additive fields are allowed.
- AC-3: PASS. Tests use pytest `tmp_path` synthetic SQLite DBs and committed schema metadata only. Smoke evidence also reports `fixture: synthetic` and `operating_db_used: false` where applicable.
- AC-4: PASS. `.github/workflows/ci.yml` includes a `lint` job running `uv run ruff check .`; local ruff verification passed.
- AC-5: PASS. Required-check job names are documented and existing BAT-006 job names are preserved.
- AC-6: PASS. `docs/interface-contract.md`, `docs/project-structure.md`, and `docs/runtime-flows.md` reflect contract-regression/lint/required-check/synthetic-only boundaries.
- AC-7: PASS. Baseline docs state actual branch protection toggles are external operator-managed GitHub repository settings.
## Requirement state decision
- REQ-007: Implemented.
- REQ-008: Implemented.
## Blockers
None.