Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions .agents/skills/babysit/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,10 @@ merge` merges the exact green head with the repository's enabled method and
verifies the merge.

Read the slice boundary before the first fix: the addressed issue's acceptance
criteria and the work-intent comment carry the observable evidence that ends
this slice and the actors, scenarios, variants, and extensions it leaves out.
criteria and this pull request's work-intent claim carry the observable evidence
that ends this slice and the actors, scenarios, variants, and extensions it
leaves out. An issue can carry several claims for slices running in parallel, so
read the one whose slice this pull request delivers.
When neither records one, state the boundary you will use in the first response
and proceed. Ask before the first triage when the ambiguity would change how a
finding is sorted. The boundary is the authority for triage.
Expand Down
22 changes: 12 additions & 10 deletions .agents/skills/babysit/references/merge.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,17 @@ URL. Run `done` so every matching local review reaches Done; zero matching
reviews is success. Report a lookup or Markover failure without weakening the
verified GitHub merge result.

When the merged pull request carries a work-intent claim, it completes with the
merge, so set its phase to `completed`. Then refresh the issue conversation for
comments added during the merge before recommending next steps or closing it,
and account for every remaining adjunct item. If work remains, prepare concrete
next steps for the report; the issue's own claim stays as it is. If the issue
is complete, perform the remaining state-only housekeeping, set its claim to
`completed` as well, verify the issue and its trackers reflect completion, and
prepare an archive-ready conclusion.
Complete the claim for the merged slice: the pull request's own claim when it
carries one, otherwise the claim on the addressed issue whose slice this pull
request delivered. Set that claim's phase to `completed` and leave every
sibling claim alone — other slices of the same issue may still be running.

Then refresh the issue conversation for comments added during the merge before
recommending next steps or closing it, and account for every remaining adjunct
item. If work remains, prepare concrete next steps for the report. If the issue
is complete, perform the remaining state-only housekeeping, verify the issue and
its trackers reflect completion, and prepare an archive-ready conclusion.

**Complete when:** the merge is verified, matching Markover reviews are Done,
every completed claim says so, and the issue and its trackers match the real
state.
the merged slice's claim says `completed` with its siblings untouched, and the
issue and its trackers match the real state.
56 changes: 35 additions & 21 deletions .agents/skills/start-issue/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,12 @@ description: Use before implementation when the user asks to start or take over
# Start Issue

Starting work means making it visible before changing it: one **work item** on
GitHub, the **tracker** the user reads, and one **claim** other agents can see.
The interview then fixes the **slice boundary** — the evidence that ends this
slice and what it leaves out — so babysit and the tripwire have something
finite to compare against. Complete the stages in order.
GitHub, the **tracker** the user reads, and a **claim** other agents can see on
the slice you are taking. A claim owns one bounded slice rather than the whole
item, so separate slices of one issue can run at the same time. The interview
then fixes the **slice boundary** — the evidence that ends this slice and what
it leaves out — so babysit and the tripwire have something finite to compare
against. Complete the stages in order.

Enter this workflow when the user asks to start, take over, implement untracked
repository work, or record work. Diagnosing a failure, explaining behavior,
Expand Down Expand Up @@ -94,11 +96,19 @@ plausible overlap has been assessed or raised with the user.
## 3. Claim it

**When the target already carries an active claim** — any claim whose phase is
not `completed` — show it to the user and ask whether this run continues it,
takes it over, or belongs on a different item, before attaching or claiming
anything. Add no second claim. Edit another run's claim only after the user
says that run has stopped, and preserve its intent data when taking it over.
One item carries one active intent.
not `completed` — compare its slice with the one you are taking before
attaching or claiming anything, reading its summary, touch points, and branch:
Comment thread
lastobelus marked this conversation as resolved.
Outdated

- Clearly separate slices: claim yours and continue. Another claim on the item
is not by itself a reason to ask.
Comment thread
lastobelus marked this conversation as resolved.
Outdated
- Clearly the same slice: show that claim and ask whether this run continues
it, takes it over, or belongs on a different item. One slice carries one
active claim.
- Plausible overlap the live evidence does not settle: show both slices and ask.

Edit another run's claim only after the user says that run has stopped, and
preserve its intent data when taking it over. A pull request is one slice, so
it normally carries one claim.

Attach the target to the tracker set if it is not already attached, and move
each mapped Project to `In Progress`. An already-correct value is a no-op.
Expand All @@ -118,8 +128,9 @@ An item belongs to many Projects but one milestone. Treat every other Project
field, milestone property, and repository label as read-only; the claim carries
the rest.

With no active claim on the target, post one claim comment and maintain it by
editing that exact comment ID:
With no active claim on your slice, post one claim comment and maintain it by
editing that exact comment ID rather than a sibling slice's claim on the same
item:

````markdown
<!-- start-issue-work-intent -->
Expand All @@ -146,12 +157,14 @@ keep the phase truthful — `implementing` only after implementation is
authorized.

After posting, read the target's own claim comments once more — that comment
thread only, not the trackers. When more than one active claim is present,
pause, show the collision, and let the user resolve it before implementation.
Two runs pausing is a good outcome; do not invent a winner.
thread only, not the trackers. A claim that appeared while you were writing
collides only when its slice overlaps or may overlap yours; two disjoint
slices both continue. On a real overlap, pause, show both slices, and let the
user resolve it before implementation. Two runs pausing is a good outcome;
do not invent a winner.

**Complete when:** the target is attached, mapped Projects show `In Progress`,
one truthful claim exists, and no unresolved collision remains.
this slice has one truthful claim, and no unresolved overlap remains.

## 4. Interview

Expand Down Expand Up @@ -198,16 +211,17 @@ Projects, and the milestone aligned with the real state:
`In Progress`.
- `review`: the slice is with babysit or the user; record the handoff in the
summary and leave mapped Projects `In Progress`.
- `completed`: the owned work is finished, and mapped Projects move to `Done`.
A direct pull request completes when it merges. An issue completes when the
issue closes, so a merged pull request that leaves issue work open keeps it
`In Progress`.
- `completed`: this slice's work is finished. A direct pull request's claim
completes when it merges; an issue slice's claim completes when that slice
lands, even while sibling slices continue. Mapped Projects move to `Done`
only when the item itself is done, so an issue with slices still running
stays `In Progress`.

Keep the milestone attached throughout; its progress changes when the item
closes.

Re-read the claim before resuming after an interruption, and before entering a
surface it does not declare. When implementation materially changes the
Re-read your claim before resuming after an interruption, and before entering
a surface it does not declare. When implementation materially changes the
summary, touch points, dependencies, or branch, update the claim and reassess
overlap for the newly added surface before working inside it.

Expand Down
49 changes: 47 additions & 2 deletions test/start-issue-evals.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,28 @@ test('branch-only guidance is progressively disclosed', () => {
assert.doesNotMatch(markoverReference, /open '<reviewUrl>'/)
})

test('duplicate claims are detected and handed to the user without an election', () => {
test('a claim owns one slice, so disjoint slices of an issue run in parallel', () => {
assert.match(
skillSource,
/A claim owns one bounded slice rather than the whole/
)
assert.match(
skillSource,
/Clearly separate slices: claim yours and continue\./
)
assert.match(
skillSource,
/collides only when its slice overlaps or may overlap yours/
)
assert.match(
skillSource,
/even while sibling slices continue/
)
assert.doesNotMatch(skillSource, /Add no second claim|One item carries one active intent/)
assert.doesNotMatch(skillSource, /more than one active claim is present/)
})

test('an overlapping slice is detected and handed to the user without an election', () => {
const existingClaim = skillSource.indexOf(
'**When the target already carries an active claim**'
)
Expand All @@ -170,11 +191,35 @@ test('duplicate claims are detected and handed to the user without an election',
assert.match(skillSource, /any claim whose phase is\nnot `completed`/)
assert.match(
skillSource,
/read the target's own claim comments once more[\s\S]*pause, show the collision[\s\S]*do not invent a winner/
/Clearly the same slice: show that claim and ask/
)
assert.match(
skillSource,
/Plausible overlap the live evidence does not settle: show both slices and ask\./
)
assert.match(
skillSource,
/read the target's own claim comments once more[\s\S]*pause, show both slices[\s\S]*do not invent a winner/
)
assert.doesNotMatch(skillSource, /owner token|earliest `created_at`|self-demot/i)
})

test('merging one slice leaves its sibling claims alone', () => {
const merge = fs.readFileSync(
path.join(root, '.agents/skills/babysit/references/merge.md'),
'utf8'
)
assert.match(
merge,
/Complete the claim for the merged slice[\s\S]*sibling claim alone/
)
assert.doesNotMatch(merge, /`completed` as well/)
assert.match(
fs.readFileSync(path.join(root, '.agents/skills/babysit/SKILL.md'), 'utf8'),
/An issue can carry several claims for slices running in parallel/
)
})

test('root guidance owns the terminal-friendly Markover handoff', () => {
assert.match(agentsSource, /^`open '<reviewUrl>'`$/m)
assert.match(agentsSource, /best-effort Markdown link and raw review ID/)
Expand Down