Collapse semantic state contracts into core
This commit is contained in:
parent
3421af57a4
commit
07529fb521
20 changed files with 99 additions and 300 deletions
99
Cargo.lock
generated
99
Cargo.lock
generated
|
|
@ -507,12 +507,6 @@ version = "1.0.5"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "92773504d58c093f6de2459af4af33faa518c13451eb8f2b5698ed3d36e7c813"
|
||||
|
||||
[[package]]
|
||||
name = "dyn-clone"
|
||||
version = "1.0.20"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d0881ea181b1df73ff77ffaaf9c7544ecc11e82fba9b5f27b262a3c73a332555"
|
||||
|
||||
[[package]]
|
||||
name = "ed25519"
|
||||
version = "2.2.3"
|
||||
|
|
@ -551,7 +545,6 @@ dependencies = [
|
|||
"epiphany-model-adapter",
|
||||
"epiphany-openai-adapter",
|
||||
"epiphany-release-construction",
|
||||
"epiphany-state-model",
|
||||
"epiphany-tool-adapter",
|
||||
"ghostlight-persona-projection",
|
||||
"ignore",
|
||||
|
|
@ -649,15 +642,6 @@ dependencies = [
|
|||
"uuid",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "epiphany-state-model"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"schemars",
|
||||
"serde",
|
||||
"ts-rs",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "epiphany-tool-adapter"
|
||||
version = "0.1.0"
|
||||
|
|
@ -1867,30 +1851,6 @@ dependencies = [
|
|||
"windows-sys 0.61.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "schemars"
|
||||
version = "0.8.22"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3fbf2ae1b8bc8e02df939598064d22402220cd5bbcca1c76f7d6a310974d5615"
|
||||
dependencies = [
|
||||
"dyn-clone",
|
||||
"schemars_derive",
|
||||
"serde",
|
||||
"serde_json",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "schemars_derive"
|
||||
version = "0.8.22"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "32e265784ad618884abaea0600a9adf15393368d840e0222d101a072f3f7534d"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"serde_derive_internals",
|
||||
"syn 2.0.119",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "security-framework"
|
||||
version = "3.7.0"
|
||||
|
|
@ -1964,17 +1924,6 @@ dependencies = [
|
|||
"syn 3.0.3",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_derive_internals"
|
||||
version = "0.29.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "18d26a20a969b9e3fdf2fc2d9f21eda6c40e2de84c9408bb5d3b05d499aae711"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.119",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_json"
|
||||
version = "1.0.151"
|
||||
|
|
@ -2177,15 +2126,6 @@ dependencies = [
|
|||
"windows-sys 0.61.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "termcolor"
|
||||
version = "1.4.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "06794f8f6c5c898b3275aebefa6b8a1cb24cd2c6c79397ab15774837a0bc5755"
|
||||
dependencies = [
|
||||
"winapi-util",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thiserror"
|
||||
version = "2.0.20"
|
||||
|
|
@ -2414,30 +2354,6 @@ version = "0.2.5"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b"
|
||||
|
||||
[[package]]
|
||||
name = "ts-rs"
|
||||
version = "11.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4994acea2522cd2b3b85c1d9529a55991e3ad5e25cdcd3de9d505972c4379424"
|
||||
dependencies = [
|
||||
"serde_json",
|
||||
"thiserror",
|
||||
"ts-rs-macros",
|
||||
"uuid",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ts-rs-macros"
|
||||
version = "11.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ee6ff59666c9cbaec3533964505d39154dc4e0a56151fdea30a09ed0301f62e2"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.119",
|
||||
"termcolor",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "typenum"
|
||||
version = "1.20.1"
|
||||
|
|
@ -3047,18 +2963,3 @@ name = "zmij"
|
|||
version = "1.0.23"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "29666d0abbfad1e3dc4dcf6144730dd3a3ab225bbbdac83319345b1b44ccfc1b"
|
||||
|
||||
[[patch.unused]]
|
||||
name = "tungstenite"
|
||||
version = "0.27.0"
|
||||
source = "git+https://github.com/openai-oss-forks/tungstenite-rs?rev=9200079d3b54a1ff51072e24d81fd354f085156f#9200079d3b54a1ff51072e24d81fd354f085156f"
|
||||
|
||||
[[patch.unused]]
|
||||
name = "tokio-tungstenite"
|
||||
version = "0.28.0"
|
||||
source = "git+https://github.com/openai-oss-forks/tokio-tungstenite?rev=132f5b39c862e3a970f731d709608b3e6276d5f6#132f5b39c862e3a970f731d709608b3e6276d5f6"
|
||||
|
||||
[[patch.unused]]
|
||||
name = "tungstenite"
|
||||
version = "0.27.0"
|
||||
source = "git+https://github.com/openai-oss-forks/tungstenite-rs?rev=9200079d3b54a1ff51072e24d81fd354f085156f#9200079d3b54a1ff51072e24d81fd354f085156f"
|
||||
|
|
|
|||
|
|
@ -5,7 +5,6 @@ members = [
|
|||
"epiphany-openai-adapter",
|
||||
"epiphany-openai-runtime",
|
||||
"epiphany-release-construction",
|
||||
"epiphany-state-model",
|
||||
"epiphany-tool-adapter",
|
||||
"epiphany-tool-mcp-runtime",
|
||||
]
|
||||
|
|
@ -54,13 +53,6 @@ incremental = true
|
|||
[dev-dependencies]
|
||||
tempfile = "3"
|
||||
|
||||
[patch.crates-io]
|
||||
tokio-tungstenite = { git = "https://github.com/openai-oss-forks/tokio-tungstenite", rev = "132f5b39c862e3a970f731d709608b3e6276d5f6" }
|
||||
tungstenite = { git = "https://github.com/openai-oss-forks/tungstenite-rs", rev = "9200079d3b54a1ff51072e24d81fd354f085156f" }
|
||||
|
||||
[patch."ssh://git@github.com/openai-oss-forks/tungstenite-rs.git"]
|
||||
tungstenite = { git = "https://github.com/openai-oss-forks/tungstenite-rs", rev = "9200079d3b54a1ff51072e24d81fd354f085156f" }
|
||||
|
||||
[[bin]]
|
||||
name = "epiphany-release"
|
||||
path = "epiphany-core/src/bin/epiphany-release.rs"
|
||||
|
|
|
|||
|
|
@ -120,15 +120,15 @@ Epiphany is a native GameCult runtime that began as an opinionated Codex fork.
|
|||
|
||||
Her body is made of:
|
||||
|
||||
- typed Rust domain organs in `epiphany-core` and `epiphany-state-model`
|
||||
- typed Rust domain organs owned by `epiphany-core`
|
||||
- CultCache `.cc` stores for runtime, heartbeat, agent state, local Verse,
|
||||
memory graph, and thread state
|
||||
- CultMesh and CultNet contracts for local and distributed state
|
||||
- provider-neutral model and tool request/receipt documents
|
||||
- Mind, Substrate Gate, Eyes, Hands, Soul, Continuity, Persona, and heartbeat
|
||||
authority surfaces
|
||||
- Codex retained only for honest OpenAI subscription auth and model transport;
|
||||
Epiphany does not publish a Codex-owned project-state surface
|
||||
- a narrow standalone CodexConnector process for OpenAI subscription auth and
|
||||
model transport; Epiphany compiles no Codex crate and keeps cognition local
|
||||
|
||||
That last clause matters. Codex and other frontier agents can be excellent
|
||||
workers. They do not decide which organizational state is authoritative, who
|
||||
|
|
|
|||
|
|
@ -48,7 +48,7 @@ The practical definition in this repository is:
|
|||
|
||||
\begin{itemize}
|
||||
\item the root checkout at \code{F:\Projects\Epiphany};
|
||||
\item Epiphany Rust crates such as \code{epiphany-core}, \code{epiphany-state-model}, model/tool adapters, and OpenAI transport crates;
|
||||
\item Epiphany Rust crates such as \code{epiphany-core}, model/tool adapters, and provider runtimes;
|
||||
\item vendored substrate in \code{vendor/codex}, \code{vendor/cultcache-rs}, \code{vendor/cultnet-rs}, and \code{vendor/cultmesh-rs};
|
||||
\item typed state stores under \code{state/};
|
||||
\item schemas under \code{schemas/cultnet/};
|
||||
|
|
@ -59,20 +59,19 @@ The practical definition in this repository is:
|
|||
|
||||
\section{Executive Map}
|
||||
|
||||
Epiphany's current Body is a hybrid machine in transition. Its center of gravity
|
||||
has moved into typed Rust/CultCache organs, but compatibility arteries still
|
||||
run through vendored Codex. The live target is not a cleaner pile of Codex
|
||||
routes. The target is an Epiphany-native CultCache/CultMesh/CultNet body with a
|
||||
relatively vanilla Codex-derived reliquary retained for OpenAI subscription
|
||||
auth and model transport.
|
||||
Epiphany's current Body is a typed Rust/CultCache organism with provider
|
||||
transport outside its cognition boundary. Codex requests cross a lean client
|
||||
ABI into the independent CodexConnector daemon, which owns subscription
|
||||
credential refresh, transport, and replay. Epiphany owns prompts, tools,
|
||||
reasoning context, decisions, and Mind admission; it compiles no Codex crate.
|
||||
|
||||
\begin{longtable}{>{\raggedright\arraybackslash}p{0.23\linewidth}>{\raggedright\arraybackslash}p{0.32\linewidth}>{\raggedright\arraybackslash}p{0.35\linewidth}}
|
||||
\textbf{Body Region} & \textbf{Current Owner} & \textbf{Invariant} \\
|
||||
\hline
|
||||
Durable Mind state & keyed CultCache documents assembled by \code{epiphany-core} & Prompt rendering consumes sealed typed projections; no persisted thread aggregate or global authority revision exists. \\
|
||||
Domain policy & \code{epiphany-core} & Verdicts, launch policy, acceptance rules, runtime lifecycle, and mutation law live here, not in bridge DTOs. \\
|
||||
Vendored Codex & \code{vendor/codex} & Retain host/app-server/auth/model compatibility where useful; do not let Codex own Epiphany prompts, scheduler, or state. \\
|
||||
Runtime spine & \code{epiphany-core/src/runtime_spine.rs} and \code{state/runtime-spine.cc} & Runtime identity, jobs, events, receipts, tool/model documents are typed CultCache records. \\
|
||||
Codex transport & independent \code{GameCult/CodexConnector} daemon & Own subscription credentials, provider transport, and exact replay only; never own Epiphany prompts, scheduler, decisions, or state. \\
|
||||
Runtime spine & \code{epiphany-core/src/runtime_spine.rs} and \code{state/runtime-spine.cc} & Runtime identity, jobs, receipts, and tool/model documents are typed CultCache records. \\
|
||||
Persona memory & keyed Mind Persona-memory documents & Persona decisions admit bounded memories by semantic identity; no parallel role-memory aggregate or generation head exists. \\
|
||||
Resident Self physiology & Resident Self CultCache documents via \code{epiphany-swarm} & Typed pressure, exact grant creation, launch exclusion, leases, terminal receipts, retry, and bounded retention have one owner. No scheduler singleton or acknowledgement loop exists. \\
|
||||
Local Verse & CultMesh over \code{state/local-verse.cc} & Local Verse context is compact prompt/operator context; private state does not become public by flipping a flag. \\
|
||||
|
|
@ -82,27 +81,21 @@ Operator artifacts & \code{.epiphany-*}, \code{tools/epiphany_local_run.ps1} & A
|
|||
|
||||
\section{Repository Body}
|
||||
|
||||
The checkout has nine primary Epiphany Rust crates:
|
||||
The checkout has eight primary Epiphany Rust packages:
|
||||
|
||||
\begin{itemize}
|
||||
\item \code{epiphany-core}: the main domain organ. It owns state-update
|
||||
validation, launch documents, runtime spine, Resident Self, Persona
|
||||
projection, Substrate Gate, Mind, Eyes, Hands, Soul, Continuity, CultMesh
|
||||
integration, surface derivation, smokes, and local operator binaries.
|
||||
\item \code{epiphany-state-model}: the durable \code{EpiphanyThreadState}
|
||||
type plus \code{render_epiphany_state}. This is the typed Mind surface that
|
||||
prompt fragments and views read.
|
||||
\item \code{epiphany-core}: the main domain organ. It owns semantic state
|
||||
contracts, keyed Mind admission, launch documents, runtime spine, Resident
|
||||
Self, Persona projection, Substrate Gate, Eyes, Hands, Soul, Continuity,
|
||||
CultMesh integration, and surface derivation.
|
||||
\item \code{epiphany-model-adapter}: provider-neutral model request, stream
|
||||
event, receipt, and status documents.
|
||||
\item \code{epiphany-openai-adapter}: OpenAI-shaped request/event/receipt and
|
||||
status documents.
|
||||
\item \code{epiphany-openai-auth-spine}: Codex-derived auth boundary over
|
||||
\code{codex-login}. It preserves honest Codex-compatible credential and token
|
||||
behavior rather than impersonating it from scratch.
|
||||
\item \code{epiphany-openai-codex-spine}: model transport over vendored Codex
|
||||
client machinery.
|
||||
\item \code{epiphany-openai-runtime}: executable model runtime, including
|
||||
\code{epiphany-model-runtime}.
|
||||
\item \code{epiphany-release-construction}: exact package construction and
|
||||
release-witness verification.
|
||||
\item \code{epiphany-tool-adapter}: typed tool capability, invocation intent,
|
||||
and invocation receipt documents.
|
||||
\item \code{epiphany-tool-mcp-runtime}: first-party tool executor. Native
|
||||
|
|
@ -114,8 +107,8 @@ The checkout has nine primary Epiphany Rust crates:
|
|||
The vendored region contains:
|
||||
|
||||
\begin{itemize}
|
||||
\item \code{vendor/codex}: the Codex-derived host and compatibility substrate.
|
||||
It is tracked directly, not as a submodule.
|
||||
\item \code{vendor/codex}: retained Codex-fork source history. It is not in
|
||||
Epiphany's compiled runtime graph.
|
||||
\item \code{vendor/cultcache-rs}, \code{vendor/cultnet-rs}, and
|
||||
\code{vendor/cultmesh-rs}: repo-contained Rust Cult substrate.
|
||||
\end{itemize}
|
||||
|
|
|
|||
|
|
@ -77,7 +77,7 @@ conflicts, or a consequential judgment cannot be derived honestly.
|
|||
|
||||
The current native Epiphany body includes:
|
||||
|
||||
- typed Rust domain organs in `epiphany-core` and `epiphany-state-model`
|
||||
- typed Rust domain organs owned by `epiphany-core`
|
||||
- keyed Mind state with typed projection and promotion paths
|
||||
- RepoModel and Model Atlas surfaces for source-grounded architectural belief
|
||||
- CultCache `.cc` state and CultMesh/CultNet contracts
|
||||
|
|
@ -86,7 +86,7 @@ The current native Epiphany body includes:
|
|||
- runtime-spine job and worker-result documents
|
||||
- Mind, Modeling, Substrate Gate, Eyes, Hands, Soul, Continuity, Persona, and
|
||||
heartbeat authority surfaces
|
||||
- local operator status, coordinator, smoke, and Verse-context commands
|
||||
- local operator status, coordinator, and Verse-context commands
|
||||
|
||||
Codex is retained only for OpenAI authentication and model transport. Epiphany
|
||||
does not publish Codex app-server state as its project Mind.
|
||||
|
|
|
|||
|
|
@ -21,7 +21,6 @@ epiphany-openai-adapter = { path = "../epiphany-openai-adapter" }
|
|||
epiphany-release-construction = { path = "../epiphany-release-construction" }
|
||||
epiphany-model-adapter = { path = "../epiphany-model-adapter" }
|
||||
epiphany-tool-adapter = { path = "../epiphany-tool-adapter" }
|
||||
epiphany-state-model = { path = "../epiphany-state-model" }
|
||||
ghostlight-persona-projection = { git = "https://github.com/GameCult/Ghostlight.git", rev = "22281891cbf9258db80c15a9fd465e6fa251e7dd", package = "ghostlight-persona-projection" }
|
||||
ed25519-dalek = "2"
|
||||
ignore = "0.4.23"
|
||||
|
|
|
|||
|
|
@ -3406,7 +3406,7 @@ fn resolve_body_modeling_work(
|
|||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use epiphany_state_model::{
|
||||
use crate::state_model::{
|
||||
EpiphanyMemoryDomain, EpiphanyMemoryLifecycle, EpiphanyMemoryNode, EpiphanyMemoryNodeKind,
|
||||
RepoFrontierItem, RepoFrontierStatus,
|
||||
};
|
||||
|
|
@ -5792,12 +5792,12 @@ mod tests {
|
|||
research_cache.put(&research_context.context_id, &research_context)?;
|
||||
let stale_research_store = temp.path().join("stale-research-output.cc");
|
||||
std::fs::copy(&store, &stale_research_store)?;
|
||||
let evidence = epiphany_state_model::EpiphanyEvidenceRecord {
|
||||
let evidence = crate::EpiphanyEvidenceRecord {
|
||||
id: "research-evidence-1".into(),
|
||||
kind: "external-source".into(),
|
||||
status: "ok".into(),
|
||||
summary: "The bounded external claim is supported.".into(),
|
||||
code_refs: vec![epiphany_state_model::EpiphanyCodeRef {
|
||||
code_refs: vec![crate::EpiphanyCodeRef {
|
||||
path: "epiphany-core/src/current_work.rs".into(),
|
||||
start_line: Some(1),
|
||||
end_line: None,
|
||||
|
|
@ -5805,7 +5805,7 @@ mod tests {
|
|||
note: None,
|
||||
}],
|
||||
};
|
||||
let observation = epiphany_state_model::EpiphanyObservation {
|
||||
let observation = crate::EpiphanyObservation {
|
||||
id: "research-observation-1".into(),
|
||||
summary: "External evidence answers the exact frontier question.".into(),
|
||||
source_kind: "research".into(),
|
||||
|
|
|
|||
|
|
@ -32,6 +32,7 @@ mod runtime_spine;
|
|||
mod runtime_store_backend;
|
||||
mod runtime_worker_attempt;
|
||||
mod soul_gateway;
|
||||
mod state_model;
|
||||
mod state_ledger;
|
||||
mod substrate_gate;
|
||||
mod surfaces;
|
||||
|
|
@ -99,11 +100,6 @@ pub use cultmesh_integration::{
|
|||
};
|
||||
|
||||
pub use current_work::*;
|
||||
pub use epiphany_state_model::EpiphanyMemoryAnchor;
|
||||
pub use epiphany_state_model::EpiphanyMemoryDomain;
|
||||
pub use epiphany_state_model::EpiphanyMemoryEdge;
|
||||
pub use epiphany_state_model::EpiphanyMemoryLifecycle;
|
||||
pub use epiphany_state_model::EpiphanyMemoryNode;
|
||||
pub use hands_gateway::*;
|
||||
pub use idunn_provider_health::{
|
||||
EPIPHANY_IDUNN_PROVIDER_HEALTH_ADMISSION_SCHEMA, EPIPHANY_IDUNN_PROVIDER_HEALTH_ADMISSION_TYPE,
|
||||
|
|
@ -133,13 +129,7 @@ pub use imagination_consideration::{
|
|||
validate_candidate as validate_imagination_consideration_candidate,
|
||||
validate_current_request as validate_current_imagination_consideration_request,
|
||||
};
|
||||
pub use memory_graph::EpiphanyMemoryEdgeKind;
|
||||
pub use memory_graph::EpiphanyMemoryGraphSnapshot;
|
||||
pub use memory_graph::EpiphanyMemoryGraphValidationError;
|
||||
pub use memory_graph::EpiphanyMemoryNodeKind;
|
||||
pub use memory_graph::RepoFrontierAdoptedPlan;
|
||||
pub use memory_graph::RepoFrontierItem;
|
||||
pub use memory_graph::RepoFrontierStatus;
|
||||
pub use memory_graph::validate_memory_graph_snapshot;
|
||||
pub use mind_documents::*;
|
||||
pub use packaged_release::{
|
||||
|
|
@ -301,6 +291,7 @@ pub use runtime_spine::select_and_commit_repo_frontier_route;
|
|||
pub use runtime_spine::terminalize_model_pass_failure_session;
|
||||
pub(crate) use runtime_worker_attempt::{RuntimeTypedRequestRef, WorkerProcessStatus};
|
||||
pub use soul_gateway::*;
|
||||
pub use state_model::*;
|
||||
pub use state_ledger::EpiphanyBranchRecord;
|
||||
pub use state_ledger::EpiphanyLedgerEvidenceRecord;
|
||||
pub use state_ledger::EpiphanyStateLedgerEntry;
|
||||
|
|
|
|||
|
|
@ -1,16 +1,5 @@
|
|||
pub mod validation;
|
||||
|
||||
pub use epiphany_state_model::EpiphanyMemoryDomain;
|
||||
pub use epiphany_state_model::EpiphanyMemoryEdge;
|
||||
pub use epiphany_state_model::EpiphanyMemoryEdgeKind;
|
||||
pub use epiphany_state_model::EpiphanyMemoryGraphSnapshot;
|
||||
pub use epiphany_state_model::EpiphanyMemoryLifecycle;
|
||||
pub use epiphany_state_model::EpiphanyMemoryNode;
|
||||
pub use epiphany_state_model::EpiphanyMemoryNodeKind;
|
||||
pub use epiphany_state_model::RepoFrontierAdoptedPlan;
|
||||
pub use epiphany_state_model::RepoFrontierItem;
|
||||
pub use epiphany_state_model::RepoFrontierStatus;
|
||||
|
||||
pub use validation::EpiphanyMemoryGraphValidationError;
|
||||
pub(crate) use validation::frontier_item_has_routeable_repository_scope;
|
||||
pub(crate) use validation::repo_paths_are_canonical_and_safe;
|
||||
|
|
|
|||
|
|
@ -1,9 +1,9 @@
|
|||
use super::EpiphanyMemoryDomain;
|
||||
use super::EpiphanyMemoryEdge;
|
||||
use super::EpiphanyMemoryGraphSnapshot;
|
||||
use super::EpiphanyMemoryLifecycle;
|
||||
use super::EpiphanyMemoryNode;
|
||||
use super::RepoFrontierStatus;
|
||||
use crate::EpiphanyMemoryDomain;
|
||||
use crate::EpiphanyMemoryEdge;
|
||||
use crate::EpiphanyMemoryGraphSnapshot;
|
||||
use crate::EpiphanyMemoryLifecycle;
|
||||
use crate::EpiphanyMemoryNode;
|
||||
use crate::RepoFrontierStatus;
|
||||
use std::collections::{HashMap, HashSet};
|
||||
|
||||
pub(crate) fn repo_paths_are_canonical_and_safe(paths: &[String]) -> bool {
|
||||
|
|
@ -23,7 +23,7 @@ pub(crate) fn repo_paths_are_canonical_and_safe(paths: &[String]) -> bool {
|
|||
}
|
||||
|
||||
pub(crate) fn frontier_item_has_routeable_repository_scope(
|
||||
item: &epiphany_state_model::RepoFrontierItem,
|
||||
item: &crate::RepoFrontierItem,
|
||||
) -> bool {
|
||||
!item.repository_scope.is_empty() && repo_paths_are_canonical_and_safe(&item.repository_scope)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ use std::path::Path;
|
|||
|
||||
use anyhow::{Result, anyhow};
|
||||
use cultcache_rs::{CultCache, CultCacheEnvelope, DatabaseEntry};
|
||||
use epiphany_state_model::{
|
||||
use crate::state_model::{
|
||||
EpiphanyEvidenceRecord, EpiphanyInvariant, EpiphanyInvestigationCheckpoint,
|
||||
EpiphanyModeState, EpiphanyObservation, EpiphanySubgoal,
|
||||
};
|
||||
|
|
|
|||
|
|
@ -68,10 +68,10 @@ impl From<EpiphanyRoleWorkerLaunchDocument> for EpiphanyRolePassAuthorityProject
|
|||
pub struct EpiphanyRepoModelPromptProjection {
|
||||
pub identity: crate::EpiphanyRepoModelIdentityDocument,
|
||||
pub projection_digest: String,
|
||||
pub domains: Vec<epiphany_state_model::EpiphanyMemoryDomain>,
|
||||
pub nodes: Vec<epiphany_state_model::EpiphanyMemoryNode>,
|
||||
pub edges: Vec<epiphany_state_model::EpiphanyMemoryEdge>,
|
||||
pub frontier: Vec<epiphany_state_model::RepoFrontierItem>,
|
||||
pub domains: Vec<crate::EpiphanyMemoryDomain>,
|
||||
pub nodes: Vec<crate::EpiphanyMemoryNode>,
|
||||
pub edges: Vec<crate::EpiphanyMemoryEdge>,
|
||||
pub frontier: Vec<crate::RepoFrontierItem>,
|
||||
pub claim_obligations: Vec<crate::EpiphanyRepoModelClaimObligationsDocument>,
|
||||
pub surface_offers: Vec<crate::AtlasSurfaceOffer>,
|
||||
pub dependency_claims: Vec<crate::AtlasDependencyClaim>,
|
||||
|
|
@ -104,16 +104,16 @@ pub struct EpiphanyMindPromptProjection {
|
|||
pub projection_digest: String,
|
||||
pub objective: Option<String>,
|
||||
pub active_subgoal_id: Option<String>,
|
||||
pub subgoals: Vec<epiphany_state_model::EpiphanySubgoal>,
|
||||
pub invariants: Vec<epiphany_state_model::EpiphanyInvariant>,
|
||||
pub observations: Vec<epiphany_state_model::EpiphanyObservation>,
|
||||
pub evidence: Vec<epiphany_state_model::EpiphanyEvidenceRecord>,
|
||||
pub subgoals: Vec<crate::EpiphanySubgoal>,
|
||||
pub invariants: Vec<crate::EpiphanyInvariant>,
|
||||
pub observations: Vec<crate::EpiphanyObservation>,
|
||||
pub evidence: Vec<crate::EpiphanyEvidenceRecord>,
|
||||
pub verification_audits: Vec<crate::EpiphanyMindVerificationAuditDocument>,
|
||||
pub reorientation_decisions: Vec<crate::EpiphanyMindReorientationDecisionDocument>,
|
||||
pub reorientation_failures: Vec<crate::EpiphanyMindReorientationPassFailureDocument>,
|
||||
pub agent_pass_admission_refusals: Vec<crate::EpiphanyAgentPassAdmissionRefusal>,
|
||||
pub investigation_checkpoint: Option<epiphany_state_model::EpiphanyInvestigationCheckpoint>,
|
||||
pub mode: Option<epiphany_state_model::EpiphanyModeState>,
|
||||
pub investigation_checkpoint: Option<crate::EpiphanyInvestigationCheckpoint>,
|
||||
pub mode: Option<crate::EpiphanyModeState>,
|
||||
pub repository_body_observation: Option<crate::RepositoryBodyObservationBasis>,
|
||||
pub repo_model: Option<EpiphanyRepoModelPromptProjection>,
|
||||
}
|
||||
|
|
@ -2627,7 +2627,7 @@ mod tests {
|
|||
let make = |key: &str, summary: &str| -> Result<CultCacheEnvelope> {
|
||||
let cache = runtime_spine_cache(&store)?;
|
||||
let document = crate::EpiphanyMindObservationDocument {
|
||||
value: epiphany_state_model::EpiphanyObservation {
|
||||
value: crate::EpiphanyObservation {
|
||||
id: key.into(),
|
||||
summary: summary.into(),
|
||||
source_kind: "test".into(),
|
||||
|
|
|
|||
|
|
@ -19,10 +19,10 @@ pub struct EpiphanyReorientationStateProjection {
|
|||
pub runtime_id: String,
|
||||
pub objective: Option<String>,
|
||||
pub active_subgoal_id: Option<String>,
|
||||
pub investigation_checkpoint: Option<epiphany_state_model::EpiphanyInvestigationCheckpoint>,
|
||||
pub mode: Option<epiphany_state_model::EpiphanyModeState>,
|
||||
pub investigation_checkpoint: Option<crate::EpiphanyInvestigationCheckpoint>,
|
||||
pub mode: Option<crate::EpiphanyModeState>,
|
||||
pub repository_body_observation: Option<crate::RepositoryBodyObservationBasis>,
|
||||
pub frontier: Vec<epiphany_state_model::RepoFrontierItem>,
|
||||
pub frontier: Vec<crate::RepoFrontierItem>,
|
||||
pub projection_digest: String,
|
||||
}
|
||||
|
||||
|
|
@ -1060,7 +1060,7 @@ mod tests {
|
|||
cache.put(
|
||||
"unrelated-observation",
|
||||
&crate::EpiphanyMindObservationDocument {
|
||||
value: epiphany_state_model::EpiphanyObservation {
|
||||
value: crate::EpiphanyObservation {
|
||||
id: "unrelated-observation".into(),
|
||||
summary: "Persona observed an unrelated social fact.".into(),
|
||||
..Default::default()
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ use std::path::Path;
|
|||
|
||||
use anyhow::{Result, anyhow};
|
||||
use cultcache_rs::{CultCache, CultCacheEnvelope, DatabaseEntry};
|
||||
use epiphany_state_model::{
|
||||
use crate::state_model::{
|
||||
EpiphanyMemoryDomain, EpiphanyMemoryEdge, EpiphanyMemoryGraphSnapshot, EpiphanyMemoryNode,
|
||||
RepoFrontierItem,
|
||||
};
|
||||
|
|
@ -835,7 +835,7 @@ pub fn plan_repo_model_mutation(
|
|||
{
|
||||
insert_strong_envelope(&mut strong, existing)?;
|
||||
}
|
||||
node.lifecycle = epiphany_state_model::EpiphanyMemoryLifecycle::Retired;
|
||||
node.lifecycle = crate::EpiphanyMemoryLifecycle::Retired;
|
||||
nodes.insert(node_id.clone(), node.clone());
|
||||
insert_envelope(
|
||||
&mut writes,
|
||||
|
|
@ -879,7 +879,7 @@ pub fn plan_repo_model_mutation(
|
|||
.get_envelope::<EpiphanyRepoModelEdgeDocument>(edge_id)?
|
||||
.ok_or_else(|| anyhow!("RepoModel edge lost its envelope"))?;
|
||||
insert_strong_envelope(&mut strong, existing)?;
|
||||
edge.lifecycle = epiphany_state_model::EpiphanyMemoryLifecycle::Retired;
|
||||
edge.lifecycle = crate::EpiphanyMemoryLifecycle::Retired;
|
||||
edges.insert(edge_id.clone(), edge.clone());
|
||||
insert_envelope(
|
||||
&mut writes,
|
||||
|
|
@ -1319,9 +1319,9 @@ fn require_semantic_id(value: &str, label: &str) -> Result<()> {
|
|||
fn frontier_is_unresolved(item: &RepoFrontierItem) -> bool {
|
||||
matches!(
|
||||
item.status,
|
||||
epiphany_state_model::RepoFrontierStatus::Proposed
|
||||
| epiphany_state_model::RepoFrontierStatus::Active
|
||||
| epiphany_state_model::RepoFrontierStatus::Blocked
|
||||
crate::RepoFrontierStatus::Proposed
|
||||
| crate::RepoFrontierStatus::Active
|
||||
| crate::RepoFrontierStatus::Blocked
|
||||
)
|
||||
}
|
||||
|
||||
|
|
@ -1509,9 +1509,9 @@ fn validate_claim_obligations(
|
|||
if !item.target_claim_ids.contains(&obligation.node_id)
|
||||
|| !matches!(
|
||||
item.status,
|
||||
epiphany_state_model::RepoFrontierStatus::Proposed
|
||||
| epiphany_state_model::RepoFrontierStatus::Active
|
||||
| epiphany_state_model::RepoFrontierStatus::Blocked
|
||||
crate::RepoFrontierStatus::Proposed
|
||||
| crate::RepoFrontierStatus::Active
|
||||
| crate::RepoFrontierStatus::Blocked
|
||||
)
|
||||
{
|
||||
return Err(anyhow!("RepoModel claim obligation is not live"));
|
||||
|
|
@ -1521,9 +1521,9 @@ fn validate_claim_obligations(
|
|||
for item in frontier.iter().filter(|item| {
|
||||
matches!(
|
||||
item.status,
|
||||
epiphany_state_model::RepoFrontierStatus::Proposed
|
||||
| epiphany_state_model::RepoFrontierStatus::Active
|
||||
| epiphany_state_model::RepoFrontierStatus::Blocked
|
||||
crate::RepoFrontierStatus::Proposed
|
||||
| crate::RepoFrontierStatus::Active
|
||||
| crate::RepoFrontierStatus::Blocked
|
||||
)
|
||||
}) {
|
||||
for node_id in &item.target_claim_ids {
|
||||
|
|
@ -1542,7 +1542,7 @@ fn validate_claim_obligations(
|
|||
mod tests {
|
||||
use super::*;
|
||||
use crate::{RuntimeSpineInitOptions, initialize_runtime_spine};
|
||||
use epiphany_state_model::{
|
||||
use crate::state_model::{
|
||||
EpiphanyMemoryEdgeKind, EpiphanyMemoryLifecycle, EpiphanyMemoryNodeKind, RepoFrontierStatus,
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -418,7 +418,7 @@ pub struct RepoFrontierRoute {
|
|||
#[cultcache(key = 11)]
|
||||
pub authorized_paths: Vec<String>,
|
||||
#[cultcache(key = 12, default)]
|
||||
pub adopted_plan: Option<epiphany_state_model::RepoFrontierAdoptedPlan>,
|
||||
pub adopted_plan: Option<crate::RepoFrontierAdoptedPlan>,
|
||||
#[cultcache(key = 13)]
|
||||
pub selected_at: String,
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,83 +1,70 @@
|
|||
//! Core-owned semantic state contracts.
|
||||
|
||||
use std::path::PathBuf;
|
||||
|
||||
use schemars::JsonSchema;
|
||||
use serde::Deserialize;
|
||||
use serde::Serialize;
|
||||
use ts_rs::TS;
|
||||
|
||||
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, JsonSchema, TS, Default)]
|
||||
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, Default)]
|
||||
pub struct EpiphanySubgoal {
|
||||
pub id: String,
|
||||
pub title: String,
|
||||
pub status: String,
|
||||
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||
#[ts(type = "string | null")]
|
||||
pub summary: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, JsonSchema, TS, Default)]
|
||||
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, Default)]
|
||||
pub struct EpiphanyInvariant {
|
||||
pub id: String,
|
||||
pub description: String,
|
||||
pub status: String,
|
||||
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||
#[ts(type = "string | null")]
|
||||
pub rationale: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, JsonSchema, TS, Default)]
|
||||
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, Default)]
|
||||
pub struct EpiphanyCodeRef {
|
||||
pub path: PathBuf,
|
||||
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||
#[ts(type = "number | null")]
|
||||
pub start_line: Option<u32>,
|
||||
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||
#[ts(type = "number | null")]
|
||||
pub end_line: Option<u32>,
|
||||
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||
#[ts(type = "string | null")]
|
||||
pub symbol: Option<String>,
|
||||
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||
#[ts(type = "string | null")]
|
||||
pub note: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Clone, Copy, Debug, PartialEq, Eq, JsonSchema, TS, Default)]
|
||||
#[derive(Serialize, Deserialize, Clone, Copy, Debug, PartialEq, Eq, Default)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
#[ts(rename_all = "snake_case")]
|
||||
pub enum EpiphanyInvestigationDisposition {
|
||||
#[default]
|
||||
ResumeReady,
|
||||
RegatherRequired,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, JsonSchema, TS, Default)]
|
||||
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, Default)]
|
||||
pub struct EpiphanyInvestigationCheckpoint {
|
||||
pub checkpoint_id: String,
|
||||
pub kind: String,
|
||||
pub disposition: EpiphanyInvestigationDisposition,
|
||||
pub focus: String,
|
||||
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||
#[ts(type = "string | null")]
|
||||
pub summary: Option<String>,
|
||||
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||
#[ts(type = "string | null")]
|
||||
pub next_action: Option<String>,
|
||||
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||
#[ts(type = "string | null")]
|
||||
pub captured_at_turn_id: Option<String>,
|
||||
#[serde(default, skip_serializing_if = "Vec::is_empty")]
|
||||
#[ts(type = "Array<string>")]
|
||||
pub open_questions: Vec<String>,
|
||||
#[serde(default, skip_serializing_if = "Vec::is_empty")]
|
||||
#[ts(type = "Array<EpiphanyCodeRef>")]
|
||||
pub code_refs: Vec<EpiphanyCodeRef>,
|
||||
#[serde(default, skip_serializing_if = "Vec::is_empty")]
|
||||
#[ts(type = "Array<string>")]
|
||||
pub evidence_ids: Vec<String>,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, JsonSchema, TS, Default)]
|
||||
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, Default)]
|
||||
pub struct EpiphanyObservation {
|
||||
pub id: String,
|
||||
pub summary: String,
|
||||
|
|
@ -89,7 +76,7 @@ pub struct EpiphanyObservation {
|
|||
pub evidence_ids: Vec<String>,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, JsonSchema, TS, Default)]
|
||||
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, Default)]
|
||||
pub struct EpiphanyEvidenceRecord {
|
||||
pub id: String,
|
||||
pub kind: String,
|
||||
|
|
@ -99,16 +86,15 @@ pub struct EpiphanyEvidenceRecord {
|
|||
pub code_refs: Vec<EpiphanyCodeRef>,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, JsonSchema, TS, Default)]
|
||||
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, Default)]
|
||||
pub struct EpiphanyModeState {
|
||||
pub name: String,
|
||||
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||
#[ts(type = "ModeKind | null")]
|
||||
pub kind: Option<EpiphanyModeKind>,
|
||||
}
|
||||
|
||||
#[derive(
|
||||
Serialize, Deserialize, Clone, Copy, Debug, PartialEq, Eq, Hash, JsonSchema, TS, Default,
|
||||
Serialize, Deserialize, Clone, Copy, Debug, PartialEq, Eq, Hash, Default,
|
||||
)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum EpiphanyModeKind {
|
||||
|
|
@ -123,36 +109,30 @@ pub enum EpiphanyModeKind {
|
|||
Default,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, JsonSchema, TS, Default)]
|
||||
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, Default)]
|
||||
pub struct EpiphanyMemoryGraphSnapshot {
|
||||
pub graph_id: String,
|
||||
#[serde(default, skip_serializing_if = "Vec::is_empty")]
|
||||
#[ts(type = "Array<EpiphanyMemoryDomain>")]
|
||||
pub domains: Vec<EpiphanyMemoryDomain>,
|
||||
#[serde(default, skip_serializing_if = "Vec::is_empty")]
|
||||
#[ts(type = "Array<EpiphanyMemoryNode>")]
|
||||
pub nodes: Vec<EpiphanyMemoryNode>,
|
||||
#[serde(default, skip_serializing_if = "Vec::is_empty")]
|
||||
#[ts(type = "Array<EpiphanyMemoryEdge>")]
|
||||
pub edges: Vec<EpiphanyMemoryEdge>,
|
||||
#[serde(default, skip_serializing_if = "Vec::is_empty")]
|
||||
#[ts(type = "Array<RepoFrontierItem>")]
|
||||
pub frontier: Vec<RepoFrontierItem>,
|
||||
}
|
||||
|
||||
/// A durable piece of unfinished repository anatomy. This is Modeling-owned state,
|
||||
/// not a scheduler job or a presentation card.
|
||||
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, JsonSchema, TS, Default)]
|
||||
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, Default)]
|
||||
pub struct RepoFrontierItem {
|
||||
pub id: String,
|
||||
pub migration_body: String,
|
||||
pub question: String,
|
||||
pub gap: String,
|
||||
#[serde(default, skip_serializing_if = "Vec::is_empty")]
|
||||
#[ts(type = "Array<string>")]
|
||||
pub target_claim_ids: Vec<String>,
|
||||
#[serde(default, skip_serializing_if = "Vec::is_empty")]
|
||||
#[ts(type = "Array<string>")]
|
||||
/// Canonical repository-relative path ceiling for this wound. This is the
|
||||
/// scope that downstream Planning may narrow and Hands may eventually
|
||||
/// change; inspected files and evidence provenance belong elsewhere.
|
||||
|
|
@ -162,36 +142,28 @@ pub struct RepoFrontierItem {
|
|||
/// propose this payload, but only the dedicated model transition may make
|
||||
/// it part of Modeling-owned truth.
|
||||
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||
#[ts(type = "RepoFrontierAdoptedPlan | null")]
|
||||
pub adopted_plan: Option<RepoFrontierAdoptedPlan>,
|
||||
#[serde(default, skip_serializing_if = "Vec::is_empty")]
|
||||
#[ts(type = "Array<string>")]
|
||||
pub dependency_item_ids: Vec<String>,
|
||||
#[serde(default)]
|
||||
pub status: RepoFrontierStatus,
|
||||
#[serde(default, skip_serializing_if = "Vec::is_empty")]
|
||||
#[ts(type = "Array<string>")]
|
||||
pub evidence_refs: Vec<String>,
|
||||
/// Exact immutable public sources selected upstream for Eyes. These are
|
||||
/// causal retrieval inputs, not evidence produced by Modeling.
|
||||
#[serde(default, skip_serializing_if = "Vec::is_empty")]
|
||||
#[ts(type = "Array<string>")]
|
||||
pub public_source_refs: Vec<String>,
|
||||
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||
#[ts(type = "string | null")]
|
||||
pub created_at: Option<String>,
|
||||
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||
#[ts(type = "string | null")]
|
||||
pub updated_at: Option<String>,
|
||||
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||
#[ts(type = "string | null")]
|
||||
pub retired_at: Option<String>,
|
||||
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||
#[ts(type = "string | null")]
|
||||
pub superseded_by: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, JsonSchema, TS, Default)]
|
||||
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, Default)]
|
||||
pub struct RepoFrontierAdoptedPlan {
|
||||
pub planning_request_id: String,
|
||||
pub result_id: String,
|
||||
|
|
@ -199,18 +171,14 @@ pub struct RepoFrontierAdoptedPlan {
|
|||
pub candidate_id: String,
|
||||
pub candidate_sha256: String,
|
||||
#[serde(default, skip_serializing_if = "Vec::is_empty")]
|
||||
#[ts(type = "Array<string>")]
|
||||
pub safe_paths: Vec<String>,
|
||||
pub action: String,
|
||||
pub command: String,
|
||||
#[serde(default, skip_serializing_if = "Vec::is_empty")]
|
||||
#[ts(type = "Array<string>")]
|
||||
pub checks: Vec<String>,
|
||||
#[serde(default, skip_serializing_if = "Vec::is_empty")]
|
||||
#[ts(type = "Array<string>")]
|
||||
pub stop_conditions: Vec<String>,
|
||||
#[serde(default, skip_serializing_if = "Vec::is_empty")]
|
||||
#[ts(type = "Array<string>")]
|
||||
pub rollback_steps: Vec<String>,
|
||||
pub commit_message: String,
|
||||
}
|
||||
|
|
@ -225,9 +193,8 @@ impl RepoFrontierAdoptedPlan {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Clone, Copy, Debug, PartialEq, Eq, JsonSchema, TS, Default)]
|
||||
#[derive(Serialize, Deserialize, Clone, Copy, Debug, PartialEq, Eq, Default)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
#[ts(rename_all = "snake_case")]
|
||||
pub enum RepoFrontierStatus {
|
||||
#[default]
|
||||
Proposed,
|
||||
|
|
@ -238,22 +205,20 @@ pub enum RepoFrontierStatus {
|
|||
Superseded,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, JsonSchema, TS, Default)]
|
||||
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, Default)]
|
||||
pub struct EpiphanyMemoryDomain {
|
||||
pub id: String,
|
||||
pub title: String,
|
||||
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||
#[ts(type = "string | null")]
|
||||
pub description: Option<String>,
|
||||
#[serde(default)]
|
||||
pub lifecycle: EpiphanyMemoryLifecycle,
|
||||
}
|
||||
|
||||
#[derive(
|
||||
Serialize, Deserialize, Clone, Copy, Debug, PartialEq, Eq, Hash, JsonSchema, TS, Default,
|
||||
Serialize, Deserialize, Clone, Copy, Debug, PartialEq, Eq, Hash, Default,
|
||||
)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
#[ts(rename_all = "snake_case")]
|
||||
pub enum EpiphanyMemoryLifecycle {
|
||||
#[default]
|
||||
Observed,
|
||||
|
|
@ -264,10 +229,9 @@ pub enum EpiphanyMemoryLifecycle {
|
|||
}
|
||||
|
||||
#[derive(
|
||||
Serialize, Deserialize, Clone, Copy, Debug, PartialEq, Eq, Hash, JsonSchema, TS, Default,
|
||||
Serialize, Deserialize, Clone, Copy, Debug, PartialEq, Eq, Hash, Default,
|
||||
)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
#[ts(rename_all = "snake_case")]
|
||||
pub enum EpiphanyMemoryNodeKind {
|
||||
#[default]
|
||||
Domain,
|
||||
|
|
@ -283,7 +247,7 @@ pub enum EpiphanyMemoryNodeKind {
|
|||
Other,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, JsonSchema, TS, Default)]
|
||||
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, Default)]
|
||||
pub struct EpiphanyMemoryNode {
|
||||
pub id: String,
|
||||
pub domain_id: String,
|
||||
|
|
@ -294,26 +258,21 @@ pub struct EpiphanyMemoryNode {
|
|||
pub tension: String,
|
||||
pub action_implication: String,
|
||||
#[serde(default, skip_serializing_if = "Vec::is_empty")]
|
||||
#[ts(type = "Array<EpiphanyMemoryAnchor>")]
|
||||
pub anchors: Vec<EpiphanyMemoryAnchor>,
|
||||
#[serde(default, skip_serializing_if = "Vec::is_empty")]
|
||||
#[ts(type = "Array<string>")]
|
||||
pub source_hashes: Vec<String>,
|
||||
#[serde(default)]
|
||||
pub lifecycle: EpiphanyMemoryLifecycle,
|
||||
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||
#[ts(type = "string | null")]
|
||||
pub created_at: Option<String>,
|
||||
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||
#[ts(type = "string | null")]
|
||||
pub updated_at: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(
|
||||
Serialize, Deserialize, Clone, Copy, Debug, PartialEq, Eq, Hash, JsonSchema, TS, Default,
|
||||
Serialize, Deserialize, Clone, Copy, Debug, PartialEq, Eq, Hash, Default,
|
||||
)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
#[ts(rename_all = "snake_case")]
|
||||
pub enum EpiphanyMemoryEdgeKind {
|
||||
#[default]
|
||||
Owns,
|
||||
|
|
@ -332,7 +291,7 @@ pub enum EpiphanyMemoryEdgeKind {
|
|||
Other,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, JsonSchema, TS, Default)]
|
||||
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, Default)]
|
||||
pub struct EpiphanyMemoryEdge {
|
||||
pub id: String,
|
||||
pub source_id: String,
|
||||
|
|
@ -340,27 +299,22 @@ pub struct EpiphanyMemoryEdge {
|
|||
pub kind: EpiphanyMemoryEdgeKind,
|
||||
pub claim: String,
|
||||
#[serde(default, skip_serializing_if = "Vec::is_empty")]
|
||||
#[ts(type = "Array<EpiphanyMemoryAnchor>")]
|
||||
pub anchors: Vec<EpiphanyMemoryAnchor>,
|
||||
#[serde(default)]
|
||||
pub lifecycle: EpiphanyMemoryLifecycle,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, JsonSchema, TS, Default)]
|
||||
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, Default)]
|
||||
pub struct EpiphanyMemoryAnchor {
|
||||
pub id: String,
|
||||
pub kind: String,
|
||||
pub target: String,
|
||||
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||
#[ts(type = "EpiphanyCodeRef | null")]
|
||||
pub code_ref: Option<EpiphanyCodeRef>,
|
||||
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||
#[ts(type = "string | null")]
|
||||
pub evidence_id: Option<String>,
|
||||
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||
#[ts(type = "string | null")]
|
||||
pub source_hash: Option<String>,
|
||||
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||
#[ts(type = "string | null")]
|
||||
pub note: Option<String>,
|
||||
}
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
use anyhow::{Result, anyhow};
|
||||
use epiphany_state_model::EpiphanyEvidenceRecord;
|
||||
use epiphany_state_model::EpiphanyInvestigationCheckpoint;
|
||||
use epiphany_state_model::EpiphanyObservation;
|
||||
use crate::state_model::EpiphanyEvidenceRecord;
|
||||
use crate::state_model::EpiphanyInvestigationCheckpoint;
|
||||
use crate::state_model::EpiphanyObservation;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::collections::BTreeSet;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,19 +0,0 @@
|
|||
[package]
|
||||
name = "epiphany-state-model"
|
||||
version = "0.1.0"
|
||||
edition = "2024"
|
||||
publish = false
|
||||
license-file = "../LICENSE"
|
||||
|
||||
[lib]
|
||||
name = "epiphany_state_model"
|
||||
path = "src/lib.rs"
|
||||
|
||||
[dependencies]
|
||||
schemars = "0.8"
|
||||
serde = { version = "1", features = ["derive"] }
|
||||
ts-rs = { version = "11", features = [
|
||||
"uuid-impl",
|
||||
"serde-json-impl",
|
||||
"no-serde-warnings",
|
||||
] }
|
||||
|
|
@ -188,11 +188,11 @@ application. `codex-core` re-exports the contract only as a compatibility
|
|||
alias, and `CodexThread` now calls native state-update functions around its
|
||||
remaining revision check, persistence validation, and rollout/session writeback.
|
||||
|
||||
The credential extraction overcut has been corrected. Codex file/keyring/auto
|
||||
auth, env API key handling, ChatGPT token refresh, account metadata parsing,
|
||||
and header-client setup remain in vendored `codex-login`. The redundant
|
||||
Epiphany re-export crate is gone; the root workspace carries the Codex
|
||||
`tokio-tungstenite` / `tungstenite` patches required for standalone builds.
|
||||
This paragraph describes the superseded embedded-auth phase. Exact `ed7357a2`
|
||||
later removed Codex credential and transport anatomy from Epiphany entirely;
|
||||
the independent CodexConnector owns that boundary. The unused root
|
||||
`tokio-tungstenite` / `tungstenite` patches are gone with the compiled Codex
|
||||
graph.
|
||||
|
||||
The point is ownership: Epiphany calls a model adapter; it does not live inside
|
||||
the Codex host brain.
|
||||
|
|
|
|||
|
|
@ -7,14 +7,13 @@ of app-server routes.
|
|||
## Objective
|
||||
|
||||
Build an inspectable native organism whose typed state, runtime, organ gates,
|
||||
memory, scheduling, interfaces, and social crossings can operate without Codex
|
||||
owning Epiphany cognition. Retain Codex-derived code only where it provides an
|
||||
earned OpenAI-compatible authentication or model-transport capability.
|
||||
memory, scheduling, interfaces, and social crossings operate without Codex
|
||||
owning Epiphany cognition. OpenAI subscription authentication and model
|
||||
transport belong to the independent CodexConnector daemon, not Epiphany's body.
|
||||
|
||||
## Current Mechanism
|
||||
|
||||
- `epiphany-state-model` owns shared typed semantic contracts; durable Mind is keyed CultCache owned by `epiphany-core`.
|
||||
- `epiphany-core` owns keyed Mind admission, runtime spine, organ gates,
|
||||
- `epiphany-core` owns the semantic contracts, keyed Mind admission, runtime spine, organ gates,
|
||||
Resident Self physiology, Persona, and CultMesh integration. Coordinator policy,
|
||||
status, and every migrated work family consume keyed Mind plus exact runtime
|
||||
receipts. Persisted `EpiphanyThreadStateEntry`, the in-memory
|
||||
|
|
|
|||
Reference in a new issue