Major additions: - Staged scanning modes (working tree, staged, committed) with git integration - Drift detection for baseline vs current state comparisons - Hosted API handlers for policy CRUD operations via StemeDB API - stemedb-ontology crate with domain definitions and medical extractors - Consumer health vertical UAT scenarios (GLP-1, gastroparesis, etc.) - Aphoria development skill documentation Code organization: - Split large files into focused modules to stay under 500-line limit - Extracted config tests, episteme helpers/drift/aliases, API helpers Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
206 lines
4.6 KiB
Markdown
206 lines
4.6 KiB
Markdown
# UAT: Time Travel Query (as_of Snapshot)
|
|
|
|
**Date:** YYYY-MM-DD
|
|
**Feature:** Historical Snapshot Queries
|
|
**Status:** [ ] PASS / [ ] FAIL / [ ] BLOCKED
|
|
|
|
## Scenario
|
|
|
|
Query the knowledge graph as it existed at a specific point in time. This enables:
|
|
- Audit trails ("What did we know on date X?")
|
|
- Debugging ("Why did the agent make that decision?")
|
|
- Historical analysis
|
|
|
|
## Acceptance Criteria
|
|
|
|
| Criterion | Expected | Met? |
|
|
|-----------|----------|------|
|
|
| Current query | Returns all assertions | [ ] |
|
|
| `as_of` past date | Returns only assertions before date | [ ] |
|
|
| `as_of` before data | Returns empty | [ ] |
|
|
| Newer data excluded | Verified | [ ] |
|
|
| Epoch-aware + as_of | Both filters applied | [ ] |
|
|
|
|
## Test Matrix
|
|
|
|
| Step | Action | Expected | Actual | Status |
|
|
|------|--------|----------|--------|--------|
|
|
| 1 | Create assertion at T1 | Hash returned | | [ ] |
|
|
| 2 | Create assertion at T2 | Hash returned | | [ ] |
|
|
| 3 | Create assertion at T3 | Hash returned | | [ ] |
|
|
| 4 | Query as_of=T1 | Only T1 assertion | | [ ] |
|
|
| 5 | Query as_of=T2 | T1 and T2 assertions | | [ ] |
|
|
| 6 | Query as_of=T0 (before) | Empty | | [ ] |
|
|
| 7 | Query current | All 3 assertions | | [ ] |
|
|
|
|
## Setup Commands
|
|
|
|
```bash
|
|
# Start StemeDB
|
|
cargo run --bin stemedb-api &
|
|
sleep 2
|
|
```
|
|
|
|
## Test Commands
|
|
|
|
### Record Timestamps
|
|
|
|
```bash
|
|
# Record T0 (before any data)
|
|
T0=$(date +%s)
|
|
sleep 1
|
|
```
|
|
|
|
### Step 1: Create Assertion at T1
|
|
|
|
```bash
|
|
T1=$(date +%s)
|
|
|
|
curl -X POST http://localhost:18180/v1/assertions \
|
|
-H "Content-Type: application/json" \
|
|
-d '{
|
|
"subject": "Semaglutide",
|
|
"predicate": "max_approved_dose_mg",
|
|
"object": {"Number": 1.0},
|
|
"confidence": 1.0,
|
|
"source_class": "Regulatory"
|
|
}'
|
|
|
|
echo "T1 = $T1"
|
|
sleep 2
|
|
```
|
|
|
|
**Expected:** Hash returned
|
|
**Actual:**
|
|
**Status:** [ ]
|
|
|
|
### Step 2: Create Assertion at T2 (Dose Increase)
|
|
|
|
```bash
|
|
T2=$(date +%s)
|
|
|
|
curl -X POST http://localhost:18180/v1/assertions \
|
|
-H "Content-Type: application/json" \
|
|
-d '{
|
|
"subject": "Semaglutide",
|
|
"predicate": "max_approved_dose_mg",
|
|
"object": {"Number": 2.4},
|
|
"confidence": 1.0,
|
|
"source_class": "Regulatory"
|
|
}'
|
|
|
|
echo "T2 = $T2"
|
|
sleep 2
|
|
```
|
|
|
|
**Expected:** Hash returned
|
|
**Actual:**
|
|
**Status:** [ ]
|
|
|
|
### Step 3: Create Assertion at T3 (Formulation Variant)
|
|
|
|
```bash
|
|
T3=$(date +%s)
|
|
|
|
curl -X POST http://localhost:18180/v1/assertions \
|
|
-H "Content-Type: application/json" \
|
|
-d '{
|
|
"subject": "Semaglutide:Oral",
|
|
"predicate": "max_approved_dose_mg",
|
|
"object": {"Number": 14.0},
|
|
"confidence": 1.0,
|
|
"source_class": "Regulatory"
|
|
}'
|
|
|
|
echo "T3 = $T3"
|
|
```
|
|
|
|
**Expected:** Hash returned
|
|
**Actual:**
|
|
**Status:** [ ]
|
|
|
|
### Step 4: Query as_of=T1 (Historical Snapshot)
|
|
|
|
```bash
|
|
# Should only see the 1.0mg dose
|
|
curl "http://localhost:18180/v1/query?subject=Semaglutide&predicate=max_approved_dose_mg&as_of=$T1"
|
|
```
|
|
|
|
**Expected:** Returns only `{"Number": 1.0}` assertion
|
|
**Actual:**
|
|
**Status:** [ ]
|
|
|
|
### Step 5: Query as_of=T2
|
|
|
|
```bash
|
|
# Should see 1.0mg and 2.4mg doses
|
|
curl "http://localhost:18180/v1/query?subject=Semaglutide&predicate=max_approved_dose_mg&as_of=$T2"
|
|
```
|
|
|
|
**Expected:** Returns both 1.0 and 2.4 assertions
|
|
**Actual:**
|
|
**Status:** [ ]
|
|
|
|
### Step 6: Query as_of=T0 (Before Any Data)
|
|
|
|
```bash
|
|
curl "http://localhost:18180/v1/query?subject=Semaglutide&predicate=max_approved_dose_mg&as_of=$T0"
|
|
```
|
|
|
|
**Expected:** Empty result (no assertions existed yet)
|
|
**Actual:**
|
|
**Status:** [ ]
|
|
|
|
### Step 7: Query Current (No as_of)
|
|
|
|
```bash
|
|
curl "http://localhost:18180/v1/query?subject=Semaglutide&predicate=max_approved_dose_mg"
|
|
```
|
|
|
|
**Expected:** Returns all 3 assertions (including Oral formulation)
|
|
**Actual:**
|
|
**Status:** [ ]
|
|
|
|
## Edge Cases
|
|
|
|
### ISO 8601 Date Format
|
|
|
|
```bash
|
|
# Using ISO format instead of Unix timestamp
|
|
curl "http://localhost:18180/v1/query?subject=Semaglutide&as_of=2023-06-15T00:00:00Z"
|
|
```
|
|
|
|
**Expected:** Works with ISO 8601 format
|
|
**Actual:**
|
|
**Status:** [ ]
|
|
|
|
### as_of + lens Combination
|
|
|
|
```bash
|
|
# Time travel + recency lens
|
|
curl "http://localhost:18180/v1/query?subject=Semaglutide&predicate=max_approved_dose_mg&as_of=$T2&lens=recency"
|
|
```
|
|
|
|
**Expected:** Returns most recent (by T2 standards) which is 2.4mg
|
|
**Actual:**
|
|
**Status:** [ ]
|
|
|
|
## Sign-Off Checklist
|
|
|
|
- [ ] Historical snapshot returns only assertions before date
|
|
- [ ] Future assertions excluded
|
|
- [ ] Empty result for dates before data
|
|
- [ ] Current query returns all
|
|
- [ ] ISO 8601 date format supported
|
|
- [ ] Combines correctly with other filters (lens, epoch)
|
|
|
|
## Notes
|
|
|
|
*Time travel queries are read-only views. The underlying assertions are immutable and not affected by as_of filters.*
|
|
|
|
---
|
|
|
|
**Tester:**
|
|
**Date:**
|
|
**Result:**
|