Pushing changes upstream
This repo was created from a parent template repo (see system/config/parent.toml for the upstream URL and branch). The default flow for pushing improvements back is: one logical fix per PR, on a submit/<short-name> branch. We do not push directly to upstream main.
What to push (and what not to)
Push shared infrastructure that benefits other agents derived from the template:
- Skills (
.agents/skills/)
- Scripts (
system/scripts/, .agents/shared/scripts/)
- CLAUDE.md scaffolding (template-level sections only)
- Dockerfile
system/supervisord.conf (template-level service programs)
Do not push agent-specific content:
PURPOSE.md
- Memory contents
- Workspace data and runtime state (
data/)
- Agent-specific services, settings, or CLAUDE.md sections
Do not include changes under system/vendor/mngr/ -- that is a vendored
snapshot of the mngr repo, and mngr changes get their own PR on the mngr repo,
not a template PR. See references/mngr-changes.md
for the flow (test in the vendored tree, then prepare the mngr PR from a
standalone checkout at .external_worktrees/mngr).
PR conventions
- Branch name:
submit/<short-feature-name> (kebab-case, ~3-5 words). Same name on the upstream remote.
- One logical fix per PR. Multiple commits are fine if they form one logical unit; otherwise split them across PRs so each can be reviewed/CI'd/merged independently.
- Title: short, imperative, scoped. e.g.
forwarder: redirect HTTPS by default.
- Body: a single paragraph explaining the why (the motivating bug, missing capability, or constraint). Reviewers can read the diff for the what. Skip checklists and section headers.
- Co-Authored-By trailer on the commit (the standard one used in this repo).
Recipe
The upstream URL and base branch are in system/config/parent.toml.
Ensure the upstream remote points at the template (idempotent):
git remote get-url upstream 2>/dev/null || git remote add upstream "$(python3 -c "
import tomllib
with open('system/config/parent.toml', 'rb') as f:
print(tomllib.load(f)['url'])
")"
Stage the commit(s) you want to push onto a clean throwaway branch rooted at upstream's base, then push that branch. Pushing the local working branch directly (git push upstream <local_branch>:submit/<short-name>) would publish every ancestor commit not yet on upstream -- including unrelated WIP, merge, and scaffolding commits that happen to share the branch tip's history -- producing a noisy PR that violates the "one logical fix per PR" rule.
If your working tree is dirty (git status shows modifications you don't want to disturb), do the cherry-pick in a fresh git worktree rooted at upstream/<base>. Switching branches in-place would either carry the dirty tracked changes into the submit branch (and into the cherry-pick context, where they cause conflicts) or refuse the checkout outright. A worktree sidesteps both:
git fetch upstream
BASE=$(python3 -c "
import tomllib
with open('system/config/parent.toml', 'rb') as f:
print(tomllib.load(f)['branch'])
")
git worktree add /tmp/wt-<short-name> "upstream/$BASE"
(cd /tmp/wt-<short-name> \
&& git checkout -b submit/<short-name> \
&& git cherry-pick <sha-1> [<sha-2> ...] \
&& git push upstream submit/<short-name>:submit/<short-name>)
git worktree remove /tmp/wt-<short-name>
git branch -D submit/<short-name> # the throwaway local branch
With a clean working tree, the simpler in-place form is fine:
git fetch upstream
BASE=$(python3 -c "
import tomllib
with open('system/config/parent.toml', 'rb') as f:
print(tomllib.load(f)['branch'])
")
git branch -f submit/<short-name> "upstream/$BASE"
git checkout submit/<short-name>
git cherry-pick <sha-1> [<sha-2> ...] # the commit(s) for this logical fix, oldest first
git push upstream submit/<short-name>:submit/<short-name>
git checkout - # back to your working branch
If the cherry-pick conflicts against current upstream (a real conflict, not the dirty-tree case above), resolve it the same way you would for any cherry-pick (or rebase your fix on a fresh update-self first).
Open the PR against the template's default branch (read from system/config/parent.toml, usually main):
gh pr create \
--repo imbue-ai/default-workspace-template \
--base main \
--head submit/<short-name> \
--title "<short imperative title>" \
--body "<one-paragraph why>"
Report the PR URL back to the user.
When to push
- When the user asks you to push changes upstream.
- After improving shared skills, scripts, or configuration that would benefit other agents.
Important
- Always commit your local changes before pushing.
- Double-check the diff:
git show <sha> -- make sure no agent-specific content is in the commit.
- One upstream PR per logical fix. Don't bundle.
- When finalizing a worker's branch, cherry-pick only the substantive commits -- skip scaffolding, WIP, and auto-generated commits that don't belong upstream.
- Never push directly to upstream
main.
- To pull updates from upstream, use the
update-self skill.
1---2name: submit-upstream-changes3description: Push local improvements to shared infrastructure (skills, scripts, CLAUDE.md scaffolding, Dockerfile, system/supervisord.conf) back to the parent template repo so other agents derived from the template benefit. Opens a separate per-feature PR per logical fix; never pushes directly to upstream `main`. Do not push agent-specific content (PURPOSE.md, memory, runtime state). For pulling updates from upstream, use the `update-self` skill instead.4---56# Pushing changes upstream78This repo was created from a parent template repo (see `system/config/parent.toml` for the upstream URL and branch). The default flow for pushing improvements back is: **one logical fix per PR, on a `submit/<short-name>` branch**. We do not push directly to upstream `main`.910## What to push (and what not to)1112Push **shared infrastructure** that benefits other agents derived from the template:1314- Skills (`.agents/skills/`)15- Scripts (`system/scripts/`, `.agents/shared/scripts/`)16- CLAUDE.md scaffolding (template-level sections only)17- Dockerfile18- `system/supervisord.conf` (template-level service programs)1920Do **not** push agent-specific content:2122- `PURPOSE.md`23- Memory contents24- Workspace data and runtime state (`data/`)25- Agent-specific services, settings, or CLAUDE.md sections2627Do **not** include changes under `system/vendor/mngr/` -- that is a vendored28snapshot of the mngr repo, and mngr changes get their own PR on the mngr repo,29not a template PR. See [references/mngr-changes.md](references/mngr-changes.md)30for the flow (test in the vendored tree, then prepare the mngr PR from a31standalone checkout at `.external_worktrees/mngr`).3233## PR conventions3435- **Branch name:** `submit/<short-feature-name>` (kebab-case, ~3-5 words). Same name on the upstream remote.36- **One logical fix per PR.** Multiple commits are fine if they form one logical unit; otherwise split them across PRs so each can be reviewed/CI'd/merged independently.37- **Title:** short, imperative, scoped. e.g. `forwarder: redirect HTTPS by default`.38- **Body:** a single paragraph explaining the *why* (the motivating bug, missing capability, or constraint). Reviewers can read the diff for the *what*. Skip checklists and section headers.39- **Co-Authored-By trailer** on the commit (the standard one used in this repo).4041## Recipe4243The upstream URL and base branch are in `system/config/parent.toml`.44451. Ensure the `upstream` remote points at the template (idempotent):4647 ```bash48 git remote get-url upstream 2>/dev/null || git remote add upstream "$(python3 -c "49 import tomllib50 with open('system/config/parent.toml', 'rb') as f:51 print(tomllib.load(f)['url'])52 ")"53 ```54552. Stage the commit(s) you want to push onto a clean throwaway branch rooted at upstream's base, then push that branch. Pushing the local working branch directly (`git push upstream <local_branch>:submit/<short-name>`) would publish every ancestor commit not yet on upstream -- including unrelated WIP, merge, and scaffolding commits that happen to share the branch tip's history -- producing a noisy PR that violates the "one logical fix per PR" rule.5657 **If your working tree is dirty** (`git status` shows modifications you don't want to disturb), do the cherry-pick in a fresh `git worktree` rooted at `upstream/<base>`. Switching branches in-place would either carry the dirty tracked changes into the submit branch (and into the cherry-pick context, where they cause conflicts) or refuse the checkout outright. A worktree sidesteps both:5859 ```bash60 git fetch upstream61 BASE=$(python3 -c "62 import tomllib63 with open('system/config/parent.toml', 'rb') as f:64 print(tomllib.load(f)['branch'])65 ")66 git worktree add /tmp/wt-<short-name> "upstream/$BASE"67 (cd /tmp/wt-<short-name> \68 && git checkout -b submit/<short-name> \69 && git cherry-pick <sha-1> [<sha-2> ...] \70 && git push upstream submit/<short-name>:submit/<short-name>)71 git worktree remove /tmp/wt-<short-name>72 git branch -D submit/<short-name> # the throwaway local branch73 ```7475 With a clean working tree, the simpler in-place form is fine:7677 ```bash78 git fetch upstream79 BASE=$(python3 -c "80 import tomllib81 with open('system/config/parent.toml', 'rb') as f:82 print(tomllib.load(f)['branch'])83 ")84 git branch -f submit/<short-name> "upstream/$BASE"85 git checkout submit/<short-name>86 git cherry-pick <sha-1> [<sha-2> ...] # the commit(s) for this logical fix, oldest first87 git push upstream submit/<short-name>:submit/<short-name>88 git checkout - # back to your working branch89 ```9091 If the cherry-pick conflicts against current upstream (a real conflict, not the dirty-tree case above), resolve it the same way you would for any cherry-pick (or rebase your fix on a fresh `update-self` first).92933. Open the PR against the template's default branch (read from `system/config/parent.toml`, usually `main`):9495 ```bash96 gh pr create \97 --repo imbue-ai/default-workspace-template \98 --base main \99 --head submit/<short-name> \100 --title "<short imperative title>" \101 --body "<one-paragraph why>"102 ```1031044. Report the PR URL back to the user.105106## When to push107108- When the user asks you to push changes upstream.109- After improving shared skills, scripts, or configuration that would benefit other agents.110111## Important112113- Always commit your local changes before pushing.114- Double-check the diff: `git show <sha>` -- make sure no agent-specific content is in the commit.115- One upstream PR per logical fix. Don't bundle.116- When finalizing a worker's branch, cherry-pick only the substantive commits -- skip scaffolding, WIP, and auto-generated commits that don't belong upstream.117- Never push directly to upstream `main`.118- To pull updates from upstream, use the `update-self` skill.