Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
dfd5d5f
fix(models): Card/Review carry datetime dues + new step field
ImmortalDemonGod Jun 29, 2026
0440ed3
fix(scheduler): store full datetime due + restore/persist FSRS step
ImmortalDemonGod Jun 29, 2026
47f0ba7
fix(review_processor): full prior-review timestamp + persist step
ImmortalDemonGod Jun 29, 2026
5d96cc4
fix(db): timestamp due columns + cards.step
ImmortalDemonGod Jun 29, 2026
5f034db
fix(db): timestamp due predicates + persist step
ImmortalDemonGod Jun 29, 2026
103312d
fix(db): include step in card insert tuple
ImmortalDemonGod Jun 29, 2026
85959f3
fix(cli): days-until-due from datetime next_due_date
ImmortalDemonGod Jun 29, 2026
e8df5fb
fix(cli): review-all days-until-due from datetime
ImmortalDemonGod Jun 29, 2026
966032e
feat(db): idempotent datetime-fidelity migration script
ImmortalDemonGod Jun 29, 2026
fd41993
test(scheduler): datetime fidelity + step-persistence regressions
ImmortalDemonGod Jun 29, 2026
2d28a38
test(db): adapt to timestamp next_due
ImmortalDemonGod Jun 29, 2026
d7a5cdf
test(review_manager): step field + datetime due
ImmortalDemonGod Jun 29, 2026
77929c7
test(review_processor): step field + datetime due
ImmortalDemonGod Jun 29, 2026
f97a3ca
test(review_logic): step field in fixture
ImmortalDemonGod Jun 29, 2026
661a3f9
test(cli): mock datetime next_due in review_ui tests
ImmortalDemonGod Jun 29, 2026
b826924
test(cli): mock datetime next_due in review_all tests
ImmortalDemonGod Jun 29, 2026
993a370
docs(aiv): verification packet for change 'fsrs-datetime-fidelity'
ImmortalDemonGod Jun 29, 2026
f49ed7e
docs(aiv): add Class F (Provenance) evidence to the packet
ImmortalDemonGod Jun 29, 2026
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
61 changes: 43 additions & 18 deletions .github/aiv-evidence/EVIDENCE_FLASHCORE_CLI_REVIEW_UI.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
# AIV Evidence File (v1.0)

**File:** `flashcore/cli/review_ui.py`
**Commit:** `7911e17`
**Previous:** `c029942`
**Generated:** 2026-06-19T21:43:46Z
**Commit:** `103312d`
**Previous:** `1287d7c`
**Generated:** 2026-06-29T20:45:06Z
**Protocol:** AIV v2.0 + Addendum 2.7 (Zero-Touch Mandate)

---
Expand All @@ -12,18 +12,18 @@

```yaml
classification:
risk_tier: R0
risk_tier: R1
sod_mode: S0
critical_surfaces: []
blast_radius: "flashcore/cli/review_ui.py"
classification_rationale: "R0: formatting-only; no logic change"
classified_by: "Claude"
classified_at: "2026-06-19T21:43:46Z"
classification_rationale: "R1 CLI in the review path"
classified_by: "Miguel Ingram"
classified_at: "2026-06-29T20:45:06Z"
```

## Claim(s)

1. black -l 79 applied to flashcore/cli/review_ui.py, tests/cli/test_review_ui.py, tests/cli/test_main.py; make lint now exits 0
1. start_review_flow computes days-until-due from next_due_date.date() so it works with datetime dues
2. No existing tests were modified or deleted during this change.

---
Expand All @@ -32,31 +32,56 @@ classification:

### Class E (Intent Alignment)

- **Link:** [https://github.com/ImmortalDemonGod/flashcore/blob/5bb2ea2ab72239e0d2de7cc51fd4b5b766e44bfb/audit/02-static-audit.md#L92](https://github.com/ImmortalDemonGod/flashcore/blob/5bb2ea2ab72239e0d2de7cc51fd4b5b766e44bfb/audit/02-static-audit.md#L92)
- **Requirements Verified:** lint gate [10]
- **Link:** [https://github.com/ImmortalDemonGod/flashcore/pull/58](https://github.com/ImmortalDemonGod/flashcore/pull/58)
- **Requirements Verified:** The CLI must handle datetime next_due_date when printing days-until-due

### Class B (Referential Evidence)

**Scope Inventory** (SHA: [`7911e17`](https://github.com/ImmortalDemonGod/flashcore/tree/7911e179ccf0cb626dce97bc8775297a87991a79))
**Scope Inventory** (SHA: [`103312d`](https://github.com/ImmortalDemonGod/flashcore/tree/103312d2e75181178b9c761c1cf8babdbb7c7807))

- [`flashcore/cli/review_ui.py#L145-L147`](https://github.com/ImmortalDemonGod/flashcore/blob/7911e179ccf0cb626dce97bc8775297a87991a79/flashcore/cli/review_ui.py#L145-L147)
- [`flashcore/cli/review_ui.py#L125-L127`](https://github.com/ImmortalDemonGod/flashcore/blob/103312d2e75181178b9c761c1cf8babdbb7c7807/flashcore/cli/review_ui.py#L125-L127)

### Class A (Execution Evidence)

- Local checks skipped (--skip-checks).
- **Skip reason:** Black formatting only; no logic changed
**Per-symbol test coverage (AST analysis):**

- **`start_review_flow`** (L125-L127): PASS -- 11 test(s) call `start_review_flow` directly
- `tests/cli/test_review_ui.py::test_start_review_flow_no_due_cards`
- `tests/cli/test_review_ui.py::test_start_review_flow_with_one_card`
- `tests/cli/test_review_ui.py::test_start_review_flow_invalid_rating_input`
- `tests/cli/test_review_ui.py::test_start_review_flow_submit_review_exception`
- `tests/cli/test_review_ui.py::test_start_review_flow_card_without_next_due_date`
- `tests/cli/test_review_ui.py::test_start_review_flow_submit_returns_none`
- `tests/cli/test_review_ui.py::test_all_submit_review_fail_output_omits_well_done_guards_against_false_success_message`
- `tests/cli/test_review_ui.py::test_persistent_submit_failure_retries_same_card_guards_against_infinite_retry_loop`
- `tests/cli/test_review_ui.py::test_start_review_flow_all_fail_suppresses_well_done`
- `tests/cli/test_review_ui.py::test_start_review_flow_success_emits_well_done`

**Coverage summary:** 1/1 symbols verified by tests.

### Code Quality (Linting & Types)

- **ruff:** All checks passed
- **mypy:** Success: no issues found in 1 source file

## Claim Verification Matrix

| # | Claim | Type | Evidence | Verdict |
|---|-------|------|----------|---------|
| 1 | start_review_flow computes days-until-due from next_due_date... | symbol | 11 test(s) call `start_review_flow` | PASS VERIFIED |
| 2 | No existing tests were modified or deleted during this chang... | structural | Class C not collected | REVIEW MANUAL REVIEW |

**Verdict summary:** 1 verified, 0 unverified, 1 manual review.
---

## Verification Methodology

**R0 (trivial) -- local checks skipped.**
**Reason:** Black formatting only; no logic changed
Only git diff scope inventory was collected. No execution evidence.
**Zero-Touch Mandate:** Verifier inspects artifacts only.
Evidence collected by `aiv commit` running: git diff (scope inventory), AST symbol-to-test binding (1/1 symbols verified).
Ruff/mypy results are in Code Quality (not Class A) because they prove syntax/types, not behavior.

---

## Summary

Black formatting to satisfy make lint (CI determinism)
CLI days-until-due from datetime due
81 changes: 81 additions & 0 deletions .github/aiv-evidence/EVIDENCE_FLASHCORE_CLI__REVIEW_ALL_LOGIC.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
# AIV Evidence File (v1.0)

**File:** `flashcore/cli/_review_all_logic.py`
**Commit:** `85959f3`
**Generated:** 2026-06-29T20:45:51Z
**Protocol:** AIV v2.0 + Addendum 2.7 (Zero-Touch Mandate)

---

## Classification (required)

```yaml
classification:
risk_tier: R1
sod_mode: S0
critical_surfaces: []
blast_radius: "flashcore/cli/_review_all_logic.py"
classification_rationale: "R1 CLI in the review path"
classified_by: "Miguel Ingram"
classified_at: "2026-06-29T20:45:51Z"
```

## Claim(s)

1. _review_all_logic computes days-until-due from next_due_date.date() so it works with datetime dues
2. No existing tests were modified or deleted during this change.

---

## Evidence

### Class E (Intent Alignment)

- **Link:** [https://github.com/ImmortalDemonGod/flashcore/pull/58](https://github.com/ImmortalDemonGod/flashcore/pull/58)
- **Requirements Verified:** The review-all CLI must handle datetime next_due_date

### Class B (Referential Evidence)

**Scope Inventory** (SHA: [`85959f3`](https://github.com/ImmortalDemonGod/flashcore/tree/85959f35e6393a8de382c4868174bdd8246c94fb))

- [`flashcore/cli/_review_all_logic.py#L88`](https://github.com/ImmortalDemonGod/flashcore/blob/85959f35e6393a8de382c4868174bdd8246c94fb/flashcore/cli/_review_all_logic.py#L88)

### Class A (Execution Evidence)

**Per-symbol test coverage (AST analysis):**

- **`review_all_logic`** (L88): PASS -- 5 test(s) call `review_all_logic` directly
- `tests/cli/test_review_all_logic.py::test_review_all_logic_no_due_cards`
- `tests/cli/test_review_all_logic.py::test_review_all_logic_with_cards_success`
- `tests/cli/test_review_all_logic.py::test_review_all_logic_with_review_error`
- `tests/cli/test_review_all_logic.py::test_review_all_logic_with_failed_review`
- `tests/cli/test_review_all_logic.py::test_review_all_logic_integration`

**Coverage summary:** 1/1 symbols verified by tests.

### Code Quality (Linting & Types)

- **ruff:** All checks passed
- **mypy:** Success: no issues found in 1 source file

## Claim Verification Matrix

| # | Claim | Type | Evidence | Verdict |
|---|-------|------|----------|---------|
| 1 | _review_all_logic computes days-until-due from next_due_date... | symbol | 5 test(s) call `review_all_logic` | PASS VERIFIED |
| 2 | No existing tests were modified or deleted during this chang... | structural | Class C not collected | REVIEW MANUAL REVIEW |

**Verdict summary:** 1 verified, 0 unverified, 1 manual review.
---

## Verification Methodology

**Zero-Touch Mandate:** Verifier inspects artifacts only.
Evidence collected by `aiv commit` running: git diff (scope inventory), AST symbol-to-test binding (1/1 symbols verified).
Ruff/mypy results are in Code Quality (not Class A) because they prove syntax/types, not behavior.

---

## Summary

review-all days-until-due from datetime due
124 changes: 124 additions & 0 deletions .github/aiv-evidence/EVIDENCE_FLASHCORE_DB_DATABASE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
# AIV Evidence File (v1.0)

**File:** `flashcore/db/database.py`
**Commit:** `5d96cc4`
**Generated:** 2026-06-29T20:43:26Z
**Protocol:** AIV v2.0 + Addendum 2.7 (Zero-Touch Mandate)

---

## Classification (required)

```yaml
classification:
risk_tier: R1
sod_mode: S0
critical_surfaces: []
blast_radius: "flashcore/db/database.py"
classification_rationale: "R1 correctness-critical DB layer"
classified_by: "Miguel Ingram"
classified_at: "2026-06-29T20:43:26Z"
```

## Claim(s)

1. FlashcardDatabase.get_due_cards compares next_due_date against a timestamp, coercing a bare date to end-of-day
2. FlashcardDatabase persists the FSRS step via the cards upsert and the post-review card update
3. No existing tests were modified or deleted during this change.

---

## Evidence

### Class E (Intent Alignment)

- **Link:** [https://github.com/ImmortalDemonGod/flashcore/pull/58](https://github.com/ImmortalDemonGod/flashcore/pull/58)
- **Requirements Verified:** Due queries and writes must use timestamps and persist the step

### Class B (Referential Evidence)

**Scope Inventory** (SHA: [`5d96cc4`](https://github.com/ImmortalDemonGod/flashcore/tree/5d96cc4406821652303022d0633d15a29a02862e))

- [`flashcore/db/database.py#L145-L146`](https://github.com/ImmortalDemonGod/flashcore/blob/5d96cc4406821652303022d0633d15a29a02862e/flashcore/db/database.py#L145-L146)
- [`flashcore/db/database.py#L176-L180`](https://github.com/ImmortalDemonGod/flashcore/blob/5d96cc4406821652303022d0633d15a29a02862e/flashcore/db/database.py#L176-L180)
- [`flashcore/db/database.py#L400-L407`](https://github.com/ImmortalDemonGod/flashcore/blob/5d96cc4406821652303022d0633d15a29a02862e/flashcore/db/database.py#L400-L407)
- [`flashcore/db/database.py#L416`](https://github.com/ImmortalDemonGod/flashcore/blob/5d96cc4406821652303022d0633d15a29a02862e/flashcore/db/database.py#L416)
- [`flashcore/db/database.py#L453-L462`](https://github.com/ImmortalDemonGod/flashcore/blob/5d96cc4406821652303022d0633d15a29a02862e/flashcore/db/database.py#L453-L462)
- [`flashcore/db/database.py#L467`](https://github.com/ImmortalDemonGod/flashcore/blob/5d96cc4406821652303022d0633d15a29a02862e/flashcore/db/database.py#L467)
- [`flashcore/db/database.py#L533`](https://github.com/ImmortalDemonGod/flashcore/blob/5d96cc4406821652303022d0633d15a29a02862e/flashcore/db/database.py#L533)
- [`flashcore/db/database.py#L704`](https://github.com/ImmortalDemonGod/flashcore/blob/5d96cc4406821652303022d0633d15a29a02862e/flashcore/db/database.py#L704)
- [`flashcore/db/database.py#L717-L718`](https://github.com/ImmortalDemonGod/flashcore/blob/5d96cc4406821652303022d0633d15a29a02862e/flashcore/db/database.py#L717-L718)
- [`flashcore/db/database.py#L726`](https://github.com/ImmortalDemonGod/flashcore/blob/5d96cc4406821652303022d0633d15a29a02862e/flashcore/db/database.py#L726)
- [`flashcore/db/database.py#L733-L736`](https://github.com/ImmortalDemonGod/flashcore/blob/5d96cc4406821652303022d0633d15a29a02862e/flashcore/db/database.py#L733-L736)
- [`flashcore/db/database.py#L746`](https://github.com/ImmortalDemonGod/flashcore/blob/5d96cc4406821652303022d0633d15a29a02862e/flashcore/db/database.py#L746)
- [`flashcore/db/database.py#L758`](https://github.com/ImmortalDemonGod/flashcore/blob/5d96cc4406821652303022d0633d15a29a02862e/flashcore/db/database.py#L758)
- [`flashcore/db/database.py#L783-L786`](https://github.com/ImmortalDemonGod/flashcore/blob/5d96cc4406821652303022d0633d15a29a02862e/flashcore/db/database.py#L783-L786)
- [`flashcore/db/database.py#L807`](https://github.com/ImmortalDemonGod/flashcore/blob/5d96cc4406821652303022d0633d15a29a02862e/flashcore/db/database.py#L807)

### Class A (Execution Evidence)

**Per-symbol test coverage (AST analysis):**

- **`FlashcardDatabase`** (L145-L146): PASS -- 36 test(s) call `FlashcardDatabase` directly
- `tests/test_db_coverage.py::test_safety_check_with_data`
- `tests/test_db_coverage.py::test_safety_check_catalog_exception`
- `tests/test_db_coverage.py::test_recreate_tables_drops_in_order`
- `tests/test_db_coverage.py::test_backup_database_success`
- `tests/test_db.py::test_instantiation_requires_db_path`
- `tests/test_db.py::test_instantiation_custom_file_path`
- `tests/test_db.py::test_instantiation_in_memory`
- `tests/test_db.py::test_context_manager_usage`
- `tests/test_db.py::test_read_only_mode_connection`
- `tests/test_db.py::test_initialize_schema_on_readonly_db_fails_for_force_recreate`
- **`FlashcardDatabase.get_due_card_count`** (L176-L180): PASS -- 3 test(s) call `get_due_card_count` directly
- `tests/test_review_manager.py::test_get_due_card_count_calls_db`
- `tests/test_review_manager.py::test_e2e_session_flow`
- `tests/test_db_errors.py::test_get_due_card_count_handles_db_error`
- **`FlashcardDatabase.get_due_cards`** (L400-L407): PASS -- 3 test(s) call `get_due_cards` directly
- `tests/test_db.py::test_get_due_cards_logic`
- `tests/test_db_errors.py::test_get_due_cards_handles_db_error`
- `tests/test_db_errors.py::test_get_due_cards_handles_validation_error`
- **`FlashcardDatabase.get_database_stats`** (L416): FAIL -- WARNING: No tests import or call `get_database_stats`
- **`FlashcardDatabase._update_card_after_review`** (L453-L462): FAIL -- WARNING: No tests import or call `_update_card_after_review`
- **`FlashcardDatabase._execute_review_transaction`** (L467): FAIL -- WARNING: No tests import or call `_execute_review_transaction`
- **`FlashcardDatabase.add_review_and_update_card`** (L533): PASS -- 19 test(s) call `add_review_and_update_card` directly
- `tests/test_review_manager.py::test_e2e_session_flow`
- `tests/test_db.py::test_get_due_cards_logic`
- `tests/test_db.py::test_add_review_success`
- `tests/test_db.py::test_add_review_fk_violation`
- `tests/test_db.py::test_add_review_check_constraint_violation`
- `tests/test_db.py::test_add_reviews_individually`
- `tests/test_db.py::test_add_review_transactionality`
- `tests/test_db.py::test_get_reviews_for_card`
- `tests/test_db.py::test_get_latest_review_for_card`
- `tests/test_db.py::test_get_all_reviews_with_data_and_filtering`

**Coverage summary:** 4/7 symbols verified by tests.

### Code Quality (Linting & Types)

- **ruff:** All checks passed
- **mypy:** Success: no issues found in 1 source file

## Claim Verification Matrix

| # | Claim | Type | Evidence | Verdict |
|---|-------|------|----------|---------|
| 1 | FlashcardDatabase.get_due_cards compares next_due_date again... | symbol | 39 test(s) call `FlashcardDatabase.get_due_cards`, `FlashcardDatabase` | PASS VERIFIED |
| 2 | FlashcardDatabase persists the FSRS step via the cards upser... | symbol | 36 test(s) call `FlashcardDatabase` | PASS VERIFIED |
| 3 | No existing tests were modified or deleted during this chang... | structural | Class C not collected | REVIEW MANUAL REVIEW |

**Verdict summary:** 2 verified, 0 unverified, 1 manual review.
---

## Verification Methodology

**Zero-Touch Mandate:** Verifier inspects artifacts only.
Evidence collected by `aiv commit` running: git diff (scope inventory), AST symbol-to-test binding (4/7 symbols verified).
Ruff/mypy results are in Code Quality (not Class A) because they prove syntax/types, not behavior.

---

## Summary

Timestamp due predicates and step persistence
61 changes: 61 additions & 0 deletions .github/aiv-evidence/EVIDENCE_FLASHCORE_DB_DB_UTILS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
# AIV Evidence File (v1.0)

**File:** `flashcore/db/db_utils.py`
**Commit:** `5f034db`
**Generated:** 2026-06-29T20:44:48Z
**Protocol:** AIV v2.0 + Addendum 2.7 (Zero-Touch Mandate)

---

## Classification (required)

```yaml
classification:
risk_tier: R0
sod_mode: S0
critical_surfaces: []
blast_radius: "flashcore/db/db_utils.py"
classification_rationale: "R0 trivial one-line marshalling addition"
classified_by: "Miguel Ingram"
classified_at: "2026-06-29T20:44:48Z"
```

## Claim(s)

1. card_to_db_params_list includes card.step as the trailing value of the cards insert tuple
2. No existing tests were modified or deleted during this change.

---

## Evidence

### Class E (Intent Alignment)

- **Link:** [https://github.com/ImmortalDemonGod/flashcore/pull/58](https://github.com/ImmortalDemonGod/flashcore/pull/58)
- **Requirements Verified:** The marshalling tuple must carry the step column

### Class B (Referential Evidence)

**Scope Inventory** (SHA: [`5f034db`](https://github.com/ImmortalDemonGod/flashcore/tree/5f034dbd0999113fa449af9507aaa64933096f43))

- [`flashcore/db/db_utils.py#L97`](https://github.com/ImmortalDemonGod/flashcore/blob/5f034dbd0999113fa449af9507aaa64933096f43/flashcore/db/db_utils.py#L97)

### Class A (Execution Evidence)

- Local checks skipped (--skip-checks).
- **Skip reason:** One-line addition of card.step to the cards insert tuple; exercised indirectly by the DB round-trip tests


---

## Verification Methodology

**R0 (trivial) -- local checks skipped.**
**Reason:** One-line addition of card.step to the cards insert tuple; exercised indirectly by the DB round-trip tests
Only git diff scope inventory was collected. No execution evidence.

---

## Summary

Step in the card insert tuple
Loading
Loading