General-purpose coding policy for Baruch's AI agents
76
95%
Does it follow best practices?
Run evals on this skill
Adds up to 20 points to the overall score
View guide
Low
Low-risk findings worth noting
Process steps in order. Do not skip ahead.
You are the lead of three coding agents running in Herdr panes: a developer, a reviewer/architect, and a tester. You assign the roles, write the briefs, read the reports, and gate the round. You never edit the shared checkout, and you never write code for a worker.
A round runs in two phases:
Herdr command surface, worker quirks, and the usage-parsing details:
skills/herdr-teamlead/references/herdr.mdRole weights, report reading, and the pre-PR review sequence:
skills/herdr-teamlead/references/round-flow.md.tessl/plugins/jbaruch/coding-policy/skills/herdr-teamlead/roster.shTakes no arguments. Emits {"caller":{"pane_id":...},"agents":[{"name","kind","pane_id","state"}]},
listing every named live agent other than your own pane.
agents — proceed to Step 2.agents: [] — nobody is named. Report the unnamed panes from
herdr agent list and the herdr agent rename <pane-id> <name> command that
fixes it, then finish here.herdr absent).
Report the message verbatim and finish here.Fewer named workers than roles is a decision, not a detail: either name another agent or fold two roles onto one worker in that worker's brief, and say which you did.
.tessl/plugins/jbaruch/coding-policy/skills/herdr-teamlead/verify-authority.sh <owner/repo>Emits {"repo","viewer_login","owner_login","owner_type","viewer_permission","namespace_owner","authorized"}.
authorized reflects namespace ownership alone; write permission never sets it
(rules/external-repo-contributions.md Default Deny).
authorized: true — record the authority line for the briefs:
owner of <owner/repo>. Set EXTERNAL_PERMISSION to none. Proceed to
Step 3.authorized: false — the operator does not own this repo. Ask the
operator for permission naming the repo AND each action type, then record
their exact words in EXTERNAL_PERMISSION and set the authority line to
not owner; permitted this round: <their words>. Without that answer, the
round is read-only: compose briefs that forbid every external write, or stop.
Never compose a brief that claims authority the operator did not give.gh or jq absent, or gh not
logged in. Report the message verbatim, finish here.Proceed immediately to Step 3.
.tessl/plugins/jbaruch/coding-policy/skills/herdr-teamlead/teamlead.sh measureSends each configured worker its own usage command and parses the reply. Emits
one snapshot document — per agent: kind, state, herdr_state,
state_source, windows, credits, plan, headroom_pct, skipped — and
appends it to the state file (skills/herdr-teamlead/state-schema.md). A worker that
is working or blocked is reported as skipped with null windows, never
interrupted. A working verdict is confirmed against the pane before it counts:
state_source names which signal decided, herdr or probe, and herdr_state
carries what herdr claimed. Exit 1 means at least one agent could not be
measured; the snapshot still prints and names it in failed_agents.
The usage marker is confirmed in the text that gets parsed, never in a wait
alone. --marker-poll-attempts and --marker-poll-interval bound the
confirming poll; --marker-timeout and --lines size the pane read. Attempt
counts and intervals default to the script's own constants; see
skills/herdr-teamlead/teamlead/measure.py.
Add --trace (or TEAMLEAD_TRACE=1) when a live run does something the JSON
does not explain: every herdr invocation, its exit status, and its output go to
stderr, and stdout stays the machine-readable document. Traced fields are
redacted for credential shapes and capped per field with a [truncated N bytes]
marker; the shape list and the cap are constants in
skills/herdr-teamlead/teamlead/herdr.py.
Report a failed_agents entry to the user and measure that worker by hand
before relying on its role. Proceed immediately to Step 4.
.tessl/plugins/jbaruch/coding-policy/skills/herdr-teamlead/teamlead.sh plan \
--roles developer,tester,reviewer \
[--exclude <role>=<agent>[,<agent>...]]...Pure computation over the newest snapshot plus the assignment ledger. Contacts
no agent, writes nothing. Emits {"assignments":{"<role>":"<agent>"},"rationale":[...],"snapshot_ref":{...}}.
Exit 1 names the reason it could not plan.
--exclude bars agents from one role and repeats, once per role. Phase 2 bars
the author of the branch from reviewer and tester (rules/agent-team-operation.md
Review Before PR). Exit 1 covers an exclusion naming a role outside --roles,
and an exclusion set no assignment satisfies.
Each seat carries a cost weight, and the heaviest is filled first; --roles
keys the output document and no longer decides which seat that is. role_costs
in config.json re-weighs a seat per install. The weights, the fill order, and
the tie-breaks are the planner's contract; see
skills/herdr-teamlead/teamlead/planner.py — the plan docstring and
DEFAULT_ROLE_COSTS.
Save the output to a file for Step 5. Relay the rationale lines to the user
as the round's role announcement: they name the weight behind each seat, the
exclusions applied, and any worker whose headroom reading is stale. Proceed
immediately to Step 5.
Write a values file for the round, then compose:
.tessl/plugins/jbaruch/coding-policy/skills/herdr-teamlead/compose-briefs.sh \
.tessl/plugins/jbaruch/coding-policy/skills/herdr-teamlead/templates \
<values.json> <round-reports-dir>The values file is {"shared": {...}, "roles": {"<role>": {...}}}; a role's
own value beats the shared one. Emits
{"common":"<path>","briefs":{"<role>":"<path>"}}. Exit 2 means validation
failed and nothing was written — an unfilled placeholder, a supplied key no
template uses, a value that is not text, or a REPORT longer than the
script's limit (the worker's REPORT: <path> line must fit one pane row for
Step 9 to confirm it; use a short reports directory). Exit 3 means the placeholder scan
itself failed, so whether the briefs are clean is unknown: re-run, never
dispatch on it. The placeholder set and both validation directions are the
script's contract; see the header of
skills/herdr-teamlead/compose-briefs.sh.
What you decide, and it is the whole of your job here:
SHARED_CHECKOUT — the checkout the workers read.AUTHORITY_STATEMENT and EXTERNAL_PERMISSION — verbatim from Step 2. Never
a claim you composed yourself.ISSUE, BRANCH, WORKTREE, REPORT, REPORTS_DIR, and the
phase and mode that role runs this round.| Phase | Role | Mode | Output |
|---|---|---|---|
| 1 | reviewer | A | design note on the issue |
| 1 | tester | A or B | test plan, or acceptance tests as a patch |
| 1 | developer | — | implementation, pushed branch, no PR |
| 2 | reviewer | B | COMMENT review of the pushed branch |
| 2 | tester | C | gates plus acceptance tests against the pushed branch |
| 3 | release | — | PR opened, bot rounds answered, merged, branch deleted |
Phase 2 briefs name the branch AND the commit SHA the worker must report against. A report against an older tip does not gate anything.
A worker starts each round with a cleared context. A brief that says "see the reviewer's earlier comment" reaches an agent that cannot see it. Name the issue, the file, the finding, and the path in full. Proceed immediately to Step 6.
One call per worker that writes anything:
.tessl/plugins/jbaruch/coding-policy/skills/herdr-teamlead/provision-worktree.sh \
<shared-checkout> <branch> <worktree-path> [base-ref]Emits {"path","branch","base_ref","state"}, where state is created,
attached, or already-provisioned. Exit 1 is a precondition (an invalid
branch name, a path outside the worktree root); exit 2 means git refused, or
the path holds something else. Branch-name and path rules are the script's
contract; see the header of
skills/herdr-teamlead/provision-worktree.sh.
The lead provisions every worktree a brief names, so a worker never runs git
against the shared checkout (rules/agent-team-operation.md Writers and
Checkouts). A read-only Phase 1 reviewer needs none. Remove them per
rules/agent-worktree-isolation.md Cleanup once the branch lands.
On any non-zero exit, fix the input it names and re-run this step; do not dispatch a brief whose worktree does not exist. Proceed immediately to Step 7.
.tessl/plugins/jbaruch/coding-policy/skills/herdr-teamlead/label-workspaces.sh \
<lead-label> [<agent>=<workspace-id>]...Names the lead's workspace, each worker's workspace after its agent, and each
worker's pane after its kind. With no pairs, the workspaces come from the
roster. Emits {"lead":{...},"agents":[...]} with a per-target
renamed|unchanged|failed. Exit 3 means at least one rename failed and the
JSON says which — labels are cosmetic, so that never stops a round.
Run this once per team, not once per round: a name already in place is
reported unchanged and nothing is sent. Skip it on a team whose sidebar is
already named. Proceed immediately to Step 8.
.tessl/plugins/jbaruch/coding-policy/skills/herdr-teamlead/teamlead.sh apply \
--assignments <plan-file> \
--brief developer=<path> --brief tester=<path> --brief reviewer=<path> \
--common <path-to-COMMON.md> [--task <label>]Clears each worker's context and hands it its brief. Emits one JSON object:
per role a record carrying cleared, landed, started, and status.
Each outcome names where the round goes next. Only a dispatched worker can produce a report, so Step 9 waits on exactly the roles that landed here.
"status": "sent_but_not_started" — the message was sent
and no turn began for that role. Read that worker's pane; do not re-dispatch
on top of it. Go to Step 9 for the roles whose records say started, and
treat this role as producing no report this round.apply sent that worker nothing: a brief goes out only behind a confirmed
clear. Read the pane and clear it by hand. Once the pane shows a fresh
session, re-run this step for that role with --no-clear; that is the one
path on which a record carries cleared: false, and it means the lead did
the clearing. Never brief a worker on top of the previous task's context.--allow-recovery once
you know whose text it is. Codex sends no recovery key at all: its clear key
exits an idle Codex.--dry-run prints every command it would run and makes no herdr calls. It
dispatches nothing, so finish here after reading it.--task <label> puts the round's task in the label. A hand-off that never
started is left unlabelled.The delivery mechanics behind those outcomes — composer confirmation, recovery keys, ghost text, the rejection strings, the settle knobs — are in:
skills/herdr-teamlead/references/herdr.mdThe prompt text, the refusal predicate, and every constant are the utility's
own contract; see skills/herdr-teamlead/teamlead/assign.py.
Proceed to Step 9 with the roles that were dispatched.
One call per dispatched worker, in the order the round needs them:
.tessl/plugins/jbaruch/coding-policy/skills/herdr-teamlead/wait-report.sh <agent-name> <report-path>Emits {"agent","state","report_path","found","elapsed_seconds"} on every
outcome except exit 2, which leaves stdout empty and puts its diagnostic on
stderr. Exit 4 adds reason. Completion requires both the report file on disk and the REPORT:
marker in the worker's pane. A single idle or done observation is not
completion. Poll interval and give-up budget are the script's own constants.
herdr agent read <name> --source visible. If the worker is still working,
re-run this step for it: the script's own budget applies again, never a
number chosen here. Otherwise go to Step 10 recording that it produced no
report.idle or done on
consecutive polls, but the pane never showed the marker whole. This is not
delivery: a marker the pane wrapped cannot be told from a newline, so no
reading of the pane confirms it. Read the live state with
herdr agent get <name> and take the first continuation that applies:
blocked or working — re-run this step for that worker
once. Exits 0–3 from that re-run take their branches above. A second
exit 4 is terminal: record the worker as producing no report and
continue to the next worker.idle or done — record the worker as producing no report
and continue to the next worker. Never re-dispatch on top of it. The
cause is a report path too long for one pane row; Step 5's compose gate
refuses those, so this outcome means a brief bypassed it.herdr pane read <pane-id> --source visible, relay its text to the operator
verbatim, and stop the round for that worker. You never answer it: the
operator does. Resume only once herdr agent get <name> reports a state
other than blocked, then re-run this step for that worker.Proceed to Step 10 once every dispatched worker has been waited on, or once you have recorded which of them produced no report.
Read every report file in full, including a report whose worker exited cleanly.
A ## BLOCKED section can sit under a report that otherwise reads as finished.
Classify each finding blocking or advisory per rules/review-severity.md.
The release hand-off has one condition, and all four parts are required:
A Phase 1 design note or test plan does NOT satisfy 2 or 3
(rules/agent-team-operation.md Review Before PR). A report against an older
SHA does not either — re-run Phase 2 against the current tip.
With all four met, the release is one more assignment, never a prompt into
the developer's existing context: return to Step 5 with the role release for
the developer's agent (template templates/brief-release.md, the same
WORKTREE and BRANCH, a fresh REPORT), run Step 6 (it reports
already-provisioned), dispatch through Step 8 so the context is cleared and
the brief is fresh, and wait on the report in Step 9. The worker merges; you
do not. After its report, fast-forward the shared checkout, remove the
worktree, and delete the branch per rules/agent-worktree-isolation.md.
Log the round: the assignments, the report paths, the findings, and the outcome. If the round produced no findings at all, log it and say so in one line rather than reproducing the reports. Finish here.
For the daily standup, which is a different round shape entirely, use
Skill(skill: "herdr-standup").
.tessl-plugin
hooks
rules
skills
adopt-fork-pr
herdr-standup
herdr-teamlead
references
teamlead
tests
migrate-to-plugin
onboard-repo
release
tests