diff --git a/openspec/changes/code-review-06-reward-ledger/TDD_EVIDENCE.md b/openspec/changes/code-review-06-reward-ledger/TDD_EVIDENCE.md new file mode 100644 index 00000000..7091d844 --- /dev/null +++ b/openspec/changes/code-review-06-reward-ledger/TDD_EVIDENCE.md @@ -0,0 +1,21 @@ +# TDD Evidence: code-review-06-reward-ledger + +## Pre-implementation failing run + +- **Timestamp**: 2026-03-16 09:34:27 +0100 +- **Repository**: `specfact-cli-modules` +- **Command**: `hatch run test -- tests/unit/specfact_code_review/ledger/test_client.py tests/unit/specfact_code_review/ledger/test_commands.py` +- **Result**: Failed as expected +- **Failure summary**: + - `tests/unit/specfact_code_review/ledger/test_client.py` failed during collection with `ModuleNotFoundError: No module named 'specfact_code_review.ledger'` + - This confirms the new ledger surface is not implemented yet and the tests are exercising the intended missing behavior + +## Post-implementation passing run + +- **Timestamp**: 2026-03-16 09:37:09 +0100 +- **Repository**: `specfact-cli-modules` +- **Command**: `hatch run test -- tests/unit/specfact_code_review/ledger/test_client.py tests/unit/specfact_code_review/ledger/test_commands.py` +- **Result**: Passed +- **Summary**: + - Focused ledger client and command tests passed after implementing `specfact_code_review.ledger` + - The run completed in the modules default Hatch environment, which is the repo-approved test path for sibling `specfact-cli` dependency resolution diff --git a/openspec/changes/code-review-06-reward-ledger/design.md b/openspec/changes/code-review-06-reward-ledger/design.md index ba3cf816..e684f0e0 100644 --- a/openspec/changes/code-review-06-reward-ledger/design.md +++ b/openspec/changes/code-review-06-reward-ledger/design.md @@ -2,6 +2,10 @@ ## Supabase Schema +The reviewed SQL source is stored with the bundle at +`packages/specfact-code-review/src/specfact_code_review/resources/supabase/review_ledger_ddl.sql` +so the module owns its own persistence setup artifact. + ```sql CREATE TABLE ai_sync.review_runs ( id uuid PRIMARY KEY DEFAULT gen_random_uuid(), diff --git a/openspec/changes/code-review-06-reward-ledger/proposal.md b/openspec/changes/code-review-06-reward-ledger/proposal.md index 68fd431e..0f9a5710 100644 --- a/openspec/changes/code-review-06-reward-ledger/proposal.md +++ b/openspec/changes/code-review-06-reward-ledger/proposal.md @@ -15,7 +15,7 @@ A local JSON fallback (`~/.specfact/ledger.json`) ensures the feature works offl - **NEW**: `specfact code review ledger status` — prints coins (2dp), streak_pass, streak_block, last verdict, top-3 violations - **NEW**: `specfact code review ledger reset` — resets local ledger (requires `--confirm`) - **NEW**: Coin update formula: `coins += reward_delta / 10.0`; streak bonuses: pass>=5 → +0.5, block>=3 → -1.0 -- **NEW**: Supabase DDL migration file: `infra/supabase/review_ledger_ddl.sql` +- **NEW**: Bundle-local Supabase DDL file: `packages/specfact-code-review/src/specfact_code_review/resources/supabase/review_ledger_ddl.sql` - **NEW**: Unit tests for `LedgerClient` and ledger commands (TDD-first) ## Capabilities @@ -38,7 +38,7 @@ A local JSON fallback (`~/.specfact/ledger.json`) ensures the feature works offl ## Source Tracking -- **GitHub Issue**: TBD -- **Issue URL**: TBD +- **GitHub Issue**: #395 +- **Issue URL**: https://github.com/nold-ai/specfact-cli/issues/395 - **Repository**: nold-ai/specfact-cli -- **Last Synced Status**: proposed +- **Last Synced Status**: in-progress diff --git a/openspec/changes/code-review-06-reward-ledger/tasks.md b/openspec/changes/code-review-06-reward-ledger/tasks.md index cd865685..0a50f666 100644 --- a/openspec/changes/code-review-06-reward-ledger/tasks.md +++ b/openspec/changes/code-review-06-reward-ledger/tasks.md @@ -6,60 +6,61 @@ Tests before code. Do not implement until failing tests exist. --- -## 1. Create git worktree +## 1. Create git worktrees -- [ ] 1.1 `git fetch origin` -- [ ] 1.2 `git worktree add ../specfact-cli-worktrees/feature/code-review-06-reward-ledger -b feature/code-review-06-reward-ledger origin/dev` -- [ ] 1.3 `cd ../specfact-cli-worktrees/feature/code-review-06-reward-ledger` -- [ ] 1.4 `python -m venv .venv && source .venv/bin/activate && pip install -e ".[dev]"` +- [x] 1.1 `git fetch origin` in both `specfact-cli` and `specfact-cli-modules` +- [x] 1.2 Create `feature/code-review-06-reward-ledger` worktree in `../specfact-cli-worktrees/feature/code-review-06-reward-ledger` for OpenSpec artifacts +- [x] 1.3 Create `feature/code-review-06-reward-ledger` worktree in `../specfact-cli-modules-worktrees/feature/code-review-06-reward-ledger` for module implementation +- [x] 1.4 Bootstrap both worktrees (`hatch env create`; `hatch run dev-deps` in modules repo; pre-flight status commands in `specfact-cli`) ## 2. Verify blocker resolved -- [ ] 2.1 Confirm `code-review-01-module-scaffold` is merged (ReviewReport model required) +- [x] 2.1 Confirm `code-review-01-module-scaffold` is merged (ReviewReport model required) ## 3. Write DDL migration -- [ ] 3.1 Create `infra/supabase/review_ledger_ddl.sql` with `ai_sync.review_runs` and `ai_sync.reward_ledger` tables -- [ ] 3.2 Verify DDL does not conflict with existing `coding_run_logs` / `active_runs` tables (inspect current ai_sync schema) +- [x] 3.1 Create bundle-local DDL at `packages/specfact-code-review/src/specfact_code_review/resources/supabase/review_ledger_ddl.sql` with `ai_sync.review_runs` and `ai_sync.reward_ledger` tables +- [x] 3.2 Verify DDL does not conflict with existing `coding_run_logs` / `active_runs` tables (inspect current ai_sync schema) ## 4. Write tests BEFORE implementation (TDD-first) -- [ ] 4.1 Write `tests/unit/specfact_code_review/ledger/test_client.py` - - [ ] 4.1.1 Test `record_run` with Supabase available (mock HTTP calls) → inserts row - - [ ] 4.1.2 Test `record_run` without SUPABASE_URL → writes to local JSON - - [ ] 4.1.3 Test streak pass bonus at streak >= 5 - - [ ] 4.1.4 Test streak block penalty at streak >= 3 - - [ ] 4.1.5 Test `get_status` returns correct dict - - [ ] 4.1.6 Test coin delta formula: `reward_delta / 10.0` -- [ ] 4.2 Write `tests/unit/specfact_code_review/ledger/test_commands.py` - - [ ] 4.2.1 Test `ledger update` reads valid JSON stdin → calls record_run - - [ ] 4.2.2 Test `ledger update` with invalid JSON → exit 1, stderr message - - [ ] 4.2.3 Test `ledger status` prints coins (2dp), streak, verdict - - [ ] 4.2.4 Test `ledger reset` without --confirm → error, no deletion - - [ ] 4.2.5 Test `ledger reset --confirm` → local ledger cleared, exit 0 -- [ ] 4.3 Run tests → expect failure; record in `TDD_EVIDENCE.md` +- [x] 4.1 Write `tests/unit/specfact_code_review/ledger/test_client.py` + - [x] 4.1.1 Test `record_run` with Supabase available (mock HTTP calls) → inserts row + - [x] 4.1.2 Test `record_run` without SUPABASE_URL → writes to local JSON + - [x] 4.1.3 Test streak pass bonus at streak >= 5 + - [x] 4.1.4 Test streak block penalty at streak >= 3 + - [x] 4.1.5 Test `get_status` returns correct dict + - [x] 4.1.6 Test coin delta formula: `reward_delta / 10.0` +- [x] 4.2 Write `tests/unit/specfact_code_review/ledger/test_commands.py` + - [x] 4.2.1 Test `ledger update` reads valid JSON stdin → calls record_run + - [x] 4.2.2 Test `ledger update` with invalid JSON → exit 1, stderr message + - [x] 4.2.3 Test `ledger status` prints coins (2dp), streak, verdict + - [x] 4.2.4 Test `ledger reset` without --confirm → error, no deletion + - [x] 4.2.5 Test `ledger reset --confirm` → local ledger cleared, exit 0 +- [x] 4.3 Run tests → expect failure; record in `TDD_EVIDENCE.md` ## 5. Implement ledger -- [ ] 5.1 Implement `ledger/client.py` — `LedgerClient` with Supabase + local JSON fallback; all public methods with `@require`/`@ensure`/`@beartype` -- [ ] 5.2 Implement `ledger/commands.py` — `update`, `status`, `reset` Typer commands -- [ ] 5.3 Create `ledger/__init__.py` +- [x] 5.1 Implement `ledger/client.py` — `LedgerClient` with Supabase + local JSON fallback; all public methods with `@require`/`@ensure`/`@beartype` +- [x] 5.2 Implement `ledger/commands.py` — `update`, `status`, `reset` Typer commands +- [x] 5.3 Create `ledger/__init__.py` ## 6. Quality gates -- [ ] 6.1 Run tests → expect passing; record in `TDD_EVIDENCE.md` -- [ ] 6.2 `hatch run format && hatch run type-check && hatch run contract-test && hatch run lint` -- [ ] 6.3 Test local JSON fallback manually: `SUPABASE_URL="" specfact code review ledger status` +- [x] 6.1 Run tests → expect passing; record in `TDD_EVIDENCE.md` +- [x] 6.2 `hatch run format && hatch run type-check && hatch run contract-test && hatch run lint` +- [x] 6.3 Test local JSON fallback manually from the modules worktree using the local bundle source: + `HOME=/tmp/specfact-ledger-smoke PYTHONPATH=packages/specfact-code-review/src SPECFACT_MODULES_ROOTS=packages SUPABASE_URL="" .venv/bin/specfact code review ledger status` ## 7. Module signing, docs, version, changelog -- [ ] 7.1 Verify/re-sign module -- [ ] 7.2 Update `docs/modules/code-review.md` with ledger commands section; document offline fallback -- [ ] 7.3 Bump minor version (new feature); update CHANGELOG.md +- [x] 7.1 Verify/re-sign module +- [x] 7.2 Update `docs/modules/code-review.md` with ledger commands section; document offline fallback +- [x] 7.3 Bump minor version (new feature); update CHANGELOG.md ## 8. Create GitHub issue and PR -- [ ] 8.1 Create issue: `[Change] Add reward ledger Supabase persistence and ledger subcommands` +- [x] 8.1 Link existing issue: `[Change] code-review-06 - Reward Ledger Supabase Persistence and ledger Subcommands` (#395) - [ ] 8.2 Update proposal.md Source Tracking; commit, push, create PR ## Post-merge cleanup