- AgentHub: 13 files updated with non-engineering examples (content drafts, research, strategy) — engineering stays primary, cross-domain secondary - AgentHub: 7 slash commands, 5 Python scripts, 3 references, 1 agent, dry_run.py validation (57 checks) - Marketplace: agenthub entry added with cross-domain keywords, engineering POWERFUL updated (25→30), product (12→13), counts synced across all configs - SEO: generate-docs.py now produces keyword-rich <title> tags and meta descriptions using SKILL.md frontmatter — "Claude Code Skills" in site_name propagates to all 276 HTML pages - SEO: per-domain title suffixes (Agent Skill for Codex & OpenClaw, etc.), slug-as-title cleanup, domain label stripping from titles - Broken links: 141→0 warnings — new rewrite_skill_internal_links() converts references/, scripts/, assets/ links to GitHub source URLs; skills/index.md phantom slugs fixed (6 marketing, 7 RA/QM) - Counts synced: 204 skills, 266 tools, 382 refs, 16 agents, 17 commands, 21 plugins — consistent across CLAUDE.md, README.md, docs/index.md, marketplace.json, getting-started.md, mkdocs.yml - Platform sync: Codex 163 skills, Gemini 246 items, OpenClaw compatible Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
150 lines
4.0 KiB
Markdown
150 lines
4.0 KiB
Markdown
# Git DAG Patterns for Multi-Agent Collaboration
|
|
|
|
## Core Concepts
|
|
|
|
### Directed Acyclic Graph (DAG)
|
|
|
|
Git's commit history is a DAG where:
|
|
- Each commit points to one or more parents
|
|
- No cycles exist (you can't be your own ancestor)
|
|
- Branches are just pointers to commit nodes
|
|
|
|
In AgentHub, the DAG represents all approaches ever tried:
|
|
- Base commit = task starting point
|
|
- Each agent creates a branch from the base
|
|
- Commits on each branch = incremental progress
|
|
- Frontier = branch tips with no children
|
|
|
|
### Frontier Detection
|
|
|
|
The **frontier** is the set of commits (branch tips) that have no children. These are the "leaves" of the DAG — the latest state of each agent's work.
|
|
|
|
Algorithm:
|
|
```
|
|
1. Collect all branch tips: T = {tip(b) for b in hub_branches}
|
|
2. For each tip t in T:
|
|
a. Check if t is an ancestor of any other tip t' in T
|
|
b. If yes: t is NOT on the frontier (it's been extended)
|
|
c. If no: t IS on the frontier
|
|
3. Return frontier set
|
|
```
|
|
|
|
Git command equivalent:
|
|
```bash
|
|
# For each branch, check if it's an ancestor of any other
|
|
git merge-base --is-ancestor <commit-a> <commit-b>
|
|
```
|
|
|
|
### Branch Naming Convention
|
|
|
|
```
|
|
hub/{session-id}/agent-{N}/attempt-{M}
|
|
```
|
|
|
|
Components:
|
|
- `session-id`: YYYYMMDD-HHMMSS timestamp (unique per session)
|
|
- `agent-N`: Sequential agent number (1 to agent-count)
|
|
- `attempt-M`: Retry counter (starts at 1, increments on re-spawn)
|
|
|
|
This creates a natural namespace:
|
|
- `hub/*` — all AgentHub work
|
|
- `hub/{session}/*` — all work for one session
|
|
- `hub/{session}/agent-{N}/*` — all attempts by one agent
|
|
|
|
## Merge Strategies
|
|
|
|
### No-Fast-Forward Merge (Default)
|
|
|
|
```bash
|
|
git merge --no-ff hub/{session}/agent-{N}/attempt-1
|
|
```
|
|
|
|
Creates a merge commit that:
|
|
- Preserves the branch topology in the DAG
|
|
- Makes it clear which commits came from which agent
|
|
- Allows `git log --first-parent` to show only merge points
|
|
|
|
### Squash Merge (Alternative)
|
|
|
|
```bash
|
|
git merge --squash hub/{session}/agent-{N}/attempt-1
|
|
```
|
|
|
|
Use when:
|
|
- Agent made many small commits that aren't individually meaningful
|
|
- Clean history is preferred over detailed history
|
|
- The approach matters, not the journey
|
|
|
|
### Cherry-Pick (Selective)
|
|
|
|
```bash
|
|
git cherry-pick <specific-commits>
|
|
```
|
|
|
|
Use when:
|
|
- Only some of an agent's commits are wanted
|
|
- Combining work from multiple agents
|
|
- The agent solved a bonus problem along the way
|
|
|
|
## Archive Strategy
|
|
|
|
After merging the winner, losers are archived via tags:
|
|
|
|
```bash
|
|
# Create archive tag
|
|
git tag hub/archive/{session}/agent-{N} hub/{session}/agent-{N}/attempt-1
|
|
|
|
# Delete branch ref
|
|
git branch -D hub/{session}/agent-{N}/attempt-1
|
|
```
|
|
|
|
Why tags instead of branches:
|
|
- Tags are immutable (can't be moved or accidentally pushed to)
|
|
- Tags don't clutter `git branch --list` output
|
|
- Tags are still reachable by `git log` and `git show`
|
|
- Git GC won't collect tagged commits
|
|
|
|
## Immutability Rules
|
|
|
|
1. **Never rebase agent branches** — rewrites history, breaks DAG
|
|
2. **Never force-push** — could overwrite other agents' work
|
|
3. **Never delete commits** — only delete branch refs (commits preserved via tags)
|
|
4. **Never amend** agent commits — append-only history
|
|
5. **Board is append-only** — new posts only, no edits
|
|
|
|
## DAG Visualization
|
|
|
|
Use `git log` flags to see the multi-agent DAG:
|
|
|
|
```bash
|
|
# Full graph with branch decoration
|
|
git log --all --oneline --graph --decorate --branches=hub/*
|
|
|
|
# Commits since base, all agents
|
|
git log --all --oneline --graph base..HEAD --branches=hub/{session}/*
|
|
|
|
# Per-agent linear history
|
|
git log --oneline hub/{session}/agent-1/attempt-1
|
|
```
|
|
|
|
## Worktree Isolation
|
|
|
|
Git worktrees provide filesystem isolation:
|
|
|
|
```bash
|
|
# Create worktree for an agent
|
|
git worktree add /tmp/hub-agent-1 -b hub/{session}/agent-1/attempt-1
|
|
|
|
# List active worktrees
|
|
git worktree list
|
|
|
|
# Remove after merge
|
|
git worktree remove /tmp/hub-agent-1
|
|
```
|
|
|
|
Key properties:
|
|
- Each worktree has its own working directory and index
|
|
- All worktrees share the same `.git` object store
|
|
- Commits in one worktree are immediately visible in another
|
|
- Cannot check out the same branch in two worktrees
|