Severity: high. Found by an adversarial-operator user test. Pre-existing.
An empty --repo falls through to the flag's default (.) rather than being rejected — the unset-variable bug every fleet script eventually has.
Repro
cd /tmp/cwdvictim
REPO="" # e.g. REPO=$(lookup_repo "$name") returned nothing
cot sync --repo "$REPO" --op 'add_owner(important.txt, @attacker/team)'
Observed: exit 0, and cwdvictim/.github/CODEOWNERS is modified. The emitted record carries "repo":"", so results.jsonl gets a success row that does not say which repository was changed.
A typo'd path fails correctly. The empty string is the one wrong value that gets a default instead of an error — and it is the value a shell produces by accident.
Suggested fix
Reject --repo "" at argument-parsing time (exit 3, repo-independent). . remains the default when the flag is absent.
Severity: high. Found by an adversarial-operator user test. Pre-existing.
An empty
--repofalls through to the flag's default (.) rather than being rejected — the unset-variable bug every fleet script eventually has.Repro
Observed: exit 0, and
cwdvictim/.github/CODEOWNERSis modified. The emitted record carries"repo":"", soresults.jsonlgets a success row that does not say which repository was changed.A typo'd path fails correctly. The empty string is the one wrong value that gets a default instead of an error — and it is the value a shell produces by accident.
Suggested fix
Reject
--repo ""at argument-parsing time (exit 3, repo-independent)..remains the default when the flag is absent.