Skip to content

feat(fleet): add /task-manager skill + CI skills-install gate (v0.10.0) - #9

Merged
convenientlymike merged 1 commit into
mainfrom
feat/task-manager-skill
Sep 10, 2026
Merged

convenientlymike merged 1 commit into
mainfrom
feat/task-manager-skill

Conversation

@convenientlymike

Copy link
Copy Markdown
Owner

What & why

Adds a fourth dedicated-seat skill — the peer of /coordinator (git) and /brain (knowledge) — for goals + tasks + agent-status coordination. A multi-window fleet benefits from one window owning "who's doing what, what's next, what's stalled, who won't get their wakes."

Changes

  • /task-manager onboards a window as the fleet's coordination seat: keeps every agent lane's active goal current, surfaces stalls + reachability gaps + stale claims + blockers from fleet.sh roster / monitors, routes work with fleet.sh msg, keeps the board tidy, and gives the operator a who's on what / what's next / what's stuck readout.
  • Generic + leak-free for this public repo: Fleet's own roster / board / msg / goal / retire are the substrate; any richer project-specific task board is an optional integration referenced by capability only (no project paths, dashboard port, or store/UI specifics). The seat works with Fleet alone.
  • No new script / no install.sh change — install.sh already copies every dir under .fleet/skills/ into the target's .claude/skills/.

Forcing function (new)

A skills-install CI job runs install.sh into a temp project and asserts every skill under .fleet/skills/ propagates into .claude/skills/ — dynamic over the source (future skills auto-covered), with explicit asserts for the known skills to guard a silent glob no-op. Closes a real gap: the smoke job only ran fleet.sh init (which does not copy skills), so skill propagation was previously untested. Negative-control-verified locally: the job goes red when a skill fails to land.

Verification (byproduct)

  • leak audit clean (no phantom / :9477 / taskboard.py / private paths)
  • install.sh mirror: all 4 skills (arm, coordinator, brain, task-manager) propagate
  • neg-control bites (rc=1 when a skill is removed)
  • ci.yml valid YAML · shellcheck clean · retire+brain selftest still 15/15

VERSION 0.9.0 → 0.10.0; CHANGELOG + README updated.

🤖 Generated with Claude Code

Adds a fourth dedicated-seat skill — the peer of /coordinator (git) and
/brain (knowledge) — for GOALS + TASKS + AGENT STATUS coordination.

- /task-manager onboards a window as the fleet's coordination seat: it keeps
  every agent lane's active goal current, surfaces stalls + reachability gaps
  + stale claims + blockers from `fleet.sh roster` / `monitors`, routes work
  with `fleet.sh msg`, keeps the board tidy, and gives the operator a
  "who's on what / what's next / what's stuck" readout.
- Generic + leak-free for this PUBLIC repo: Fleet's own roster / board / msg /
  goal / retire are the substrate; any richer project-specific task board is an
  OPTIONAL integration, referenced by capability only (no project paths, no
  dashboard port, no SQLite/UI specifics). The seat works with Fleet alone.
- No new script or install.sh change needed — install.sh already copies every
  dir under .fleet/skills/ into the target's .claude/skills/.

Forcing function: a new `skills-install` CI job runs install.sh into a temp
project and asserts EVERY skill under .fleet/skills/ propagates into
.claude/skills/ (dynamic over the source, so future skills are auto-covered;
explicit asserts for the known skills guard a silent glob no-op). This closes
a real gap — the smoke job only ran `fleet.sh init`, which does not copy skills,
so skill propagation was previously untested. Negative-control-verified: the
job goes red when a skill fails to land.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@convenientlymike
convenientlymike merged commit a7bde5f into main Sep 10, 2026
4 checks passed
@convenientlymike
convenientlymike deleted the feat/task-manager-skill branch September 10, 2026 20:46
convenientlymike added a commit that referenced this pull request Sep 11, 2026
…ing (#9)

Per coordinator decision, finding #9 (upgrade-transition collision) is
propagation-gating and folds into this PR so the pre-propagation head is
complete and #9 is closed BY CONSTRUCTION, not by rollout timing.

On a rollout onto an ACTIVE fleet, existing windows carry an agent-FILE label
but have no reservation yet (created on their next register.sh). Without a
guard, a NEW registration during that window is handed an agent-N a live
window's file already shows — the duplicate-agent-N collision, reintroduced
purely by rollout order.

reserve_label (step 1b preferred + step 2) and next_label now consult a new
_label_held_by_live_file(label, self): a label carried by a LIVE agent-file
owned by a different sid OCCUPIES its slot, so a new registration skips it.
Self-excluded (a session re-registering its own label is never blocked by its
own file); live-only (a stale/dead file-label stays reusable). The check runs
only on an otherwise-free slot (mkdir won / dir absent), so it is ~free in
steady state and only bites during the transition.

Forcing test L8: a LIVE agent-file labeled agent-1 with NO reservation → a new
window's reserve_label returns agent-2, NOT agent-1; control: a DEAD/stale
agent-1 file-label IS reusable (new window takes agent-1 — no over-block).
Watched to BITE with the guard reverted.

Gate: shellcheck clean; selftest-labels 19/19 (L1-L8); collateral 16/16 +
brain-retire 15/15 (no regression); smoke green.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
convenientlymike added a commit that referenced this pull request Sep 11, 2026
…ardening (#11)

* fix(fleet): close reap-vs-reserve race + complete label-reservation hardening

Pre-merge red-team follow-up to #10 (atomic agent-N reservation). A 6-lens
adversarial review (each finding refuted before trust) surfaced one critical
residual and two completions.

CRITICAL — reap-vs-reserve race (reintroduced the collision #10 fixed):
reap()'s label-GC removed a reservation whose owner had no agent file, but
register.sh creates the reservation BEFORE writing the agent file, so a
concurrent reap (runs on every fleet command in every session) could delete a
just-created in-flight reservation → a 3rd session re-mkdir's the same agent-N →
two live agent-N. The reap-GC path now carries the same reservation-age grace
guard _label_reclaimable uses: GC only when owner departed AND the reservation
dir aged past FLEET_LABEL_GRACE. Protects the fresh in-flight slot and the
empty-sid sub-window (mkdir→sid-write); a genuinely-departed owner's minutes-old
reservation still frees promptly.

COMPLETIONS:
- sid_for_target pass-2 (kept-stale files) now fails loud (exit 3 + candidate
  shorts) on a duplicate label, symmetric with pass-1 — a handoff DM to a
  departed agent-N is no longer silently delivered to one of two same-label inboxes.
- FLEET_LABEL_GRACE is config-readable (label_grace_s) like stale_after_s, and
  its default is raised 3→10s to comfortably exceed the reserve→agent-file write
  gap on a cold host spawning many windows.

FORCING COVERAGE (selftest-labels.sh, each watched to BITE with its guard reverted):
- L7:  a concurrent reap during an in-flight reserve → the fresh reservation
       SURVIVES; control: an aged departed reservation IS still GC-removed.
- L7b: the empty-sid sub-window (mkdir'd, sid not yet written) is likewise protected.
- L4b: pass-2 kept-stale duplicate fails loud; control: a unique stale label still delivers.

Gate: shellcheck clean; selftest-labels 17/17; selftest-collateral 16/16 +
selftest-brain-retire 15/15 (no regression); smoke green.

Follow-ups tracked in the PR (confirmed but out of this PR's tight scope):
reclaim-vs-reclaim atomicity, and file-label↔reservation reconciliation on the
upgrade transition (existing windows carry file-labels but no reservation).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* fix(fleet): fold upgrade-transition guard into the reservation hardening (#9)

Per coordinator decision, finding #9 (upgrade-transition collision) is
propagation-gating and folds into this PR so the pre-propagation head is
complete and #9 is closed BY CONSTRUCTION, not by rollout timing.

On a rollout onto an ACTIVE fleet, existing windows carry an agent-FILE label
but have no reservation yet (created on their next register.sh). Without a
guard, a NEW registration during that window is handed an agent-N a live
window's file already shows — the duplicate-agent-N collision, reintroduced
purely by rollout order.

reserve_label (step 1b preferred + step 2) and next_label now consult a new
_label_held_by_live_file(label, self): a label carried by a LIVE agent-file
owned by a different sid OCCUPIES its slot, so a new registration skips it.
Self-excluded (a session re-registering its own label is never blocked by its
own file); live-only (a stale/dead file-label stays reusable). The check runs
only on an otherwise-free slot (mkdir won / dir absent), so it is ~free in
steady state and only bites during the transition.

Forcing test L8: a LIVE agent-file labeled agent-1 with NO reservation → a new
window's reserve_label returns agent-2, NOT agent-1; control: a DEAD/stale
agent-1 file-label IS reusable (new window takes agent-1 — no over-block).
Watched to BITE with the guard reverted.

Gate: shellcheck clean; selftest-labels 19/19 (L1-L8); collateral 16/16 +
brain-retire 15/15 (no regression); smoke green.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant