docs(bug-triage): retarget skill at the Go rewrite and upstream repo (#2339)

* docs(bug-triage): retarget skill at the Go rewrite and upstream repo

Rewrite the bug-triage skill for this repository: file issues/PRs on the
upstream AgentWrapper/agent-orchestrator, swap the Zellij runtime notes for
tmux (ConPTY on Windows), refresh the label list to match upstream, and drop
ReverbCode-specific naming. Port 3001, ~/.ao paths, and the CLI/daemon layout
are unchanged and were re-verified against backend/.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* chore: format with prettier [skip ci]

---------

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
This commit is contained in:
Harshit Singh Bhandari 2026-07-02 22:03:13 +05:30 committed by GitHub
parent e74fb65a85
commit 6186458df7
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
1 changed files with 104 additions and 93 deletions

View File

@ -6,53 +6,56 @@ trigger: User reports a bug, or asks to triage/file an issue for a reported prob
# Bug Triage Skill
Triage bugs into well-structured GitHub issues on the ReverbCode repo.
Triage bugs into well-structured GitHub issues on the upstream **`AgentWrapper/agent-orchestrator`** repo (issues are enabled there; the `origin` fork is not the issue tracker).
> **ReverbCode is Go + Electron.** The backend is a Go daemon (`backend/`)
> exposing a loopback HTTP API on `127.0.0.1:3001`; the frontend is an Electron +
> React supervisor (`frontend/`). There is **no** pm2/tmux/Node runtime here —
> the daemon owns lifecycle and sessions run under the **Zellij** runtime
> adapter. Triage against _this_ stack, not the old TypeScript agent-orchestrator.
> **Agent Orchestrator (AO) is Go + Electron.** The backend is a Go daemon
> (`backend/`) exposing a loopback HTTP API on `127.0.0.1:3001`; the frontend is an
> Electron + React supervisor (`frontend/`). There is **no** pm2/tmux-per-session
> Node runtime here: the daemon owns lifecycle and terminals run under the **tmux**
> runtime adapter (ConPTY on Windows). Triage against _this_ Go rewrite, not the old
> TypeScript agent-orchestrator implementation.
## ⚠️ Which `ao` are you running?
**`ReverbCode` ships no `ao` on your PATH.** A bare `ao` very likely resolves to a
**different** AO install — e.g. an old npm build at `~/.nvm/.../bin/ao` that talks
to port **:3000**. Triaging with the wrong binary produces bugs that don't exist
in ReverbCode (and miss ones that do).
**A bare `ao` on your PATH may resolve to a different AO install** (for example an
old npm build at `~/.nvm/.../bin/ao` that talks to port **:3000**). Triaging with
the wrong binary produces bugs that don't exist in this rewrite (and misses ones
that do).
Before any diagnostics:
```bash
which -a ao # see every ao on PATH expect surprises
ao status 2>/dev/null # if this shows port 3000, it is NOT ReverbCode
which -a ao # see every ao on PATH; expect surprises
ao status 2>/dev/null # if this shows port 3000, it is NOT this rewrite
```
Use a ReverbCode binary explicitly:
Use a rewrite binary explicitly:
```bash
# Option A build from this repo (preferred during triage)
# Option A: build from this repo (preferred during triage)
cd backend && go build -o /tmp/ao ./cmd/ao
/tmp/ao status # must report port: 3001
# Option B the packaged app's bundled daemon
# Option B: the packaged app's bundled daemon
"/Applications/Agent Orchestrator.app/Contents/Resources/daemon/ao" status
```
**Confirm `ao status` reports `port: 3001` before trusting any output.** Throughout
this skill, `ao` means _your verified ReverbCode binary_ (`/tmp/ao` or the bundled
this skill, `ao` means _your verified rewrite binary_ (`/tmp/ao` or the bundled
one), never a bare PATH lookup.
> Note: spawned sessions get a PATH pin so the _session's_ `ao` resolves to the
> daemon's own executable (see `hookPATH` in
> `backend/internal/session_manager/manager.go`). That pin only applies inside
> sessions your interactive shell is still on its own PATH, so pin it yourself.
> sessions; your interactive shell is still on its own PATH, so pin it yourself.
## 1. Pre-flight
- **Pull latest code:** `git pull origin main`. Stale code = bad triage.
- **Target repo:** Always file on **`aoagents/ReverbCode`** (the product repo, not
a fork). ReverbCode is the product, not a thin fork of upstream.
- **Pull latest code:** `git fetch upstream && git log --oneline upstream/main -5`.
Stale code means bad triage. (`upstream` = `AgentWrapper/agent-orchestrator`.)
- **Target repo:** Always file on **`AgentWrapper/agent-orchestrator`** (the upstream
product repo, where issues live). Never file on the `origin` fork or on
`aoagents/*`.
- **Verify your binary:** confirm `ao status` shows port **3001** (see warning above).
- **Record source:** chat URL, reporter name, attachments.
@ -63,7 +66,7 @@ one), never a bare PATH lookup.
| Source | How to gather |
| ------------------------ | ------------------------------------------------------------------------------------------------------------------------------------ |
| **Discord/Slack thread** | Read full thread. Extract: reporter name, original description (the thread starter, not whoever tagged you), screenshots, follow-ups |
| **GitHub issue** | `gh issue view <number> --repo aoagents/ReverbCode --json body,comments` |
| **GitHub issue** | `gh issue view <number> --repo AgentWrapper/agent-orchestrator --json body,comments` |
| **Live observation** | Pull live state via the daemon: `ao status`, `ao session ls`, `ao session get <id>` |
### 2b. Minimum viable report gate
@ -81,7 +84,7 @@ If insufficient, ask:
### 2c. Local diagnostics (if bug is on same machine)
Gather everything yourself before asking the reporter. Use your **verified**
ReverbCode binary (`/tmp/ao` here) for every `ao` call:
rewrite binary (`/tmp/ao` here) for every `ao` call:
```bash
# Environment
@ -98,7 +101,7 @@ tail -n 100 ~/.ao/daemon.log # daemon log
# Sessions & runtime
/tmp/ao session ls # all sessions and their state
/tmp/ao session get <id> # one session: spawn config, runtime, lifecycle
zellij list-sessions # Zellij runtime sessions backing terminals
tmux ls # tmux runtime sessions backing terminals (macOS/Linux)
# Durable state (SQLite at ~/.ao/data)
sqlite3 ~/.ao/data/ao.db '.tables' # inspect schema/rows if state looks wrong
@ -115,49 +118,52 @@ handshake is `~/.ao/running.json`.
### 3a. Trace the code path
**Always trace the actual code** — don't surface-level diagnose. A symptom that
**Always trace the actual code**; do not surface-level diagnose. A symptom that
looks like a simple `ao stop` issue is often a lifecycle/session-manager problem
one layer down. ReverbCode's layers:
one layer down. The layers:
- CLI (Cobra, thin client over daemon HTTP): `backend/internal/cli/`, entrypoint
`backend/cmd/ao/main.go`
- Daemon (loopback HTTP on :3001): `backend/internal/daemon/daemon.go`,
controllers under `backend/internal/httpd/controllers/`
- Sessions & lifecycle: `backend/internal/session_manager/manager.go`
- Runtime adapter (Zellij): `backend/internal/adapters/runtime/`
- Runtime adapter (tmux / ConPTY): `backend/internal/adapters/runtime/`
(`tmux/`, `conpty/`, `ptyexec/`, selected by `runtimeselect/`)
- Agent harness adapters: `backend/internal/adapters/agent/<harness>/`
- Terminal mux: `backend/internal/terminal/`
- Agent hooks: `backend/internal/cli/hooks.go`
```bash
git fetch origin main && git log --oneline origin/main -5 # current HEAD
git fetch upstream main && git log --oneline upstream/main -5 # current HEAD
# Record the commit hash you're analyzing against
```
**Git archaeology** find which commits introduced/removed specific code:
**Git archaeology**: find which commits introduced/removed specific code:
```bash
git log --oneline -S 'exact-string' -- <file>
git show <sha> -- <file> | grep -B 5 -A 10 'pattern'
```
**Research dependencies** (Zellij, the agent harness binary, Electron, React, the
SQLite driver) check installed vs latest version, search their issue trackers,
check changelogs. Root cause is sometimes in a dependency, not ReverbCode.
**Research dependencies** (tmux, the agent harness binary, Electron, React, the
SQLite driver): check installed vs latest version, search their issue trackers,
check changelogs. Root cause is sometimes in a dependency, not AO itself.
### 3b. Cross-platform check
AO targets **macOS, Linux, and Windows**. If env info indicates Windows (or is
unknown), check for these patterns:
- **Path separators** — hardcoded `/` or `\`; use `filepath.Join`, not string concat
- **Shell syntax** — PowerShell lacks `&&`, `$VAR`, `$(cat ...)`, `/dev/null`, here-docs
- **`runtime.GOOS == "windows"` scattered inline** — centralize platform checks
- **Process-tree kills** — POSIX process groups vs Windows job objects
- **`localhost`** — Windows resolves to `::1` first; the daemon binds the explicit
- **Path separators**: hardcoded `/` or `\`; use `filepath.Join`, not string concat
- **Shell syntax**: PowerShell lacks `&&`, `$VAR`, `$(cat ...)`, `/dev/null`, here-docs
- **`runtime.GOOS == "windows"` scattered inline**: centralize platform checks
- **Runtime backend**: tmux on macOS/Linux vs ConPTY on Windows
(`runtimeselect` picks per platform); Windows has no tmux
- **Process-tree kills**: POSIX process groups vs Windows job objects
- **`localhost`**: Windows resolves to `::1` first; the daemon binds the explicit
loopback host (see `config.LoopbackHost`) to avoid IPv4/IPv6 stalls
- **Case-insensitive filesystems** — don't compare paths with raw `==`
- **PATH / binary resolution** `.exe`/`PATHEXT` lookup, the session PATH pin
- **Case-insensitive filesystems**: do not compare paths with raw `==`
- **PATH / binary resolution**: `.exe`/`PATHEXT` lookup, the session PATH pin
(`hookPATH` in `backend/internal/session_manager/manager.go`)
Key files: `backend/internal/config/config.go`, `backend/internal/session_manager/manager.go`,
@ -167,26 +173,26 @@ Key files: `backend/internal/config/config.go`, `backend/internal/session_manage
Stop and ask for more info if:
- **3 failed hypotheses** traced 3 code paths, none explain it
- **Root cause is a dependency** file with the dependency reference, don't guess a local fix
- **UI-only bug** and you can't screenshot ask reporter to describe
- **Can't reproduce** ask for different config/sequence
- **3 failed hypotheses**: traced 3 code paths, none explain it
- **Root cause is a dependency**: file with the dependency reference, don't guess a local fix
- **UI-only bug** and you can't screenshot, ask reporter to describe
- **Can't reproduce**: ask for different config/sequence
## 4. Search for Duplicates
Search with multiple strategies, always using `--state all` (closed bugs regress):
```bash
gh issue list --repo aoagents/ReverbCode --state all --search "<symptom>"
gh issue list --repo aoagents/ReverbCode --state all --search "<component-name>"
gh issue list --repo aoagents/ReverbCode --state all --search "<error-message>"
gh pr list --repo aoagents/ReverbCode --state all --search "<keywords>"
gh issue list --repo AgentWrapper/agent-orchestrator --state all --search "<symptom>"
gh issue list --repo AgentWrapper/agent-orchestrator --state all --search "<component-name>"
gh issue list --repo AgentWrapper/agent-orchestrator --state all --search "<error-message>"
gh pr list --repo AgentWrapper/agent-orchestrator --state all --search "<keywords>"
```
### Duplicate found → comment on existing issue
```bash
gh issue comment <number> --repo aoagents/ReverbCode --body "$(cat <<'EOF'
gh issue comment <number> --repo AgentWrapper/agent-orchestrator --body "$(cat <<'EOF'
## New Report
**Reported by:** @<reporter> in [chat](<url>)
**Date:** <YYYY-MM-DD> | **Checkout:** `<commit-hash>`
@ -204,7 +210,7 @@ EOF
- [ ] Reporter attribution correct (original reporter, not who tagged you)
- [ ] Commit hash recorded
- [ ] AO version recorded (`ao version`)
- [ ] Reproduced against ReverbCode (:3001 / Go code path), not another AO install
- [ ] Reproduced against the rewrite (:3001 / Go code path), not another AO install
- [ ] Root cause confidence scored (see 5c)
- [ ] Related issues cross-linked
- [ ] Reproduction steps are concrete
@ -217,23 +223,23 @@ EOF
```bash
SLUG="descriptive-slug"
# Create asset branch
gh api -X POST repos/aoagents/ReverbCode/git/refs \
gh api -X POST repos/AgentWrapper/agent-orchestrator/git/refs \
-f ref="refs/heads/issue-assets-${SLUG}" \
-f sha=$(git rev-parse origin/main)
-f sha=$(git rev-parse upstream/main)
# Upload (portable base64)
IMG_B64=$(base64 < /path/to/screenshot.png | tr -d '\n')
gh api -X PUT "repos/aoagents/ReverbCode/contents/.issue-assets/${SLUG}/name.png" \
gh api -X PUT "repos/AgentWrapper/agent-orchestrator/contents/.issue-assets/${SLUG}/name.png" \
-f message="chore: upload screenshot" \
-f content="$IMG_B64" \
-f branch="issue-assets-${SLUG}"
# Use: ![screenshot](https://raw.githubusercontent.com/aoagents/ReverbCode/issue-assets-<slug>/.issue-assets/<file>)
# Use: ![screenshot](https://raw.githubusercontent.com/AgentWrapper/agent-orchestrator/issue-assets-<slug>/.issue-assets/<file>)
```
### 5c. Create the issue
```bash
gh issue create --repo aoagents/ReverbCode --title "<title>" --body "$(cat <<'EOF'
gh issue create --repo AgentWrapper/agent-orchestrator --title "<title>" --body "$(cat <<'EOF'
## Bug
<summary>
@ -260,16 +266,19 @@ EOF
**Check which labels actually exist first**, then apply only those:
```bash
gh label list --repo aoagents/ReverbCode # source of truth — apply only these
gh issue edit <number> --repo aoagents/ReverbCode --add-label "bug"
gh label list --repo AgentWrapper/agent-orchestrator # source of truth; apply only these
gh issue edit <number> --repo AgentWrapper/agent-orchestrator --add-label "bug"
```
The repo currently carries `bug`, `enhancement`, `priority: critical/high/medium/low`,
lane labels (`daemon`, `frontend`, `storage`, `coding-agents`, `lcm-sm`, `scm`,
`core`, `port`, `adapter`, `domain`), and workflow labels (`needs-triage`,
`needs-review`, `blocked`). **Do not invent labels** — if a priority or confidence
label you want doesn't exist, **state it in the issue body instead** (e.g.
"**Priority:** high — core feature broken, no workaround" / "**Confidence:** medium").
The repo currently carries `bug`, `enhancement`, `documentation`, `question`,
`priority: critical/high/medium/low` (plus the hyphen-free `priority:high` /
`priority:medium` variants), status labels (`todo`, `in-progress`, `review`,
`blocked`, `verify-if-fixed`, `to-reproduce`, `to-explore`), `sub-issue`,
`ready-for-agent`, `good-first-issue`, `help wanted`, and `upstream complication`
(for bugs rooted in Claude Code / Codex / tmux etc.). **Do not invent labels**: if
a priority or confidence label you want doesn't exist, **state it in the issue body
instead** (e.g. "**Priority:** high: core feature broken, no workaround" /
"**Confidence:** medium").
| Priority | Criteria |
| -------------------- | ----------------------------------- |
@ -292,27 +301,27 @@ Search by subsystem and add a `## Related` section to the issue body:
```
## Related
- [#20](url) stale session blocking ao start (same subsystem)
- [#35](url) same race condition
- [#20](url): stale session blocking ao start (same subsystem)
- [#35](url): same race condition
```
### 5f. Push a fix PR (always attempt)
ReverbCode is a Go repo — fixes go through a local branch, build, and `gh pr create`.
There is no remote-patch script.
This is a Go repo: fixes go through a local branch, build, and `gh pr create`
against upstream. There is no remote-patch script. Branch off `upstream/main`.
- **Unclear fix:** Don't push a guess. Document and flag in the issue.
- **Trivial, verifiable fix** (you can build and test it yourself):
```bash
git checkout -b fix/<slug> origin/main
git fetch upstream main && git checkout -b fix/<slug> upstream/main
# make the edit
cd backend && go build ./... && go test ./... # must pass before pushing
git commit -am "fix(<scope>): <summary>
Fixes #<n>"
git push -u origin fix/<slug>
gh pr create --repo aoagents/ReverbCode --fill \
gh pr create --repo AgentWrapper/agent-orchestrator --fill \
--title "fix(<scope>): <summary>" \
--body "Fixes #<n>
@ -324,13 +333,13 @@ There is no remote-patch script.
```
- **Non-trivial fix** (broad change, needs iteration, or you can't fully verify):
spawn a ReverbCode worker session to do the work in its own worktree instead of
pushing a guess:
spawn a worker session to do the work in its own worktree instead of pushing a
guess:
```bash
ao spawn --project reverbcode --prompt "Fix #<n>: <one-line problem statement>. \
Root cause: <file:line + mechanism>. Suggested approach: <approach>. \
Build with 'cd backend && go build ./... && go test ./...' before opening a PR against aoagents/ReverbCode."
ao spawn --project agent-orchestrator --prompt "Fix #<n>: <one-line problem statement>. \
Root cause: <file:line + mechanism>. Suggested approach: <approach>. Branch off upstream/main. \
Build with 'cd backend && go build ./... && go test ./...' before opening a PR against AgentWrapper/agent-orchestrator."
```
Note the issue with which path you took (PR or spawned worker).
@ -351,7 +360,7 @@ any priority/confidence stated in the body), root cause summary.
| **CLI** (`ao start/stop/spawn`) | Version, install method, OS, which binary | `backend/internal/cli/`, `backend/cmd/ao/main.go` |
| **Daemon / HTTP API** | `ao status`, port, daemon.log | `backend/internal/daemon/daemon.go`, `backend/internal/httpd/controllers/` |
| **Sessions / Lifecycle** | Session ID, spawn config, runtime, state | `backend/internal/session_manager/manager.go` |
| **Runtime (Zellij)** | Zellij version, `zellij list-sessions` | `backend/internal/adapters/runtime/` |
| **Runtime (tmux / ConPTY)** | tmux version, `tmux ls` (macOS/Linux) | `backend/internal/adapters/runtime/` |
| **Terminal mux** | Runtime type, shell, attach behavior | `backend/internal/terminal/` |
| **Agent harness** | Harness name + version | `backend/internal/adapters/agent/<harness>/` |
| **Storage** | DB state, migrations | `backend/internal/storage/sqlite/`, `~/.ao/data/ao.db` |
@ -360,10 +369,10 @@ any priority/confidence stated in the body), root cause summary.
**Misrouting patterns:**
- Terminal bugs → Zellij runtime adapter vs the terminal mux vs the Electron xterm
surface. Trace where bytes flow (daemon → mux → frontend).
- Terminal bugs → tmux/ConPTY runtime adapter vs the terminal mux vs the Electron
xterm surface. Trace where bytes flow (daemon → mux → frontend).
- "Session stuck" → lifecycle/session-manager state vs agent harness process vs
Zellij runtime connection.
tmux runtime connection.
- "Config not saving" → config loading (`backend/internal/config/config.go`) vs
project registration vs SQLite write (`~/.ao/data/ao.db`).
- "Command does nothing / wrong port" → you're on the wrong `ao` binary (:3000 vs
@ -372,47 +381,49 @@ any priority/confidence stated in the body), root cause summary.
### B. Remote Code Inspection (no local clone)
```bash
gh api repos/aoagents/ReverbCode/git/trees/main?recursive=1 --jq '.tree[].path' # list files
gh api repos/aoagents/ReverbCode/contents/{path} --jq '.content' | python3 -c "import base64,sys; sys.stdout.buffer.write(base64.b64decode(sys.stdin.read()))" # read file
gh search code "term" --repo aoagents/ReverbCode --json path --jq '.[].path' # search code
gh api "repos/aoagents/ReverbCode/commits?path={path}&per_page=10" --jq '.[] | "\(.sha[0:8]) \(.commit.message | split("\n")[0])"' # file history
gh api repos/AgentWrapper/agent-orchestrator/git/trees/main?recursive=1 --jq '.tree[].path' # list files
gh api repos/AgentWrapper/agent-orchestrator/contents/{path} --jq '.content' | python3 -c "import base64,sys; sys.stdout.buffer.write(base64.b64decode(sys.stdin.read()))" # read file
gh search code "term" --repo AgentWrapper/agent-orchestrator --json path --jq '.[].path' # search code
gh api "repos/AgentWrapper/agent-orchestrator/commits?path={path}&per_page=10" --jq '.[] | "\(.sha[0:8]) \(.commit.message | split("\n")[0])"' # file history
```
### C. Build / Version Diagnostics
ReverbCode is built from source, not published to npm. Pin the binary under test
and reproduce against a known build:
AO is built from source in this rewrite, not published to npm. Pin the binary under
test and reproduce against a known build:
```bash
cd backend && go build -o /tmp/ao ./cmd/ao # build the binary under test
/tmp/ao version # record version/commit
go version # toolchain (build issues are often here)
git log --oneline origin/main -1 # the commit you're analyzing against
git log --oneline upstream/main -1 # the commit you're analyzing against
```
To bisect a regression, build `ao` at two commits and compare behavior:
```bash
git stash; git checkout <good-sha>; (cd backend && go build -o /tmp/ao-good ./cmd/ao)
git checkout <good-sha>; (cd backend && go build -o /tmp/ao-good ./cmd/ao)
git checkout <bad-sha>; (cd backend && go build -o /tmp/ao-bad ./cmd/ao)
git checkout - ; git stash pop
git checkout -
# run the repro against /tmp/ao-good vs /tmp/ao-bad
```
## Formatting Rules
- **Linkify all issue/PR refs:** `[#123](https://github.com/aoagents/ReverbCode/issues/123)`, `[PR #456](url)`. Never bare `#123`.
- **Linkify all issue/PR refs:** `[#123](https://github.com/AgentWrapper/agent-orchestrator/issues/123)`, `[PR #456](url)`. Never bare `#123`.
## Pitfalls
- **Wrong `ao` binary.** A bare `ao` may be a different AO install (old npm build on
:3000). Always pin a ReverbCode binary and confirm `ao status` shows port **3001**.
- **Verify the bug reproduces against ReverbCode (:3001 / Go code path) before
filing** — symptoms first seen in another AO install may not reproduce here.
:3000). Always pin a rewrite binary and confirm `ao status` shows port **3001**.
- **Verify the bug reproduces against the rewrite (:3001 / Go code path) before
filing** (symptoms first seen in another AO install may not reproduce here).
- **File on upstream, not the fork.** Issues go to `AgentWrapper/agent-orchestrator`;
`origin` is a personal fork with no issue tracker.
- **Reporter ≠ person who tagged you.** Always attribute to the original reporter.
- **Record the commit hash** you analyzed — code changes fast.
- **GitHub issue is mandatory** every triaged bug gets one, even if fix is trivial.
- **Only apply labels that exist** (`gh label list --repo aoagents/ReverbCode`).
- **Record the commit hash** you analyzed; code changes fast.
- **GitHub issue is mandatory**: every triaged bug gets one, even if fix is trivial.
- **Only apply labels that exist** (`gh label list --repo AgentWrapper/agent-orchestrator`).
State priority/confidence in the body when no matching label exists.
- **Build before you push.** `cd backend && go build ./... && go test ./...` must
pass; never open a PR with an unverified Go change.