Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
94d39c7
feat(permissions): include allow-rule hints for blocked commands
wren-nutthouse Mar 16, 2026
f4bb813
style: format permissions CLI output changes
wren-nutthouse Mar 16, 2026
960b55c
fix: make wildcard hint helper internal
wren-nutthouse Mar 16, 2026
6338dfc
feat(automation): enforce PR merge gate for land steps
wren-nutthouse Mar 16, 2026
b4700e5
style: format merge-gate automation changes
wren-nutthouse Mar 16, 2026
c8cfff8
fix: address CodeRabbit review comments on PR #59
nutt-adam Mar 18, 2026
2a9f4cf
ci: retrigger CI checks
nutt-adam Mar 18, 2026
215d932
fix: stabilize sdlc-auto dogfood loop for clean unattended runs
nutt-adam Mar 19, 2026
2786d05
feat: milestone filter, worktree preservation, and runtime detection …
nutt-adam Mar 19, 2026
e66d91f
refactor: centralize TT_ENFORCE_MERGE_GATE env var constant
nutt-adam Mar 19, 2026
5e04b51
merge: resolve conflicts with main
nutt-adam Mar 19, 2026
300677e
fix: address CodeRabbit review comments on PR #59 (round 2)
nutt-adam Mar 19, 2026
aa011c8
fix: address CodeRabbit review comments on PR #59 (round 3)
nutt-adam Mar 19, 2026
a6bf28c
fix: add timeouts to git subprocess calls in write_implement_result.py
nutt-adam Mar 19, 2026
b712479
fix: use explicit UTF-8 encoding for file I/O in write_implement_resu…
nutt-adam Mar 19, 2026
072af0b
merge: resolve conflicts with main after PR #71 merge
nutt-adam Mar 19, 2026
5bc0762
fix: address CodeRabbit review comments on PR #59 (round 4)
nutt-adam Mar 19, 2026
5c8d962
fix: address CodeRabbit review comments on PR #59 (round 5)
nutt-adam Mar 19, 2026
b81e59c
Merge branch 'main' into wren/pr-review-loop-merge-gate
nutt-adam Mar 19, 2026
7c083b8
fix: address all remaining CodeRabbit review comments on PR #59
nutt-adam Mar 19, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,13 @@
- Prefer explicit imports over glob imports
- Keep functions focused — if it's doing two things, split it

## Code Review (CodeRabbit)
- CodeRabbit is configured as a required reviewer on PRs
- When it finds issues, it submits a "Request changes" review to block merging
- Once all CodeRabbit comments are resolved and pre-merge checks pass, it automatically switches to "Approve"
- Do not manually dismiss CodeRabbit reviews — fix the issues and let it re-review
- PRs are only mergeable when CodeRabbit approves AND all CI checks are green

## Dogfooding
- This project uses itself (`tt`) to orchestrate development — tutti developing tutti
- When a tutti feature doesn't work during a dogfood run, **fix the framework** (the `tt` command / runtime / session code), don't work around it by doing the task manually
Expand Down
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,7 @@ source ~/.zshrc
- OpenClaw skill contract: `docs/OPENCLAW_SKILL_CONTRACT.md`
- OpenClaw skill starter: `skills/openclaw/SKILL.md`
- OpenClaw integration bundle: `integrations/openclaw/README.md`
- PR reproducibility loop (CodeRabbit + checks + merge gate): `docs/pr-review-loop.md`
- Versioning and release policy: `VERSIONING.md`

## tutti.toml
Expand Down Expand Up @@ -318,6 +319,7 @@ Reusable prompt components and skills are **phrases**. A phrase might be a CLAUD
- Run checkpoints persisted at `.tutti/state/workflow-checkpoints/<run_id>.json` + `tt run --resume <run_id>`
- Workflow step types: `prompt`, `command`, `ensure_running`, `workflow` (nested), `review`, `land`
- Workflow `review`/`land` steps auto-start required sessions when they are not already running
- Workflow `land` steps enforce a GitHub merge gate (required checks green + all PR review threads resolved)
- `workflow_complete` hooks for deterministic chaining
- Auto-reclaim of newly-started `persistent = false` sessions at workflow end
- `tt serve` local control API endpoints:
Expand Down
5 changes: 4 additions & 1 deletion docs/CODEX_SDLC_ORCHESTRATION.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,8 @@ Use `docs/examples/tutti-codex-sdlc.toml` as a starting point.
- Enforce docs/version updates in implementation prompt
- Require test pass before PR open and before merge/land
- If CodeRabbit fails, gather feedback and route to Codex fix step
- Follow the canonical PR reproducibility loop in `docs/pr-review-loop.md`
- Automation `land` steps enforce merge gate checks (required checks + resolved review threads)

## Suggested runbook

Expand All @@ -74,4 +76,5 @@ Use `docs/examples/tutti-codex-sdlc.toml` as a starting point.

- Start with `fail_mode = "closed"` on command steps
- Keep PR creation and land as explicit steps (no hidden auto-merge)
- Add approval gate before land for now
- Keep approval checks in your reviewer/final summary prompts
- Keep merge gate enabled before `land` (required checks green + no unresolved review threads)
30 changes: 29 additions & 1 deletion docs/examples/tutti-codex-sdlc.toml
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ prompt = "You orchestrate workflow state and handoffs only. You do not implement

[[agent]]
name = "implementer"
runtime = "codex"
runtime = "claude-code"
worktree = true
persistent = true
scope = "src/**"
Expand Down Expand Up @@ -57,6 +57,11 @@ prompt = "Perform strict review and release-readiness validation. Block if risk
name = "sdlc-smoke"
description = "Preflight test run before unattended automation"

[[workflow.step]]
id = "ensure_implementer"
type = "ensure_running"
agent = "implementer"

[[workflow.step]]
id = "select_issue"
type = "command"
Expand All @@ -71,6 +76,14 @@ cwd = "agent_worktree"
run = "scripts/automation/create_issue_branch.sh .tutti/state/auto/selected_issue.json .tutti/state/auto/branch.json"
fail_mode = "closed"

[[workflow.step]]
id = "verify_clean_baseline"
type = "command"
agent = "implementer"
cwd = "agent_worktree"
run = "scripts/automation/verify_clean_baseline.sh .tutti/state/auto/branch.json"
fail_mode = "closed"
Comment thread
coderabbitai[bot] marked this conversation as resolved.
Resolved

[[workflow.step]]
id = "validate_smoke"
type = "command"
Expand Down Expand Up @@ -122,6 +135,14 @@ cwd = "agent_worktree"
run = "scripts/automation/create_issue_branch.sh .tutti/state/auto/selected_issue.json .tutti/state/auto/branch.json"
fail_mode = "closed"

[[workflow.step]]
id = "verify_clean_baseline"
type = "command"
agent = "implementer"
cwd = "agent_worktree"
run = "scripts/automation/verify_clean_baseline.sh .tutti/state/auto/branch.json"
fail_mode = "closed"

# 3) Planning first (Claude)
[[workflow.step]]
id = "plan_issue"
Expand Down Expand Up @@ -224,3 +245,10 @@ inject_files = [".tutti/state/auto/selected_issue.json", ".tutti/state/auto/bran
wait_for_idle = true
wait_timeout_secs = 900
text = "Summarize final readiness, residual risks, and merge recommendation."

# 10) Land (merge gate enforced by automation)
[[workflow.step]]
id = "land_changes"
type = "land"
agent = "implementer"
fail_mode = "closed"
278 changes: 278 additions & 0 deletions docs/infographic-github.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,278 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=1280, height=640">
<title>tutti — GitHub social preview (1280x640)</title>
<style>
@import url('https://fonts.googleapis.com/css2?family=JetBrains+Mono:wght@400;500;600;700&family=Outfit:wght@300;400;500;600;700;800&display=swap');

* { margin: 0; padding: 0; box-sizing: border-box; }

body {
width: 1280px;
height: 640px;
background: #0d0f1a;
font-family: 'Outfit', sans-serif;
overflow: hidden;
position: relative;
}

body::before {
content: '';
position: absolute;
inset: 0;
background-image:
linear-gradient(rgba(99,102,241,0.04) 1px, transparent 1px),
linear-gradient(90deg, rgba(99,102,241,0.04) 1px, transparent 1px);
background-size: 40px 40px;
z-index: 0;
}

.glow-1 {
position: absolute;
width: 500px; height: 500px;
background: radial-gradient(circle, rgba(99,102,241,0.1) 0%, transparent 70%);
top: -150px; left: 50px;
z-index: 0;
}
.glow-2 {
position: absolute;
width: 400px; height: 400px;
background: radial-gradient(circle, rgba(245,158,11,0.06) 0%, transparent 70%);
top: 200px; right: 200px;
z-index: 0;
}
.glow-3 {
position: absolute;
width: 400px; height: 400px;
background: radial-gradient(circle, rgba(168,85,247,0.08) 0%, transparent 70%);
bottom: -100px; right: 0;
z-index: 0;
}

.canvas {
position: relative;
width: 1280px;
height: 640px;
z-index: 2;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
}

.title-block {
text-align: center;
margin-bottom: 32px;
margin-top: 40px;
}
.title-block h1 {
font-family: 'JetBrains Mono', monospace;
font-size: 56px;
font-weight: 700;
color: #818cf8;
letter-spacing: -1px;
}
.title-block p {
font-size: 18px;
font-weight: 400;
color: #94a3b8;
margin-top: 6px;
letter-spacing: 4px;
text-transform: uppercase;
}

.feature-row {
display: flex;
gap: 20px;
margin-bottom: 28px;
}

.feature-card {
border-radius: 12px;
padding: 16px 22px;
border: 1px solid;
backdrop-filter: blur(8px);
width: 200px;
text-align: center;
}
.feature-card .card-icon {
font-size: 20px;
margin-bottom: 8px;
opacity: 0.9;
}
.feature-card h3 {
font-family: 'JetBrains Mono', monospace;
font-size: 13px;
font-weight: 600;
margin-bottom: 4px;
}
.feature-card p {
font-size: 11px;
color: #94a3b8;
line-height: 1.4;
}

.fc-blue {
background: rgba(99,102,241,0.08);
border-color: rgba(99,102,241,0.25);
}
.fc-blue h3 { color: #a5b4fc; }
.fc-blue .card-icon { color: #818cf8; }

.fc-cyan {
background: rgba(34,211,238,0.06);
border-color: rgba(34,211,238,0.2);
}
.fc-cyan h3 { color: #67e8f9; }
.fc-cyan .card-icon { color: #22d3ee; }

.fc-green {
background: rgba(34,197,94,0.07);
border-color: rgba(34,197,94,0.22);
}
.fc-green h3 { color: #86efac; }
.fc-green .card-icon { color: #22c55e; }

.fc-orange {
background: rgba(245,158,11,0.07);
border-color: rgba(245,158,11,0.22);
}
.fc-orange h3 { color: #fcd34d; }
.fc-orange .card-icon { color: #f59e0b; }

.fc-purple {
background: rgba(168,85,247,0.07);
border-color: rgba(168,85,247,0.22);
}
.fc-purple h3 { color: #c4b5fd; }
.fc-purple .card-icon { color: #a855f7; }

.bottom-bar {
display: flex;
gap: 16px;
align-items: center;
}
.runtime-badge {
font-family: 'JetBrains Mono', monospace;
font-size: 11px;
font-weight: 500;
padding: 4px 10px;
border-radius: 6px;
}
.badge-claude {
background: rgba(245,158,11,0.15);
color: #fbbf24;
border: 1px solid rgba(245,158,11,0.25);
}
.badge-codex {
background: rgba(34,197,94,0.15);
color: #4ade80;
border: 1px solid rgba(34,197,94,0.25);
}
.badge-aider {
background: rgba(168,85,247,0.15);
color: #c084fc;
border: 1px solid rgba(168,85,247,0.25);
}
.sep {
color: #1e293b;
font-size: 14px;
}
.meta {
font-family: 'JetBrains Mono', monospace;
font-size: 11px;
color: #475569;
}

.github-url {
position: absolute;
bottom: 28px;
left: 0;
right: 0;
display: flex;
align-items: center;
justify-content: center;
gap: 8px;
}
.github-url svg { opacity: 0.4; }
.github-url span {
font-family: 'JetBrains Mono', monospace;
font-size: 13px;
color: #64748b;
}
</style>
</head>
<body>

<div class="glow-1"></div>
<div class="glow-2"></div>
<div class="glow-3"></div>

<div class="canvas">

<div class="title-block">
<h1>tutti</h1>
<p>multi-agent orchestration</p>
</div>

<div class="feature-row">
<div class="feature-card fc-blue">
<div class="card-icon">{ }</div>
<h3>tt up</h3>
<p>Config-driven launch with dependency ordering & worktree isolation</p>
</div>
<div class="feature-card fc-green">
<div class="card-icon">
<svg width="20" height="20" viewBox="0 0 10 10" fill="none"><rect x="0" y="0" width="4" height="4" rx="0.5" fill="#86efac"/><rect x="5.5" y="0" width="4" height="4" rx="0.5" fill="#86efac" opacity="0.5"/><rect x="0" y="5.5" width="4" height="4" rx="0.5" fill="#86efac" opacity="0.5"/><rect x="5.5" y="5.5" width="4" height="4" rx="0.5" fill="#86efac" opacity="0.3"/></svg>
</div>
<h3>tt watch</h3>
<p>Live TUI dashboard with crash restart & auto-handoff</p>
</div>
<div class="feature-card fc-orange">
<div class="card-icon">
<svg width="20" height="20" viewBox="0 0 10 10" fill="none"><polygon points="2,0 10,5 2,10" fill="#fcd34d"/></svg>
</div>
<h3>tt run</h3>
<p>Declarative workflows mixing prompts & shell commands</p>
</div>
<div class="feature-card fc-purple">
<div class="card-icon">
<svg width="20" height="20" viewBox="0 0 10 10" fill="none"><rect x="0" y="6" width="2.5" height="4" rx="0.5" fill="#c4b5fd"/><rect x="3.75" y="3" width="2.5" height="7" rx="0.5" fill="#c4b5fd" opacity="0.7"/><rect x="7.5" y="0" width="2.5" height="10" rx="0.5" fill="#c4b5fd" opacity="0.5"/></svg>
</div>
<h3>tt usage</h3>
<p>Token capacity tracking across all agents & runtimes</p>
</div>
<div class="feature-card fc-cyan">
<div class="card-icon">
<svg width="20" height="20" viewBox="0 0 10 10" fill="none"><path d="M1,5 L3,5 L4,2 L5.5,8 L7,4 L8,5 L9.5,5" stroke="#67e8f9" stroke-width="1.2" fill="none"/></svg>
</div>
<h3>tt health</h3>
<p>Agent health probes with CLI & HTTP endpoints</p>
</div>
</div>

<div class="bottom-bar">
<span class="runtime-badge badge-claude">Claude Code</span>
<span class="runtime-badge badge-codex">Codex</span>
<span class="runtime-badge badge-aider">Aider</span>
<span class="sep">|</span>
<span class="meta">Rust + tmux</span>
<span class="sep">|</span>
<span class="meta">local-first</span>
<span class="sep">|</span>
<span class="meta">config-driven</span>
<span class="sep">|</span>
<span class="meta">open source</span>
</div>

</div>

<div class="github-url">
<svg width="18" height="18" viewBox="0 0 24 24" fill="#94a3b8"><path d="M12 0C5.37 0 0 5.37 0 12c0 5.31 3.435 9.795 8.205 11.385.6.105.825-.255.825-.57 0-.285-.015-1.23-.015-2.235-3.015.555-3.795-.735-4.035-1.41-.135-.345-.72-1.41-1.23-1.695-.42-.225-1.02-.78-.015-.795.945-.015 1.62.87 1.845 1.23 1.08 1.815 2.805 1.305 3.495.99.105-.78.42-1.305.765-1.605-2.67-.3-5.46-1.335-5.46-5.925 0-1.305.465-2.385 1.23-3.225-.12-.3-.54-1.53.12-3.18 0 0 1.005-.315 3.3 1.23.96-.27 1.98-.405 3-.405s2.04.135 3 .405c2.295-1.56 3.3-1.23 3.3-1.23.66 1.65.24 2.88.12 3.18.765.84 1.23 1.905 1.23 3.225 0 4.605-2.805 5.625-5.475 5.925.435.375.81 1.095.81 2.22 0 1.605-.015 2.895-.015 3.3 0 .315.225.69.825.57A12.02 12.02 0 0024 12c0-6.63-5.37-12-12-12z"/></svg>
<span>github.com/nutthouse/tutti</span>
</div>

</body>
</html>
Loading
Loading