7075cf9ab9
- Session is root (not Mission): Field Session → Mission → Asset → Observation... - Event Sourcing: never overwrite status, status is projection of history - Artifact Registry: first-class object with id, type, version, hash, lineage - Decision Case immutability: Review → Revision → Approved Version (like Git) - Review Task: Assigned → Reviewed → Approved → Closed - Processing Graph: nodes not hardcoded chain, swap models without changing rest - Data Quality as domain: Blur, Duplicate, Bad GPS, Low Resolution, etc. - Decision Case comparison: show exactly what changed, which evidence, model, human - Golden Missions + Golden Datasets: two levels - Domain Event Viewer: timeline (09:42 Mission Created, 09:43 Video Uploaded...) - KPI: Verified Decision Throughput (verified decisions per day) - Architecture Principle: 'Produces verified Decision Cases through reproducible and traceable pipeline' Updated PR-001 Domain Model: - Added FieldSession (root) - Added Artifact interface - Added Event sourcing types - Session ID format: session_YYYYMMDD_NNNNNN - Updated API to include /sessions endpoints Rationale: Three fundamental objects (Session, Artifact, Event) make the rest natural. Scalable, auditable, well-suited for public sector traceability requirements.
757 lines
15 KiB
Markdown
757 lines
15 KiB
Markdown
# EPIC-001: First Verified Decision
|
|
|
|
**Goal:** Prove the Intelligence Lab works end-to-end with real data
|
|
|
|
| | |
|
|
|---|---|
|
|
| **Epic** | 001 |
|
|
| **Status** | READY FOR DEVELOPMENT |
|
|
| **Goal** | A pilot can film a real object, upload, get a Decision Case, review AI, correct annotations, see the evidence chain, approve the case, with full version control and traceability |
|
|
| **Success** | Complete vertical slice from reality to verified decision |
|
|
|
|
---
|
|
|
|
## STOP Rule
|
|
|
|
**No new pipeline may be implemented until at least 20 real Decision Cases have been produced through the existing pipeline.**
|
|
|
|
Observe first, improve later.
|
|
|
|
---
|
|
|
|
## Field Readiness Gate
|
|
|
|
Before building any new feature, answer:
|
|
|
|
| Question | Must Answer |
|
|
|----------|-------------|
|
|
| Can we use this during a real pilot day? | Yes |
|
|
| Will it give us better observation data? | Yes |
|
|
| Will it reduce manual work? | Yes |
|
|
| Will it improve Decision Cases? | Yes |
|
|
| Will it help us validate the model? | Yes |
|
|
|
|
If **no** on most questions — the feature waits.
|
|
|
|
---
|
|
|
|
## Vertical User Journey (Demo)
|
|
|
|
The complete journey that can be demonstrated in minutes:
|
|
|
|
```
|
|
quiXzoom
|
|
↓
|
|
Take photo or video
|
|
↓
|
|
Mission Import
|
|
↓
|
|
Raw Dataset saved
|
|
↓
|
|
Dataset Explorer shows mission
|
|
↓
|
|
AI creates Observation
|
|
↓
|
|
User corrects if needed
|
|
↓
|
|
Decision Case created
|
|
↓
|
|
Decision Viewer shows:
|
|
Observation
|
|
↓
|
|
Evidence
|
|
↓
|
|
Finding
|
|
↓
|
|
Decision
|
|
↓
|
|
Business Impact
|
|
```
|
|
|
|
If this journey works, the core is proven.
|
|
|
|
## Sprint Goal
|
|
|
|
**Every sprint must result in more verified Decision Cases from real pilot missions.**
|
|
|
|
Keep development close to user reality. Intelligence Lab grows from actual needs, not assumptions.
|
|
|
|
---
|
|
|
|
## Stories
|
|
|
|
### Story 1: Mission Import
|
|
|
|
**As a** field engineer
|
|
**I want to** upload mission data
|
|
**So that** raw data is stored immutably
|
|
|
|
```
|
|
Video + Images + GPS + EXIF
|
|
↓
|
|
Raw Dataset (immutable, versioned)
|
|
```
|
|
|
|
**Acceptance:**
|
|
- [ ] Upload video and images
|
|
- [ ] Extract and display GPS, timestamp, device metadata
|
|
- [ ] Store raw data with checksum
|
|
- [ ] Show upload progress and confirmation
|
|
|
|
**Why first:** Proves we can receive real data.
|
|
|
|
---
|
|
|
|
### Story 2: Dataset Explorer
|
|
|
|
**As a** field engineer
|
|
**I want to** browse and search missions
|
|
**So that** I can find specific observations
|
|
|
|
**Features:**
|
|
- List view
|
|
- Map view
|
|
- Filter by date, location, type
|
|
- Search by metadata
|
|
- Open mission to see details
|
|
|
|
**Acceptance:**
|
|
- [ ] Browse all missions
|
|
- [ ] Filter by date range
|
|
- [ ] Filter by location
|
|
- [ ] Search by metadata
|
|
- [ ] Open mission detail view
|
|
|
|
**Why second:** Makes data visible and searchable.
|
|
|
|
---
|
|
|
|
### Story 3: Annotation Workspace
|
|
|
|
**As a** field engineer
|
|
**I want to** review and correct AI suggestions
|
|
**So that** observations are accurate
|
|
|
|
```
|
|
Image
|
|
↓
|
|
AI Detection (bounding box + label + confidence)
|
|
↓
|
|
Human Review (correct / modify / reject)
|
|
↓
|
|
Version History
|
|
```
|
|
|
|
**Acceptance:**
|
|
- [ ] Show image with AI bounding boxes
|
|
- [ ] Display AI label and confidence
|
|
- [ ] Allow correction of label
|
|
- [ ] Allow adjustment of bounding box
|
|
- [ ] Allow rejection of detection
|
|
- [ ] Save version history
|
|
- [ ] Show before/after comparison
|
|
|
|
**Why third:** First human-in-the-loop.
|
|
|
|
---
|
|
|
|
### Story 4: Decision Case
|
|
|
|
**As a** field engineer
|
|
**I want to** see the full decision chain
|
|
**So that** I understand why a decision was recommended
|
|
|
|
```
|
|
Observation
|
|
↓
|
|
Evidence
|
|
↓
|
|
Finding
|
|
↓
|
|
Decision
|
|
↓
|
|
Business Impact
|
|
```
|
|
|
|
**Acceptance:**
|
|
- [ ] Display observation with image/video
|
|
- [ ] Show evidence (linked observations)
|
|
- [ ] Show finding (pattern/conclusion)
|
|
- [ ] Show decision (recommended action)
|
|
- [ ] Show business impact (risk, cost, time)
|
|
- [ ] Allow approval or rejection
|
|
- [ ] Show explainability chain (clickable)
|
|
|
|
**Why fourth:** First verified decision.
|
|
|
|
---
|
|
|
|
### Story 5: Replay
|
|
|
|
**As a** field engineer
|
|
**I want to** replay a mission
|
|
**So that** I can review the entire chain
|
|
|
|
**V1:** Simple playback — step through the chain
|
|
**Not in V1:** AI comparison, model versioning
|
|
|
|
```
|
|
Mission-001
|
|
↓
|
|
Step 1: Observation
|
|
Step 2: Evidence
|
|
Step 3: Finding
|
|
Step 4: Decision
|
|
Step 5: Business Impact
|
|
```
|
|
|
|
**Acceptance:**
|
|
- [ ] Select mission to replay
|
|
- [ ] Step through each stage
|
|
- [ ] Show data at each stage
|
|
- [ ] Navigate forward and backward
|
|
|
|
**Why fifth:** Proves the chain is reproducible.
|
|
|
|
---
|
|
|
|
### Story 6: Session Management
|
|
|
|
**As a** field engineer
|
|
**I want to** create and manage field sessions
|
|
**So that** missions are organized by location and date
|
|
|
|
```
|
|
Field Session
|
|
├── Location: Huddinge
|
|
├── Date: 2026-08-14
|
|
└── Missions: [Mission-001, Mission-002, ...]
|
|
```
|
|
|
|
**Acceptance:**
|
|
- [ ] Create session with location and date
|
|
- [ ] List all sessions
|
|
- [ ] Open session to see missions
|
|
|
|
**Why last:** Organizational layer on top of working core.
|
|
|
|
---
|
|
|
|
## Golden Mission
|
|
|
|
**A real mission that never changes, used as regression test.**
|
|
|
|
```
|
|
Golden Mission 001
|
|
├── Location: Huddinge
|
|
├── Images: 52
|
|
├── Videos: 4
|
|
├── Observations: 31
|
|
└── Verified Decision Cases: 8
|
|
```
|
|
|
|
Every new model runs against the same mission. See immediately if something got better or worse.
|
|
|
|
## Review (First-Class Object)
|
|
|
|
Not just Annotation. Full quality flow:
|
|
|
|
```
|
|
Observation
|
|
↓
|
|
AI
|
|
↓
|
|
Human Review
|
|
↓
|
|
Approved / Rejected / Needs More Evidence
|
|
```
|
|
|
|
Makes the entire quality flow traceable.
|
|
|
|
## Dashboard v1
|
|
|
|
Extremely simple:
|
|
|
|
```
|
|
FIELD STATUS
|
|
|
|
Sessions: 3
|
|
Missions: 27
|
|
Decision Cases: 11
|
|
Pending Reviews: 6
|
|
Verified Decisions: 8
|
|
|
|
[Continue Reviewing]
|
|
```
|
|
|
|
Should feel like a work tool, not a BI system.
|
|
|
|
## Not in First Release
|
|
|
|
Intentionally postponed:
|
|
|
|
| Feature | Why Postponed |
|
|
|---------|---------------|
|
|
| GPU Queue | Not needed for 20 Decision Cases |
|
|
| Hyperparameter Search | Not needed for validation |
|
|
| Distributed Training | Not needed for MVP |
|
|
| Benchmark (15 models) | Not needed for first cases |
|
|
| Canary Deployment | Not needed for internal tool |
|
|
| Auto Retraining | Not needed until model validated |
|
|
| Bias Dashboard | Not needed until diverse data |
|
|
| Drift Detection | Not needed until production |
|
|
|
|
These are important but don't help reach the first verified workflow.
|
|
|
|
---
|
|
|
|
## Definition of "First Verified Decision"
|
|
|
|
**A First Verified Decision is a Decision Case that:**
|
|
- Is built on real observation data
|
|
- Has been reviewed by a human
|
|
- Has a complete evidence chain
|
|
- Is fully reproducible from raw data to recommendation
|
|
|
|
## Definition of Done (Epic)
|
|
|
|
- [ ] A pilot can film a real object in quiXzoom
|
|
- [ ] Upload material to Intelligence Lab
|
|
- [ ] Get a Decision Case created automatically
|
|
- [ ] Review AI results
|
|
- [ ] Correct annotations
|
|
- [ ] See full evidence chain
|
|
- [ ] Approve Decision Case
|
|
- [ ] Everything saved versioned and traceable
|
|
- [ ] At least 1 real Decision Case produced
|
|
- [ ] Meets "First Verified Decision" definition
|
|
|
|
---
|
|
|
|
## Definition of Ready (Next Epic)
|
|
|
|
**Epic-002 can start when:**
|
|
- 20 real Decision Cases exist
|
|
- Field Readiness Gate passed
|
|
- STOP rule satisfied
|
|
|
|
---
|
|
|
|
## Technical Stack (Recommended)
|
|
|
|
| Layer | Technology | Rationale |
|
|
|-------|-----------|-----------|
|
|
| Frontend | React + TypeScript (strict) | Type safety, component ecosystem |
|
|
| Backend | Node.js + Express + TypeScript | Same language, fast development |
|
|
| Database | PostgreSQL | ACID, JSON support, proven |
|
|
| Storage | S3/R2 | Immutable object storage |
|
|
| Queue | Bull (Redis) | Proven, observable job queue |
|
|
| AI | Python microservice | Model inference separate from API |
|
|
| Git | All code versioned | Traceability |
|
|
|
|
---
|
|
|
|
## Quality Gates
|
|
|
|
| Gate | Requirement |
|
|
|------|-------------|
|
|
| **Code** | TypeScript strict, ≥80% test coverage |
|
|
| **Security** | No secrets in code, OAuth 2.0 |
|
|
| **Audit** | All actions logged, immutable |
|
|
| **Deploy** | GitOps, reproducible builds |
|
|
|
|
---
|
|
|
|
## ändringshistoria
|
|
|
|
| Version | Datum | Beskrivning |
|
|
|---------|-------|-------------|
|
|
| 1.0 | 2026-07-02 | Initial Epic-001 specification |
|
|
| 1.1 | 2026-07-02 | Reordered stories (Mission Import first, Session Management last), added Golden Mission, Review object, Dashboard v1, vertical user journey, First Verified Decision definition |
|
|
|
|
---
|
|
|
|
## Vision
|
|
|
|
**LandveX Intelligence Lab is the internal factory where raw reality is refined into verified Control Intelligence.**
|
|
|
|
**Architecture Goal:** Every artifact must be traceable backward to its source and forward to its decision.
|
|
|
|
**Architecture Principle:**
|
|
**LandveX Intelligence Lab does not produce AI results. It produces verified Decision Cases through a reproducible and traceable pipeline.**
|
|
|
|
## Core Objects
|
|
|
|
Three fundamental objects:
|
|
|
|
| Object | Purpose |
|
|
|--------|---------|
|
|
| **Session** | Organizes field work |
|
|
| **Artifact** | Organizes everything produced (video, dataset, models, reports, Decision Cases) |
|
|
| **Event** | Organizes history and makes the entire chain reproducible |
|
|
|
|
## Development Rule
|
|
|
|
**No Story may start with UI. Every Story starts with:**
|
|
1. Domain model
|
|
2. API
|
|
3. Storage
|
|
4. Tests
|
|
5. UI
|
|
|
|
This keeps architecture clean and allows testing each part without frontend.
|
|
|
|
## Hierarchy
|
|
|
|
```
|
|
Field Session
|
|
↓
|
|
Mission
|
|
↓
|
|
Mission Asset
|
|
↓
|
|
Observation
|
|
↓
|
|
Evidence
|
|
↓
|
|
Finding
|
|
↓
|
|
Decision
|
|
↓
|
|
Action
|
|
↓
|
|
Outcome
|
|
```
|
|
|
|
**Session is the root.** A pilot day produces many missions.
|
|
|
|
## Event Sourcing
|
|
|
|
**Never overwrite status. Status is a projection of history.**
|
|
|
|
```
|
|
MissionCreated
|
|
↓
|
|
AssetUploaded
|
|
↓
|
|
AssetValidated
|
|
↓
|
|
ObservationCreated
|
|
↓
|
|
EvidenceLinked
|
|
↓
|
|
DecisionApproved
|
|
```
|
|
|
|
Always replayable.
|
|
|
|
## Artifact Registry
|
|
|
|
First-class object. Not just buckets.
|
|
|
|
```
|
|
Artifact
|
|
├── id
|
|
├── type // video | dataset | model | decision_case | evaluation_report | replay
|
|
├── version
|
|
├── hash
|
|
├── created
|
|
├── created_by
|
|
├── storage_uri
|
|
├── parent
|
|
└── lineage
|
|
```
|
|
|
|
Everything becomes traceable.
|
|
|
|
## Decision Case Immutability
|
|
|
|
Never modify a Decision Case.
|
|
|
|
```
|
|
Decision Case
|
|
↓
|
|
Review
|
|
↓
|
|
Revision
|
|
↓
|
|
Approved Version
|
|
```
|
|
|
|
Like Git.
|
|
|
|
## Review Task
|
|
|
|
```
|
|
Review Task
|
|
↓
|
|
Assigned
|
|
↓
|
|
Reviewed
|
|
↓
|
|
Approved
|
|
↓
|
|
Closed
|
|
```
|
|
|
|
Makes future quality assurance much easier.
|
|
|
|
## Processing Graph
|
|
|
|
Not a list of pipelines. Each step is a node.
|
|
|
|
```
|
|
Mission
|
|
↓
|
|
Dataset
|
|
↓
|
|
Annotation
|
|
↓
|
|
Evaluation
|
|
↓
|
|
Decision
|
|
↓
|
|
Learning
|
|
```
|
|
|
|
Swap models without changing the rest:
|
|
```
|
|
YOLO → Grounding DINO → Custom model
|
|
```
|
|
|
|
## Data Quality Domain
|
|
|
|
```
|
|
Quality Issue
|
|
├── Blur
|
|
├── Duplicate
|
|
├── Bad GPS
|
|
├── Low Resolution
|
|
├── Missing Metadata
|
|
├── Wrong Timestamp
|
|
└── Occlusion
|
|
```
|
|
|
|
Then: Quality Report.
|
|
|
|
## Decision Case Comparison
|
|
|
|
```
|
|
Decision A
|
|
↓
|
|
Decision B
|
|
```
|
|
|
|
Show exactly:
|
|
- What changed?
|
|
- Which evidence?
|
|
- Which confidence?
|
|
- Which model?
|
|
- Which human?
|
|
|
|
## Golden Missions & Golden Datasets
|
|
|
|
| Level | Description |
|
|
|-------|-------------|
|
|
| **Golden Mission** | Real mission that never changes |
|
|
| **Golden Dataset** | Selected observations from Golden Mission |
|
|
|
|
## Domain Event Viewer
|
|
|
|
Timeline, not logs:
|
|
|
|
```
|
|
09:42 Mission Created
|
|
09:43 Video Uploaded
|
|
09:44 GPS Extracted
|
|
09:45 AI Analysis
|
|
09:47 Human Review
|
|
09:50 Decision Approved
|
|
```
|
|
|
|
Incredibly useful.
|
|
|
|
## KPI: Verified Decision Throughput
|
|
|
|
Not number of models. Not number of missions.
|
|
|
|
```
|
|
Verified Decision Throughput = Verified decisions per day
|
|
```
|
|
|
|
This is your factory capacity.
|
|
|
|
## Story 1: Mission Import — Implementation Plan
|
|
|
|
### PR-001: Domain Model
|
|
|
|
```typescript
|
|
// FieldSession
|
|
interface FieldSession {
|
|
id: string; // session_20260814_000001
|
|
location: Location;
|
|
date: Date;
|
|
status: SessionStatus;
|
|
missions: string[]; // mission IDs
|
|
createdAt: Date;
|
|
}
|
|
|
|
// Mission
|
|
interface Mission {
|
|
id: string; // mission_20260814_000123
|
|
sessionId: string;
|
|
status: MissionStatus;
|
|
location: Location;
|
|
device: Device;
|
|
createdAt: Date;
|
|
updatedAt: Date;
|
|
}
|
|
|
|
// MissionAsset
|
|
interface MissionAsset {
|
|
id: string; // asset_000456
|
|
missionId: string;
|
|
type: AssetType; // image | video
|
|
storagePath: string;
|
|
checksum: string;
|
|
sizeBytes: number;
|
|
mimeType: string;
|
|
metadata: AssetMetadata;
|
|
createdAt: Date;
|
|
}
|
|
|
|
// AssetMetadata
|
|
interface AssetMetadata {
|
|
exif: ExifData;
|
|
gps: GpsCoordinates;
|
|
device: DeviceInfo;
|
|
}
|
|
|
|
// Upload
|
|
interface Upload {
|
|
id: string;
|
|
missionId: string;
|
|
status: UploadStatus;
|
|
progress: number;
|
|
startedAt: Date;
|
|
completedAt?: Date;
|
|
}
|
|
|
|
// Artifact
|
|
interface Artifact {
|
|
id: string;
|
|
type: ArtifactType;
|
|
version: number;
|
|
hash: string;
|
|
createdBy: string;
|
|
storageUri: string;
|
|
parentId?: string;
|
|
lineage: string[];
|
|
}
|
|
|
|
// Enums
|
|
type SessionStatus = 'planned' | 'active' | 'completed';
|
|
type MissionStatus = 'created' | 'uploading' | 'processing' | 'completed' | 'failed';
|
|
type AssetType = 'image' | 'video';
|
|
type ArtifactType = 'video' | 'dataset' | 'model' | 'decision_case' | 'evaluation_report' | 'replay';
|
|
type UploadStatus = 'pending' | 'in_progress' | 'completed' | 'failed';
|
|
```
|
|
|
|
### PR-002: Storage
|
|
|
|
- Upload to bucket (S3/R2)
|
|
- Metadata in PostgreSQL
|
|
- Checksums (SHA-256)
|
|
- File size
|
|
- MIME type
|
|
- EXIF extraction
|
|
- GPS parsing
|
|
- **No AI yet**
|
|
|
|
### PR-003: API
|
|
|
|
```
|
|
POST /sessions
|
|
POST /sessions/{id}/missions
|
|
POST /missions/{id}/assets
|
|
GET /sessions/{id}
|
|
GET /sessions
|
|
GET /missions/{id}
|
|
GET /missions
|
|
```
|
|
|
|
### PR-004: Events
|
|
|
|
```
|
|
SessionCreated
|
|
↓
|
|
MissionCreated
|
|
↓
|
|
AssetUploaded
|
|
↓
|
|
AssetValidated
|
|
↓
|
|
RawDatasetReady
|
|
```
|
|
|
|
**No pipeline yet. Just events.**
|
|
|
|
### PR-005: UI
|
|
|
|
Extremely simple:
|
|
|
|
```
|
|
Mission Import
|
|
|
|
[Drag files] or [Choose files]
|
|
|
|
[Upload]
|
|
|
|
Progress: ████████░░ 80%
|
|
|
|
Done! Mission mission_20260814_000123 created.
|
|
```
|
|
|
|
### Definition of Done (Story 1)
|
|
|
|
```
|
|
Phone → Video → Upload → Bucket → Metadata → Mission visible in Dataset Explorer
|
|
```
|
|
|
|
This is the first proof.
|
|
|
|
## ID Convention
|
|
|
|
**Never UUID in UI. UUID internally.**
|
|
|
|
| Entity | ID Format | Example |
|
|
|--------|-----------|---------|
|
|
| Session | `session_YYYYMMDD_NNNNNN` | `session_20260814_000001` |
|
|
| Mission | `mission_YYYYMMDD_NNNNNN` | `mission_20260814_000123` |
|
|
| Asset | `asset_NNNNNN` | `asset_000456` |
|
|
| Observation | `obs_NNNNNN` | `obs_000981` |
|
|
| Decision | `decision_NNNNNN` | `decision_000044` |
|
|
|
|
## Artifact Viewer
|
|
|
|
When clicking a file, show:
|
|
|
|
```
|
|
Raw Asset
|
|
├── Filename: IMG_20260814_143052.jpg
|
|
├── Size: 4.2 MB
|
|
├── MIME: image/jpeg
|
|
├── Hash: sha256:a3f7...
|
|
├── GPS: 59.2371, 18.1456
|
|
├── EXIF: Device=iPhone14,2, ISO=100, Exposure=1/120s
|
|
├── Created: 2026-08-14 14:30:52 UTC
|
|
├── Storage: s3://landvex-raw/2026/08/14/mission_20260814_000123/
|
|
└── Version: 1
|
|
```
|
|
|
|
Saves enormous time during debugging.
|
|
|
|
## Status
|
|
|
|
**READY FOR DEVELOPMENT — PR-001: Domain Model**
|