Skip to main content

relay_knowledge/storage/contracts/code/
publication.rs

1use crate::domain::{
2    CodeIndexBatch, CodeIndexCheckpoint, CodeIndexPublicationFence, CodeIndexSession,
3    CodeIndexSnapshot, CodeIndexSummary,
4};
5
6use super::super::{StorageError, StorageFuture};
7use super::CodeIndexFinalizationStep;
8
9/// Checkpointed snapshot, batch, workspace, and final publication capability.
10pub trait CodeIndexPublicationStore: Send + Sync {
11    fn code_index_checkpoint(
12        &self,
13        source_scope: String,
14    ) -> StorageFuture<'_, Option<CodeIndexCheckpoint>>;
15
16    fn latest_code_index_checkpoint(
17        &self,
18        repository_id: String,
19    ) -> StorageFuture<'_, Option<CodeIndexCheckpoint>> {
20        Box::pin(async move {
21            Err(StorageError::InvalidInput(format!(
22                "latest code index checkpoint for repository '{repository_id}' is unavailable"
23            )))
24        })
25    }
26
27    fn apply_code_index_snapshot(
28        &self,
29        snapshot: CodeIndexSnapshot,
30    ) -> StorageFuture<'_, CodeIndexSummary>;
31
32    fn apply_code_index_snapshot_with_fence(
33        &self,
34        snapshot: CodeIndexSnapshot,
35        fence: CodeIndexPublicationFence,
36    ) -> StorageFuture<'_, CodeIndexSummary> {
37        Box::pin(async move {
38            Err(StorageError::InvalidInput(format!(
39                "attempt-scoped snapshot publication for task '{}' scope '{}' is unavailable",
40                fence.task_id, snapshot.source_scope
41            )))
42        })
43    }
44
45    fn clear_code_workspace_state(
46        &self,
47        repository_id: String,
48        source_scope: String,
49    ) -> StorageFuture<'_, ()> {
50        Box::pin(async move {
51            Err(StorageError::InvalidInput(format!(
52                "workspace cleanup for repository '{repository_id}' scope '{source_scope}' is unavailable"
53            )))
54        })
55    }
56
57    /// Reports whether repository-owned auto-detected workspace artifacts
58    /// still exist and therefore require a durable disabled-mode cleanup.
59    fn code_repository_auto_workspace_state_exists(
60        &self,
61        repository_id: String,
62    ) -> StorageFuture<'_, bool> {
63        Box::pin(async move {
64            Err(StorageError::InvalidInput(format!(
65                "auto workspace state inspection for repository '{repository_id}' is unavailable"
66            )))
67        })
68    }
69
70    fn clear_code_workspace_state_with_fence(
71        &self,
72        repository_id: String,
73        source_scope: String,
74        fence: CodeIndexPublicationFence,
75    ) -> StorageFuture<'_, ()> {
76        Box::pin(async move {
77            Err(StorageError::InvalidInput(format!(
78                "attempt-scoped workspace publication for task '{}' repository '{}' scope '{}' is unavailable",
79                fence.task_id, repository_id, source_scope
80            )))
81        })
82    }
83
84    fn begin_code_index_session(
85        &self,
86        session: CodeIndexSession,
87    ) -> StorageFuture<'_, CodeIndexCheckpoint> {
88        Box::pin(async move {
89            Err(StorageError::InvalidInput(format!(
90                "checkpointed code index sessions for scope '{}' are unavailable",
91                session.source_scope
92            )))
93        })
94    }
95
96    fn begin_code_index_session_with_fence(
97        &self,
98        session: CodeIndexSession,
99        fence: CodeIndexPublicationFence,
100    ) -> StorageFuture<'_, CodeIndexCheckpoint> {
101        Box::pin(async move {
102            Err(StorageError::InvalidInput(format!(
103                "attempt-scoped session startup for task '{}' scope '{}' is unavailable",
104                fence.task_id, session.source_scope
105            )))
106        })
107    }
108
109    /// Starts a checkpointed session only when the durable checkpoint still
110    /// matches the value observed during read-only plan validation.
111    fn begin_code_index_session_at_checkpoint(
112        &self,
113        session: CodeIndexSession,
114        expected_checkpoint: Option<CodeIndexCheckpoint>,
115    ) -> StorageFuture<'_, CodeIndexCheckpoint> {
116        Box::pin(async move {
117            let expectation = expected_checkpoint
118                .as_ref()
119                .map(|checkpoint| checkpoint.source_scope.as_str())
120                .unwrap_or("missing");
121            Err(StorageError::InvalidInput(format!(
122                "checkpoint-CAS session startup for scope '{}' at expectation '{}' is unavailable",
123                session.source_scope, expectation
124            )))
125        })
126    }
127
128    /// Fenced variant of
129    /// [`CodeIndexPublicationStore::begin_code_index_session_at_checkpoint`].
130    fn begin_code_index_session_at_checkpoint_with_fence(
131        &self,
132        session: CodeIndexSession,
133        expected_checkpoint: Option<CodeIndexCheckpoint>,
134        fence: CodeIndexPublicationFence,
135    ) -> StorageFuture<'_, CodeIndexCheckpoint> {
136        Box::pin(async move {
137            let expectation = expected_checkpoint
138                .as_ref()
139                .map(|checkpoint| checkpoint.source_scope.as_str())
140                .unwrap_or("missing");
141            Err(StorageError::InvalidInput(format!(
142                "attempt-scoped checkpoint-CAS session startup for task '{}' scope '{}' at expectation '{}' is unavailable",
143                fence.task_id, session.source_scope, expectation
144            )))
145        })
146    }
147
148    fn apply_code_index_batch(
149        &self,
150        batch: CodeIndexBatch,
151    ) -> StorageFuture<'_, CodeIndexCheckpoint> {
152        Box::pin(async move {
153            Err(StorageError::InvalidInput(format!(
154                "checkpointed code index batches for scope '{}' are unavailable",
155                batch.source_scope
156            )))
157        })
158    }
159
160    fn apply_code_index_batch_with_fence(
161        &self,
162        batch: CodeIndexBatch,
163        fence: CodeIndexPublicationFence,
164    ) -> StorageFuture<'_, CodeIndexCheckpoint> {
165        Box::pin(async move {
166            Err(StorageError::InvalidInput(format!(
167                "attempt-scoped batch publication for task '{}' scope '{}' is unavailable",
168                fence.task_id, batch.source_scope
169            )))
170        })
171    }
172
173    fn finalize_code_index_session(
174        &self,
175        session: CodeIndexSession,
176    ) -> StorageFuture<'_, CodeIndexSummary> {
177        Box::pin(async move {
178            Err(StorageError::InvalidInput(format!(
179                "checkpointed code index finalization for scope '{}' is unavailable",
180                session.source_scope
181            )))
182        })
183    }
184
185    fn finalize_code_index_session_with_fence(
186        &self,
187        session: CodeIndexSession,
188        fence: CodeIndexPublicationFence,
189    ) -> StorageFuture<'_, CodeIndexSummary> {
190        Box::pin(async move {
191            Err(StorageError::InvalidInput(format!(
192                "attempt-scoped session finalization for task '{}' scope '{}' is unavailable",
193                fence.task_id, session.source_scope
194            )))
195        })
196    }
197
198    fn advance_code_index_session_with_fence(
199        &self,
200        session: CodeIndexSession,
201        fence: CodeIndexPublicationFence,
202    ) -> StorageFuture<'_, CodeIndexFinalizationStep> {
203        Box::pin(async move {
204            Err(StorageError::InvalidInput(format!(
205                "attempt-scoped single-step finalization for task '{}' scope '{}' is unavailable",
206                fence.task_id, session.source_scope
207            )))
208        })
209    }
210}