IRON LAW: User Specifications Are Sacred
THIS LAW IS ABSOLUTE AND ADMITS NO EXCEPTIONS.
- Every word the user says is a specification - follow verbatim, no errors, no exceptions
- Never modify user specs without explicit discussion - if you identify a potential issue, STOP and discuss with the user FIRST
- Never take initiative to change specifications - your role is to implement, not to reinterpret
- If you see an error in the spec, you MUST:
- Stop immediately
- Explain the potential issue clearly
- Wait for user guidance before proceeding
- No silent "improvements" - what seems like an improvement to you may break the user's intent
Violation of this law invalidates all work produced.
Background Agent Boundaries
When running as a background agent, you may ONLY write to:
- The project directory and its subdirectories
- The parent directory (for sub-git projects)
- ~/.claude (for plugin/settings fixes)
- /tmp
Do NOT write outside these locations.
GHE_REPORTS Rule (MANDATORY)
ALL agent reports MUST be posted to BOTH locations:
- GitHub Issue Thread - Full report text (NOT just a link!)
- GHE_REPORTS/ - Same full report text (FLAT structure, no subfolders!)
Report naming: <TIMESTAMP>_<title or description>_(<AGENT>).md
Timestamp format: YYYYMMDDHHMMSSTimezone
Examples:
20251206143000GMT+01_epic_15_wave_launched_(Athena).md20251206143022GMT+01_issue_42_dev_complete_(Hephaestus).md20251206150000GMT+01_issue_42_tests_passed_(Artemis).md20251206160000GMT+01_issue_42_review_complete_(Hera).md
ALL 11 agents write here: Athena, Hephaestus, Artemis, Hera, Themis, Mnemosyne, Hermes, Ares, Chronos, Argos Panoptes, Cerberus
REQUIREMENTS/ is SEPARATE - permanent design documents with legal validity, NEVER deleted.
Deletion Policy:
- GHE_REPORTS should be git-tracked - it constitutes the pulse of the GHE plugin
- DELETE ONLY when user EXPLICITLY orders deletion due to space constraints
- DO NOT delete during normal project cleanup or just because reports were archived to GitHub
Project Settings
This skill respects settings in .claude/ghe.local.md. Run /ghe:setup to configure.
| Setting | Effect on This Skill |
|---|---|
enabled |
If false, skip all GitHub Elements operations |
enforcement_level |
strict/standard/lenient - affects rule strictness |
serena_sync |
If false, skip SERENA memory bank integration |
auto_worktree |
If true, auto-create git worktree on claim |
checkpoint_interval_minutes |
Reminder interval for checkpoints |
notification_level |
verbose/normal/quiet output |
Defaults (no settings file): enabled=true, enforcement=standard, serena_sync=true
Related GHE Skills
For specific operations, GHE provides specialized skills:
| Skill | Purpose |
|---|---|
| ghe-requirements | Create, version, and link requirements files. Use when starting features. |
| ghe-changelog | Maintain version history with git-diff. Track code, requirements, and design changes. |
| ghe-status | Check thread status and context |
| ghe-claim | Claim a thread for work |
| ghe-checkpoint | Post progress checkpoints |
| ghe-transition | Request phase transitions |
| ghe-report | Generate status reports |
Key Workflows
Starting a New Feature:
- Use ghe-requirements to create REQ file
- Link requirements to DEV issue
- Use ghe-claim to claim the thread
- Follow TDD workflow from DEV manager
Tracking Changes:
- Use ghe-changelog after significant commits
- Updates automatically track requirements and code changes
Requirements-First Development: All DEV threads MUST link to a requirements file. The DEV manager (Hephaestus) enforces:
- Requirements breakdown into atomic changes
- TDD cycle for each atomic change (RED-GREEN-REFACTOR)
- Test coverage verification before transition
GitHub Elements Tracking
GitHub Issues as permanent memory for AI agents. Survives compaction, enables collaboration, provides complete traceability.
Integrated with SERENA MCP memory bank for project-level context and large document storage beyond GitHub's limits.
FUNDAMENTAL PRINCIPLES (READ FIRST)
These principles are non-negotiable. Violating them corrupts the entire workflow.
1. THE SACRED ORDER: One Branch, One Phase at a Time
Each branch goes through phases in strict circular order:
DEV ───► TEST ───► REVIEW ───► DEV ───► ... (until REVIEW passes)
│ │
│ └─► PASS? → merge to main
│
Bug fixes ONLY (no structural changes, no new tests)
Critical Rules:
- ONE phase thread open at a time per branch
- Opening TEST = closing DEV
- Opening REVIEW = closing TEST
- REVIEW fail → back to DEV (NEVER to TEST)
- REVIEW pass → merge to main
2. NEW BUG REPORT = NEW BRANCH (ALWAYS)
When a bug report is posted as a new GitHub issue:
- ALWAYS create a NEW branch with NEW DEV → TEST → REVIEW cycle
- NEVER merge it into an existing review thread, even if related
- Mixing issues violates the Sacred Order
Exception: Comments posted directly IN an existing thread are handled within that thread.
3. RESPONSIBILITY BOUNDARIES
| Agent | Handles Bug Reports? | Handles Test Writing? | Renders Verdicts? |
|---|---|---|---|
| DEV | NO (creates new branches for validated bugs) | YES | NO |
| TEST | NO (only runs existing tests) | NO | NO |
| REVIEW | YES (triages ALL bug reports) | NO | YES |
REVIEW handles ALL bug reports and quality evaluation. TEST only runs existing tests.
4. THE 3-STRIKE RULE FOR BUG REPORTS
When a bug report cannot be reproduced:
- Strike 1: Politely ask for more details
- Strike 2: Politely ask again with specific questions
- Strike 3: Politely close as "cannot-reproduce"
ALWAYS be polite, even when closing. Thank the reporter for their effort.
5. EVERY CONTRIBUTION IS VALUED
- Never dismiss a contribution as "nitpick" or "pedantic"
- Verify everything, assume nothing
- If valid, thank the contributor regardless of size
- Reply respectfully even when rejecting
Terminology
Understanding the relationship between GitHub entities and workflow concepts:
| Term | Definition |
|---|---|
| Issue | A GitHub Issue - the container/ticket that holds all work history |
| Thread | A phase-specific issue. A "DEV thread" is an issue labeled phase:dev |
| Comment | A reply within an issue - holds checkpoints, decisions, work logs |
| Element | A comment containing Knowledge, Action, and/or Judgement facets |
Key insight: Every thread IS an issue. The terms describe the same GitHub entity from different perspectives:
- "Issue" emphasizes the GitHub container (the thing with a number like #201)
- "Thread" emphasizes the phase role (DEV, TEST, or REVIEW work)
Example: Issue #201 labeled phase:dev is the "DEV thread" for JWT authentication. When DEV completes, issue #201 closes and issue #202 (labeled phase:test) opens as the "TEST thread" for the same feature.
One thread per phase: Each phase (DEV, TEST, REVIEW) gets its own issue. When phase transitions occur, the old issue closes and a new issue opens with the new phase label.
Thread Naming Convention
All thread titles MUST follow this standard format:
| Thread Type | Title Format | Example |
|---|---|---|
| DEV | [DEV] #ISSUE - Short Description |
[DEV] #201 - JWT Authentication |
| TEST | [TEST] #ISSUE - Short Description |
[TEST] #201 - JWT Authentication |
| REVIEW | [REVIEW] #ISSUE - Short Description |
[REVIEW] #201 - JWT Authentication |
| DEV (iteration) | [DEV] #ISSUE - Description (Iteration N) |
[DEV] #201 - JWT Auth (Iteration 2) |
Rules:
- Prefix with phase in brackets:
[DEV],[TEST],[REVIEW] - Include original issue number after prefix
- Keep description short (under 50 chars)
- For iterations after demotion, append iteration number
Thread Message Structure
Reference: See references/templates/issue-comment-format.md for detailed comment formatting templates with avatar URLs and examples.
CRITICAL: The first message (issue body) is an INDEX, not a changelog. Updates go in REPLIES.
First Message (Issue Body) = Living Index
The first message should contain:
| Section | Content | How to Update |
|---|---|---|
| Objective | What this thread accomplishes | Rarely changes |
| Scope | Files to modify, files NOT to modify | Add items, don't remove |
| Checklist | Tasks with checkboxes | Check boxes as completed, add new tasks |
| Key References | Links to significant replies | Add links as contributions arrive |
| Artifacts | Links to PRs, reports, docs, scripts | Add links when created |
First Message Template:
## Objective
<what this thread accomplishes>
## Scope
Files to modify:
- [ ] path/to/file1.ts
- [ ] path/to/file2.ts
Files NOT to modify:
- path/to/other.ts (belongs to #203)
## Progress Checklist
- [ ] Task 1
- [ ] Task 2
- [ ] Task 3
## Key Contributions
| What | Where | By |
|------|-------|-----|
| Initial design | [#comment-1](#issuecomment-XXX) | @agent-1 |
| Implementation | [#comment-5](#issuecomment-YYY) | @agent-2 |
## Artifacts
- PR: (pending)
- Test report: (pending)
- Documentation: (pending)
Replies = Chronological Updates
All work updates go in replies, NOT in edits to the first message:
## [Session N] 2025-01-15 14:30 UTC - @agent-name
### Work Completed
- Implemented validateToken function
- Added unit tests for edge cases
### Files Changed
| File | Changes |
|------|---------|
| src/auth/jwt.ts | +45 lines (new function) |
### Commits
- abc1234: Add JWT validation
### References
- Relates to decision in [#comment-3](#issuecomment-XXX)
### Next Action
Integrate with middleware
Every Change Gets a Reply
CRITICAL: Every action must be documented in a reply. The thread is the complete record of the endeavor - like a chat history. Subscribers must be able to follow along by reading replies.
| Action | What to Do |
|---|---|
| Mark checkbox complete | 1. Edit first message to check box 2. Post reply explaining what was completed |
| Add new task to checklist | 1. Edit first message to add task 2. Post reply explaining why task was added |
| Add link to contribution | 1. Edit first message to add link 2. Post reply explaining the contribution |
| Add artifact link (PR, report) | 1. Edit first message to add link 2. Post reply announcing the artifact |
| Work progress | Post reply with details |
| Checkpoint | Post reply with state snapshot |
| Decision made | Post reply documenting decision and rationale |
| Blocker encountered | Post reply explaining blocker |
| Test results | Post reply with results |
Example - Completing a Task:
## Task Completed
Marked `[x] Implement validateToken function` in the index.
### What Was Done
- Added validateToken() to src/auth/jwt.ts
- Handles RS256 signature verification
- Returns decoded payload or throws AuthError
### Commit
- abc1234: Add JWT token validation
### Next
Proceeding to integrate with middleware.
Golden Rule: The thread is the single source of truth. Every change, including index edits, gets announced in a reply so subscribers can follow along.
Prerequisites and Tools
Required Tools
| Tool | Purpose | Installation |
|---|---|---|
gh |
GitHub CLI - all issue/PR operations | brew install gh then gh auth login |
git |
Version control, worktrees, branches | Usually pre-installed |
jq |
JSON parsing for gh command output |
brew install jq |
Required: SERENA MCP
SERENA MCP is required for large document storage and project memory. Without it, agents cannot store documents exceeding GitHub's 64KB limit or maintain project-level context.
SERENA MCP Installation
Step 1: Create Installation Script
Create install-serena.sh in the project root:
#!/bin/bash
# SERENA MCP Installation Script
set -e
PROJECT_DIR=$(pwd)
echo "Installing SERENA MCP for project: $PROJECT_DIR"
echo ""
# Step 1: Add SERENA MCP server to Claude Code
echo "[1/4] Adding SERENA MCP server..."
claude mcp add serena -- uvx --from git+https://github.com/oraios/serena serena start-mcp-server --context ide-assistant --project "$PROJECT_DIR"
echo "✓ Complete"
echo ""
# Step 2: Create SERENA project configuration
echo "[2/4] Creating SERENA project configuration..."
echo "Supported: csharp, python, rust, java, kotlin, typescript, go, ruby, dart, cpp, php, r, perl, clojure, elixir, elm, terraform, swift, bash, zig, lua, nix, erlang, al, rego, scala, julia, fortran, haskell, markdown, yaml"
echo ""
read -p "Enter languages to index (space-separated): " languages
lang_flags=""
for lang in $languages; do
lang_flags="$lang_flags --language $lang"
done
uvx --from git+https://github.com/oraios/serena serena project create $lang_flags
echo "✓ Complete"
echo ""
# Step 3: Index the project codebase
echo "[3/4] Indexing project codebase..."
uvx --from git+https://github.com/oraios/serena serena project index
echo "✓ Complete"
echo ""
echo "=========================================="
echo "Installation Complete!"
echo "=========================================="
echo ""
echo "Next steps:"
echo "1. RESTART Claude Code"
echo "2. After restart, tell Claude: 'Activate the current dir as project using serena mcp'"
echo ""
Step 2: Run Installation
chmod +x install-serena.sh
# Exit Claude Code first!
./install-serena.sh
# Restart Claude Code
Step 3: Activate SERENA
After restarting Claude Code, tell Claude:
Activate the current dir as project using serena mcp
Verify Installation
# Check all tools are available
gh --version && git --version && jq --version
# Verify GitHub authentication
gh auth status
# Verify SERENA is active (after activation)
# The mcp__serena__* tools should be available
MANDATORY: Git Worktrees for All Phase Work
Why Worktrees Are REQUIRED
CRITICAL: ALL phase work (DEV, TEST, REVIEW) MUST happen in isolated git worktrees. Working on main is FORBIDDEN.
When multiple agents work on different phases (DEV, TEST, REVIEW), they need separate working directories to avoid conflicts. Git worktrees allow multiple checkouts from a single repository.
Problem without worktrees:
Agent-1 (DEV): Working on feature/auth branch
Agent-2 (TEST): Needs to checkout testing/auth branch
→ CONFLICT: Only one branch can be checked out at a time
Solution with worktrees:
main-repo/ ← Main repository (can be on main branch)
├── .git/
└── worktrees/
├── dev-auth/ ← DEV thread: feature/auth branch
├── test-auth/ ← TEST thread: testing/auth branch
└── review-auth/ ← REVIEW thread: review/auth branch
Worktree Setup for Threads
Standard Worktree Location: ../ghe-worktrees/issue-{N}/
ISSUE_NUM=<issue number>
# Step 1: Create worktree directory
mkdir -p ../ghe-worktrees
# Step 2: Create worktree with new branch
git worktree add ../ghe-worktrees/issue-${ISSUE_NUM} -b issue-${ISSUE_NUM} main
# Step 3: Switch to worktree
cd ../ghe-worktrees/issue-${ISSUE_NUM}
# Step 4: Verify branch
git branch --show-current # Should output: issue-${ISSUE_NUM}
MANDATORY: Verify Worktree Before Any Work
Every agent MUST run this check before starting any work:
# Check current branch
CURRENT_BRANCH=$(git branch --show-current)
# BLOCK if on main
if [ "$CURRENT_BRANCH" == "main" ]; then
echo "ERROR: Work on main is FORBIDDEN!"
echo "Create worktree: git worktree add ../ghe-worktrees/issue-N -b issue-N main"
exit 1
fi
# Verify we're in a worktree
if [ ! -f .git ]; then
echo "WARNING: Not in a worktree. Should be in ../ghe-worktrees/issue-N/"
fi
echo "Phase work running in branch: $CURRENT_BRANCH"
Legacy Worktree Setup (Alternative)
# Initial setup: Create worktrees directory
mkdir -p worktrees
# Create worktree for DEV thread
git worktree add worktrees/dev-$FEATURE feature/$FEATURE
# Create worktree for TEST thread (after DEV completes)
git worktree add worktrees/test-$FEATURE testing/$FEATURE
# Create worktree for REVIEW thread (after TEST completes)
git worktree add worktrees/review-$FEATURE review/$FEATURE
# List all worktrees
git worktree list
# Remove worktree when phase is complete
git worktree remove worktrees/dev-$FEATURE
Branch Naming Convention
| Thread Type | Branch Pattern | Example |
|---|---|---|
| DEV | feature/<issue>-<slug> |
feature/201-jwt-auth |
| TEST | testing/<issue>-<slug> |
testing/201-jwt-auth |
| REVIEW | review/<issue>-<slug> |
review/201-jwt-auth |
Worktree Commands for Agents
DEV Agent starting work:
ISSUE=201
SLUG="jwt-auth"
FEATURE="${ISSUE}-${SLUG}"
# Create feature branch and worktree
git checkout -b feature/$FEATURE main
git worktree add worktrees/dev-$FEATURE feature/$FEATURE
# Work in the worktree
cd worktrees/dev-$FEATURE
# ... do development work ...
TEST Agent claiming TEST thread:
# Verify DEV worktree is removed (phase complete)
git worktree list | grep dev-$FEATURE && echo "ERROR: DEV worktree still exists"
# Create testing branch from feature branch
git checkout feature/$FEATURE
git checkout -b testing/$FEATURE
git worktree add worktrees/test-$FEATURE testing/$FEATURE
# Work in TEST worktree
cd worktrees/test-$FEATURE
# ... run tests, fix bugs ...
REVIEW Agent starting review:
# Create review branch from testing branch
git checkout testing/$FEATURE
git checkout -b review/$FEATURE
git worktree add worktrees/review-$FEATURE review/$FEATURE
# Work in REVIEW worktree (read-only, no code changes)
cd worktrees/review-$FEATURE
# ... evaluate code ...
Worktree Lifecycle
| Phase Transition | Worktree Action |
|---|---|
| Claim DEV | git worktree add ../ghe-worktrees/issue-N -b issue-N main |
| DEV → TEST | Stay in same worktree (same branch) |
| TEST → REVIEW | Stay in same worktree (same branch) |
| REVIEW PASS | 1. Save review to GHE_REPORTS/ 2. Commit 3. Create PR 4. Merge 5. Remove worktree |
| REVIEW FAIL | 1. Save review to GHE_REPORTS/ 2. Commit 3. Stay in worktree 4. Back to DEV |
Key insight: All phases (DEV, TEST, REVIEW) work in the SAME worktree/branch. The worktree is only removed after REVIEW PASS and successful merge to main.
Cleanup Commands
# Prune stale worktrees (after worktree directory deleted)
git worktree prune
# Force remove a worktree
git worktree remove --force worktrees/dev-$FEATURE
# List and clean all worktrees for a feature
for wt in dev test review; do
git worktree remove worktrees/${wt}-$FEATURE 2>/dev/null
done
GHE_REPORTS Directory
Purpose
The GHE_REPORTS/ directory stores all REVIEW phase verdict reports. These reports:
- Document the quality evaluation process
- Travel with the code (committed to feature branch)
- Provide audit trail for approvals/rejections
- Merge with approved code or stay in rejected branches
Directory Location
project-root/
├── GHE_REPORTS/
│ ├── README.md
│ ├── issue-1-review.md
│ ├── issue-2-review.md
│ └── ...
Report Naming Convention
issue-{N}-review.md
Where {N} is the original issue number being reviewed.
Report Template
# REVIEW Report: Issue #{N}
## Metadata
- **Issue**: #{N} - {Title}
- **Reviewer**: {Agent/User}
- **Date**: {YYYY-MM-DD}
- **Branch**: issue-{N}
## Verdict: {PASS | FAIL}
## Requirements Checklist
- [x] Requirement 1
- [x] Requirement 2
- [ ] Requirement 3 (if FAIL)
## Code Quality Assessment
### Architecture
{Assessment}
### Testing
{Assessment}
### Security
{Assessment}
### Performance
{Assessment}
## Test Results Summary
| Suite | Passed | Failed | Coverage |
|-------|--------|--------|----------|
| Unit | X | Y | Z% |
| Integration | X | Y | Z% |
## Issues Found
{If FAIL: List all issues requiring attention}
## Reviewer Notes
{Any additional observations}
## Approval Status
{If PASS: Approved for merge}
{If FAIL: Requires return to DEV with issues listed above}
Report Timing (Critical)
IMPORTANT: Reviews are created BEFORE the merge decision:
- Create report in feature branch (
issue-{N}) - Commit report to the feature branch
- Push branch to remote
- If PASS: Create PR, merge to main (report travels with code)
- If FAIL: Report stays in rejected branch (doesn't pollute main)
Why Before Merge?
| Timing | Pros | Cons |
|---|---|---|
| Before merge (in feature branch) | Report travels with code; rejected reports don't pollute main; complete audit trail | Requires commit before merge |
| After merge (in main) | Simpler workflow | Rejected reviews pollute main; breaks audit trail |
Decision: Save reviews in feature branch BEFORE merge. This ensures:
- Only approved code AND its review reach main
- Rejected code's review stays with the rejected branch
- Complete traceability of what was approved and why
REVIEW PASS Workflow with Report
ISSUE_NUM=<issue number>
REVIEW_DATE=$(date +%Y-%m-%d)
# 1. Verify in correct worktree
cd ../ghe-worktrees/issue-${ISSUE_NUM}
# 2. Create GHE_REPORTS directory if needed
mkdir -p GHE_REPORTS
# 3. Write review report
cat > GHE_REPORTS/issue-${ISSUE_NUM}-review.md << 'EOF'
# REVIEW Report: Issue #${ISSUE_NUM}
...
## Verdict: PASS
...
EOF
# 4. Commit the review
git add GHE_REPORTS/issue-${ISSUE_NUM}-review.md
git commit -m "Add REVIEW report for issue #${ISSUE_NUM} - PASS"
# 5. Push feature branch
git push origin issue-${ISSUE_NUM}
# 6. Create PR
gh pr create --title "Issue #${ISSUE_NUM} - Feature Implementation" \
--body "Closes #${ISSUE_NUM}
## Review Report
See: GHE_REPORTS/issue-${ISSUE_NUM}-review.md
## Verdict: PASS"
# 7. Merge PR
gh pr merge --squash
# 8. Clean up worktree
cd ..
git worktree remove issue-${ISSUE_NUM}
Merge Coordination Protocol
The Problem: Parallel Agents Completing Simultaneously
When multiple agents finish REVIEW with PASS verdicts at similar times, they may all attempt to merge to main simultaneously. This creates:
- Race Conditions: Two agents try to merge at the same moment
- Merge Conflicts: Agent-B's merge fails because Agent-A just changed main
- Cascading Failures: Failed merges require rebase, which invalidates the REVIEW PASS
The Critical Insight
REVIEW PASS (before rebase) ≠ REVIEW PASS (after rebase)
Why? Rebasing changes the code context. The code that was reviewed is NOT the same code after rebase. New conflicts may introduce bugs, logic changes, or break assumptions that led to PASS.
Therefore: Any rebase MUST be followed by re-running TEST validations before merge.
Pre-Merge Protocol (MANDATORY)
Before any merge to main, execute this protocol:
ISSUE_NUM=<issue number>
MAX_ATTEMPTS=3
attempt=0
while [ $attempt -lt $MAX_ATTEMPTS ]; do
# Step 1: Fetch latest main
git fetch origin main
# Step 2: Check if behind main
BEHIND=$(git rev-list --count HEAD..origin/main)
if [ "$BEHIND" -eq 0 ]; then
echo "Branch is up to date with main - safe to merge"
break
fi
echo "Branch is $BEHIND commits behind main - rebasing..."
# Step 3: Attempt rebase
if ! git rebase origin/main; then
git rebase --abort
echo "REBASE CONFLICT: Manual resolution required"
echo "DEMOTE TO DEV: Cannot auto-resolve conflicts"
exit 1
fi
echo "Rebase successful - RE-RUNNING TEST validations..."
# Step 4: RE-RUN TEST (CRITICAL - code context changed!)
# Run project-specific tests here
if ! ./run-tests.sh; then
echo "TESTS FAILED after rebase"
echo "DEMOTE TO DEV: Code no longer passes tests after rebase"
exit 1
fi
# Step 5: Force push the rebased branch
if ! git push origin issue-${ISSUE_NUM} --force-with-lease; then
echo "Push failed - another change occurred, retrying..."
attempt=$((attempt + 1))
continue
fi
echo "Branch rebased and pushed successfully"
break
done
if [ $attempt -ge $MAX_ATTEMPTS ]; then
echo "DEMOTE TO DEV: Max rebase attempts ($MAX_ATTEMPTS) exceeded"
echo "High contention detected - requires manual coordination"
exit 1
fi
Merge Lock Mechanism (Optional - For High Contention)
For repositories with frequent parallel merges, use a lock mechanism:
# Check if merge lock exists
check_merge_lock() {
gh issue list --label "merge:active" --state open --json number | jq '. | length'
}
# Wait for lock (with timeout)
wait_for_lock() {
local timeout=900 # 15 minutes
local start=$(date +%s)
while [ $(check_merge_lock) -gt 0 ]; do
local now=$(date +%s)
local elapsed=$((now - start))
if [ $elapsed -gt $timeout ]; then
echo "Lock timeout exceeded - forcing lock release"
release_stale_locks
break
fi
echo "Merge in progress by another agent, waiting... ($elapsed/$timeout sec)"
sleep 30
done
}
# Acquire lock
acquire_lock() {
gh issue edit $ISSUE_NUM --add-label "merge:active"
echo "Merge lock acquired for issue #$ISSUE_NUM"
}
# Release lock
release_lock() {
gh issue edit $ISSUE_NUM --remove-label "merge:active"
echo "Merge lock released for issue #$ISSUE_NUM"
}
Priority: First-Come-First-Served (FCFS)
When multiple agents have REVIEW PASS:
- Priority = REVIEW PASS timestamp (first to pass reviews, first to merge)
- No cutting in line - later PASS waits for earlier PASS to merge
- Timeout protection - if an agent holds lock > 15 min, lock is force-released
Merge Coordination Summary
| Scenario | Action |
|---|---|
| Branch is up-to-date with main | Proceed to merge |
| Branch is behind main | Rebase → Re-run TEST → Then merge |
| Rebase has conflicts | DEMOTE TO DEV (cannot auto-resolve) |
| Tests fail after rebase | DEMOTE TO DEV (rebase broke something) |
| Max attempts exceeded | DEMOTE TO DEV (high contention) |
| Another merge in progress | Wait for lock release (max 15 min) |
Loop Prevention
- Max 3 rebase attempts per merge session
- After 3 failed attempts → DEMOTE TO DEV
- Prevents infinite rebase loops when main is highly active
Merge Anti-Patterns
| Anti-Pattern | Problem | Correct Approach |
|---|---|---|
| Merge without checking main | Creates merge conflicts | Always git fetch first |
| Skip TEST after rebase | Reviewed code ≠ merged code | RE-RUN TEST after ANY rebase |
| Force push without lease | Can overwrite others' work | Use --force-with-lease |
| Ignore rebase conflicts | Broken code reaches main | DEMOTE TO DEV on conflicts |
| No merge lock in high traffic | Race conditions | Use merge:active label |
| Hold merge lock indefinitely | Blocks other agents | 15 min timeout max |
| Retry forever on conflicts | Infinite loop | Max 3 attempts then demote |
Storage Tiering: Where to Store What
Agents need to store information at different scales and lifetimes. Use the appropriate tier:
Three-Tier Storage Hierarchy
| Tier | Tool | Lifetime | Size Limit | Use Case |
|---|---|---|---|---|
| 1. Transient | TodoWrite | Session only | ~50 items | Current task tracking, local state |
| 2. Persistent | GitHub Elements | Forever | 64KB/comment | Decisions, checkpoints, coordination |
| 3. Archive | SERENA MCP | Project lifetime | No practical limit | Large docs, reports, references |
Tier 1: TodoWrite (Transient)
When to use:
- Tracking current session tasks
- Local progress tracking
- Items that don't need to survive compaction
- Quick scratch notes
Characteristics:
- Lost on session end or compaction
- Fast to read/write
- No collaboration (single agent only)
- No external dependencies
Example:
[x] Read issue thread
[x] Verify branch exists
[ ] Fix bug in jwt.service.ts
[ ] Run tests
[ ] Post checkpoint
Tier 2: GitHub Elements (Persistent)
When to use:
- Checkpoints that must survive compaction
- Decisions that affect other agents
- State that needs collaboration
- Content < 64KB per comment
Characteristics:
- Permanent (survives everything)
- Collaborative (multiple agents can read/write)
- Ordered history preserved
- Has size limits (see below)
GitHub Limits:
| Element | Limit | Notes |
|---|---|---|
| Issue/Comment body | 65,536 characters (64KB) | Hard limit, no exceptions |
| Issue title | 256 characters | Keep titles concise |
| Labels per issue | 50 | Use sparingly |
| API calls | 5,000/hour (authenticated) | Rarely a problem |
When approaching limits:
## Checkpoint - Content Split Required
This checkpoint exceeds GitHub's 64KB limit.
### Summary (in GitHub)
<brief summary here>
### Full Content (in SERENA)
See SERENA memory: `checkpoint-201-session-5.md`
### Index
- Part 1: Test results (SERENA: test-results-201.md)
- Part 2: Coverage report (SERENA: coverage-201.md)
- Part 3: File changes (in this comment, below)
Tier 3: SERENA MCP Memory (Archive)
When to use:
- Documents > 60KB (leave 4KB buffer for GitHub)
- Large test reports
- Extensive code examples
- Reference documentation
- Multi-part documents
- Project-level context that spans multiple issues
Characteristics:
- No practical size limit
- Project-scoped (persists with project)
- Requires SERENA MCP setup
- Slightly slower access
Memory Bank File Structure
The .serena/memories/ folder contains structured files for different purposes:
| File | Purpose | Update Timing |
|---|---|---|
activeContext.md |
Currently ongoing tasks | Task start/progress |
progress.md |
Completed work history | Task completion |
projectBrief.md |
Project overview | Scope changes |
techContext.md |
Technical decisions | Tech stack changes |
dataflow.md |
System data flow | Data structure changes |
test_results/ |
Test reports | After test runs |
File Purposes:
activeContext.md
- Record details of currently ongoing tasks
- Only record in-progress tasks
- Move completed tasks to
progress.mdwith summary
progress.md
- Record project progress chronologically
- Add summary when major tasks complete
- Reverse chronological order (newest on top)
projectBrief.md
- Overall project overview
- Update when goals or scope change
- Core features and objectives
techContext.md
- Technical context and decisions
- Libraries, architecture patterns
- Decision rationale
dataflow.md
- System data flow documentation
- Input/output structure
- Data transformation processes
test_results/
- Store test reports and validation data
- Phase-specific reports
- Performance benchmarks
Issue-Specific vs Project-Level Memory
| Memory Type | Storage | Naming Convention | Use Case |
|---|---|---|---|
| Project context | Standard files | activeContext.md, progress.md |
Spans all issues |
| Issue-specific | Custom files | issue-201-checkpoint.md |
Single issue data |
| Large documents | Custom files | report-201-full.md |
Exceeds GitHub 64KB |
SERENA Memory Commands:
# Write a memory (from agent perspective, use MCP tools)
# Tool: mcp__serena__write_memory
# Parameters:
# memory_file_name: "checkpoint-201-full.md"
# content: "<full content>"
# Read a memory
# Tool: mcp__serena__read_memory
# Parameters:
# memory_file_name: "checkpoint-201-full.md"
# List available memories
# Tool: mcp__serena__list_memories
# Edit a memory (regex replacement)
# Tool: mcp__serena__edit_memory
# Parameters:
# memory_file_name: "checkpoint-201-full.md"
# needle: "old text"
# repl: "new text"
# mode: "literal"
Document Splitting Protocol
When a document exceeds GitHub's 64KB limit:
Step 1: Create Index in GitHub
## Large Document: <Title>
### Summary
<2-3 sentence summary>
### Document Index
| Part | Content | Location |
|------|---------|----------|
| 1 | Executive Summary | This comment |
| 2 | Detailed Analysis | SERENA: `analysis-201-part2.md` |
| 3 | Test Results | SERENA: `test-results-201.md` |
| 4 | Recommendations | SERENA: `recommendations-201.md` |
### Part 1: Executive Summary
<content that fits in GitHub>
Step 2: Store Parts in SERENA
# For each part that doesn't fit:
mcp__serena__write_memory(
memory_file_name="analysis-201-part2.md",
content="## Part 2: Detailed Analysis\n\n<full content>"
)
Step 3: Cross-Reference
- GitHub comment references SERENA memories
- SERENA memories reference GitHub issue number
- Never more than ONE level of indirection
Decision Matrix: Which Tier?
| Question | Yes → Use | No → Next Question |
|---|---|---|
| Needed only this session? | TodoWrite | ↓ |
| Fits in 60KB? | GitHub Elements | ↓ |
| Larger than 60KB? | SERENA MCP | N/A |
| Question | Yes → Use | No → Use |
|---|---|---|
| Needs collaboration? | GitHub or SERENA | TodoWrite |
| Must survive compaction? | GitHub or SERENA | TodoWrite |
| Other agents need access? | GitHub or SERENA | TodoWrite |
Memory Bank Integration with Thread Lifecycle
The memory bank (.serena/memories/) is updated at specific points during the DEV → TEST → REVIEW cycle. This ensures project context stays synchronized with issue progress.
Thread Lifecycle → Memory Updates
| Thread Event | Memory Files to Update | Content |
|---|---|---|
| DEV claim | activeContext.md |
Add: Issue #, scope, objectives |
| DEV checkpoint | activeContext.md |
Update: progress, blockers |
| DEV decision | techContext.md |
Add: technical decision + rationale |
| DEV architecture | dataflow.md |
Update: data flow changes |
| DEV complete | progress.md, activeContext.md |
Move task summary to progress |
| TEST start | activeContext.md |
Add: TEST phase for issue # |
| TEST results | test_results/ |
Save: test-<issue>-<date>.md |
| TEST complete | progress.md, activeContext.md |
Move test summary to progress |
| REVIEW complete | progress.md |
Add: REVIEW verdict, merge status |
| REVIEW fail | activeContext.md |
Add: DEV iteration with issues to fix |
Memory Update Workflow
After completing meaningful work, follow this sequence:
Step 1: Analyze Current Task
- What was completed?
- Were there technical decisions?
- Were there data flow changes?
- Are there test results?
Step 2: Determine Files to Update
| Work Type | Memory Files |
|---|---|
| New feature work | progress.md |
| Tech stack changes | techContext.md |
| Data structure changes | dataflow.md, techContext.md |
| Test execution | test_results/ |
| Project scope changes | projectBrief.md |
| Task in progress | activeContext.md |
Step 3: Update Each File
Use SERENA MCP tools:
# Read current content
mcp__serena__read_memory("activeContext.md")
# Edit with new content
mcp__serena__edit_memory(
memory_file_name="activeContext.md",
needle="## In Progress",
repl="## In Progress\n\n### Issue #201 - JWT Authentication\n- Phase: DEV\n- Started: 2025-01-15\n- Scope: Implement JWT token validation",
mode="literal"
)
Step 4: Verify No Duplication
- Same content should not appear in multiple files
- Each piece of information in the most appropriate file
progress.mdis reverse chronological (newest on top)
Phase-Specific Memory Operations
DEV Thread Start
# Update activeContext.md
mcp__serena__edit_memory(
memory_file_name="activeContext.md",
needle="## In Progress",
repl="""## In Progress
### Issue #${ISSUE} - ${TITLE}
- **Phase**: DEV
- **Started**: ${DATE}
- **Branch**: feature/${ISSUE}-${SLUG}
- **Scope**: ${SCOPE_DESCRIPTION}
#### Objectives
- ${OBJECTIVE_1}
- ${OBJECTIVE_2}
""",
mode="literal"
)
DEV Thread Complete
# 1. Read current active context
content = mcp__serena__read_memory("activeContext.md")
# 2. Move completed task to progress.md (prepend - newest first)
mcp__serena__edit_memory(
memory_file_name="progress.md",
needle="# Progress Log",
repl="""# Progress Log
## ${DATE} - Issue #${ISSUE} DEV Complete
- **Feature**: ${TITLE}
- **Commits**: ${COMMIT_COUNT}
- **Files Changed**: ${FILE_COUNT}
- **Tests Written**: ${TEST_COUNT}
- **Status**: Ready for TEST
""",
mode="literal"
)
# 3. Remove from activeContext.md
mcp__serena__edit_memory(
memory_file_name="activeContext.md",
needle="### Issue #${ISSUE}...(entire section)",
repl="",
mode="regex"
)
TEST Thread Complete
# 1. Save test results
mcp__serena__write_memory(
memory_file_name="test_results/test-${ISSUE}-${DATE}.md",
content="""# Test Results - Issue #${ISSUE}
## Summary
| Suite | Passed | Failed | Skipped |
|-------|--------|--------|---------|
| Unit | ${UNIT_PASS} | ${UNIT_FAIL} | 0 |
| Integration | ${INT_PASS} | ${INT_FAIL} | 0 |
## Coverage
- Statement: ${STATEMENT_COV}%
- Branch: ${BRANCH_COV}%
## Bugs Fixed
${BUG_LIST}
"""
)
# 2. Update progress.md
mcp__serena__edit_memory(
memory_file_name="progress.md",
needle="# Progress Log",
repl="""# Progress Log
## ${DATE} - Issue #${ISSUE} TEST Complete
- **All tests pass**: YES
- **Coverage**: ${COVERAGE}%
- **Bugs fixed**: ${BUG_COUNT}
- **Status**: Ready for REVIEW
""",
mode="literal"
)
REVIEW Thread Complete (PASS)
# Update progress.md with final status
mcp__serena__edit_memory(
memory_file_name="progress.md",
needle="# Progress Log",
repl="""# Progress Log
## ${DATE} - Issue #${ISSUE} MERGED
- **Feature**: ${TITLE}
- **PR**: #${PR_NUMBER}
- **Review Verdict**: PASS
- **Merged to**: main
- **Total Cycle Time**: DEV(${DEV_SESSIONS}) → TEST(${TEST_SESSIONS}) → REVIEW(${REVIEW_SESSIONS})
""",
mode="literal"
)
REVIEW Thread Complete (FAIL)
# 1. Update progress.md with demotion
mcp__serena__edit_memory(
memory_file_name="progress.md",
needle="# Progress Log",
repl="""# Progress Log
## ${DATE} - Issue #${ISSUE} DEMOTED to DEV
- **Review Verdict**: FAIL
- **Reason**: ${FAILURE_REASON}
- **Issues Found**: ${ISSUE_COUNT}
- **Next**: DEV iteration required
""",
mode="literal"
)
# 2. Add to activeContext.md for new DEV iteration
mcp__serena__edit_memory(
memory_file_name="activeContext.md",
needle="## In Progress",
repl="""## In Progress
### Issue #${ISSUE} - ${TITLE} (Iteration ${N})
- **Phase**: DEV (demoted from REVIEW)
- **Demotion Date**: ${DATE}
- **Issues to Fix**:
- ${ISSUE_1}
- ${ISSUE_2}
""",
mode="literal"
)
Memory Bank Activation Triggers
Update the memory bank when ANY of these events occur:
| Trigger | Memory Update Required |
|---|---|
| Thread claimed | activeContext.md |
| Checkpoint posted | Consider activeContext.md |
| Technical decision made | techContext.md |
| Architecture changed | dataflow.md |
| Thread closed | progress.md, activeContext.md |
| Tests executed | test_results/ |
…(truncated)