Skip to content

Instantly share code, notes, and snippets.

@dabit3
Created July 20, 2026 18:23
Show Gist options
  • Select an option

  • Save dabit3/2b4c3349525d6c0d16613675354b18d8 to your computer and use it in GitHub Desktop.

Select an option

Save dabit3/2b4c3349525d6c0d16613675354b18d8 to your computer and use it in GitHub Desktop.
Daily Hermes → Sonic upstream sync

Outcome

Keep dabit3/sonic-agent caught up with upstream NousResearch/hermes-agent every day. If there are new upstream commits, produce ONE open PR into main that merges those changes while preserving Sonic-specific branding and speed work. Verify with tests, leave proof in the PR, self-review the PR, and stop so the human only has to review/merge the morning PR.

If there is nothing new upstream, do NOT open a PR. Leave a short “no upstream changes” note and end the session.

Context

  • This repo: dabit3/sonic-agent (default branch main)
  • Upstream: https://github.com/NousResearch/hermes-agent.git (branch main)
  • Sonic is a fork of Hermes optimized for speed (startup, TTFT, streaming). Fork identity must survive the merge:
    • CLI / package / paths: sonic, sonic-agent, ~/.sonic, SONIC_*
    • NOT hermes, hermes-agent, ~/.hermes, HERMES_* (except intentional upstream docs links)
    • Speed profile / latency work in config and code must be preserved
    • README fork badge and “fork of Hermes” messaging must stay Sonic’s, not stock Hermes branding
  • Canonical tests: scripts/run_tests.sh (matches CI; do not invent a different pytest invocation)
  • CI installs with: uv venv .venv --python 3.11 && source .venv/bin/activate && uv pip install -e ".[all,dev]"

Procedure

0. Setup

  • Work only in dabit3/sonic-agent.
  • git fetch origin and start from latest origin/main.
  • Ensure upstream remote exists:
    • git remote add upstream https://github.com/NousResearch/hermes-agent.git if missing
    • git fetch upstream --tags
  • Record baselines:
    • SONIC_BASE=$(git rev-parse origin/main)
    • UPSTREAM_HEAD=$(git rev-parse upstream/main)
    • Last synced upstream SHA if discoverable from prior sync PR/branch notes; otherwise compute merge-base:
      • MERGE_BASE=$(git merge-base origin/main upstream/main)

1. Decide whether work is needed

  • If origin/main already contains upstream/main (merge-base == upstream/main, or no commits in upstream/main.. relative to integration point), STOP:
    • Write a short status: date, upstream SHA, “no new upstream commits”
    • Do not create a branch, PR, or empty commit
  • If an open PR already exists for today’s sync (title prefix chore(upstream): and body contains the same upstream range), reuse it — update that branch instead of opening a duplicate
  • Otherwise continue

2. Create sync branch

  • Branch name: chore/upstream-hermes-YYYY-MM-DD (UTC date)
  • Base: origin/main
  • Prefer a merge of upstream/main into the branch (preserves history). Use rebase only if merge is clearly worse.
  • Command sketch:
    • git checkout -B chore/upstream-hermes-YYYY-MM-DD origin/main
    • git merge upstream/main (allow conflicts)

3. Resolve conflicts with Sonic policy

When resolving conflicts, apply this priority order:

  1. Keep Sonic branding & identity (names, paths, CLI entry points, docs that describe Sonic)
  2. Keep Sonic speed-profile / latency behavior unless upstream fix is clearly a bugfix in the same code and can be ported without dropping speed semantics
  3. Take upstream bugfixes, security fixes, new features, tests, and refactors when they don’t fight (1)/(2)
  4. Re-apply rename invariants after conflict resolution (search the diff):
    • User-facing CLI must remain sonic (pyproject scripts, help text, install scripts)
    • Home/config dir ~/.sonic / get_sonic_home() patterns — do not reintroduce ~/.hermes
    • Package/distribution name stays sonic-agent where Sonic already diverged
    • Do NOT blindly replace every “Hermes” string: keep attribution (“fork of Hermes Agent”) and upstream doc links
  5. Prefer small, reviewable conflict resolutions over large rewrites
  6. If a conflict is too ambiguous to resolve safely, leave a clear TODO(upstream-sync): comment AND list it in the PR under “Needs human judgment” — but still finish everything else you can

4. Post-merge cleanup checklist (mandatory)

Run searches on the working tree / diff vs origin/main and fix accidental upstream leakage:

  • Branding regressions: new hermes CLI references, ~/.hermes, HERMES_HOME, package name flips, install URLs pointing at NousResearch/hermes-agent for this project’s install path
  • Preserve Sonic README positioning and speed section
  • Ensure pyproject.toml scripts still expose sonic, sonic-agent, sonic-acp as before unless upstream added a net-new entry point that should be added under Sonic naming
  • Update lockfiles only if dependencies changed (uv lock / project’s normal lock workflow)
  • Do not commit secrets, local venv, or unrelated dirty files

5. Verify (proof required)

Install if needed (fresh env ok):

  • uv venv .venv --python 3.11
  • source .venv/bin/activate
  • uv pip install -e ".[all,dev]"

Then run verification in this order; capture logs:

  1. Import/smoke
    • python -c "import sonic_cli, run_agent; print('ok')"
    • Confirm CLI entry: sonic --help (or module equivalent if path setup requires it)
  2. Targeted tests for touched areas
    • From the merge diff, identify highest-risk packages (agent/, gateway/, tools/, sonic_cli/, ui-tui/, tui_gateway/)
    • Run focused tests first, e.g. scripts/run_tests.sh tests/<affected> -j 4
  3. Broader suite
    • Prefer scripts/run_tests.sh -j 4 for a substantial run
    • If full suite is too long for the session, run a wide slice covering affected areas + a representative core set, and state exactly what ran vs skipped
  4. Lint/type only if cheap and relevant to touched files — don’t block the PR on unrelated repo-wide lint debt
  5. Fix failures caused by the merge. Do not weaken or delete tests to “make green” unless the test is Hermes-branding-specific and must be updated to Sonic naming — in that case update the test, don’t delete coverage.

If tests fail and you cannot fix within reasonable effort:

  • Still open the PR as draft if code merged
  • Mark clearly FAILING with logs
  • Do not claim success

6. Self-review (before requesting human review)

Review your own PR diff as a skeptical maintainer:

  • Correctness of conflict resolutions
  • No accidental rebrand-to-Hermes
  • No dropped Sonic speed behavior without justification
  • No unrelated refactors
  • Tests adequate for the risk
  • Security-sensitive paths (auth, shell, gateway, install scripts) get extra scrutiny

Leave a PR review comment (or PR body section) titled Devin self-review with:

  • Summary of upstream range merged (SHAs + commit count + highlights)
  • Conflict hotspots and how they were resolved
  • Branding/speed preservation checks performed
  • Test commands + pass/fail counts
  • Residual risks / “Needs human judgment” items

7. Deliver PR

  • Push branch to origin
  • Open PR into main (or update existing sync PR)
  • Title: chore(upstream): sync Hermes <short-sha> (YYYY-MM-DD)
  • Body must include:
## Summary
Daily upstream sync from `NousResearch/hermes-agent` into Sonic.

- Upstream range: `<merge_base_or_previous>..<upstream_sha>`
- Upstream commits: N
- Highlights:
  -- Sonic-preserving decisions:
  -## Proof
- Smoke: …
- Tests run: exact commands
- Results: pass/fail counts (paste key tail of log)
- CI: link once available

## Self-review
-- Needs human judgment: …

## Test plan
- [ ] `scripts/run_tests.sh …` (commands actually run)
- [ ] Branding grep clean for accidental hermes regressions
- [ ] Speed profile / Sonic identity intact
  • Add label if available: upstream-sync
  • Request reviewers only if repo convention requires it; otherwise leave for the human morning review
  • Do not merge the PR
  • Do not force-push after the PR is opened unless fixing a critical issue you just introduced
  • Final message in the Devin session: PR URL + one-screen status (synced range, tests, residual risks)

Specifications (done means all true)

  • Either (A) no upstream changes and no PR, with a clear status note, OR (B) exactly one sync PR open/updated for this run
  • PR merges upstream main into Sonic main on a dated branch
  • Sonic branding, CLI, and ~/.sonic identity preserved
  • Speed-oriented Sonic behavior not silently reverted
  • Proof of verification is in the PR body (commands + results)
  • Self-review section present
  • PR is not merged by Devin
  • No secrets committed; no destructive git history rewrites on main

Advice

  • Optimize for a PR a human can review in ≤15 minutes: crisp summary, conflict notes, proof
  • Upstream moves fast; favor merging today’s delta cleanly over boiling the ocean
  • When upstream renames/refactors large files, merge first, then re-apply Sonic deltas rather than hand-replaying commits
  • For ui-tui/TS changes: run the package’s existing npm test / npm run type-check if JS/TS was touched and deps allow
  • If yesterday’s sync PR is still open and unmerged, continue on that branch (include new upstream commits) instead of stacking multiple daily PRs
  • Quote exact SHAs everywhere — never say “latest” without a SHA
  • Keep commits on the branch coherent; a single merge commit + follow-up fix commits is fine

Forbidden actions

  • Do not merge the PR to main
  • Do not force-push main or rewrite published history
  • Do not close/supersede unrelated human PRs
  • Do not “fix” tests by deleting assertions or skipping broad suites with pytest -k hacks that hide failures
  • Do not rebrand the project back to Hermes
  • Do not change GitHub remote to make Sonic track hermes-agent as origin
  • Do not spend the whole session on unrelated refactors, dependency upgrades beyond what upstream brought, or docs rewrites
  • Do not run destructive data deletion or production deploys

Required from user (one-time)

  • Repo access to dabit3/sonic-agent with permission to push branches and open PRs
  • Schedule/automation attached to this playbook (daily morning)
  • Human reviews/merges the PR (that is the only ongoing job)

How to run this playbook

  1. Create a Playbook in Devin from this file (or drag-and-drop daily-hermes-sync.devin.md when starting a session).
  2. Create an Automation with a Schedule trigger (e.g. daily morning cron 0 7 * * * in your TZ).
  3. Attach this playbook; set the repo to dabit3/sonic-agent.
  4. Optional session prompt each run: Run the daily Hermes upstream sync playbook.
  5. Each morning: open the PR (if any), review Devin’s self-review + proof, merge.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment