chore(agents): check for latest main at agent session start
Requested by roshan desai · Slack thread
Before: an agent could start work on a stale branch or an old main, so it read an out-of-date feature map (.agents/feature-map/) and missed recent changes.
After: at session start, Claude Code and Codex fetch origin/main and tell the agent to rebase on it only when the branch has merge conflicts with origin/main or its merge base with origin/main is more than 3 days old. Otherwise the hook is silent. Keeping a branch current avoids a much more involved conflict resolution later.
This adds a SessionStart hook that, when it fires, reports how far HEAD is behind origin/main, why (conflicts, stale, or both) and which .agents/ files changed on main since the branch diverged. A branch that already contains origin/main, or is only a few recent commits behind without conflicts, gets no message.
How: .agents/hooks/ensure_latest_main.py runs git fetch origin main (20 second limit, no credential prompts) and checks for conflicts with git merge-tree --write-tree HEAD origin/main (exit 1) and for staleness (merge-base commit date older than _STALE_AFTER_DAYS = 3), and prints a message that the agent reads as context only if either applies. It never rebases, pulls or touches the working tree, and it always exits 0, so an offline or failed fetch only adds a note. It is wired for the startup and resume sources in .claude/settings.json and .codex/hooks.json. Other agents (for example Cursor, which has no hook config in this repo) get the same rule as a line in AGENTS.md. Set ONYX_SKIP_MAIN_SYNC_CHECK=1 (or true, yes, on) to turn it off; 0 or false leaves it on. It also repeats the check, fetching at most once an hour, on later prompts.
How Has This Been Tested?
External dependency tests (backend/tests/external_dependency_unit/scripts/test_ensure_latest_main_repos.py, run by the scripts group of the PR workflow) run the script against throwaway git repos: up to date, fresh and clean (silent), merge base older than 3 days (warns), conflicting (warns), a dirty or untracked-only tree, an offline remote, malformed payloads, skip-variable values, fetch throttling, and a directory that is not a repo. All exit 0 and leave the working tree unchanged. A stubbed unit test (backend/tests/unit/scripts/test_ensure_latest_main.py) covers the ssh command handling. ruff and mypy --strict pass.
🤖 Generated with Claude Code
https://claude.ai/code/session_01TYt2dm3XFyAdzZygsG6CN7
Generated by Claude Code
Summary by cubic
Agents now check at session start and on later prompts whether their checkout conflicts with origin/main or is stale, so they stop working from an outdated .agents/feature-map/ and missing recent changes.
- Claude Code and Codex run a new hook that fetches
origin/mainand tells the agent how to update, without ever pulling, rebasing, or touching the working tree. - The hook speaks only when the branch has merge conflicts with
origin/main(viagit merge-tree --write-tree) or its merge base is more than 3 days old; a branch that is merely a few recent commits behind stays silent. It always exits 0, so offline or hanging fetches degrade gracefully, and on prompts it fetches at most once an hour. SetONYX_SKIP_MAIN_SYNC_CHECKto a truthy value to disable it. When a merge or rebase is already in progress, it tells the agent to finish or abort it instead of starting another update. - Other agents without hook config get the same rule in
AGENTS.md, and the suggested update command uses an explicit refspec so it works in single-branch clones. - Git-repo integration tests run under the external dependency test group; the unit file keeps the one fully stubbed test.
Summary by CodeRabbit
- New Features
- Added checks at session start and during later prompts to flag branches that may conflict with
mainor have an outdated merge base, with guidance for updating. Checks use the last known remote state if fetching fails and do not change the working tree. - Prompt-triggered fetches are limited to once per hour.
- Added checks at session start and during later prompts to flag branches that may conflict with
- Documentation
- Added guidance for keeping work up to date while preserving uncommitted changes.
- Tests
- Added coverage for up-to-date, stale, conflicting, offline, and other branch scenarios.