use serde::{Deserialize, Serialize};
use crate::hooks::decide::Action;
use crate::store::{
PolicyMode as StorePolicyMode, PolicyRecord, PolicyStage as StorePolicyStage,
Priority as StorePriority, ReceiptSource as StoreReceiptSource,
};
#[derive(Debug, Serialize, Deserialize)]
#[serde(deny_unknown_fields)]
pub struct GetInput {
pub key: String,
}
#[derive(Debug, Serialize, Deserialize)]
#[serde(deny_unknown_fields)]
pub struct HookEvaluateInput {
pub file_key: String,
#[serde(default)]
pub include_recent: bool,
#[serde(default)]
pub actor: Option<String>,
}
#[derive(Debug, Serialize, Deserialize)]
#[serde(deny_unknown_fields)]
pub struct PolicyEvaluateInput {
pub action: Action,
#[serde(default)]
pub actor: Option<String>,
#[serde(default)]
pub raw_command: Option<String>,
}
#[derive(Debug, Serialize, Deserialize)]
pub struct PolicyVerdict {
pub key: String,
pub stage: StorePolicyStage,
pub mode: StorePolicyMode,
pub rule: String,
pub reason: String,
pub severity: StorePriority,
pub requires_key: String,
#[serde(default)]
pub via: Vec<StoreReceiptSource>,
pub satisfied: bool,
#[serde(default)]
pub strict: bool,
}
#[derive(Debug, Serialize, Deserialize)]
pub struct PolicyEvaluateResult {
pub verdicts: Vec<PolicyVerdict>,
#[serde(default)]
pub bypass_key: Option<String>,
}
#[derive(Debug, Serialize, Deserialize)]
#[serde(deny_unknown_fields)]
pub struct ScanPrefixInput {
pub prefix: String,
}
#[derive(Debug, Serialize, Deserialize)]
#[serde(deny_unknown_fields)]
pub struct ScanKeysInput {
pub prefix: String,
}
#[derive(Debug, Serialize, Deserialize)]
#[serde(deny_unknown_fields)]
pub struct ScanEnforcementEventsInput {
#[serde(default)]
pub since_seq: u64,
#[serde(default = "default_until_seq")]
pub until_seq: u64,
}
#[derive(Debug, Serialize, Deserialize)]
#[serde(deny_unknown_fields)]
pub struct ScanEnforcementEventsSinceMsInput {
#[serde(default)]
pub since_ms: u64,
#[serde(default = "default_until_ms")]
pub until_ms: u64,
}
fn default_until_ms() -> u64 {
u64::MAX
}
fn default_until_seq() -> u64 {
u64::MAX
}
#[derive(Debug, Serialize, Deserialize)]
#[serde(deny_unknown_fields)]
pub struct HistoryInput {
pub key: String,
#[serde(default = "default_history_limit")]
pub limit: u64,
}
#[derive(Debug, Serialize, Deserialize)]
#[serde(deny_unknown_fields)]
pub struct HistorySinceInput {
pub key: String,
pub since_ts: u64,
#[serde(default = "default_history_limit")]
pub limit: u64,
}
fn default_history_limit() -> u64 {
50
}
#[derive(Debug, Serialize, Deserialize)]
#[serde(deny_unknown_fields)]
pub struct SessionCheckConsultedInput {
pub key: String,
}
#[derive(Debug, Serialize, Deserialize)]
#[serde(deny_unknown_fields)]
pub struct SessionCheckConsultedRecentInput {
pub key: String,
#[serde(default = "default_ttl_secs")]
pub ttl_secs: u64,
}
fn default_ttl_secs() -> u64 {
900
}
#[derive(Debug, Serialize, Deserialize)]
#[serde(deny_unknown_fields)]
pub struct MemQueryInput {
pub query: String,
#[serde(default = "default_query_mode")]
pub mode: QueryMode,
#[serde(default = "default_query_limit")]
pub limit: u32,
#[serde(default)]
pub since: Option<u64>,
}
fn default_query_mode() -> QueryMode {
QueryMode::Text
}
fn default_query_limit() -> u32 {
20
}
#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, Eq)]
#[serde(rename_all = "snake_case")]
pub enum QueryMode {
Text,
Tag,
Graph,
DirGotchas,
Semantic,
PolicyObservations,
PolicyActivity,
Analytics,
}
#[derive(Debug, Serialize, Deserialize)]
#[serde(deny_unknown_fields)]
pub struct MemGetInput {
pub key: String,
#[serde(default)]
pub actor: Option<String>,
}
#[derive(Debug, Serialize, Deserialize)]
#[serde(deny_unknown_fields)]
pub struct MemBootstrapInput {
#[serde(default)]
pub context_files: Vec<String>,
}
#[derive(Debug, Serialize, Deserialize)]
#[serde(deny_unknown_fields)]
pub struct GotchaDraftInput {
pub key: String,
pub rule: String,
pub reason: String,
pub severity: Severity,
#[serde(default)]
pub affected_files: Vec<String>,
#[serde(default)]
pub ref_url: Option<String>,
#[serde(default)]
pub tags: Vec<String>,
#[serde(default)]
pub priority: Priority,
#[serde(default)]
pub source: Option<String>,
#[serde(default)]
pub confirmed: bool,
}
#[derive(Debug, Serialize, Deserialize)]
#[serde(deny_unknown_fields)]
pub struct GotchaConfirmInput {
pub key: String,
#[serde(default)]
pub via_elicitation: bool,
}
#[derive(Debug, Serialize, Deserialize)]
#[serde(deny_unknown_fields)]
pub struct GotchaTombstoneInput {
pub key: String,
}
#[derive(Debug, Clone, Copy, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum PolicyWriteOp {
Create,
Edit,
Enable,
Disable,
Stage,
Delete,
}
#[derive(Debug, Serialize, Deserialize)]
#[serde(deny_unknown_fields)]
pub struct PolicyWriteInput {
pub op: PolicyWriteOp,
pub key: String,
#[serde(default)]
pub policy: Option<PolicyRecord>,
#[serde(default)]
pub stage: Option<StorePolicyStage>,
}
#[derive(Debug, Serialize, Deserialize)]
#[serde(deny_unknown_fields)]
pub struct FileEnrichInput {
pub path: String,
pub purpose: String,
#[serde(default)]
pub entry_points: Vec<String>,
#[serde(default)]
pub decision_keys: Vec<String>,
#[serde(default)]
pub todos: Vec<String>,
#[serde(default)]
pub tags: Vec<String>,
#[serde(default)]
pub priority: Priority,
}
#[derive(Debug, Serialize, Deserialize)]
#[serde(deny_unknown_fields)]
pub struct FileReparseInput {
pub path: String,
}
#[derive(Debug, Serialize, Deserialize)]
#[serde(deny_unknown_fields)]
pub struct FileEditHookInput {
pub path: String,
}
#[derive(Debug, Serialize, Deserialize)]
#[serde(deny_unknown_fields)]
pub struct DocCaptureInput {
pub path: String,
}
#[derive(Debug, Serialize, Deserialize)]
#[serde(deny_unknown_fields)]
pub struct DecisionUpsertInput {
pub slug: String,
pub value: String,
pub summary: String,
pub rationale: String,
#[serde(default)]
pub tags: Vec<String>,
#[serde(default)]
pub priority: Priority,
}
#[derive(Debug, Serialize, Deserialize)]
#[serde(deny_unknown_fields)]
pub struct DevNoteUpsertInput {
#[serde(default)]
pub key: Option<String>,
pub text: String,
#[serde(default)]
pub tags: Vec<String>,
#[serde(default)]
pub priority: Priority,
}
#[derive(Debug, Serialize, Deserialize)]
#[serde(deny_unknown_fields)]
pub struct SessionLogInput {
pub event: SessionEvent,
pub key: String,
#[serde(default)]
pub session_id: Option<String>,
#[serde(default)]
pub actor: Option<String>,
#[serde(default)]
pub decision_basis_hash: Option<String>,
}
#[derive(Debug, Serialize, Deserialize)]
#[serde(deny_unknown_fields)]
pub struct InstructionsLoadedInput {
pub payload: crate::hooks::decide::InstructionsLoadedPayload,
}
#[derive(Debug, Serialize, Deserialize)]
#[serde(deny_unknown_fields)]
pub struct PolicyShadowObserveInput {
pub policy_key: String,
pub action: Action,
pub would: crate::hooks::decide::ShadowOutcome,
}
#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, Eq)]
#[serde(rename_all = "snake_case")]
pub enum SessionEvent {
Miss,
ComplianceMiss,
ComplianceHit,
EditConsulted,
EditBlocked,
FloorConsultMiss,
PolicyConsultMiss,
PolicyConsultHit,
PolicySteered,
CodexShellMiss,
CodexShellBlocked,
UnclassifiedPolicyLiteralBypass,
Bootstrap,
PromptNudge,
WrappedDbClientMiss,
TombstoneBypassedDeny,
}
#[derive(Debug, Serialize, Deserialize)]
#[serde(deny_unknown_fields)]
pub struct ConsultationHitInput {
pub key: String,
#[serde(default = "default_capture_fingerprint")]
pub capture_fingerprint: bool,
#[serde(default)]
pub actor: Option<String>,
#[serde(default)]
pub session_id: Option<String>,
#[serde(default)]
pub agent_id: Option<String>,
#[serde(default)]
pub source: Option<crate::store::ReceiptSource>,
#[serde(default)]
pub decision_basis_hash: Option<String>,
}
fn default_capture_fingerprint() -> bool {
true
}
#[derive(Debug, Serialize, Deserialize)]
#[serde(deny_unknown_fields)]
pub struct SubagentHarvestInput {
pub summary: String,
#[serde(default)]
pub session_id: Option<String>,
#[serde(default)]
pub agent_id: Option<String>,
#[serde(default)]
pub agent_type: Option<String>,
#[serde(default)]
pub transcript_path: Option<String>,
}
#[derive(Debug, Serialize, Deserialize)]
#[serde(deny_unknown_fields)]
pub struct SubagentSpawnedInput {
#[serde(default)]
pub agent_id: Option<String>,
#[serde(default)]
pub session_id: Option<String>,
#[serde(default)]
pub agent_type: Option<String>,
}
#[derive(Debug, Serialize, Deserialize)]
#[serde(deny_unknown_fields)]
pub struct SubagentEdgeInput {
#[serde(default)]
pub child_agent_id: Option<String>,
#[serde(default)]
pub parent_agent_id: Option<String>,
#[serde(default)]
pub session_id: Option<String>,
#[serde(default)]
pub agent_type: Option<String>,
}
#[derive(Debug, Serialize, Deserialize)]
#[serde(deny_unknown_fields)]
pub struct RecordImportInput {
pub records: Vec<crate::store::Record>,
}
#[derive(Debug, Serialize, Deserialize)]
#[serde(deny_unknown_fields)]
pub struct ConfigGetInput {
pub key: String,
}
#[derive(Debug, Serialize, Deserialize)]
#[serde(deny_unknown_fields)]
pub struct ConfigSetInput {
pub key: String,
pub value: String,
}
#[derive(Debug, Serialize, Deserialize)]
#[serde(deny_unknown_fields)]
pub struct SandboxAuditInput {
pub setting: String,
#[serde(default)]
pub old_value: String,
pub new_value: String,
pub reason: String,
}
#[derive(Debug, Clone, Default, Deserialize, Serialize, PartialEq, Eq)]
#[serde(rename_all = "snake_case")]
pub enum Severity {
Critical,
High,
#[default]
Normal,
Low,
}
#[derive(Debug, Clone, Default, Deserialize, Serialize, PartialEq, Eq)]
#[serde(rename_all = "snake_case")]
pub enum Priority {
Critical,
High,
#[default]
Normal,
Low,
}
impl From<crate::store::Priority> for Severity {
fn from(p: crate::store::Priority) -> Self {
match p {
crate::store::Priority::Low => Severity::Low,
crate::store::Priority::Normal => Severity::Normal,
crate::store::Priority::High => Severity::High,
crate::store::Priority::Critical => Severity::Critical,
}
}
}
impl From<crate::store::Priority> for Priority {
fn from(p: crate::store::Priority) -> Self {
match p {
crate::store::Priority::Low => Priority::Low,
crate::store::Priority::Normal => Priority::Normal,
crate::store::Priority::High => Priority::High,
crate::store::Priority::Critical => Priority::Critical,
}
}
}