use openmoat_core::Kind;
use super::Filesystem;
use super::Report;
use crate::sandbox::patterns::{RUNS_LATER, push_unique};
const GIT_INTERNALS: &str = "claude-code.git-internals";
const GIT_EXEC_VECTORS: &[&str] = &[
"/**/.git/hooks",
"/**/.git/hooks/**",
"/**/.git/config",
"/**/.git/config.worktree",
"/**/.git/info/attributes",
"/**/.git/worktrees/*/config.worktree",
"/**/.git/worktrees/*/commondir",
"/**/.git/modules/**/hooks",
"/**/.git/modules/**/hooks/**",
"/**/.git/modules/**/config",
"/**/.git/modules/**/config.worktree",
"/**/.git/modules/**/info/attributes",
"/**/.git/modules/**/commondir",
];
impl Filesystem {
pub(super) fn git_internals(&mut self, report: &mut Report) {
if report.allowances.iter().any(|a| a.rule == GIT_INTERNALS) {
return;
}
for vector in GIT_EXEC_VECTORS {
push_unique(&mut self.deny_write, (*vector).to_owned());
}
report.allowance(
Kind::FsWrite,
GIT_INTERNALS,
vec!["/**/.git/**".to_owned()],
"user settings cannot name the project, so sandboxed commands may write `.git` \
(objects, refs, index: `git commit` works) in every directory, except what makes git \
run code or follow another repository (hooks, config, config.worktree, \
info/attributes, a linked worktree's commondir, the same in submodules); a script \
can still rewrite history or create a `.git` file (`gitdir: …`) in a subdirectory, \
and the hook still holds file-tool writes to any `.git` for review",
);
}
}
pub(super) fn runs_later(report: &mut Report, rule: &str) {
if report.allowances.iter().any(|a| a.rule == rule) {
return;
}
report.allowance(
Kind::FsWrite,
rule,
RUNS_LATER.iter().map(|f| (*f).to_owned()).collect(),
"sandboxed commands may write CI configuration, commit-hook managers' files and \
editor tasks; the hook holds the agent's writes of one for review (`runs-later`)",
);
}