Repository navigation
feat(first-mate-skill): 1.3.0 - one coordinator and loop per effort, plus lessons from a long session - #5
Merged
Merged
Conversation
The wait script now holds an flock on FIRST_MATE_DIR/.wait.lock keyed on the caller's PASEO_AGENT_ID. Starting is idempotent (exit 4 if you own the running loop, 5 if another agent does), and status, stop, and take-over subcommands are added. The skill treats a resumed or forked session as a non-coordinator until the user says otherwise, and never reports a loop as running without a status result from the same turn. scripts/test-wait-lock covers the lock offline with a stub detector and is run from scripts/verify.
The detector can now watch a branch (each new commit) and a workflow (latest run on a branch: head, status, conclusion), alongside PRs, issues, and releases. A PR-only watch list misses work that lands from other sessions and a deploy that stays red after a merge. The skill says to always watch the default branch and the workflows the milestone depends on, and to reconcile open recommendations against any merge a branch report shows.
New workspaces are created from a freshly fetched origin/<default> with the base SHA recorded in the prompt and re-checked by the agent. Coordinator reports must verify agent claims about the baseline (fails on main, CI started, no conflicts) before repeating them, and must read a finish notice against the agent's status and the latest prompt sent.
…st-merge proof A green pipeline does not show the deployed thing runs, so the acceptance signal must be a named runtime observable, and changes that can only be proven by the first run after merge stay open until it is watched and observed. New guards need a mutation proof stating what the test does not cover.
…he handoff The seven-section PR template is now only a fallback. The target repository's own PR standard (prefixes, closing keywords, attribution, sections) takes precedence and goes into every delegation prompt, including a newer standard the user points at. The handoff gains a Pending Decisions and Held Items section recording recommendations with their triggers, and records standing answers to routine permission prompts.
…ds, cleanup on merge Adds the remaining working rules: ask the user for shape-only output when reading live systems, show a draft and options before posting on a human's thread, cite the log line or file:line when naming a cause, report checks a sandbox could not run instead of skipping them, apply recorded permission policies, and retire an agent, workspace, watch entry and exact-match local branch when a PR merges.
…; clearer mechanisms Adversarial review findings: - first-mate-wait.sh ran the detector in a command substitution, so SIGTERM was deferred until its network calls finished and stop/take-over timed out. The detector now runs in the background and is waited on, and the cleanup trap kills it. The owner file is written then renamed so status and stop never read a partial file. A test with a slow stub detector fails on the previous script and passes now. - first-mate-check.py stored a bare repo name for unregistered repos, which later failed to resolve and aborted the whole run; it now keeps the full OWNER/repo. The state file is written atomically. - SKILL.md: take-over and stop --force need the user's explicit word each time (invariant 12), and the heartbeat preference is folded into the heartbeat mechanism instead of reading as a third one.
stop verified the loop's pid through /proc, which macOS lacks, so stop failed and the test's bare wait blocked forever on the loop it could not stop. The script now uses ps -p -o args=. The test uses gtimeout when timeout is missing, avoids pgrep -c (not on macOS), and has a watchdog (default 120s, FIRST_MATE_TEST_WATCHDOG) so a regression fails instead of hanging. Also drops an unused local flagged by shellcheck (SC2034).
…as not published its owner CI failed in the take-over test. The loop takes the lock first and writes its owner file after, so on a slow runner a start, status, or stop in that gap saw a held lock with no owner (or a stale file from a SIGKILLed loop) and treated the loop as someone else's or as unverifiable. Callers now wait up to about 5s for an owner file naming a live first-mate-wait.sh process before deciding, and fall back to none if the loop dies meanwhile. The test gains a slow-starting-loop case (lock held, owner file delayed, stale file present). It fails on the previous script and passes now, including with the owner write delayed 1s everywhere and under CPU load.
…status probe shellcheck (host and CI) flagged an unused loop variable in await_info; it is now `_`. The local shellcheck install also made the gap visible: scripts/verify failed intermittently in the locking test. Cause: status and stop probe the lock by briefly taking it, so a start that runs at the same instant failed flock -n and was refused as if another owner held a loop. cmd_start now retries until the owner file names a live loop, the lock is free, or about 5s pass. A test holds the lock for 1s with no owner file and starts in the middle; it fails on the previous script and passes now.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Skill 1.3.0 for
first-mate-skill, from a long coordinating session that showed several repeated failures. The wait loop now holds one owner-keyed lock, a forked or resumed session is a non-coordinator by default, the detector watches branches and workflows, and the skill gains rules for fresh bases, verified agent claims, runtime acceptance signals, post-merge proof, repo PR standards, and a handoff section for pending decisions.AI-assisted: written by an AI coding agent (OpenCode, Claude Sonnet 5.5) under the owner's direction. A human should review before merge.
Changes
first-mate-wait.sh:flockonFIRST_MATE_DIR/.wait.lock, keyed onPASEO_AGENT_ID.status,stop [--force], andtake-over. The lock frees itself when the loop dies, so there is no stale pidfile.stopworks mid-run.ps, not/proc, so it runs on macOS. Needsflock(util-linux, orbrew install flock).first-mate-check.py:branchesandworkflowswatch entries; atomic state write; unregistered repos keep their fullOWNER/repo.SKILL.md(1.3.0): invariant 12 (one coordinator per effort;take-overandstop --forceneed the user's explicit word), fork-aware adoption steps, fresh-base rule, verified agent claims, runtime acceptance signal, mutation proof, post-merge proof, repo PR standard overrides the template, Pending Decisions section, shape-only host reads, drafts for human threads, cleanup on merge, new troubleshooting rows.scripts/test-wait-lock(new, run byscripts/verify), README, TROUBLESHOOTING, and an update to decision record 0001.Verification
7a8492c.scripts/verify: 21 of 21 on the author's macOS host (including shellcheck andacq kit validate); 20 of 20 on Linux, five runs in a row (acqnot installed there).scripts/test-wait-lock: 26 assertions, with a watchdog (default 120s,FIRST_MATE_TEST_WATCHDOG) so a regression fails instead of hanging.stop;/prochang, and two shellcheck warnings. Each fix has a regression test.mainandci.yml.PASEO_AGENT_IDkeying is exercised only with injected owner names.Merge Guard
None. Standalone change.
Rollback
Revert the merge. Kit consumers pin by SHA, so existing pins are unaffected.
Security Impact
No new network access, secrets, or commands.
stopkills a process only after checking that the recorded PID's command line containsfirst-mate-wait.sh.