Skip to content

bug: the fleet-wide .gitignore merge never runs at agent creation — in-container auto-sync commits .trinity/ runtime state before any Push can migrate #2069

Description

@vybe

Summary

The fleet-wide .gitignore list (_GITIGNORE_PATTERNS, src/backend/services/git_service.py:1269) is never applied at agent creation. It is applied at exactly two later moments, both operator-initiated — so an agent created from an external github: template whose repo ships no .gitignore (or a partial one) starts life with no platform exclusions, while the in-container 15-min auto-sync loop is already committing with git add -A. Runtime state — .trinity/, .claude/projects/, content/, and the credential files — reaches the user's own repo before any Push can migrate the list.

Where the canonical list is actually applied

Call site Trigger Reaches a new template agent?
initialize_git_in_container step 2 (git_service.py:1545) POST /api/agents/{name}/git/initialize — "create a new repo for this agent" ❌ not on the github:-template path
_migrate_workspace_gitignore (git_service.py:1440, called at git_service.py:1112) sync_to_github — the operator Push button / MCP git_sync ❌ only once a human pushes

Creation itself (services/agent_service/crud.py) calls neither. _materialize_agent_files touches .gitignore only via _append_agent_gitignore (git_service.py:709), and only for data_paths entries (#1169) — opt-in, and unrelated to the canonical list. startup.sh deliberately never writes .gitignore (#953, comments at docker/base-image/startup.sh:239, :446, :561). So a template agent's .gitignore is exactly what the template repo shipped.

Why the Push-time fallback loses the race

The fallback assumed by #1908 ("it depends entirely on the fleet-wide .gitignore merge … at sync time") is not the default writer. The default writer is the in-container auto-sync loop, which never merges the list:

  • agent_server/auto_sync.py:44 → agent_server/routers/git.py::_run_auto_sync_once
  • stages with a bare git add -A (agent_server/routers/git.py:485) against whatever .gitignore exists in the container

and it is on from creation for the two paths that push to a repo the user owns — env_vars['GIT_SYNC_AUTO'] = 'true' at crud.py:1567 for non-source-mode (legacy working-branch) and fork-to-own (trinity-enterprise#93) agents. So such an agent auto-commits every 15 minutes from birth, and converges only if and when someone clicks Push.

Impact

Scope — what this is not

#1908 (status-in-dev) fixed the bundled templates and proposes a CI guard scoped to them. Verified locally that this landed: 16 of the 17 bundled templates carrying a .gitignore now list .trinity/, and the remainder are hidden fixtures plus trinity-system. This issue is about the platform-side timing, which no template-side fix can reach — external github: templates are the general case and are outside any bundled-template CI guard.

Proposed fix

Apply the existing merge at creation (and/or at start, before the auto-sync loop can run a cycle) for any agent that has a .git directory — reusing _build_gitignore_merge_command rather than adding a fourth copy of the pattern list.

Acceptance Criteria

  • An agent created from an external github: template whose repo ships no .gitignore (or one lacking the canonical patterns) has the merged list on disk before the first auto-sync cycle can commit
  • The first in-container auto-sync of such an agent commits no .trinity/, .claude/projects/, content/, .env or .mcp.json path
  • The merge reuses _build_gitignore_merge_command — _GITIGNORE_PATTERNS stays the single source of truth (no fourth call site with its own list)
  • Idempotent: an agent whose template already ships the patterns shows no M .gitignore drift against origin (the exact regression Freshly deployed agents report M .gitignore against origin/main #953 removed the shell-level append for)
  • Existing agents keep converging via the Push-time migration — no behaviour change on sync_to_github
  • Regression test covers the fork-to-own / non-source-mode path, since that is where GIT_SYNC_AUTO is on from creation

Technical Notes

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions