Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
135 changes: 135 additions & 0 deletions crates/code-intel-cli/src/providers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1224,7 +1224,89 @@ fn validate_codenexus_integration(
}
}

/// Resolves the trusted orchestration manifest, refusing the case where the
/// resolved manifest belongs to a different checkout than the one the process
/// is standing in.
///
/// The refusal exists because the silent version of this is a false PASS, not
/// a false failure. `CODE_INTEL_HOME` is commonly set to a primary checkout;
/// run a validation from a git worktree of the same repository and every
/// provider/route check reads the *primary* checkout's manifest while
/// appearing to validate the worktree. A worktree whose manifest is genuinely
/// broken then reports green as long as the primary checkout is consistent.
/// Naming both roots costs one error message; not naming them costs a
/// verification result that means nothing.
///
/// `CODE_INTEL_INTEGRATIONS_MANIFEST` is exempt: it is an explicit operator
/// instruction to use one specific file, so there is no ambiguity to resolve.
fn orchestration_manifest() -> std::result::Result<(PathBuf, PathBuf), String> {
let explicit = env::var("CODE_INTEL_INTEGRATIONS_MANIFEST").is_ok();
let (manifest, root) = resolve_orchestration_manifest()?;
if !explicit {
reject_foreign_checkout(&manifest, cwd_manifest_path())?;
}
Ok((manifest, root))
}

/// The manifest a cwd-anchored reader would have picked, used only to detect
/// disagreement. This never grants trust — `orchestration_manifest`'s own cwd
/// fallback still gates on [`is_safe_cwd_manifest`].
fn cwd_manifest_path() -> Option<PathBuf> {
let cwd = env::current_dir().ok()?;
cwd.ancestors()
.map(|ancestor| ancestor.join("orchestration").join("integrations.json"))
// `is_safe_cwd_manifest` is what separates the two cases that both
// look like "cwd disagrees with CODE_INTEL_HOME". Standing in an
// unrelated repository that merely happens to have a file at
// orchestration/integrations.json is not ambiguity — the operator
// named a checkout and nothing here rivals it, which is exactly what
// test-integration-orchestration.ps1:243 has always asserted. Only a
// real code-intel registry is a rival, and that is the worktree case
// this guard exists for.
.find(|candidate| candidate.is_file() && is_safe_cwd_manifest(candidate))
}

fn reject_foreign_checkout(
resolved: &Path,
local: Option<PathBuf>,
) -> std::result::Result<(), String> {
let Some(local) = local else {
return Ok(());
};
let canonical = |path: &Path| path.canonicalize().unwrap_or_else(|_| path.to_path_buf());
if canonical(&local) == canonical(resolved) {
return Ok(());
}
Err(format!(
"orchestration manifest ambiguity: resolved {} but the current directory belongs to {}. \
These are different checkouts, so validating one while standing in the other proves nothing. \
Set CODE_INTEL_HOME to the checkout you mean, or CODE_INTEL_INTEGRATIONS_MANIFEST to one manifest explicitly.",
resolved.display(),
local.display()
))
}

// Registry tests must assert against the checkout they were built from, not
// against whatever `CODE_INTEL_HOME` happens to name on the developer's
// machine. Reading the ambient variable is what let a worktree's registry
// look valid while the primary checkout was the thing actually validated.
#[cfg(test)]
fn test_manifest_override() -> Option<PathBuf> {
let candidate = Path::new(env!("CARGO_MANIFEST_DIR"))
.join("../..")
.join("orchestration")
.join("integrations.json");
candidate.is_file().then_some(candidate)
}

fn resolve_orchestration_manifest() -> std::result::Result<(PathBuf, PathBuf), String> {
#[cfg(test)]
if let Some(path) = test_manifest_override() {
return manifest_candidate(path).ok_or_else(|| {
"built-from checkout has no readable integrations manifest".to_string()
});
}

if let Ok(explicit) = env::var("CODE_INTEL_INTEGRATIONS_MANIFEST") {
let path = PathBuf::from(explicit);
let path = if path.is_absolute() {
Expand Down Expand Up @@ -1670,6 +1752,59 @@ mod tests {
);
}

#[test]
fn manifest_from_another_checkout_is_refused_and_names_both_roots() {
// The worktree case: CODE_INTEL_HOME points at the primary checkout
// while the process stands in a worktree of the same repository.
let primary = Path::new(r"D:\projects\code-intel-pipeline\orchestration\integrations.json");
let worktree = Path::new(
r"D:\projects\code-intel-pipeline\.claude\worktrees\wt\orchestration\integrations.json",
);
let error = reject_foreign_checkout(primary, Some(worktree.to_path_buf()))
.expect_err("two different checkouts must not validate silently");
assert!(error.contains("ambiguity"), "{error}");
assert!(error.contains(&primary.display().to_string()), "{error}");
assert!(error.contains(&worktree.display().to_string()), "{error}");
assert!(
error.contains("CODE_INTEL_INTEGRATIONS_MANIFEST"),
"{error}"
);
}

#[test]
fn an_unrelated_cwd_manifest_never_rivals_code_intel_home() {
// Regression guard for test-integration-orchestration.ps1:243. A
// directory holding {"policy":{"name":"unrelated"},"integrations":[]}
// is not a code-intel registry, so CODE_INTEL_HOME still wins and
// nothing is ambiguous.
let root = std::env::temp_dir().join(format!(
"code-intel-unrelated-manifest-{}-{}",
std::process::id(),
SystemTime::now()
.duration_since(UNIX_EPOCH)
.expect("clock after epoch")
.as_nanos()
));
let manifest = root.join("orchestration").join("integrations.json");
fs::create_dir_all(manifest.parent().expect("orchestration dir")).expect("fixture");
fs::write(
&manifest,
br#"{"policy":{"name":"unrelated"},"integrations":[]}"#,
)
.expect("write fixture manifest");
assert!(!is_safe_cwd_manifest(&manifest));
fs::remove_dir_all(&root).expect("cleanup");
}

#[test]
fn matching_checkout_and_absent_local_manifest_both_pass() {
let same = Path::new(r"D:\repo\orchestration\integrations.json");
assert!(reject_foreign_checkout(same, Some(same.to_path_buf())).is_ok());
// Running against an arbitrary directory that has no manifest of its
// own is the normal installed-CLI case, not an ambiguity.
assert!(reject_foreign_checkout(same, None).is_ok());
}

#[test]
fn codenexus_plan_quotes_repo_paths_for_powershell() {
let command = render_command(
Expand Down
11 changes: 11 additions & 0 deletions crates/code-intel-cli/tests/graph_adapter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -414,8 +414,19 @@ fn public_route_usage_registry_facade_and_schemas_are_real() {
assert_eq!(output.status.code(), Some(64));
assert!(output.stdout.is_empty());

// Name the manifest this test means. Without it the spawned binary
// resolves whatever `CODE_INTEL_HOME` points at, which on a developer
// machine is usually a different checkout than the one being tested —
// the assertion below would then be about someone else's tree.
let validation = Command::new(env!("CARGO_BIN_EXE_code-intel"))
.args(["provider", "--action", "Validate", "--json"])
.env(
"CODE_INTEL_INTEGRATIONS_MANIFEST",
Path::new(env!("CARGO_MANIFEST_DIR"))
.join("../..")
.join("orchestration")
.join("integrations.json"),
)
.output()
.unwrap();
let validation_json: Value = serde_json::from_slice(&validation.stdout).unwrap();
Expand Down
6 changes: 5 additions & 1 deletion legacy/install-code-intel-pipeline.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -437,7 +437,11 @@ param(
[string[]]`$RemainingArgs
)

`$repoRoot = '$repoRootLiteral'
# CODE_INTEL_REPO_ROOT is honoured here because the error below tells the
# operator to set it. The literal is the install-time location, which goes
# stale the moment the repository is moved or a directory is renamed — the
# override is how you recover without reinstalling.
`$repoRoot = if (-not [string]::IsNullOrWhiteSpace(`$env:CODE_INTEL_REPO_ROOT)) { `$env:CODE_INTEL_REPO_ROOT } else { '$repoRootLiteral' }
`$target = Join-Path `$repoRoot '$relativeLiteral'

if (-not (Test-Path -LiteralPath `$target -PathType Leaf)) {
Expand Down
Loading
Loading