Base de connaissance persistante par projet, indépendante de tout modèle/CLU
et de git. Cadrage archi en §14.5 (ARCHITECTURE.md), cycle Archi→Dev→Test.
LOT A — étage 1 (.md, source de vérité)
- domaine: entité Memory (+ MemorySlug, MemoryType, MemoryFrontmatter,
MemoryLink, MemoryIndexEntry), liens [[slug]], index MEMORY.md dérivé
- port MemoryStore + MemoryError, adapter FsMemoryStore (.ideai/memory/)
- application: 7 use cases (Create/Update/List/Get/Delete/ReadIndex/
ResolveLinks), From<MemoryError> for AppError
- app-tauri: commandes + DTO, events MemorySaved/MemoryDeleted
- suppression de la variante morte DomainError::MalformedFrontmatter
LOT B — rappel adaptatif (étage 1)
- port MemoryRecall + MemoryQuery, adapter NaiveMemoryRecall (troncature
au budget de tokens, court-circuit budget-0), use case RecallMemory
LOT C — étage 2 vectoriel (structure complète, zéro dépendance lourde)
- port Embedder + EmbedderError, profils déclaratifs EmbedderProfile/
EmbedderStrategy (embedder.json)
- VectorMemoryRecall (cosinus, cache .ideai/memory/.index/ gitignoré)
- AdaptiveMemoryRecall (bascule pure should_use_vector), défaut none
- HashEmbedder (déterministe, tests), StubEmbedder (onnx/server/api)
Tests: 57 binaires verts, build + clippy --workspace sans warning.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
79 lines
2.4 KiB
Rust
79 lines
2.4 KiB
Rust
//! Domain-level validation errors.
|
|
//!
|
|
//! These errors are raised by validating constructors (`new`/`try_new`) when an
|
|
//! invariant documented in `ARCHITECTURE.md` §3.2 is violated. They are pure
|
|
//! data — no I/O, no platform coupling.
|
|
|
|
use thiserror::Error;
|
|
|
|
/// Error raised when an entity or value object invariant is violated at
|
|
/// construction time.
|
|
#[derive(Debug, Clone, PartialEq, Eq, Error)]
|
|
pub enum DomainError {
|
|
/// A required string field was empty.
|
|
#[error("field `{field}` must not be empty")]
|
|
EmptyField {
|
|
/// Name of the offending field.
|
|
field: &'static str,
|
|
},
|
|
|
|
/// A path that must be absolute was relative.
|
|
#[error("path `{path}` must be absolute")]
|
|
PathNotAbsolute {
|
|
/// The offending path.
|
|
path: String,
|
|
},
|
|
|
|
/// A path that must be relative was absolute, or escaped its root via `..`.
|
|
#[error("path `{path}` must be relative and must not contain `..`")]
|
|
PathNotRelativeSafe {
|
|
/// The offending path.
|
|
path: String,
|
|
},
|
|
|
|
/// An environment variable name was not a valid identifier.
|
|
#[error("`{value}` is not a valid environment variable identifier")]
|
|
InvalidEnvVar {
|
|
/// The offending value.
|
|
value: String,
|
|
},
|
|
|
|
/// An SSH port was outside the valid `1..=65535` range.
|
|
#[error("ssh port must be in 1..=65535, got {port}")]
|
|
InvalidPort {
|
|
/// The offending port.
|
|
port: u32,
|
|
},
|
|
|
|
/// A PTY dimension was zero.
|
|
#[error("pty size must have rows>0 and cols>0, got rows={rows} cols={cols}")]
|
|
InvalidPtySize {
|
|
/// Requested rows.
|
|
rows: u16,
|
|
/// Requested cols.
|
|
cols: u16,
|
|
},
|
|
|
|
/// `synchronized == true` requires an agent originating from a template.
|
|
#[error("a synchronized agent must originate from a template")]
|
|
SyncRequiresTemplate,
|
|
|
|
/// A manifest entry was inconsistent (e.g. synchronized without template metadata).
|
|
#[error("manifest entry inconsistent: {reason}")]
|
|
InconsistentManifest {
|
|
/// Human-readable reason.
|
|
reason: String,
|
|
},
|
|
|
|
/// A memory slug was not valid kebab-case (`[a-z0-9-]`, non-empty).
|
|
#[error("`{value}` is not a valid kebab-case slug")]
|
|
InvalidSlug {
|
|
/// The offending value.
|
|
value: String,
|
|
},
|
|
|
|
/// A generic invariant violation with an explanatory message.
|
|
#[error("invariant violated: {0}")]
|
|
Invariant(String),
|
|
}
|