Skip to content

Latest commit

 

History

History
442 lines (420 loc) · 19.5 KB

File metadata and controls

442 lines (420 loc) · 19.5 KB
tracker
kind project_slug api_key active_states terminal_states archive_state archive_after_days state_descriptions
linear
my-team-project
$LINEAR_API_KEY
Todo
In Progress
Verify
Document
Human Review
Done
Blocked
Archive
Closed
Cancelled
Canceled
Duplicate
Archive
30
Todo In Progress Verify Document Human Review Done Archive
Triage; route to In Progress
Plan + TDD implementation + self-critique
Review + QA + Merge Gate
Docs + wiki write-back; Done unless intervention
Manual intervention or explicit review before Done
Verified complete
Auto-archived after 30 days idle
polling
interval_ms
30000
wiki
sweep_every_n root
10
./docs/llm-wiki
workspace
root
~/symphony_workspaces
hooks
after_create before_run after_run before_remove
bash "$SYMPHONY_WORKFLOW_DIR/scripts/symphony-setup-worktree.sh"
# NEVER `git reset --hard` inside a worktree — it discards in-progress # work between turns. Just refresh remotes; let the agent decide if/when # to rebase. set -uo pipefail git fetch origin --quiet || true
# Per-turn commit-or-amend. The branch stays at the same number of # commits across turns (amends in place when HEAD is already a `wip:` # commit), but every completed turn is durably written to .git/objects # so even a hard crash (SIGKILL, host reboot) won't lose work. The # orchestrator squashes everything into a single `<ID>: <title>` commit # on exit — see auto_commit_on_done. set -uo pipefail git add -A -- . ':(exclude).symphony' 2>/dev/null || true if git diff --cached --quiet 2>/dev/null; then echo "run finished at $(date) (no changes)" exit 0 fi # Classify the staged diff so the wip subject carries machine-readable # markers. `[no-test]` = production code changed with no paired test # file in the same diff (workflow-v0.5.2 § B1 — review.md promotes it # to a HIGH finding). `[scope-expand]` = a rewind dispatch (set by the # orchestrator when SYMPHONY_REWIND_SCOPE is exported) but the diff # touched a file outside the parsed scope list (workflow-v0.5.2 § A2). # Both markers can stack. STAGED_FILES="$(git diff --cached --name-only 2>/dev/null || true)" PROD_CHANGED=0 TESTS_CHANGED=0 SCOPE_EXPAND=0 SCOPE_FILES="" if [ -n "${SYMPHONY_REWIND_SCOPE:-}" ]; then SCOPE_FILES="$(printf '%s' "$SYMPHONY_REWIND_SCOPE" \ | tr ',' '\n' \ | sed -n 's/.*"file"[[:space:]]*:[[:space:]]*"\([^"]*\)".*/\1/p')" fi NL=$(printf '\nx'); NL=${NL%x} OLDIFS="$IFS" IFS="$NL" for f in $STAGED_FILES; do [ -n "$f" ] || continue case "$f" in tests/*|*_test.py|*.test.ts|*.test.tsx|*_test.go) TESTS_CHANGED=1 ;; esac case "$f" in tests/*|docs/*|kanban/*|.symphony/*|*.md|LICENSE|LICENSE.*|NOTICE|CHANGELOG*|README*|AGENTS.md|GEMINI.md) : # carve-out: docs/license/wiki edits never count as production change ;; *) PROD_CHANGED=1 ;; esac if [ -n "$SCOPE_FILES" ] && [ "$SCOPE_EXPAND" = 0 ]; then in_scope=0 for s in $SCOPE_FILES; do if [ "$f" = "$s" ]; then in_scope=1 break fi done if [ "$in_scope" = 0 ]; then SCOPE_EXPAND=1 fi fi done IFS="$OLDIFS" PREFIX="" if [ "$PROD_CHANGED" = 1 ] && [ "$TESTS_CHANGED" = 0 ]; then PREFIX="${PREFIX}[no-test]" fi if [ -n "${SYMPHONY_REWIND_SCOPE:-}" ] && [ "$SCOPE_EXPAND" = 1 ]; then PREFIX="${PREFIX}[scope-expand]" fi # Honors any pre-commit hooks in the host repo — if they fail, this # turn's snapshot fails and the next turn picks up where files are. MSG="$(sed -n '1{s/^[[:space:]]*//;s/[[:space:]]*$//;p;q;}' .symphony/commit-message.txt 2>/dev/null || true)" [ -n "$MSG" ] || MSG="turn $(date -u +%FT%TZ)" case "$MSG" in wip:*) COMMIT_MSG="$MSG" ;; *) COMMIT_MSG="wip: $MSG" ;; esac LAST="$(git log -1 --format=%s 2>/dev/null || echo "")" # On amend, preserve any markers the previous turn already set so a # later test-passing turn doesn't drop the historical `[no-test]`. # Markers are sticky within a wip subject. PRIOR_PREFIX="" case "$LAST" in *"[no-test]"*) PRIOR_PREFIX="${PRIOR_PREFIX}[no-test]" ;; esac case "$LAST" in *"[scope-expand]"*) PRIOR_PREFIX="${PRIOR_PREFIX}[scope-expand]" ;; esac MERGED_PREFIX="" case "$PRIOR_PREFIX$PREFIX" in *"[no-test]"*) MERGED_PREFIX="${MERGED_PREFIX}[no-test]" ;; esac case "$PRIOR_PREFIX$PREFIX" in *"[scope-expand]"*) MERGED_PREFIX="${MERGED_PREFIX}[scope-expand]" ;; esac if [ -n "$MERGED_PREFIX" ]; then COMMIT_MSG="${MERGED_PREFIX} ${COMMIT_MSG}" fi if [ "${LAST#wip:}" != "$LAST" ]; then git -c user.email=symphony@local -c user.name=symphony \ commit --amend -m "$COMMIT_MSG" >/dev/null 2>&1 || true else git -c user.email=symphony@local -c user.name=symphony \ commit -m "$COMMIT_MSG" >/dev/null 2>&1 || true fi echo "run finished at $(date)"
# Detach the worktree before Symphony rmtree's the dir, otherwise # `.git/worktrees/<ID>` lingers until `git worktree prune`. By this # point the orchestrator has already auto-committed any leftover # changes (see agent.auto_commit_on_done). set -uo pipefail HOST_REPO="${SYMPHONY_WORKFLOW_DIR:?}" WORKTREE_PATH="$PWD" ISSUE_ID="${SYMPHONY_ISSUE_ID:-$(basename "$WORKTREE_PATH")}" for dir in ${SYMPHONY_BOARD_ROOT_NAME:-kanban}; do git -C "$HOST_REPO" update-index --no-skip-worktree -- "$dir/$ISSUE_ID.md" 2>/dev/null || true done git -C "$HOST_REPO" worktree remove --force "$WORKTREE_PATH" 2>/dev/null || true
agent
kind max_concurrent_agents max_turns max_total_turns crash_continuation scheduling_policy max_total_tokens max_total_tokens_by_state budget_exhausted_state max_attempts stage_contracts max_retries auto_triage_actionable_todo max_retry_backoff_ms max_concurrent_agents_by_state auto_commit_on_done auto_merge_on_done auto_merge_push_target feature_base_branch auto_merge_target_branch auto_merge_exclude_paths auto_merge_capture_untracked
codex
1
100
200
true
fifo
100000000
In Progress Verify
500000000
500000000
Blocked
3
auto
3
true
300000
Todo In Progress Verify Document
1
1
1
1
true
true
true
codex
command model reasoning_effort approval_policy thread_sandbox turn_sandbox_policy turn_timeout_ms read_timeout_ms stall_timeout_ms
codex app-server
gpt-5.5
high
never
workspace-write
type networkAccess
workspaceWrite
true
3600000
20000
300000
claude
command resume_across_turns turn_timeout_ms read_timeout_ms stall_timeout_ms
claude -p --output-format stream-json --verbose --permission-mode acceptEdits --add-dir "$SYMPHONY_WORKFLOW_DIR"
true
3600000
20000
300000
gemini
command resume_across_turns turn_timeout_ms read_timeout_ms stall_timeout_ms
gemini -p ""
true
3600000
20000
300000
agy
command resume_across_turns turn_timeout_ms read_timeout_ms stall_timeout_ms
agy --print "$(cat)"
true
3600000
20000
300000
kiro
command resume_across_turns turn_timeout_ms read_timeout_ms stall_timeout_ms
kiro-cli chat --no-interactive --trust-all-tools "$(cat)"
true
3600000
20000
300000
opencode
command resume_across_turns turn_timeout_ms read_timeout_ms stall_timeout_ms
opencode run --format json --auto
true
3600000
20000
300000
pi
command resume_across_turns turn_timeout_ms read_timeout_ms stall_timeout_ms
pi --mode json -p ""
true
3600000
20000
300000
prime_agent
command resume_across_turns turn_timeout_ms read_timeout_ms stall_timeout_ms
prime-agent -p --mode json
true
3600000
20000
300000
server
port
9999
tui
language
en
prompts
base stages
./docs/symphony-prompts/linear/base.md
Todo In Progress Verify Document Done
./docs/symphony-prompts/linear/stages/todo.md
./docs/symphony-prompts/linear/stages/in-progress.md
./docs/symphony-prompts/linear/stages/verify.md
./docs/symphony-prompts/linear/stages/document.md
./docs/symphony-prompts/linear/stages/done.md

This workflow uses stage-specific prompt files configured under prompts. Customize docs/symphony-prompts/linear/ to change the agent instructions. If the prompts block is removed, Symphony falls back to this short legacy body.

You are working on {{ issue.identifier }}: {{ issue.title }}. Current state: {{ issue.state }}. Follow the board state instructions configured for this workflow.