Determine intent coverage for a single change. The change's modified files come from its own `file_ops` (via [`change_modified_paths`](Self::change_modified_paths)), mapped to `file: ` node ids — so coverage no longer depends on KG `MODIFIES` enrichment. The intent side stays in the KG: a file is covered when it carries an incoming `TOUCHES` edge from a `task:` node (projected on `vault sync
(&self, hash: &Hash)
| 202 | /// - `Unknown` only when the change has no file ops at all (e.g. a load |
| 203 | /// failure) — unreachable for a normally recorded change. |
| 204 | fn change_coverage(&self, hash: &Hash) -> Result<(Vec<String>, Coverage), RepositoryError> { |
| 205 | // change → file comes from the change's own ops (authoritative), mapped |
| 206 | // to the shared `file:<path>` node id the intent side also uses. |
| 207 | let modifies: Vec<String> = self |
| 208 | .change_modified_paths(hash)? |
| 209 | .into_iter() |
| 210 | .map(|p| format!("file:{p}")) |
| 211 | .collect(); |
| 212 | |
| 213 | if modifies.is_empty() { |
| 214 | // No file ops (or the change could not be loaded): coverage is |
| 215 | // genuinely indeterminate — not the same as uncovered. |
| 216 | return Ok((modifies, Coverage::Unknown)); |
| 217 | } |
| 218 | |
| 219 | // A file is "covered" if some task TOUCHES it. Only this intent side is |
| 220 | // read from the KG — per modified file, via its 1-hop neighborhood |
| 221 | // (incoming edges included), looking for a `task: --TOUCHES--> file:`. |
| 222 | let mut covered = false; |
| 223 | for file_id in &modifies { |
| 224 | let neighborhood = self.vault_kg_neighbors(file_id, 1)?; |
| 225 | if neighborhood.edges.iter().any(|e| { |
| 226 | e.kind == edge_kind::TOUCHES |
| 227 | && e.to_id == *file_id |
| 228 | && e.from_id.starts_with("task:") |
| 229 | }) { |
| 230 | covered = true; |
| 231 | break; |
| 232 | } |
| 233 | } |
| 234 | |
| 235 | let coverage = if covered { |
| 236 | Coverage::Covered |
| 237 | } else { |
| 238 | Coverage::Uncovered |
| 239 | }; |
| 240 | Ok((modifies, coverage)) |
| 241 | } |
| 242 | } |
| 243 | |
| 244 | #[cfg(test)] |