Skip to content

Cover command modes and transport attribution - #2144

Open
svarlamov wants to merge 17 commits into
codex/git-ops-07-am-e2efrom
codex/git-ops-08-command-modes-e2e
Open

Cover command modes and transport attribution#2144
svarlamov wants to merge 17 commits into
codex/git-ops-07-am-e2efrom
codex/git-ops-08-command-modes-e2e

Conversation

@svarlamov

@svarlamov svarlamov commented Aug 12, 2026

Copy link
Copy Markdown
Member
  • Adds end-to-end coverage for administrative, clean, commit, move, invocation-wrapper, and transport modes.
  • Verifies global repository selectors, nested working directories, clone and fetch variants, pull strategies, atomic pushes, force-with-lease, and ref deletion.

devin-ai-integration[bot]

This comment was marked as resolved.

@svarlamov
svarlamov force-pushed the codex/git-ops-08-command-modes-e2e branch from 47e7bcd to 305c0a5 Compare August 12, 2026 00:18
@svarlamov
svarlamov force-pushed the codex/git-ops-08-command-modes-e2e branch from 305c0a5 to 1c0b886 Compare August 12, 2026 19:47
devin-ai-integration[bot]

This comment was marked as resolved.

@svarlamov
svarlamov force-pushed the codex/git-ops-08-command-modes-e2e branch from 1c0b886 to 3eac28f Compare August 12, 2026 20:23
devin-ai-integration[bot]

This comment was marked as resolved.

@svarlamov
svarlamov force-pushed the codex/git-ops-08-command-modes-e2e branch from 3eac28f to 115d7e2 Compare August 12, 2026 20:37
@svarlamov
svarlamov force-pushed the codex/git-ops-08-command-modes-e2e branch from 119bcfb to d0d0953 Compare August 12, 2026 21:11
@svarlamov
svarlamov force-pushed the codex/git-ops-08-command-modes-e2e branch from d0d0953 to 4d6c975 Compare August 12, 2026 21:15
devin-ai-integration[bot]

This comment was marked as resolved.

@svarlamov
svarlamov force-pushed the codex/git-ops-08-command-modes-e2e branch from 4d6c975 to 9713c76 Compare August 12, 2026 21:36
devin-ai-integration[bot]

This comment was marked as resolved.

@svarlamov
svarlamov force-pushed the codex/git-ops-08-command-modes-e2e branch from 9713c76 to 6563217 Compare August 12, 2026 21:54
devin-ai-integration[bot]

This comment was marked as resolved.

@svarlamov
svarlamov force-pushed the codex/git-ops-08-command-modes-e2e branch from 6563217 to 127b85a Compare August 12, 2026 22:13
devin-ai-integration[bot]

This comment was marked as resolved.

@svarlamov
svarlamov force-pushed the codex/git-ops-08-command-modes-e2e branch from a6bfe16 to 2ad4e8a Compare August 12, 2026 22:31
devin-ai-integration[bot]

This comment was marked as resolved.

@svarlamov
svarlamov force-pushed the codex/git-ops-08-command-modes-e2e branch 2 times, most recently from 14c8d19 to 9d577da Compare August 12, 2026 23:10
@svarlamov
svarlamov force-pushed the codex/git-ops-08-command-modes-e2e branch from ffca72f to 70ae342 Compare August 13, 2026 00:39
devin-ai-integration[bot]

This comment was marked as resolved.

@svarlamov
svarlamov force-pushed the codex/git-ops-08-command-modes-e2e branch 2 times, most recently from c220de8 to aee77dd Compare August 13, 2026 00:56
devin-ai-integration[bot]

This comment was marked as resolved.

@svarlamov
svarlamov force-pushed the codex/git-ops-08-command-modes-e2e branch from aee77dd to a0af056 Compare August 13, 2026 01:22
@svarlamov
svarlamov force-pushed the codex/git-ops-08-command-modes-e2e branch from a0af056 to 7a397eb Compare August 13, 2026 01:40
@svarlamov
svarlamov force-pushed the codex/git-ops-08-command-modes-e2e branch from 7a397eb to cd4a928 Compare August 13, 2026 02:00

@devin-ai-integration devin-ai-integration Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Devin Review found 1 new potential issue.

View 10 additional findings in Devin Review.

Open in Devin Review

Comment thread src/daemon.rs
Comment on lines +857 to +883
fn capture_index_snapshot_for_workspace_command(worktree: &Path) -> Option<String> {
let git_dir = git_dir_for_worktree(worktree)?;
sweep_stale_index_snapshots(&git_dir);
let index = git_dir.join("index");
if !index.is_file() {
return None;
}
// Git updates the index by atomically replacing its directory entry. A
// hard link retains the pre-command inode in O(1) without reading index
// contents, taking an index lock, spawning Git, or writing objects.
let created_at_ms = SystemTime::now()
.duration_since(UNIX_EPOCH)
.ok()?
.as_millis();
for _ in 0..4 {
let snapshot_path = git_dir.join(format!(
"{INDEX_SNAPSHOT_PREFIX}{created_at_ms}-{}",
crate::uuid::generate_v4()
));
match fs::hard_link(&index, &snapshot_path) {
Ok(()) => return Some(snapshot_path.to_string_lossy().into_owned()),
Err(error) if error.kind() == std::io::ErrorKind::AlreadyExists => continue,
Err(_) => return None,
}
}
None
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Every removal command makes the daemon scan the whole repository metadata directory before git can continue

The daemon lists every entry in the repository's internal git directory and creates a link file (sweep_stale_index_snapshots at src/daemon.rs:859) while it is still receiving live data from the running command, adding unbounded directory work to a path documented as sub-millisecond sensitive.
Impact: Repositories with many files in their git directory add measurable delay to each removal command and to trace processing for all repositories.

Non-constant-time filesystem work added to trace ingestion

capture_index_snapshot_for_workspace_command (src/daemon.rs:857-883) is invoked from track_trace_payload_for_ingest while the trace_ingress_state mutex is held and on the trace socket listener thread. It performs git_dir_for_worktree, a full fs::read_dir of the git directory with a parse/stat per matching entry, an is_file check, and a hard_link. If the link fails (for example the index is missing) the guard !ingress.root_index_snapshot_at_start.contains_key(&root) means the sweep is retried on every subsequent non-terminal event of the same root.

The adjacent pathspec capture also reaches the filesystem on this path: workspace_pathspecs_from_command_dir (src/daemon.rs:1966-2015) canonicalizes two paths and, via restore_pathspecs, reads the --pathspec-from-file file from disk (src/daemon.rs:1745) — and it does so even for git rm --cached, whose result is never used because the analyzer emits OpaqueCommand for that mode.

AGENTS.md rule 2 explicitly says "even additional file reads have meaningful overhead on this path", and rule 3 forbids non-constant-time work. The sweep should run out of band (e.g. on the daemon's existing sweep/maintenance path) rather than per ingested rm event.

Prompt for agents
capture_index_snapshot_for_workspace_command in src/daemon.rs runs on the trace2 ingestion listener thread while the trace_ingress_state mutex is held. It calls sweep_stale_index_snapshots, which does a full fs::read_dir of the repository git directory (plus a filename parse per entry) before every snapshot capture, and it is retried on each subsequent root event when the capture fails. AGENTS.md forbids adding non-constant-time work and extra file reads on this path. Move the stale-snapshot sweep to an out-of-band maintenance path (the daemon already has sweep_coordinator / periodic sweeps) and keep only the O(1) hard_link on the ingest path. Also consider skipping workspace_pathspecs_from_command_dir entirely for `git rm --cached`, since the analyzer emits OpaqueCommand for that mode and the resolved pathspecs (which involve canonicalize calls and reading a --pathspec-from-file file from disk) are never used.
Open in Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

@devin-ai-integration devin-ai-integration Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Devin Review found 1 new potential issue.

View 9 additional findings in Devin Review.

Open in Devin Review

Comment thread src/daemon.rs
Comment on lines 990 to +992
pathspecs.iter().any(|pathspec| {
file == pathspec
pathspec == "."
|| file == pathspec

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Restoring or checking out files from a subfolder wipes AI authorship for the entire project

A selection of "." is now treated as matching every file in the repository (matches_any_pathspec at src/daemon.rs:991), so restoring or checking out the current folder discards the recorded authorship of files everywhere else in the project.
Impact: Running git restore . or git checkout -- . inside a subfolder silently loses pending AI attribution for unrelated files in other folders.

Shared pathspec matcher is used with un-rooted operands

The new pathspec == "." short-circuit makes matches_any_pathspec return true for every candidate. It is intended for the clean/rm flow, where workspace_pathspecs_from_command_dir (src/daemon.rs:1968-2029) has already re-rooted operands against the worktree, so "." only appears for a worktree-root invocation.

But the same helper is used by remove_working_log_attributions_for_pathspecs (src/daemon.rs:1603 and src/daemon.rs:1622), which is fed raw, un-rooted operands: restore_pathspecs(&parsed.command_args, ...) for restore (src/daemon.rs:1805) and parsed.pathspecs() for checkout (src/daemon.rs:1834). A literal "." typed in a subdirectory therefore prunes every file in the working log instead of only the subtree Git actually restored. Before this change "." matched nothing there.

Prompt for agents
matches_any_pathspec in src/daemon.rs gained a `pathspec == "."` case that makes it match every candidate path. That is correct for the clean/rm flow, where workspace_pathspecs_from_command_dir already re-roots operands relative to the worktree and only emits "." for a worktree-root invocation. However the same helper is shared with remove_working_log_attributions_for_pathspecs, which is called from apply_checkout_switch_working_log_side_effect with RAW operands taken straight from the command line (restore_pathspecs / parsed.pathspecs()). Those operands are relative to the invocation directory, so `git restore .` or `git checkout -- .` executed inside a subdirectory now prunes working-log attributions for the whole repository instead of just that subtree.

Consider either scoping the "." wildcard semantics to the already-rooted clean/rm call sites (e.g. a separate matcher or an explicit flag), or re-rooting the restore/checkout operands against the worktree the same way workspace_pathspecs_from_command_dir does before matching.
Open in Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant