Design-Monorepo Capabilities¶
Three AgentCapability subclasses give an agent first-class access
to the design monorepo. Bind them all at once with
design_monorepo_capability_blueprints(); each one resolves a
per-agent local clone at agent-init time so multiple agents in
the same process never collide.
One-time setup — point the colony at your repo¶
Each colony has one design monorepo. Configure it on the dashboard's landing page (the screen you see after login, before any session is started):
- In the Colonies panel, pick or create a colony with + New colony.
- On that colony's row, click the pencil next to Design monorepo, paste the GitHub (or any git) URL, optionally change the branch, and click Save.
- Click New Session.
The landing page is the right home for this gesture because the
dashboard's tabs (including the Design Monorepo inspector) only
appear once a session is active — so the URL has to be configured
before the session boots. The save writes onto the colony's row in
the colonies Postgres table (design_monorepo_url,
design_monorepo_branch, design_monorepo_commit). Every
subsequent SessionAgent created in that colony reads it at
session-creation time, attaches it to
AgentMetadata.parameters["design_monorepo_url"], and the design-
monorepo capability trio lazy-clones the repo into the per-agent
working directory on first action.
Authentication is per-tenant via the GitHub App installation flow
(see guides/github-app-setup.md).
At agent startup, DesignMonorepoCapabilityBase.initialize calls
ensure_git_credentials_from_agent_metadata (in
colony/distributed/git_credentials.py); that mints an installation
token from the tenant's github_installation_id + the deploy-wide
App credentials, writes it atomically to
/tmp/colony-git-credentials, and starts a 50-minute refresh task.
The container's system git config has a credential helper
(/usr/local/bin/colony-git-credentials, installed by
Dockerfile.base) that reads the file when git asks for credentials.
For https://github.com/... URLs this means non-interactive clone
and push work without the user embedding credentials. ssh remotes,
GitLab (still PAT-based via $GITLAB_TOKEN), and URLs that already
carry credentials pass through untouched. When the tenant hasn't
installed the App or the deploy-wide App env vars are missing, the
token file is absent and git surfaces its standard
"Authentication failed" error — the
_classify_git_clone_error
classifier reshapes that into a typed GitAuthError whose message
names the exact knobs to fix.
GET /api/v1/colonies/{colony_id}/design-monorepo
PUT /api/v1/colonies/{colony_id}/design-monorepo
{"origin_url": "https://github.com/me/my-design.git",
"branch": "main", "commit": "HEAD"}
The three capabilities¶
| Class | Role | Actions |
|---|---|---|
RepoStateProvider |
Read-only query + bootstrap surface | get_repo_state, find_existing_tool, list_recent_decisions, diff_against_checkpoint, get_branch_topology, list_packages, list_design_artifacts, summarize_project_layout, read_file, read_lines, list_directory, stat_path, grep_content, git_log, git_status, diff_working_tree, ingest_repo_map_literature, initialize_repo_map |
DesignCheckpointer |
Write side: branches, checkpoints, merges, tags, remote ops | checkpoint_state, restore_checkpoint, fork_design, merge_design, cherry_pick_decisions, commit_state, tag_checkpoint, list_checkpoints, list_forks, diff_design, create_branch, delete_branch, checkout_branch, stash_save, stash_pop, list_stashes, rebase_onto, create_tag, delete_tag, fetch_remote, pull_remote, push_remote |
ToolBuilder |
Scaffold extensions under .colony/ and tool repos under tools/<purpose>/<name>/ |
bootstrap_repo, bootstrap_plugin, bootstrap_agent, bootstrap_deployment, bootstrap_tool_capability, bootstrap_profile |
Notes:
- The
read_*/list_*/git_*/diff_*ops onRepoStateProviderare pure reads; they do not commit and do not respect protected-branch gating. They're the primary way an agent inspects the working tree before deciding what to write. initialize_repo_mapis the write-side bootstrap for an empty design monorepo — seeds.colony/repo_map.yamlfrom the canonical template and commits it through the standard attribution chain. Idempotent: never overwrites an operator-edited file.ingest_repo_map_literaturewalks theknowledge_sourcesrows declared inrepo_map.yamland ingests every matching file into the knowledge base — chat-driven bulk acquisition (seearchitecture/repo-map.md).- Five of the
DesignCheckpointeractions gate through human approval when targeting a protected branch (merge_design,push_remote,pull_remotewith rewriting strategies,cherry_pick_decisions,rebase_onto). They return a typedProtectedOpResult— seeguides/protected-branches.md. - Every commit-producing action threads through
_commit_attribution→commit_with_identity, so the colony's configuredcommit_principal/commit_co_author(seeguides/git-attribution.md) lands on every commit uniformly. - The
ToolBuilder.bootstrap_<surface>actions take an optionalscaffold=<id>+template_vars=...to dispatch to a CPS-shaped registered scaffold instead of the blank stub — seedesign-monorepo-authoring.md.
DesignCheckpointer is also event-driven: it auto-tags an
auto_quiescence_<iso8601> checkpoint when the convergence runtime
settles with uncommitted changes (@event_handler on
ConvergenceQuiescenceProtocol.quiescence_pattern()).
Minimal example — wire all three into an agent¶
from polymathera.colony.design_monorepo import (
design_monorepo_capability_blueprints,
)
SessionAgent.bind(
...,
capability_blueprints=[
...,
*design_monorepo_capability_blueprints(),
],
)
The helper returns three AgentCapabilityBlueprints, in this order:
RepoStateProvider, DesignCheckpointer, ToolBuilder. Pass
auto_checkpoint_on_quiescence=False to opt out of auto-checkpointing,
or read_only_state=True to point RepoStateProvider at the shared
read-only clone (good for agents that only read).
auto_checkpoint_on_quiescence=False does two things in lockstep: it
disables the auto-checkpoint behaviour and unsubscribes the
capability from ConvergenceQuiescenceProtocol.quiescence_pattern()
on the action policy's event queue. The second half matters for
reactive_only agents (e.g., SessionAgent) — without it, every
episode boundary would wake the LLM planner and the agent would
plan-and-act in a tight loop on infrastructure events. The
remote-change subscription stays active either way; it only fires
when the upstream actually changes.
RepoStateProvider and ToolBuilder declare no event handlers —
they are pure action surfaces. Their constructors pass
input_patterns=[] to super().__init__, which is the
AgentCapability convention
for "explicit opt-out: do not subscribe to anything on this scope."
Without that opt-out, the base class's legacy empty-patterns
fallback would subscribe to "*" and the agent's own
policy:action_started:* lifecycle writes would loop back into the
action policy's event queue — in reactive_only mode that triggers
a fresh plan_step for every action the policy itself dispatched.
Per-agent clones¶
By default each capability resolves its working directory to:
The /mnt/shared mount is the colony-shared docker volume — the
clone survives Ray actor restarts. Different agents working on the
same scope get distinct directories, so:
- Two agents can simultaneously check out different branches of the same design monorepo without colliding.
- A failed merge in one agent's clone does not corrupt another agent's view.
- Branch creation (
fork_design) writes to the per-agent clone only; the global VCM mapping (the read-only view ofmain) does not see the change until the agent merges back.
Override the path by passing working_dir=... to a specific
capability constructor (skip the helper for that one), or change
COLONY_SHARED_ROOT to redirect the entire layout.
Shared read-only clone¶
For agents that never write — typically planners that just read state — the read-only flag selects a single per-node clone:
The shared clone lives at /mnt/shared/shared_clones/<scope_id>/.
Every RepoStateProvider(read_only=True) on the same node opens it,
saving disk and clone time. DesignCheckpointer and ToolBuilder
ignore the flag — they always use a per-agent writable clone.
Branch-update events¶
When the convergence runtime rebuilds a scope's page graph after the
remote-watcher observes upstream commits, it writes a
VCMEventProtocol.reindexed:<scope_id> event. DesignCheckpointer
subscribes to that pattern and translates it into a coarser
DesignMonorepoEventProtocol.branch_changed:<scope_id> event the
agent's planner consumes.
Subscribe in your own capability (or directly in the planning prompt) to react:
@event_handler(pattern=DesignMonorepoEventProtocol.branch_changed_pattern())
async def on_branch_changed(self, event, scope):
scope_id = DesignMonorepoEventProtocol.parse_branch_changed_key(event.key)
# plan a checkout / merge / rebase against the per-agent clone
Reference — clone path¶
polymathera.colony.design_monorepo.clones.resolve_clone_path(*, agent, scope_id, read_only):
| Arg | Effect |
|---|---|
agent |
Owning agent. Required when read_only=False. |
scope_id |
Per-clone scope key (typically the VCM scope id or a branch name). |
read_only |
False → /mnt/shared/agents/<agent_id>/clones/<scope_id>/; True → /mnt/shared/shared_clones/<scope_id>/. |
Override the base by exporting COLONY_SHARED_ROOT.