You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Design ticket — for assessment before implementation. Same treatment as #279.
The observation
The Coder Lead now observes well. Verified against the repos on 2026-08-06: branch, dirty-file
counts, run timings and outcomes were all exactly right, and it volunteered the flags unprompted
("FAS and FGS both have uncommitted working tree changes").
But it only ever acts when asked. A real session looks like:
"Give me an update on all of the agents that report to you." "Focus on FAS platform. Can you clean it up?" "Okay, next agent."
Every one of those is the user doing the supervising. And the state being reported — a two-day-old
fix sitting untracked, a repo parked on a merged feature branch, three uncommitted files — is
exactly the state a manager would simply fix.
This is the only proposal on the board that reduces the operator's workload rather than adding
a surface to check.
The primitive: a policy keeps something TRUE. A goal makes something HAPPEN.
That distinction is the whole design, and it is what stops this becoming "an agent that does
whatever it feels like on a timer".
"this repo stays on its default branch with a clean tree" — standing, recurring, restorative
A policy may only restore a declared invariant. It may never decide what to build. "Fix bugs" is
not a policy; it is a goal, and it stays a goal.
Closed vocabulary, not free text
A policy is chosen from a registry, the same way connectors, pipeline steps, behaviour fields and
(proposed) stats sources are:
repo.on_default_branch violation → report | open PR | switch back
repo.tree_clean violation → branch + commit + push, or report
repo.no_stale_pr(days) violation → chase | report
repo.builds violation → report (never auto-fix: that is a goal)
Free-form policy text would hand an agent an open-ended standing instruction to act on real repos
unattended. Every other extension point in this platform is a closed, reviewed vocabulary; there is
no reason for the one that acts on its own schedule to be the exception.
Concurrency → the single-flight claim (claimDelivery / runDueTriggers / claimSessionDriver)
so a policy cannot start a second run on a repo already being worked.
Escalation → when a policy cannot be satisfied (merge conflict, failing tests), raise a needs_human board item. That status and column already exist; retrying forever does not become
an option.
Observe-first is not optional
A new policy starts in observe and must be explicitly promoted to act. It reports what it would have done, on the board, for as long as the user wants.
Without this the feature's first act is a surprise commit at 3am, which is exactly the reaction #314 exists to prevent — three unattended merges that nobody chose and nobody saw. Earning the
promotion with a week of accurate observations is cheap; losing trust on day one is not.
Do not build a second scheduler
Triggers already do cron → action (runDueTriggers, per-minute, with an atomic claim). A policy is
a trigger whose action is evaluate a condition against observed state, and act only on violation.
Strongly prefer extending that over a parallel sweep. A second scheduler would be a second set of
claim semantics, retry rules and failure reporting to keep consistent — and the delivery outbox
(#239) is the standing evidence of how subtle that gets.
Visibility is the acceptance criterion
Every autonomous action lands on the board and in the run log, attributed to the policy that
caused it. "Why is there a new branch?" must be answerable without reading a diff.
This is the lesson of #314: three merges happened, correctly, on instruction — and were invisible
until someone read a run detail string days later.
Open questions for assessment
Scope: per-repo, per-agent, or a fleet default on the Lead with per-repo overrides? Fleet
default is less to configure and more to get wrong.
Cadence: evaluate on a schedule, or only after a run finishes (when state actually changed)?
The second is cheaper and more precise; the first catches drift caused outside the platform.
Design ticket — for assessment before implementation. Same treatment as #279.
The observation
The Coder Lead now observes well. Verified against the repos on 2026-08-06: branch, dirty-file
counts, run timings and outcomes were all exactly right, and it volunteered the flags unprompted
("FAS and FGS both have uncommitted working tree changes").
But it only ever acts when asked. A real session looks like:
Every one of those is the user doing the supervising. And the state being reported — a two-day-old
fix sitting untracked, a repo parked on a merged feature branch, three uncommitted files — is
exactly the state a manager would simply fix.
This is the only proposal on the board that reduces the operator's workload rather than adding
a surface to check.
The primitive: a policy keeps something TRUE. A goal makes something HAPPEN.
That distinction is the whole design, and it is what stops this becoming "an agent that does
whatever it feels like on a timer".
delegate_goal, today)A policy may only restore a declared invariant. It may never decide what to build. "Fix bugs" is
not a policy; it is a goal, and it stays a goal.
Closed vocabulary, not free text
A policy is chosen from a registry, the same way connectors, pipeline steps, behaviour fields and
(proposed) stats sources are:
Free-form policy text would hand an agent an open-ended standing instruction to act on real repos
unattended. Every other extension point in this platform is a closed, reviewed vocabulary; there is
no reason for the one that acts on its own schedule to be the exception.
Boundaries, all of which already exist
tree_cleanpolicy underprcommitsand opens a PR; under
noneit commits and stops. The policy does not get its own merge rights.claimDelivery/runDueTriggers/claimSessionDriver)so a policy cannot start a second run on a repo already being worked.
needs_humanboard item. That status and column already exist; retrying forever does not becomean option.
Observe-first is not optional
A new policy starts in
observeand must be explicitly promoted toact. It reports what itwould have done, on the board, for as long as the user wants.
Without this the feature's first act is a surprise commit at 3am, which is exactly the reaction
#314 exists to prevent — three unattended merges that nobody chose and nobody saw. Earning the
promotion with a week of accurate observations is cheap; losing trust on day one is not.
Do not build a second scheduler
Triggers already do cron → action (
runDueTriggers, per-minute, with an atomic claim). A policy isa trigger whose action is evaluate a condition against observed state, and act only on violation.
Strongly prefer extending that over a parallel sweep. A second scheduler would be a second set of
claim semantics, retry rules and failure reporting to keep consistent — and the delivery outbox
(#239) is the standing evidence of how subtle that gets.
Visibility is the acceptance criterion
Every autonomous action lands on the board and in the run log, attributed to the policy that
caused it. "Why is there a new branch?" must be answerable without reading a diff.
This is the lesson of #314: three merges happened, correctly, on instruction — and were invisible
until someone read a run
detailstring days later.Open questions for assessment
default is less to configure and more to get wrong.
The second is cheaper and more precise; the first catches drift caused outside the platform.
be an offer, on the same reasoning as [design] Agent-mediated transfer — "transfer me to that agent", seamlessly, in hands-free #279's user-requested-vs-agent-initiated split.
on the subordinate; the responsibility is the Lead's.