Repository navigation
Description
Summary
When a source is already watched, add <source>@branch:other matches its watch record and installs the watched baseline, silently ignoring the typed branch requirement. The equivalent --branch other flag is rejected. The same user intent therefore has different behavior depending on syntax.
Code evidence at 5d4987b:
Sources/Core/RuntimeService.swift:235routes ordinary adds throughresolveSourceOrWatch.Sources/Core/WatchLedger.swift:737parses the input but compares only source identity when matching a watch.Sources/Core/RuntimeService.swift:782selects the watch before normal source resolution;:786checks only the separate requirement argument used by flags.Sources/Core/RuntimeService.swift:797chooses the watch baseline/reviewed commit, and:815reconstructs source data from the watch rather than the input selectors.
Reproduction
Executed at 5d4987b.
Run in Bash after cd "<checkout>" && swift build, replacing <checkout> with the absolute path of the checkout at this revision. Use a fresh reproduction directory. The commands isolate HOME, agent configuration, and XDG_*, and remove their fixture root on exit.
set -eu
checkout="<checkout>"
skill_bin="$checkout/.build/debug/skill"
repro_root="$checkout/.build/issue-repro-watch-routing"
mkdir -p "$repro_root/home" "$repro_root/tmp" "$repro_root/project"
trap 'rm -rf "$repro_root"' EXIT
isolated() {
env -i PATH="$PATH" HOME="$repro_root/home" \
CODEX_HOME="$repro_root/home/.codex" \
CLAUDE_CONFIG_DIR="$repro_root/home/.claude" \
XDG_CONFIG_HOME="$repro_root/home/.config" \
XDG_STATE_HOME="$repro_root/home/.local/state" \
XDG_CACHE_HOME="$repro_root/home/.cache" TMPDIR="$repro_root/tmp" \
GIT_CONFIG_NOSYSTEM=1 GIT_CONFIG_GLOBAL=/dev/null \
GIT_AUTHOR_NAME=Fixture [email protected] \
GIT_COMMITTER_NAME=Fixture [email protected] \
"$@"
}
skill() { isolated "$skill_bin" "$@"; }
write_skill() {
mkdir -p "$1"
printf -- '---\nname: %s\ndescription: Reproduction fixture\n---\n%s\n' "$2" "$3" > "$1/SKILL.md"
}
cd "$repro_root/project"
write_skill "$repro_root/source/skills/demo" demo watched-main
isolated git init -q -b main "$repro_root/source"
isolated git -C "$repro_root/source" add .
isolated git -C "$repro_root/source" commit -qm main
isolated git -C "$repro_root/source" checkout -qb other
write_skill "$repro_root/source/skills/demo" demo requested-other
isolated git -C "$repro_root/source" add .
isolated git -C "$repro_root/source" commit -qm other
isolated git -C "$repro_root/source" checkout -q main
skill add "$repro_root/source" --branch main --watch-only --skill demo --agent codex
skill add "$repro_root/source@branch:other" --skill demo --agent codex --mode copy
printf 'installed content: '
tail -1 .agents/skills/demo/SKILL.md
set +e
skill add "$repro_root/source" --branch other --skill demo --agent codex --mode copy
printf 'flag form exit: %s\n' "$?"Observed output (relevant lines; temporary paths shortened to <temp>):
watched source path skills/demo
installed demo for codex at <temp>/project/.agents/skills/demo
installed content: watched-main
Error: Invalid source: source requirement flags cannot be used with a watch source
flag form exit: 1
Expected Behavior
Parse and validate requirement intent before choosing the watch/source route. A requirement supplied in typed shorthand must not be silently discarded.
Maintainer decision: either treat an explicit source requirement as ordinary source resolution, or reject it consistently while the input resolves to a watch. Keep watch-ID-based installation and its reviewed-commit rules explicit.
Completion checks:
- Flag and shorthand forms for branch/revision/version requirements have equivalent results or errors.
- The two-branch fixture never reports success while ignoring
other. - Existing watch-ID installs continue to use their accepted baseline/reviewed commit.
- Cover both a local Git path and hosted-source parsing; run
swift test.
Actual Behavior
The shorthand add exits successfully and installs watched-main, even though the requested branch contains requested-other. The flag form exits 1. The executed fixture uses one source identity, so no identity collision is involved.
Related: #10 concerns scope, and #9 concerns inspection writes. This report concerns add routing and requirement validation within one project. No duplicate found.
Environment
- Source revision:
5d4987b(5d4987b9e1f94e8b9f85124299f05d5aa4f45f07). - CLI version:
0.2.1; built successfully withswift build. - Swift: Apple Swift 6.4 (
swiftlang-6.4.0.34.1,clang-2100.3.34.1). - OS: macOS 27.0.1 (26A434).
- Architecture: arm64.
- Git: 2.42.0. Validation date: 2026-10-17.
Activity
showxu commentedon Oct 18, 2026
Superseded by the design adopted in #29 (Watch). Watch is now a subscription that reports upstream changes; it no longer routes or gates installs, so shorthand requirements are resolved only by
addandupdate.