Skip to content
Merged
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
13 changes: 8 additions & 5 deletions MISSION.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,11 +56,12 @@ You are working on GitHub issue `{{ issue.identifier }}`: {{ issue.title }}
You are working in a git worktree on branch `mission/{{ issue.identifier | downcase }}`.

1. **Read project guidelines** β€” check for AGENTS.md, CLAUDE.md, or similar files first.
2. **Post your workpad** β€” use your mission tools to post a plan on the issue before writing code.
3. **Understand the codebase** β€” explore the relevant code before making changes.
4. **Implement** β€” make focused, minimal changes. Run tests and linters.
5. **Commit** β€” keep commits clean and atomic. Update your workpad as you go.
6. **Create a PR** targeting `main` when complete. Attach it to the issue.
2. **Sync with latest `main`** β€” before writing code, fetch the latest changes and rebase your worktree branch onto `origin/main` (or the configured base branch). Prefer `git pull --rebase` / `git fetch` + `git rebase`. Do not create merge commits.
3. **Post your workpad** β€” use your mission tools to post a plan on the issue before writing code.
4. **Understand the codebase** β€” explore the relevant code before making changes.
5. **Implement** β€” make focused, minimal changes. Run tests and linters.
6. **Commit** β€” keep commits clean and atomic. Update your workpad as you go.
7. **Create a PR** targeting `main` when complete. Attach it to the issue.

## Rules

Expand All @@ -69,4 +70,6 @@ You are working in a git worktree on branch `mission/{{ issue.identifier | downc
- Do not expand scope. File follow-up issues for anything tangential.
- Keep the workpad updated β€” it is the primary way humans track your progress.
- Use gitmoji in commit messages and PR titles (e.g. ✨, πŸ›, ♻️, πŸ”§).
- Prefer rebases over merges when syncing with the base branch.
- **NEVER create merge commits.** Keep mission branches linear.
- **NEVER merge PRs.** Create the PR, verify CI passes, and address any review feedback β€” but leave merging to a human.
20 changes: 18 additions & 2 deletions orbitdock-server/crates/connector-claude/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -589,9 +589,25 @@ impl ClaudeConnector {
if allow_bypass_permissions {
args.push("--allow-dangerously-skip-permissions");
}
let allowed_joined = allowed_tools.join(",");

// When permission_mode is "acceptEdits", ensure edit tools are explicitly
// in the allowedTools list. The --permission-prompt-tool stdio flag routes
// ALL permission decisions through the control protocol, so the CLI's
// internal --permission-mode auto-accept logic may not fire. Passing them
// as --allowedTools guarantees the CLI pre-approves them.
let mut effective_allowed: Vec<String> = allowed_tools.to_vec();
if permission_mode == Some("acceptEdits") {
for tool in ["Edit", "Write", "NotebookEdit"] {
let tool_str = tool.to_string();
if !effective_allowed.contains(&tool_str) {
effective_allowed.push(tool_str);
}
}
}

let allowed_joined = effective_allowed.join(",");
let disallowed_joined = disallowed_tools.join(",");
if !allowed_tools.is_empty() {
if !effective_allowed.is_empty() {
args.extend(["--allowedTools", &allowed_joined]);
}
if !disallowed_tools.is_empty() {
Expand Down
5 changes: 5 additions & 0 deletions orbitdock-server/crates/server/src/domain/git/repo.rs
Original file line number Diff line number Diff line change
Expand Up @@ -257,6 +257,11 @@ pub async fn delete_remote_branch(repo_path: &str, branch: &str) -> Result<(), S
run_git_checked(&["push", "origin", "--delete", branch], repo_path).await
}

/// Fetch the latest refs from `origin`.
pub async fn fetch_origin(repo_path: &str) -> Result<(), String> {
run_git_checked(&["fetch", "origin"], repo_path).await
}

/// Initialize a new git repository at the given path.
pub async fn git_init(path: &str) -> Result<(), String> {
run_git_checked(&["init"], path).await
Expand Down
13 changes: 12 additions & 1 deletion orbitdock-server/crates/server/src/domain/instructions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,17 @@ multiple comments. One living document.
- Use `mission_report_blocked` only for true blockers (missing auth, secrets, permissions)
- Create a PR when complete, then use `mission_link_pr` to attach it to the issue
- **NEVER merge PRs.** After opening the PR, check CI status and address review feedback β€” but leave merging to a human.
- If you discover out-of-scope work, use `mission_create_followup` instead of expanding scope"#
- If you discover out-of-scope work, use `mission_create_followup` instead of expanding scope

## Git Workflow

Your worktree is automatically based on the latest remote base branch at dispatch time.
Keep your branch linear β€” **never create merge commits**.

- Sync with base branch: `git fetch origin && git rebase origin/main` (or the configured base branch)
- Prefer `git pull --rebase` over `git pull`
- If you need to stay current mid-work: `git fetch origin && git rebase origin/main`
- **NEVER** run `git merge` β€” always rebase
- Keep commits clean and atomic"#
.to_string()
}
Original file line number Diff line number Diff line change
Expand Up @@ -82,18 +82,22 @@ You are working on {issue_label} `{{{{ issue.identifier }}}}`: {{{{ issue.title
You are working in a git worktree on branch `mission/{{{{ issue.identifier | downcase }}}}`.

1. **Read project guidelines** β€” check for AGENTS.md, CLAUDE.md, or similar files first.
2. **Post your workpad** β€” use your mission tools to post a plan on the issue before writing code.
3. **Understand the codebase** β€” explore the relevant code before making changes.
4. **Implement** β€” make focused, minimal changes. Run tests and linters.
5. **Commit** β€” keep commits clean and atomic. Update your workpad as you go.
6. **Create a PR** targeting `main` when complete. Attach it to the issue.
2. **Sync with latest `main`** β€” before writing code, fetch the latest changes and rebase your worktree branch onto `origin/main` (or the configured base branch). Prefer `git pull --rebase` / `git fetch` + `git rebase`. Do not create merge commits.
3. **Post your workpad** β€” use your mission tools to post a plan on the issue before writing code.
4. **Understand the codebase** β€” explore the relevant code before making changes.
5. **Implement** β€” make focused, minimal changes. Run tests and linters.
6. **Commit** β€” keep commits clean and atomic. Update your workpad as you go.
7. **Create a PR** targeting `main` when complete. Attach it to the issue.

## Rules

- Work autonomously end-to-end. Do not ask for human follow-up.
- Stop early only for true blockers (missing auth, permissions, secrets).
- Do not expand scope. File follow-up issues for anything tangential.
- Keep the workpad updated β€” it is the primary way humans track your progress.
- Prefer rebases over merges when syncing with the base branch.
- **NEVER create merge commits.** Keep mission branches linear.
- **NEVER merge PRs.** Create the PR, verify CI passes, and address any review feedback β€” but leave merging to a human.
"#
)
}
Expand Down
17 changes: 16 additions & 1 deletion orbitdock-server/crates/server/src/runtime/mission_dispatch.rs
Original file line number Diff line number Diff line change
Expand Up @@ -89,12 +89,27 @@ pub async fn dispatch_issue(
);
}

// Fetch latest refs so the worktree starts from the current remote HEAD
if let Err(err) = crate::domain::git::repo::fetch_origin(&ctx.repo_root).await {
warn!(
component = "mission_control",
event = "dispatch.fetch_failed",
mission_id = %mission_id,
issue_id = %issue.id,
error = %err,
"git fetch origin failed β€” worktree will use local state"
);
}

// Use origin/<base_branch> so the worktree is based on the freshly-fetched remote ref
let remote_base = format!("origin/{}", ctx.base_branch);

// Create worktree via the runtime helper (also persists the record)
let worktree_path = match crate::runtime::worktree_creation::create_tracked_worktree(
registry,
&ctx.repo_root,
&branch_name,
Some(&ctx.base_branch),
Some(&remote_base),
orbitdock_protocol::WorktreeOrigin::Agent,
ctx.worktree_root_dir.as_deref(),
true, // always clean up stale worktrees β€” if we're dispatching, no active session owns them
Expand Down
Loading