feat(p7): AI tables + enums + migration + events + InferencePort contract

Task 7.1: 7 AI-proposal-layer tables (IiosAiJob, IiosAiModelRun, IiosAiArtifact,
IiosAiClaim, IiosAiEvidenceLink, IiosAiToolCall, IiosEmbeddingRef) + enums;
migration ai-init. Adds ai.job.created / ai.artifact.proposed / ai.artifact.accepted
events and a standalone InferencePort contract (not part of sealed IiosPlatformPorts).
resetDb truncates the new tables.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-07-01 16:26:21 +05:30
parent 54c47dd133
commit 42bb99c09f
6 changed files with 419 additions and 0 deletions
+180
View File
@@ -144,6 +144,51 @@ enum IiosRouteDecisionState {
SIMULATED
}
// ─── AI enums (P7) ────────────────────────────────────────────────
enum IiosAiJobType {
CLASSIFY
SUMMARIZE
EXTRACT
}
enum IiosAiJobStatus {
PENDING
RUNNING
DONE
FAILED
ABSTAINED
}
enum IiosAiArtifactType {
CLASSIFICATION
SUMMARY
TRANSCRIPT
DIGEST
EXTRACTION
}
enum IiosAiArtifactStatus {
PROPOSED
ACCEPTED
REJECTED
SUPERSEDED
}
enum IiosAiClaimType {
MODERATION_FLAG
EVENT
FAQ
INTENT
PRIORITY
}
enum IiosAiClaimValidation {
UNVALIDATED
ACCEPTED
REJECTED
}
// ─── Kernel tables ────────────────────────────────────────────────
/// Frozen six-vector scope. orgId + appId are REQUIRED (no global-by-null).
@@ -663,3 +708,138 @@ model IiosModerationFlag {
@@index([interactionId])
}
// ─── AI Interaction SDK tables (P7) — proposal layer, never decides ─────────
/// A scoped, purposed AI work order (classify / summarize / extract). Carries the
/// provenance the critics mandate (input_scope_hash, policy_decision_id, purpose,
/// replay_version, traceId, idempotencyKey). Idempotent per key.
model IiosAiJob {
id String @id @default(cuid())
scopeId String
jobType IiosAiJobType
interactionId String?
inputWindowRef String
purpose String
status IiosAiJobStatus @default(PENDING)
modelPolicyRef String @default("golden-v1")
policyDecisionRef String?
inputScopeHash String
replayVersion String @default("v1")
abstentionReason String?
traceId String?
idempotencyKey String @unique
createdAt DateTime @default(now())
artifacts IiosAiArtifact[]
@@index([scopeId, jobType])
@@index([interactionId])
}
/// Model/prompt/tool execution metadata + cost. The budget governor (KG-12) sums
/// costUnits per scope. In P7 provider='fake' (deterministic golden model).
model IiosAiModelRun {
id String @id @default(cuid())
scopeId String
provider String @default("fake")
model String
modelVersion String
promptVersion String
toolPolicyRef String?
tokensIn Int @default(0)
tokensOut Int @default(0)
costUnits Int @default(0)
latencyMs Int @default(0)
createdAt DateTime @default(now())
artifacts IiosAiArtifact[]
toolCalls IiosAiToolCall[]
@@index([scopeId])
}
/// A durable AI proposal/output. NEVER committed truth by itself — status starts
/// PROPOSED and only a human accept (or a deterministic gate) advances it.
model IiosAiArtifact {
id String @id @default(cuid())
jobId String
job IiosAiJob @relation(fields: [jobId], references: [id], onDelete: Cascade)
modelRunId String
modelRun IiosAiModelRun @relation(fields: [modelRunId], references: [id], onDelete: Cascade)
artifactType IiosAiArtifactType
status IiosAiArtifactStatus @default(PROPOSED)
confidence Float?
contentRef Json
explanationRef String?
abstentionReason String?
acceptedByActorId String?
createdAt DateTime @default(now())
claims IiosAiClaim[]
evidence IiosAiEvidenceLink[]
@@index([jobId])
@@index([status])
}
/// A structured extracted claim (event date, intent, priority, FAQ, moderation
/// flag). validationStatus stays UNVALIDATED until a human/deterministic accept.
model IiosAiClaim {
id String @id @default(cuid())
artifactId String
artifact IiosAiArtifact @relation(fields: [artifactId], references: [id], onDelete: Cascade)
claimType IiosAiClaimType
claimJson Json
confidence Float?
validationStatus IiosAiClaimValidation @default(UNVALIDATED)
acceptedByRef String?
createdAt DateTime @default(now())
@@index([artifactId])
}
/// Source citation for an AI claim/artifact (message / segment / KB chunk).
model IiosAiEvidenceLink {
id String @id @default(cuid())
artifactId String
artifact IiosAiArtifact @relation(fields: [artifactId], references: [id], onDelete: Cascade)
sourceType String
sourceId String
spanRef String?
relevanceScore Float?
createdAt DateTime @default(now())
@@index([artifactId])
}
/// Tool calls made by an agent under MCP/tool policy. Schema now; exercised when a
/// real provider + tools land in P9.
model IiosAiToolCall {
id String @id @default(cuid())
modelRunId String
modelRun IiosAiModelRun @relation(fields: [modelRunId], references: [id], onDelete: Cascade)
toolName String
toolInputHash String
toolOutputRef String?
policyRefId String?
status String @default("PENDING")
createdAt DateTime @default(now())
@@index([modelRunId])
}
/// Reference to a vector embedding record/index; does not expose text. Schema now;
/// exercised when RAG lands in P9.
model IiosEmbeddingRef {
id String @id @default(cuid())
sourceType String
sourceId String
embeddingModel String
vectorStoreRef String
embeddingHash String
version String
createdAt DateTime @default(now())
@@unique([sourceType, sourceId, version])
}