REMOTE/UPSTREAM were module constants, so a team-mode board whose remote is named anything but origin synced nothing at all — silently, with a healthy header. The remote is now resolved per use (config's answer, the one PRs already honour) and threaded through fetch, publish, replay and integrate; every message names whatever was resolved. The silence is the other half. Where _converge()/push_now() returned a bare 'no-origin' that both callers discarded, _remote() now _note()s at stalled level first: no remote at all names both fixes (add one, or set BOARD_GIT_REMOTE), and a BOARD_GIT_REMOTE naming a remote this checkout does not have stalls naming it rather than quietly using another. It clears with a recovery line like the offline path, and install() asks at startup so the chip is there from first paint, not the second beat. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
141 lines
6.9 KiB
Bash
141 lines
6.9 KiB
Bash
# Task manager settings — copy to manager/local/.env (gitignored) and edit.
|
|
# Precedence: process environment > local/.env > these defaults.
|
|
#
|
|
# A first run of install.py with no local/.env writes this file there for
|
|
# you, asking only what it cannot guess (solo or team, which agent
|
|
# adapter, the project's test command) and leaving every other key at the
|
|
# default below. `install.py --setup` asks again later; nothing else ever
|
|
# rewrites your copy, so new keys added here by an update are yours to
|
|
# adopt by hand.
|
|
|
|
# Port the board serves on. Pinned by default so the URL is bookmarkable;
|
|
# adapters and drivers read the same value, so changing it here changes it
|
|
# everywhere at once.
|
|
BOARD_PORT=26071
|
|
|
|
# What the tab calls this project: the title is "<project> · bench", so two
|
|
# benches side by side are told apart at tab-bar width. Empty = the repo
|
|
# directory's name, which is the right answer unless every checkout on this
|
|
# machine is called "app".
|
|
BOARD_TITLE=
|
|
|
|
# Which agent adapter runs headless jobs (core/adapters/<name>, overridable
|
|
# in local/adapters/<name>). Ships with: claude, opencode.
|
|
BOARD_AGENT_ADAPTER=claude
|
|
|
|
# The binary each adapter launches jobs with. Point them at stub scripts
|
|
# to test the board's plumbing without spending tokens.
|
|
BOARD_CLAUDE_BIN=claude
|
|
BOARD_OPENCODE_BIN=opencode
|
|
|
|
# The model headless agents run on — an opaque vendor-native name the
|
|
# adapter passes through untranslated (claude: a model name or alias for
|
|
# --model; opencode: the "provider/model-id" config key). Empty = inherit
|
|
# the vendor's own default, i.e. whatever the CLI on this machine would
|
|
# pick anyway. The per-intent settings beat the general one for their
|
|
# intent only; _REVIEW covers both PR reviews and relevance checks. Work
|
|
# agents write code; reviews just read and judge — they can ride a
|
|
# cheaper, faster model.
|
|
BOARD_AGENT_MODEL=
|
|
BOARD_AGENT_MODEL_WORK=
|
|
BOARD_AGENT_MODEL_ACT_PR=
|
|
BOARD_AGENT_MODEL_REVIEW=
|
|
|
|
# Command prefixes headless agents may run in their worktree — the
|
|
# project's test/check commands, comma-separated, in plain neutral form
|
|
# (each adapter renders them into its vendor's permission rules; the
|
|
# git/gh grants per launch intent are built in). Headless runs have no
|
|
# human at a permission prompt, so a test runner missing from this list
|
|
# is a test the work agent cannot run.
|
|
BOARD_AGENT_COMMANDS=python3 -m unittest
|
|
|
|
# What counts as a definition-of-done check (the Focus view's CHECKS
|
|
# panel) is a file, not an env var: core/checks ships a generic default,
|
|
# and a `checks` file in manager/local/ replaces it wholesale. Format
|
|
# (`<label>: <command regex>`) is documented in the default file itself.
|
|
|
|
# Where work-agent worktrees are created, relative to the repo root.
|
|
BOARD_WORKTREES=.worktrees
|
|
|
|
# GitHub plumbing. The gh CLI used for PRs (stub-able like claude); the git
|
|
# remote this board's work goes to (empty = the repo's first remote) — PRs
|
|
# and BOARD_SYNC both ride it, and a name set here is used as named, never
|
|
# swapped for another remote; and how often to poll open PRs of cards
|
|
# sitting in review/ for reviews and checks.
|
|
BOARD_GH_BIN=gh
|
|
BOARD_GIT_REMOTE=
|
|
BOARD_PR_POLL_INTERVAL=60
|
|
|
|
# Seconds a work-agent launch waits for `git fetch origin main` before
|
|
# giving up and branching from local HEAD. Fresh launches branch from
|
|
# origin/main when the fetch succeeds; no remote or a dead network just
|
|
# means today's behaviour, never a blocked launch.
|
|
BOARD_FETCH_TIMEOUT=10
|
|
|
|
# Claim on move, and commit it. On: a board-made move out of backlog/ or
|
|
# to-do/ writes **Assignee:** <git user.name> into the task file (first
|
|
# claim only — an existing assignee is preserved), walking a card back to
|
|
# backlog/ clears it, and each move commits itself — the move and the claim
|
|
# in one commit touching only that task file, messaged
|
|
# `board: <number> → <stage> (<name>)`. Nothing is pushed. Off (the
|
|
# default) means moves neither write nor clear the assignee and never
|
|
# commit — today's behaviour exactly, tasks/ committed by hand. An
|
|
# assignee added to a file by hand is still read and shown either way;
|
|
# the gate only governs whether a move writes it. Anything but
|
|
# empty/0/false/no/off turns it on.
|
|
#
|
|
# It is also what makes the claim mean something: on, ▸ start work refuses
|
|
# a card someone else holds (▸ take over is the deliberate way in) and
|
|
# claims an unheld one, and board-made edits to a card in place — the
|
|
# **PR:** line — commit themselves too. Off, nothing writes an assignee,
|
|
# so nothing reads one as a lock.
|
|
BOARD_COMMIT_MOVES=
|
|
|
|
# Sync boards through origin/main: the second half of team mode, and off
|
|
# by default. On, it implies BOARD_COMMIT_MOVES above (a move that never
|
|
# commits has nothing to publish) and: each board commit is pushed as it
|
|
# is made; a beat fetches and fast-forwards every BOARD_SYNC_INTERVAL
|
|
# seconds and once at startup; moves that arrive are narrated with their
|
|
# commit author's name; and a card someone else moved first wins the race
|
|
# — the local move is dropped with a toast naming who took it.
|
|
#
|
|
# Two things it will never do. It never publishes a commit the board did
|
|
# not make: one local-ahead commit on main without the `board: ` prefix
|
|
# stops the push and says which. And it never merges past a divergence or
|
|
# into a checkout with uncommitted changes — it says so and waits for a
|
|
# human. Both assume the discipline bench already has: code work lives in
|
|
# worktrees and PRs, so local main advances only through the board and
|
|
# origin.
|
|
#
|
|
# State syncs; reactions don't. A move that arrives over origin renders
|
|
# and narrates on every board but triggers nothing — opening a PR belongs
|
|
# to the board whose user made the move, and a review card left without
|
|
# one carries an explicit ↑ open PR action instead of N boards guessing.
|
|
# The same discipline moves merges to origin: merge & clean up runs
|
|
# `gh pr merge` and lets the beat deliver the result, so local main only
|
|
# ever fast-forwards. Whoever clicks needs merge rights on the repo.
|
|
#
|
|
# One board fetches twice a minute at the default interval; raise it on a
|
|
# rate-limited or metered remote. Sync rides one remote and `main` only —
|
|
# the remote BOARD_GIT_REMOTE names, or the checkout's first one, exactly
|
|
# as PRs do. Nothing to ride (no remote, or a BOARD_GIT_REMOTE naming one
|
|
# this checkout does not have) is a `sync stalled` chip and a ticker line,
|
|
# never a board that looks healthy while syncing nothing.
|
|
BOARD_SYNC=
|
|
BOARD_SYNC_INTERVAL=30
|
|
|
|
# Seconds between disk polls of the stage directories.
|
|
BOARD_WATCH_INTERVAL=2
|
|
|
|
# In-memory caps: events kept per session, and board-level history
|
|
# (moves + agent lifecycle). Full logs always persist to local/state/.
|
|
BOARD_EVENTS_CAP=800
|
|
BOARD_HISTORY_CAP=300
|
|
|
|
# Where update.sh fetches the task-manager's releases from (owner/repo, or
|
|
# any GitHub URL). Normally unset: the shipped update.sh is stamped at
|
|
# build time with the repo it came from, and this overrides the stamp.
|
|
# Updates replace manager/core/ and the top-level scripts; they never touch
|
|
# tasks/, plans/, reference/ or manager/local/.
|
|
BENCH_SOURCE=
|