feat: migrate workspace configuration domains to ServerApi

This commit is contained in:
2026-09-23 04:27:52 +09:00
parent c8766e9fb9
commit 6cbc3a6988
34 changed files with 10679 additions and 454 deletions
+38 -15
View File
@@ -4,6 +4,7 @@
//! backend operation boundary. Repository-local audit logs are not an authority.
use chrono::{DateTime, Utc};
use schemars::JsonSchema;
use serde::{Deserialize, Serialize};
use uuid::Uuid;
@@ -11,7 +12,7 @@ fn is_zero_usize(value: &usize) -> bool {
*value == 0
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize, JsonSchema)]
#[serde(rename_all = "snake_case")]
pub enum AuditWorker {
MemoryExtract,
@@ -27,7 +28,7 @@ impl AuditWorker {
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize, JsonSchema)]
#[serde(rename_all = "snake_case")]
pub enum WorkerLifecycleStatus {
Started,
@@ -49,7 +50,7 @@ impl WorkerLifecycleStatus {
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize, JsonSchema)]
#[serde(rename_all = "snake_case")]
pub enum AuditTrigger {
SessionEnd,
@@ -77,7 +78,7 @@ impl AuditTrigger {
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize, JsonSchema)]
#[serde(rename_all = "snake_case")]
pub enum AuditStatus {
Success,
@@ -85,7 +86,7 @@ pub enum AuditStatus {
Skipped,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, JsonSchema)]
pub struct ModelAudit {
#[serde(default, skip_serializing_if = "Option::is_none")]
pub ref_: Option<String>,
@@ -95,31 +96,39 @@ pub struct ModelAudit {
pub model_id: Option<String>,
}
#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize, JsonSchema)]
pub struct UsageAudit {
#[serde(default, skip_serializing_if = "Option::is_none")]
#[schemars(range(min = 0, max = 9_007_199_254_740_991_u64))]
pub input_tokens: Option<u64>,
#[serde(default, skip_serializing_if = "Option::is_none")]
#[schemars(range(min = 0, max = 9_007_199_254_740_991_u64))]
pub output_tokens: Option<u64>,
#[serde(default, skip_serializing_if = "Option::is_none")]
#[schemars(range(min = 0, max = 9_007_199_254_740_991_u64))]
pub total_tokens: Option<u64>,
#[serde(default, skip_serializing_if = "Option::is_none")]
#[schemars(range(min = 0, max = 9_007_199_254_740_991_u64))]
pub cache_read_input_tokens: Option<u64>,
#[serde(default, skip_serializing_if = "Option::is_none")]
#[schemars(range(min = 0, max = 9_007_199_254_740_991_u64))]
pub cache_creation_input_tokens: Option<u64>,
}
#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize, JsonSchema)]
pub struct ExtractAudit {
#[serde(default, skip_serializing_if = "Option::is_none")]
pub session_id: Option<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub segment_id: Option<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
#[schemars(with = "Option<crate::schema::JsonSafeU64Pair>")]
pub entry_range: Option<[u64; 2]>,
#[serde(default, skip_serializing_if = "Option::is_none")]
#[schemars(with = "Option<crate::schema::JsonSafeU64Pair>")]
pub history_range: Option<[u64; 2]>,
#[serde(default)]
#[schemars(range(min = 0, max = 9_007_199_254_740_991_usize))]
pub staging_count: usize,
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub staging_ids: Vec<String>,
@@ -127,13 +136,16 @@ pub struct ExtractAudit {
pub staging_paths: Vec<String>,
}
#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize, JsonSchema)]
pub struct ConsolidationAudit {
#[serde(default)]
#[schemars(range(min = 0, max = 9_007_199_254_740_991_usize))]
pub staging_count: usize,
#[serde(default, skip_serializing_if = "is_zero_usize")]
#[schemars(range(min = 0, max = 9_007_199_254_740_991_usize))]
pub invalid_staging_count: usize,
#[serde(default)]
#[schemars(range(min = 0, max = 9_007_199_254_740_991_u64))]
pub staging_bytes: u64,
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub consumed_staging_ids: Vec<String>,
@@ -141,19 +153,25 @@ pub struct ConsolidationAudit {
pub operations: OperationCounts,
}
#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize, JsonSchema)]
pub struct OperationCounts {
#[serde(default)]
#[schemars(range(min = 0, max = 9_007_199_254_740_991_usize))]
pub write: usize,
#[serde(default)]
#[schemars(range(min = 0, max = 9_007_199_254_740_991_usize))]
pub edit: usize,
#[serde(default)]
#[schemars(range(min = 0, max = 9_007_199_254_740_991_usize))]
pub delete: usize,
#[serde(default)]
#[schemars(range(min = 0, max = 9_007_199_254_740_991_usize))]
pub drop: usize,
#[serde(default)]
#[schemars(range(min = 0, max = 9_007_199_254_740_991_usize))]
pub merge: usize,
#[serde(default)]
#[schemars(range(min = 0, max = 9_007_199_254_740_991_usize))]
pub trim: usize,
}
@@ -163,15 +181,17 @@ impl OperationCounts {
}
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, JsonSchema)]
pub struct MemorySettingsAudit {
pub workspace_id: String,
#[schemars(range(min = 0, max = 9_007_199_254_740_991_u64))]
pub settings_revision: u64,
pub language: String,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, JsonSchema)]
pub struct WorkerLifecycleAudit {
#[schemars(with = "String")]
pub run_id: Uuid,
pub worker: AuditWorker,
pub status: WorkerLifecycleStatus,
@@ -189,7 +209,7 @@ pub struct WorkerLifecycleAudit {
pub consolidation: Option<ConsolidationAudit>,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, JsonSchema)]
pub struct RecordOperationAudit {
pub op: String,
pub status: AuditStatus,
@@ -204,7 +224,7 @@ pub struct RecordOperationAudit {
pub reason: Option<String>,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, JsonSchema)]
pub struct RecordUsageAudit {
pub op: String,
pub status: AuditStatus,
@@ -216,12 +236,13 @@ pub struct RecordUsageAudit {
#[serde(default, skip_serializing_if = "Option::is_none")]
pub query: Option<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
#[schemars(range(min = 0, max = 9_007_199_254_740_991_usize))]
pub result_count: Option<usize>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub reason: Option<String>,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, JsonSchema)]
#[serde(tag = "event", rename_all = "snake_case")]
pub enum AuditPayload {
WorkerLifecycle(WorkerLifecycleAudit),
@@ -229,9 +250,11 @@ pub enum AuditPayload {
RecordUsage(RecordUsageAudit),
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, JsonSchema)]
pub struct AuditEvent {
#[schemars(with = "String")]
pub id: Uuid,
#[schemars(with = "String")]
pub occurred_at: DateTime<Utc>,
#[serde(flatten)]
pub payload: AuditPayload,
+19 -13
View File
@@ -11,7 +11,7 @@ use crate::audit::AuditEvent;
use crate::extract::{ExtractedCandidate, ExtractedPayload, StagingEvidence};
use crate::schema::{SourceEvidenceRef, SourceRef};
#[derive(Debug, Clone, Serialize, Deserialize)]
#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
#[serde(tag = "operation", rename_all = "snake_case")]
pub enum MemoryBackendOperation {
Query(MemoryQueryOperation),
@@ -26,7 +26,7 @@ pub enum MemoryBackendOperation {
StagingClose(MemoryStagingCloseOperation),
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
#[serde(tag = "status", rename_all = "snake_case")]
pub enum MemoryBackendHttpResponse {
Ok {
@@ -37,7 +37,7 @@ pub enum MemoryBackendHttpResponse {
},
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
#[serde(tag = "kind", rename_all = "snake_case")]
pub enum MemoryBackendOperationResult {
ToolOutput(MemoryToolOutput),
@@ -45,14 +45,14 @@ pub enum MemoryBackendOperationResult {
StagingWritten(MemoryStagingWriteOutput),
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
pub struct MemoryToolOutput {
pub summary: String,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub content: Option<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
pub struct MemoryQueryOperation {
#[serde(default, skip_serializing_if = "Option::is_none")]
pub query: Option<String>,
@@ -61,8 +61,10 @@ pub struct MemoryQueryOperation {
#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
pub struct MemoryDocumentReadOperation {
#[serde(default, skip_serializing_if = "Option::is_none")]
#[schemars(range(min = 0, max = 9_007_199_254_740_991_usize))]
pub offset: Option<usize>,
#[serde(default, skip_serializing_if = "Option::is_none")]
#[schemars(range(min = 0, max = 9_007_199_254_740_991_usize))]
pub limit: Option<usize>,
}
@@ -74,15 +76,15 @@ pub struct MemoryDocumentUpdateOperation {
pub replace_all: bool,
}
#[derive(Debug, Clone, Serialize, Deserialize, Default)]
#[derive(Debug, Clone, Serialize, Deserialize, Default, JsonSchema)]
pub struct MemoryResidentSummaryOperation {}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
pub struct MemoryAppendAuditOperation {
pub event: AuditEvent,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
pub struct MemoryStageCandidateOperation {
pub source: SourceRef,
pub extract_run_id: String,
@@ -93,7 +95,7 @@ pub struct MemoryStageCandidateOperation {
pub source_refs: Vec<SourceEvidenceRef>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
pub struct MemoryStageExtractedOperation {
pub source: SourceRef,
pub payload: ExtractedPayload,
@@ -102,6 +104,7 @@ pub struct MemoryStageExtractedOperation {
#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
pub struct MemoryStagingListOperation {
#[serde(default, skip_serializing_if = "Option::is_none")]
#[schemars(range(min = 0, max = 9_007_199_254_740_991_usize))]
pub limit: Option<usize>,
}
@@ -140,28 +143,31 @@ pub enum MemoryStagingAffectedMemoryOperation {
Edit,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
#[serde(deny_unknown_fields)]
pub struct MemoryConsolidateStagingOperation {
#[serde(default)]
pub force: bool,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
pub struct MemoryConsolidationOutput {
pub status: String,
pub summary: String,
#[schemars(range(min = 0, max = 9_007_199_254_740_991_usize))]
pub candidate_count: usize,
#[schemars(range(min = 0, max = 9_007_199_254_740_991_u64))]
pub total_bytes: u64,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
pub struct MemoryBackendAckOutput {
pub summary: String,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
pub struct MemoryStagingWriteOutput {
#[schemars(range(min = 0, max = 9_007_199_254_740_991_usize))]
pub staging_count: usize,
pub staging_ids: Vec<String>,
}
+2 -1
View File
@@ -73,12 +73,13 @@ impl ExtractedPayload {
}
/// Bounded evidence snippet copied into a flat staging record.
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, JsonSchema)]
#[serde(deny_unknown_fields)]
pub struct StagingEvidence {
pub id: String,
pub kind: EvidenceKind,
#[serde(default, skip_serializing_if = "Option::is_none")]
#[schemars(with = "Option<crate::schema::JsonSafeU64Pair>")]
pub entry_range: Option<[u64; 2]>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub origin: Option<EvidenceOrigin>,
+12 -1
View File
@@ -4,14 +4,23 @@ use lint_common::RecordLintError;
use schemars::JsonSchema;
use serde::{Deserialize, Serialize};
/// Schema-only representation for JSON integers that must remain exactly
/// representable by JavaScript consumers.
#[allow(dead_code)]
#[derive(JsonSchema)]
pub struct MemoryJsonSafeU64(#[schemars(range(min = 0, max = 9_007_199_254_740_991_u64))] u64);
pub type JsonSafeU64Pair = [MemoryJsonSafeU64; 2];
pub use lint_common::Frontmatter;
/// Reference to a session-store entry range. Stored in `sources` /
/// `last_sources` arrays for traceability back to raw session logs.
#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
#[derive(Debug, Clone, PartialEq, Eq, Serialize, JsonSchema)]
pub struct SourceRef {
pub segment_id: String,
/// `[start_entry, end_entry]` inclusive range of session-store entry indices.
#[schemars(with = "crate::schema::JsonSafeU64Pair")]
pub range: [u64; 2],
}
@@ -99,6 +108,7 @@ pub struct EvidenceOrigin {
#[serde(default, skip_serializing_if = "Option::is_none")]
pub flow_definition_id: Option<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
#[schemars(range(min = 0, max = 9_007_199_254_740_991_u64))]
pub flow_definition_revision: Option<u64>,
}
@@ -118,6 +128,7 @@ pub struct SourceEvidenceRef {
pub segment_id: Option<String>,
/// `[start_entry, end_entry]` inclusive range of session-store entry indices.
#[serde(default, skip_serializing_if = "Option::is_none")]
#[schemars(with = "Option<crate::schema::JsonSafeU64Pair>")]
pub entry_range: Option<[u64; 2]>,
/// Host-assigned evidence id within the referenced evidence set.
#[serde(default, skip_serializing_if = "Option::is_none")]
+1
View File
@@ -8,6 +8,7 @@ mod decision;
mod request;
mod summary;
pub(crate) use common::JsonSafeU64Pair;
pub use common::{
EvidenceKind, EvidenceOrigin, EvidenceOriginKind, Frontmatter, SourceEvidenceRef, SourceRef,
split_frontmatter,