Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
64 changes: 64 additions & 0 deletions .semgrep/architecture.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -1001,3 +1001,67 @@ rules:
metadata:
category: architecture
violation: socket-churn

# ---------------------------------------------------------------------------
# 11. PR cache enforcement: daemon must use cached/batched PR lookups
#
# The daemon MUST NOT call uncached PR lookup functions directly.
# These functions shell out to `gh` CLI on every call with no caching,
# which exhausts the GitHub API rate limit (5000/hr) with just ~4 active runs.
#
# Allowed: pr.PopulateRunInfo() / pr.PopulateRunInfoWithClient() — batched + cached
# Banned: pr.LookupInfo() / pr.LookupInfoByURL() / pr.LookupInfoWithClient()
#
# Tracked by: orch-450
# ---------------------------------------------------------------------------

- id: daemon-no-uncached-pr-lookup
patterns:
- pattern-either:
- pattern: pr.LookupInfo(...)
- pattern: pr.LookupInfoWithClient(...)
paths:
include:
- /internal/daemon/
exclude:
- /internal/daemon/*_test.go
# Known debt (orch-450) — remove exclusions as each file is fixed
- /internal/daemon/monitor.go
- /internal/daemon/types.go
- /internal/daemon/proto_handler.go
message: >
Daemon must not call pr.LookupInfo() or pr.LookupInfoWithClient() directly.
These bypass the PR cache and shell out to `gh pr list` on every call,
exhausting the GitHub API rate limit (5000/hr).
Fix: Use pr.PopulateRunInfo() or pr.PopulateRunInfoWithClient() which
batch lookups and respect cache TTLs (cacheHitTTL, cacheMissTTL, cacheMaxFetches).
See: orch-450
severity: ERROR
languages: [go]
metadata:
category: architecture
violation: rate-limit-bypass

- id: daemon-no-uncached-pr-lookup-by-url
patterns:
- pattern: pr.LookupInfoByURL(...)
paths:
include:
- /internal/daemon/
exclude:
- /internal/daemon/*_test.go
# Known debt (orch-450) — remove exclusions as each file is fixed
- /internal/daemon/monitor.go
- /internal/daemon/types.go
- /internal/daemon/proto_handler.go
message: >
Daemon must not call pr.LookupInfoByURL() directly.
This bypasses the PR cache and shells out to `gh pr view` on every call,
exhausting the GitHub API rate limit (5000/hr).
Fix: Use a cache-aware lookup that respects TTLs, or batch via PopulateRunInfo.
See: orch-450
severity: ERROR
languages: [go]
metadata:
category: architecture
violation: rate-limit-bypass
16 changes: 8 additions & 8 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,14 +28,14 @@ When your PR has conflicts with main after other PRs are merged:

### Preferred Approach: Rebase via Feedback

1. **DO**: Use `orch send <run_id> "rebase message"` to send feedback to the blocked run
1. **DO**: Use `orch send <run_id> "rebase message"` to send feedback to the waiting run
2. **DO**: Let the agent resolve conflicts in its existing session context
3. **DO**: Wait for the agent to force push the rebased branch

### Avoid

1. **DON'T**: Close the PR and restart the run from scratch
2. **DON'T**: Cancel the run just because it's blocked
2. **DON'T**: Cancel the run just because it's waiting
3. **DON'T**: Manually resolve conflicts when the agent can do it

### Why This Matters
Expand All @@ -48,9 +48,9 @@ When your PR has conflicts with main after other PRs are merged:
### Example

```bash
# Run is blocked with conflicts
# Run is waiting with conflicts
orch ps
# Shows: 75731b orch-383 block conflict
# Shows: 75731b orch-383 wait conflict

# Send feedback to resume
orch send 75731b "Your PR has conflicts with main. Please run: git fetch origin main && git rebase origin/main - then resolve conflicts and force push."
Expand All @@ -66,13 +66,13 @@ orch send 75731b "Your PR has conflicts with main. Please run: git fetch origin
## Run Lifecycle

```
queued → booting → running ⟷ blocked → done
queued → booting → running ⟷ waiting → done
↓ ↓
fail cancel
```

- `blocked`: Run is waiting for user input (use `orch send`)
- `blocked_api`: Run is waiting for API response
- `waiting`: Run is waiting for user input (use `orch send`)
- `rate_limited`: Run is waiting for API response
- `done`: Run completed successfully
- `fail`: Run encountered an error
- `cancel`: Run was manually cancelled
Expand Down Expand Up @@ -119,7 +119,7 @@ Existing violations are tracked; do not add new ones.

### "Connection refused" when using `orch send`

The opencode server may have stopped while the run shows as "blocked".
The opencode server may have stopped while the run shows as "waiting".
- Check if the run is actually alive: look at the ALIVE column in `orch ps`
- If server stopped, use `orch continue <id>` to restart

Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ orch attach my-task
- **Issue**: A task specification (markdown file or external ticket)
- **Run**: One execution attempt for an issue (isolated worktree + branch)
- **Event**: Append-only log entry tracking run progress
- **Status**: Current state derived from events (running, blocked, done, etc.)
- **Status**: Current state derived from events (running, waiting, done, etc.)

```
User runs: orch run my-issue
Expand All @@ -99,7 +99,7 @@ User interacts: orch attach my-issue
| Status | Meaning | User Action |
|--------|---------|-------------|
| `running` | Agent is working | Wait, or attach to watch |
| `blocked` | Agent needs input | `orch attach` to help |
| `waiting` | Agent needs input | `orch attach` to help |
| `pr_open` | PR created | Review the PR |
| `done` | Completed | Celebrate! |
| `failed` | Error occurred | Check logs, retry |
Expand Down
114 changes: 85 additions & 29 deletions api/orch.pb.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions api/orch.proto
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@ enum RunStatus {
RUN_STATUS_QUEUED = 1;
RUN_STATUS_BOOTING = 2;
RUN_STATUS_RUNNING = 3;
RUN_STATUS_BLOCKED = 4;
RUN_STATUS_BLOCKED_API = 5;
RUN_STATUS_WAITING = 4;
RUN_STATUS_RATE_LIMITED = 5;
RUN_STATUS_PR_OPEN = 6;
RUN_STATUS_DONE = 7;
RUN_STATUS_FAILED = 8;
Expand Down
Loading
Loading