ADR-011: Four-Layer Data Architecture — Raw Archive → Knowledge → Ontology → Decision

- Layer 1: ArchiveArtifact — immutable original with retention policy
- Layer 2: KnowledgeArtifact — extracted knowledge (observations,
  segmentations, feature vectors, relations)
- Layer 3: Knowledge Graph / Ontology (documented, not implemented)
- Layer 4: Decision Intelligence (existing DecisionCase)
- DataLifecycle: tracks every step with artifact lineage
- Key principle: AI models trained on curated datasets, not whole archive
- Ontology answers 'what does it mean in our domain?'

Long-term goal: Every observation converted once to structured
knowledge, reused infinitely for analysis, decisions, training.

Next: PR-005A — Minimal Mission Import UI for MVP-0
This commit is contained in:
Bernt
2026-07-02 16:03:39 +00:00
parent 13780baeb8
commit 754c89506b
5 changed files with 268 additions and 0 deletions
@@ -0,0 +1,68 @@
/**
* Archive Artifact — Immutable Original
*
* Principle: Original files never change.
* Hash guarantees integrity.
* Storage policy: active → archive (cheaper long-term).
*
* ADR-011: Four-Layer Data Architecture
* Layer 1: Raw Archive (this file)
*/
import { ArtifactId } from '../common/ids';
import { Hash, StorageUri } from '../common/value-objects';
export interface ArchiveArtifact {
readonly id: ArtifactId;
readonly originalName: string;
readonly mimeType: string;
readonly sizeBytes: number;
readonly hash: Hash;
readonly storageUri: StorageUri;
readonly exif?: {
readonly device?: string;
readonly gpsLat?: number;
readonly gpsLng?: number;
readonly timestamp?: Date;
readonly iso?: number;
readonly exposure?: string;
readonly focalLength?: string;
};
readonly uploadedAt: Date;
readonly uploadedBy: string;
readonly retentionPolicy: 'active' | 'archive';
readonly archiveAfterDate?: Date;
}
export interface CreateArchiveArtifactParams {
readonly id: ArtifactId;
readonly originalName: string;
readonly mimeType: string;
readonly sizeBytes: number;
readonly hash: Hash;
readonly storageUri: StorageUri;
readonly exif?: ArchiveArtifact['exif'];
readonly uploadedBy: string;
readonly retentionPolicy?: 'active' | 'archive';
}
export class ArchiveArtifactFactory {
static create(params: CreateArchiveArtifactParams): ArchiveArtifact {
return {
...params,
retentionPolicy: params.retentionPolicy ?? 'active',
archiveAfterDate: params.retentionPolicy === 'archive'
? undefined
: new Date(Date.now() + 30 * 24 * 60 * 60 * 1000), // 30 days default
uploadedAt: new Date(),
};
}
static archive(artifact: ArchiveArtifact): ArchiveArtifact {
return {
...artifact,
retentionPolicy: 'archive',
archiveAfterDate: undefined,
};
}
}
@@ -0,0 +1,52 @@
/**
* Data Lifecycle — From Reality to Decision
*
* ADR-011: Four-Layer Data Architecture
*
* Flow:
* Reality (phone, video, images)
* ↓
* Raw Archive (immutable)
* ↓
* Knowledge Extraction
* ↓
* Knowledge Graph / Ontology
* ↓
* Decision Intelligence
*
* Each step produces a new Artifact with its own version history.
*/
import { ArchiveArtifact } from './archive-artifact';
import { KnowledgeArtifact } from './knowledge-artifact';
export interface DataLifecycleStep {
readonly step: 'upload' | 'archive' | 'extract_metadata' | 'extract_knowledge' | 'ontology_map' | 'decision' | 'learn' | 'retain';
readonly inputArtifactIds: string[];
readonly outputArtifactIds: string[];
readonly timestamp: Date;
readonly processor: string; // Model, human, or system
}
export interface DataLifecycle {
readonly archiveArtifact: ArchiveArtifact;
readonly knowledgeArtifacts: KnowledgeArtifact[];
readonly steps: DataLifecycleStep[];
}
export const DataLifecycleRules = {
// Original never changes
immutableArchive: (archive: ArchiveArtifact): boolean => {
return archive.hash !== undefined && archive.hash.value.length > 0;
},
// Knowledge can be re-extracted without touching archive
reextractable: (lifecycle: DataLifecycle): boolean => {
return lifecycle.archiveArtifact !== undefined;
},
// Every step produces artifacts
artifactAtEveryStep: (lifecycle: DataLifecycle): boolean => {
return lifecycle.steps.every(step => step.outputArtifactIds.length > 0);
},
} as const;
@@ -0,0 +1,60 @@
/**
* Knowledge Artifact — Extracted Knowledge
*
* Principle: Structured knowledge is the real product.
* Raw data becomes knowledge once, then reused infinitely.
*
* ADR-011: Four-Layer Data Architecture
* Layer 2: Knowledge Extraction (this file)
*/
import { ArtifactId, ObservationId } from '../common/ids';
import { Hash, StorageUri, GeoLocation } from '../common/value-objects';
export interface KnowledgeArtifact {
readonly id: ArtifactId;
readonly sourceArchiveId: ArtifactId; // Links to original
readonly type: 'observation' | 'segmentation' | 'classification' | 'feature_vector' | 'relation';
readonly extractedAt: Date;
readonly extractedBy: string; // Model or human
readonly confidence: number; // 0.0 to 1.0
readonly data: unknown; // Type-specific data
readonly hash: Hash;
readonly storageUri: StorageUri;
readonly lineage: ArtifactId[];
}
// Specific knowledge types
export interface ObservationKnowledge {
readonly observationId: ObservationId;
readonly description: string;
readonly location: GeoLocation;
readonly boundingBox?: {
readonly x: number;
readonly y: number;
readonly width: number;
readonly height: number;
};
readonly classifications: string[]; // Taxonomy references
readonly qualityScore: number;
}
export interface SegmentationKnowledge {
readonly maskUri: string;
readonly objectClass: string;
readonly pixelCount: number;
readonly areaMeters: number;
}
export interface FeatureVectorKnowledge {
readonly dimensions: number;
readonly vector: number[];
readonly modelVersion: string;
}
export interface RelationKnowledge {
readonly subjectId: string;
readonly predicate: string;
readonly objectId: string;
readonly confidence: number;
}
+21
View File
@@ -44,6 +44,27 @@ export {
Severity,
PriorityValue,
} from './common/value-objects';
// Four-Layer Data Architecture
export {
ArchiveArtifact,
CreateArchiveArtifactParams,
ArchiveArtifactFactory,
} from './artifacts/archive-artifact';
export {
KnowledgeArtifact,
ObservationKnowledge,
SegmentationKnowledge,
FeatureVectorKnowledge,
RelationKnowledge,
} from './artifacts/knowledge-artifact';
export {
DataLifecycle,
DataLifecycleStep,
DataLifecycleRules,
} from './artifacts/data-lifecycle';
export * from './common/enums';
export * from './common/errors';