feat: implement dcy-007 contract governance and ci gates
This commit is contained in:
@@ -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.
|
||||
Reference in New Issue
Block a user