Skip to content

Commit 8e60f2f

Browse files
authored
fix(workflows,commands): preserve repo identity for issue URLs; unblock .archon fixes (#2417)
1 parent 7374a23 commit 8e60f2f

4 files changed

Lines changed: 131 additions & 27 deletions

File tree

.archon/commands/defaults/archon-fix-issue.md

Lines changed: 41 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,47 @@ created a git worktree on the correct branch. In that case:
2020
operator's `.archon/` directory — workflows, commands, scripts — into every run
2121
worktree, deliberately, so a workflow can be iterated on before it is committed.
2222
Those files are present *before* you start and are not your changes.
23-
- **Modifications under `.archon/` are never yours to commit, stash, or remove.**
24-
Leave them exactly as they are and commit only the files your implementation touched.
25-
Before every commit, confirm with `git diff --cached --name-only` that nothing under
26-
`.archon/` is staged.
23+
- **Pre-existing modifications under `.archon/` are never yours to commit, stash, or
24+
remove.** Leave them exactly as they are and commit only the files your implementation
25+
touched. Before every commit, confirm with `git diff --cached --name-only` that no
26+
`.archon/` file you did not deliberately change is staged.
27+
- **The exception: when the issue's fix genuinely lives under `.archon/`.** Workflows,
28+
commands and scripts are source too, and an issue can legitimately target one. If your
29+
plan says to edit a specific `.archon/` file, edit and commit **that file** — the rule
30+
above exists to stop you sweeping up the operator's unrelated copied-in edits, not to
31+
make a whole directory unfixable.
32+
33+
Distinguish the two by intent, not by path: a file your plan names is your work; every
34+
other dirty `.archon/` file is not. On 2026-08-03 a run blocked outright on this,
35+
correctly reporting "contradictory instructions" because the issue required editing a
36+
workflow YAML while this section forbade touching anything under `.archon/`. It was
37+
right to refuse rather than guess — and the rule was wrong to be absolute.
38+
39+
**A named file is not a blank cheque for that file.** It may already carry copied-in
40+
edits from before you started, and staging it whole would commit those too — the
41+
path-level check above cannot see inside a file. So before you touch a planned
42+
`.archon/` file, record its baseline:
43+
44+
```bash
45+
# HEAD, not the index: `git diff -- <file>` compares the worktree against the
46+
# INDEX, so pre-existing changes that are already STAGED do not appear — and
47+
# `git add -p` will neither show nor remove them, so they ride into your commit
48+
# invisibly. Diffing against HEAD captures staged and unstaged alike.
49+
git diff HEAD -- <the-planned-file> > /tmp/archon-baseline.diff # empty if clean
50+
```
51+
52+
Then, before staging anything of your own, clear that file out of the index so the
53+
only thing you can stage is what you deliberately pick:
54+
55+
```bash
56+
git restore --staged <the-planned-file> # no-op if nothing was staged
57+
git add -p <the-planned-file> # stage ONLY your own hunks
58+
```
59+
60+
Reject any hunk that also appears in the baseline. If yours and theirs are entangled
61+
such that you cannot separate them, stop and say so rather than committing someone
62+
else's work under your change. That is the same call the 2026-08-03 run made, and it
63+
was the right one.
2764
- **Dirty paths outside `.archon/` are also not a reason to stop, and also not yours.**
2865
They are either your own work from an earlier attempt at this run (resume reuses the
2966
worktree) or something the operator left behind. Either way: leave them alone, do not

.archon/workflows/defaults/archon-fix-github-issue.yaml

Lines changed: 44 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -31,22 +31,55 @@ nodes:
3131
3232
Request: $ARGUMENTS
3333
34-
Rules:
35-
- If the message contains an explicit issue number (e.g., "#709", "issue 709", "709"), extract that number.
36-
- If the message is ambiguous (e.g., "fix the SQLite timestamp bug"), use `gh issue list` to search for matching issues and pick the best match.
37-
38-
CRITICAL: Your final output must be ONLY the bare number with no quotes, no markdown, no explanation. Example correct output: 709
34+
A reference is an ATOMIC pair: a number, and the repo it belongs to. Never take the
35+
number from one reference and the repo from another — that combination fetches an
36+
issue nobody asked for.
37+
38+
Recognised reference forms, each yielding one complete pair:
39+
- `#709`, `issue 709`, `709` -> {issue_number: "709", repo: ""}
40+
- `owner/repo#709` -> {issue_number: "709", repo: "owner/repo"}
41+
- `https://github.com/owner/repo/issues/709`
42+
-> {issue_number: "709", repo: "owner/repo"}
43+
44+
An empty `repo` means "the current checkout" — the common case. NEVER guess a repo.
45+
46+
Then:
47+
- Exactly one reference -> use it.
48+
- Several references, all resolving to the SAME pair -> use it.
49+
- Several DIFFERENT references (e.g. a bare number and a cross-repo URL) -> the
50+
request is ambiguous. Do NOT pick one. Fail with a message naming every pair you
51+
found and asking which was meant. Guessing here silently investigates the wrong
52+
issue, which is worse than stopping.
53+
- No reference at all (e.g. "fix the SQLite timestamp bug") -> search the CURRENT
54+
repo with `gh issue list`, pick the best match, and leave `repo` empty.
55+
output_format:
56+
type: object
57+
properties:
58+
issue_number:
59+
type: string
60+
repo:
61+
type: string
62+
required:
63+
- issue_number
64+
- repo
3965

4066
- id: fetch-issue
4167
bash: |
42-
# $extract-issue-number.output is injected pre-quoted by Archon — do NOT
43-
# wrap it in double quotes (that corrupts the value; see issue #1884).
44-
ISSUE_NUM=$(echo $extract-issue-number.output | grep -oE '[0-9]+' | head -1)
45-
if [ -z "$ISSUE_NUM" ]; then
46-
echo "Failed to extract issue number from:" $extract-issue-number.output >&2
68+
# Substitutions are injected already shell-quoted by Archon — assign them
69+
# unquoted, then quote normally as locals (see #1884).
70+
num=$extract-issue-number.output.issue_number
71+
repo=$extract-issue-number.output.repo
72+
if ! printf '%s' "$num" | grep -qE '^[0-9]+$'; then
73+
echo "extract-issue-number did not yield a numeric issue id: $num" >&2
4774
exit 1
4875
fi
49-
gh issue view "$ISSUE_NUM" --json title,body,labels,comments,state,url,author
76+
# An explicit owner/repo must be preserved: `gh issue view <n>` resolves against
77+
# the CURRENT checkout, so a cross-repo URL would silently read this repo's #<n>.
78+
if [ -n "$repo" ]; then
79+
gh issue view "$num" --repo "$repo" --json title,body,labels,comments,state,url,author
80+
else
81+
gh issue view "$num" --json title,body,labels,comments,state,url,author
82+
fi
5083
depends_on: [extract-issue-number]
5184

5285
- id: classify

.archon/workflows/experimental/archon-fix-github-issue-experimental.yaml

Lines changed: 44 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -125,22 +125,56 @@ nodes:
125125
126126
Request: $ARGUMENTS
127127
128-
Rules:
129-
- If the message contains an explicit issue number (e.g., "#709", "issue 709", "709"), extract that number.
130-
- If the message is ambiguous (e.g., "fix the SQLite timestamp bug"), use `gh issue list` to search for matching issues and pick the best match.
131-
132-
CRITICAL: Your final output must be ONLY the bare number with no quotes, no markdown, no explanation. Example correct output: 709
128+
A reference is an ATOMIC pair: a number, and the repo it belongs to. Never take the
129+
number from one reference and the repo from another — that combination fetches an
130+
issue nobody asked for.
131+
132+
Recognised reference forms, each yielding one complete pair:
133+
- `#709`, `issue 709`, `709` -> {issue_number: "709", repo: ""}
134+
- `owner/repo#709` -> {issue_number: "709", repo: "owner/repo"}
135+
- `https://github.com/owner/repo/issues/709`
136+
-> {issue_number: "709", repo: "owner/repo"}
137+
138+
An empty `repo` means "the current checkout" — the common case. NEVER guess a repo.
139+
140+
Then:
141+
- Exactly one reference -> use it.
142+
- Several references, all resolving to the SAME pair -> use it.
143+
- Several DIFFERENT references (e.g. a bare number and a cross-repo URL) -> the
144+
request is ambiguous. Do NOT pick one. Fail with a message naming every pair you
145+
found and asking which was meant. Guessing here silently investigates the wrong
146+
issue, which is worse than stopping.
147+
- No reference at all (e.g. "fix the SQLite timestamp bug") -> search the CURRENT
148+
repo with `gh issue list`, pick the best match, and leave `repo` empty.
149+
output_format:
150+
type: object
151+
properties:
152+
issue_number:
153+
type: string
154+
repo:
155+
type: string
156+
required:
157+
- issue_number
158+
- repo
133159
model: small
134160

135161
- id: fetch-issue
136162
bash: |
137-
# Strip quotes, whitespace, markdown backticks from AI output
138-
ISSUE_NUM=$(echo "$extract-issue-number.output" | tr -d "'\"\`\n " | grep -oE '[0-9]+' | head -1)
139-
if [ -z "$ISSUE_NUM" ]; then
140-
echo "Failed to extract issue number from: $extract-issue-number.output" >&2
163+
# Substitutions are injected already shell-quoted by Archon — assign them
164+
# unquoted, then quote normally as locals (see #1884).
165+
num=$extract-issue-number.output.issue_number
166+
repo=$extract-issue-number.output.repo
167+
if ! printf '%s' "$num" | grep -qE '^[0-9]+$'; then
168+
echo "extract-issue-number did not yield a numeric issue id: $num" >&2
141169
exit 1
142170
fi
143-
gh issue view "$ISSUE_NUM" --json title,body,labels,comments,state,url,author
171+
# An explicit owner/repo must be preserved: `gh issue view <n>` resolves against
172+
# the CURRENT checkout, so a cross-repo URL would silently read this repo's #<n>.
173+
if [ -n "$repo" ]; then
174+
gh issue view "$num" --repo "$repo" --json title,body,labels,comments,state,url,author
175+
else
176+
gh issue view "$num" --json title,body,labels,comments,state,url,author
177+
fi
144178
depends_on: [extract-issue-number]
145179

146180
- id: classify

0 commit comments

Comments
 (0)