mirror of
https://github.com/stablyai/orca.git
synced 2026-09-23 16:02:24 +00:00
* fix(ssh): let fork-PR worktrees add their contributor remote via the relay Creating a workspace from a fork PR on an SSH host failed with "Destructive git remote operations are not allowed via exec". The relay's git.exec allowlist blocked every `remote` write subcommand, but SSH fork-PR creation has to run `git remote add <fork> <url>` on the host before it can fetch and track the contributor's branch, so the whole create aborted. Allow exactly the two shapes that flow needs -- `remote add <name> <url>` and `remote remove <name>` -- validated with the same remote-name and URL rules the relay already applies to every pushTarget-carrying RPC. Everything else (set-url, rename, prune, extra operands, flags before the action) stays blocked, and the URL must be a github.com clone/ssh URL, so no new reach is granted beyond what push/fetch already accept. `remote remove` was blocked too, which silently leaked fork remotes on SSH hosts: worktree removal swallows the cleanup error. It works again now. A host still running an older relay gets an actionable "reconnect to deploy the latest relay" message instead of the raw policy error. * test(git-exec): pin remote read/write mutation classification Misclassifying `git remote` / `remote get-url` as mutating would flush the relay and SSH provider git read caches on every remote probe, so pin both directions.
14 lines
656 B
TypeScript
14 lines
656 B
TypeScript
const MUTATING_GIT_EXEC_SUBCOMMANDS = new Set(['clone', 'commit', 'init'])
|
|
// Why: `git remote` also serves the bare list and get-url reads, so only the
|
|
// permitted fork-remote writes may invalidate cached reads.
|
|
const MUTATING_GIT_REMOTE_ACTIONS = new Set(['add', 'remove'])
|
|
|
|
// Why: relay git.exec permits these narrow write shapes alongside read-only
|
|
// probes, so cache invalidation must distinguish them before dispatch.
|
|
export function gitExecMutatesRepository(args: readonly string[]): boolean {
|
|
if (args[0] === 'remote') {
|
|
return MUTATING_GIT_REMOTE_ACTIONS.has(args[1] ?? '')
|
|
}
|
|
return MUTATING_GIT_EXEC_SUBCOMMANDS.has(args[0] ?? '')
|
|
}
|