Skill tracker rebase
Git-backed oversight of your Hermes Agents' skills.
npx -y skills add cnuahs/skill-tracker --skill skill-tracker-rebaseAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
One thing to look at
- 0 stars0 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
What its author says it does
Copied from the file, not written here
Rebase agent branches onto main, excising rejected PRs. Run the rebase orchestrator, execute the plan per repo (excisions + main rebase), resolve conflicts, and report results.
The file declares its own license as MIT. That is the author’s claim about this one file, and it is not the same thing as the license GitHub reports for the repository, which is listed with the other numbers below.
SKILL.md
13.4 KB, ~3.3k tokens by cl100k_base, as published. Nobody here has run it
Rebase Agent Branches Onto Main
Overview
This skill reconciles the agent's branches with upstream main after PRs have been reviewed. It excises rejected PRs (closed without merge) from the agent branch, then rebases surviving commits onto the latest main.
Key concepts: Each tracked skill repo has an agent branch where all agent-made commits land. The push+PR cron (Phase 7) cherry-picks commits onto PR branches for human review. After the human merges or closes those PRs, this skill brings the agent branch back into alignment:
- Merged PRs: commits are now on
main;git rebase mainskips them (content dedup). - Rejected PRs (closed, not merged): commits are excised from the agent branch via
git rebase --onto. - Open PRs: untouched.
How it works end-to-end:
- Plan (scripted) —
rebase.pyreads config, callsplan_rebase.pyper repo, outputs a JSON plan with excisions and arebase_neededflag. - Execute (agent) — For each repo: check out agent branch, perform excisions, reset working tree, rebase onto main, reset working tree again.
- Resolve conflicts (agent) — Best-effort, prefer coherent skill over preserving every change.
- Report (agent) — Summarize excisions, conflicts, failures.
When to Use
- Triggered by the rebase cron job (daily or on webhook)
- When the user asks to "rebase agent branches" or "run the rebase workflow"
- After PRs have been reviewed/merged/rejected on GitHub
Rules
Do not modify scripts, skill files, or plugin files
The cron agent must NOT modify any file in $HERMES_HOME/plugins/skill-tracker/
or $HERMES_HOME/skills/skill-tracker/. Do not modify any of these
files. They are maintained separately and your changes will be overwritten.
If you encounter what looks like a bug, STOP and REPORT it. Do not work around it, patch the script, or improvise a fix. The correct response is to abort the run and describe the problem so a human (or a future session with explicit instructions) can fix it.
The only operations you should perform on the repo are:
git fetch(via the provided scripts)git checkout <agent_branch>— switch to the agent branchgit rebase/git rebase --onto— replay or excise commitsgit reset --hard HEAD— reset working tree after rebase- Conflict resolution (read files, stage,
git rebase --continue) git diff --quiet HEAD— dirty-tree guard
Do not check out main
The agent branch (agent/hermes-gateway) is the working branch — this is
the branch whose commits are replayed. main is the rebase target —
the base onto which agent commits are replayed.
Never git checkout main. The only git checkout in this workflow
is git checkout <agent_branch>. Always.
# CORRECT: check out the working branch, rebase onto the target
git checkout <agent_branch>
git rebase <main_branch>
# WRONG: this reverses the direction — do NOT do this
git checkout <main_branch>
git rebase <agent_branch>
Prerequisites
skill-trackerplugin is installed and configured in$HERMES_HOME/config.yamlskill_tracker.reposlist has at least one valid repo entry- Each configured repo has a valid
originremote (or expliciturlin config) - Agent branch exists on each repo (created by the plugin at registration time)
rebase.py,plan_rebase.py, and the shared modules (plugin/gitutils.py,plugin/config.py,plugin/gh_api.py,plugin/queries.py,plugin/commitmsg.py) existPyYAMLis available in the Python environment (required byrebase.pyfor reading config.yaml)token_envis configured inskill_trackerconfig and the referenced env var is set (for PR listing via GitHub API)
Finding the scripts: The scripts are in the scripts/ subdirectory of the skill-tracker plugin directory ($HERMES_HOME/plugins/skill-tracker/scripts/). All script paths below use <scripts-dir> to refer to this location.
Python environment: The scripts must run in the Hermes venv. Activate it in each terminal session before running the scripts, e.g.,
source /opt/hermes/.venv/bin/activate && python3 <scripts-dir>/rebase.py
Workflow
Step 1: Run the Orchestrator
Run rebase.py:
source /opt/hermes/.venv/bin/activate && python3 <scripts-dir>/rebase.py
The script reads $HERMES_HOME/config.yaml, iterates over all configured repos, and outputs a JSON array of per-repo rebase plans to stdout.
Output format — JSON array of plan objects:
[
{
"repo_path": "/opt/data/skills",
"agent_branch": "agent/hermes-gateway",
"main_branch": "main",
"url": "https://github.com/user/skills.git",
"token_env": "GITHUB_TOKEN",
"agent_name": "hermes-gateway",
"excisions": [
{
"pr_number": 42,
"pr_title": "hermes-gateway: consolidate 3 changes to my-skill",
"onto": "abc123def456...",
"end": "fed654321cba...",
"commit_shas": ["abc123...", "def456...", "789abc..."],
"commit_count": 3
}
],
"rebase_needed": true
}
]
Error handling: If rebase.py exits non-zero, log stderr and abort. Do not proceed with partial results.
Empty result: If the output is [], report "No repos to rebase" and exit.
Step 2: Iterate Over Repos
For each repo plan in the JSON output, perform Steps 3–5. Each repo is independent — a failure in one repo must not block others.
Extract these fields from each plan object:
repo_path— where to run git commandsagent_branch— the agent's branch to rebasemain_branch— the stable branch to rebase ontoexcisions— list of excision stepsrebase_needed— whether to rungit rebase mainafter excisions
Step 3: Check Out Agent Branch
Before switching branches, check for uncommitted changes on the current working tree:
cd <repo_path>
git diff --quiet HEAD || { echo "SKIP: dirty working tree"; exit 1; }
git checkout <agent_branch>
If dirty, skip this repo — self-improvement or the curator may be mid-operation. Do NOT reset or commit the changes. Continue with the next repo and report the failure in Step 6.
This guards against race conditions (e.g. self-improvement running concurrently).
Step 4: Perform Excisions
For each excision in the excisions list — in the order returned (newest
first) — extract the fields below and run the rebase command.
Fields per excision:
onto: SHA of the commit just before the rejected group — rebase targetend: SHA of the latest commit in the rejected group — excision boundary (everything fromendback to, but not including,ontois excised)pr_number: PR number (for logging)commit_shas: SHAs of the commits being excised (for logging)
cd <repo_path>
git rebase --onto <onto> <end> <agent_branch>
This replays commits that come after the rejected group onto the group's parent, effectively removing the rejected commits from the branch.
Order matters — excising an earlier group changes the SHAs of all later commits on the branch (git replays them). By excising newest-first, each excision only affects commits that have already been processed.
Conflicts during excision are EXPECTED. Excising commits can produce conflicts if later commits touch files modified by the commits being excised. In these cases git cannot apply the patch cleanly and reports a conflict. This is normal git behavior — not a bug, not a sign that something is wrong with the repo. You MUST resolve the conflict and continue with the rebase before moving on to the next excision in the list.
Conflict handling during excision: If git rebase --onto reports conflicts:
- Examine the conflicted files with
git diffandread_file. - Understand the skill's purpose from SKILL.md and surrounding context.
- Resolve in favor of a coherent, working skill. For conflicts arising during
excision, the goal is to preserve the intent of the commit(s) being replayed
onto the new base (
onto). - If unsure, prefer dropping the conflicting change over producing a broken skill.
- Stage resolved files and continue:
git rebase --continue.
After all excisions for this repo are complete, verify the working tree is clean:
cd <repo_path>
git diff --quiet HEAD || { echo "WARNING: dirty working tree after excisions — skipping repo"; exit 1; }
If the working tree is dirty, files from rejected commits may linger on disk. Report the issue and move on to the next repo.
Step 5: Rebase Onto Main
If rebase_needed is true:
Fetch main (script handles token injection) - updates both remote tracking ref and local ref:
source /opt/hermes/.venv/bin/activate && python3 <scripts-dir>/fetch.py <repo_path> <main_branch> \
--url <url> \
--token-env <token_env>
Rebase the agent branch onto local main (now up to date via fetch.py):
cd <repo_path>
git checkout <agent_branch>
git rebase <main_branch>
Git automatically skips commits whose content already exists on main (merged PRs). The local <main_branch> ref is kept up to date by fetch.py (which calls fetch_branch() to fetch from the remote and then updates the local ref via git update-ref), so it is safe to use directly.
Conflict handling: If git rebase reports conflicts, examine the
conflicted files, understand the skill's purpose from SKILL.md and surrounding
context, resolve in favor of coherence, then continue:
cd <repo_path>
git rebase --continue
After the main rebase, verify the working tree is clean:
cd <repo_path>
git diff --quiet HEAD || { echo "WARNING: dirty working tree after rebase — skipping repo"; exit 1; }
Same reasoning as Step 4 — ensure working tree consistency. If dirty, report and move on to the next repo.
Step 6: Report Results
After processing all repos, report:
Rebase run complete.
Repos processed:
- <repo_path>: <N> excisions, <M> conflicts resolved, rebased onto main
- <repo_path>: no excisions, rebased onto main
- <repo_path>: <N> excisions, no rebase needed (rebase_needed=false)
Failed:
- <repo_path>: <error reason>
- <repo_path>: dirty working tree (self-improvement or curator may be running)
If no repos needed any work (no excisions, no rebase_needed), report: "All agent branches are up to date. Nothing to rebase."
Common Pitfalls
Modifying scripts instead of reporting bugs
The cron agent must NOT modify any scripts or skill files. If the agent
patches fetch_branch() or rewrites push.py instead of reporting the
issue, the fix is fragile, will be overwritten, and masks the real problem.
Action: stop and describe the problem. Do not work around it.
Checking out main instead of the agent branch
main is the rebase target — never check it out. The only git checkout
is git checkout <agent_branch>. If you find yourself on main, you have
gone wrong. Abort the rebase, check out the agent branch, and retry.
Token not available in subprocess
The configured token_env variable is available in the agent process environment. The scripts read it from os.environ. If testing via execute_code, the token won't be available — use the terminal tool instead.
Partial failures
If some repos succeed and others fail, report both. Do not abort the entire run because one repo failed.
GitHub API unreachable
If plan_rebase.py cannot reach the GitHub API for a repo, it logs a warning and returns an empty PR list (no excisions). The rebase will still fetch main and rebase surviving commits — it just won't excise anything. This is safe.
Missing PyYAML
rebase.py imports yaml (PyYAML) to read config.yaml. If not installed, the script will fail with ModuleNotFoundError. Action: stop the run and report the missing dependency to the user. Do not attempt to install it yourself.
Token env var empty or insufficient
If the configured token_env variable is empty, unset, or has insufficient GitHub API permissions, PR listing silently fails and no excisions are planned. The rebase still fetches main and rebases surviving commits. Action: if the token is empty or unset, stop the run and report to the user. If the token is set but API calls fail, plan_rebase.py logs a warning — check stderr and report the auth error.
Agent invents false explanations for conflicts
When git rebase --onto reports a conflict, it is a REAL content conflict. Do NOT claim files were "moved" or there is a "directory structure mismatch" unless git log or git diff explicitly shows it. Conflicts during excision are expected. Resolve them normally and continue.
Verification Checklist
-
rebase.pycompleted successfully (exit code 0) - JSON output parsed correctly
- All repos from the JSON output were processed
- Agent branch checked out for each repo
- All excisions performed (or skipped with reason)
- Working tree clean after excisions (or repo skipped)
-
git rebase mainperformed ifrebase_neededis true - Working tree clean after main rebase (or repo skipped)
- Conflicts resolved (if any) with coherent skill content
- Results reported (excisions, conflicts, failures)
What ships with it
Read from the repository
Just SKILL.md. No reference files, no scripts.