Skip to content

skills/handoff/SKILL.md: the skill supplies the uuid (R-A11-5) but has no preemptive refusal for a lane that has never had a session recorded #98

Closed

Description

@brettheap

Found auditing skills/handoff/SKILL.md against lane-collision-protocol-amendment-11.md while resolving opensoft/openBenches#93 (the test-claude-profile-amendment-11.sh rot-and-CI pass). Confirmed against the current vendored bytes (git show HEAD:skills/handoff/SKILL.md in this repo at the commit opensoft/workBenches pins today).

The ruling

Amendment 11 Addendum 1, R-A11-5 (on the review's F6), section "(e) unknown is refused, by the writer and by the skill":

The /lane-swap skill SUPPLIES the uuid, and refuses only where it cannot. … The skill refuses before it writes and says which act supplies the uuid. Two guards rather than one, for the same reason Amendment 8(e) gives its hook two: the writer is the rule, and the caller that would otherwise hit it at the worst possible moment — mid-swap, with a session about to die — is told first.

A swap is still never left unwritten… Where a swap is somehow taken with none in hand, session_for()'s second rung still answers — the lane's own last recorded uuid… and only a lane that has never had a session recorded at all reaches the refusal. For that lane the swap writes what it legally can: the register's file-level PAUSED line and the row's state cell, with the gap named in the handoff.

Two guards are required: (1) the writer's (lanes-edit.sh log's own session_for() refusal — already shipped, lanes-edit.sh:3146 session_for()), and (2) the skill's own preemptive one, so the operator is told before hitting (1) mid-swap.

What's shipped

skills/handoff/SKILL.md implements half of this: it supplies the uuid it has in hand (LANES_SESSION="$uuid" at :507, the comment at :492-493 names this as the R-A11-5/clause (e) fix). It has no second guard. Grepping the whole file for every use of $uuid:

199:printf 'handoff=%s\nuuid=%s\n' "${handoff:-<none>}" "${uuid:-<none>}"
206:`$uuid` is the last id in the session cell — this session, and the only one Amendment 6(b) calls the
465:transcript_id="${uuid:-none}"
493:# HAS the uuid in hand ($uuid, bound in step 1 and written into the register's
507:LANES_LANE="$lane" LANES_SESSION="$uuid" "$L" log PAUSED "lane:$lane" \
514:"$L" append-line "PAUSED — lane $lane, session $uuid@$ws, $(date -u +%Y-%m-%dT%H:%M:%SZ), on <operator>'s word \"<sanitized verbatim>\"; <what's open, or NOTHING CLAIMED>; handoff refreshed"

There is no [[ -z "$uuid" ]] (or equivalent) anywhere in the file. Compare with the fully-realized sibling case the same file ships for a missing workstation (R-A11-14, :104-113): a named ws_missing flag, a message that fires before the writes, naming the variable and the fix. No such flag, message, or preemptive check exists for a lane that has never had a session recorded — :507 and :514 run unconditionally on $uuid, so a genuinely empty uuid reaches the writer un-warned (line 514 would literally render session @$ws,) rather than the skill refusing first and naming the gap.

Ask

Give the uuid/session case the same shape the workstation case already has: a preemptive check in the skill (not just relying on the helper's own session_for() refusal), a message naming which act supplies the uuid, and the gap named in what step 2 writes into the handoff for a lane with no session ever recorded — mirroring R-A11-14's ws_missing pattern.

Confirmed pre-existing (same gap against git show 8a36eb3:skills/lane-swap/SKILL.md's equivalent step, independent of any pin move).

Filed from opensoft/openBenches#93 (lane openRepoTools-1). Sibling of #79 and #80.

Activity

  1. brettheap commented on Oct 11, 2026

    @brettheap
    ContributorAuthor

    CLAIMED — lane openRepoTools-4, session e545e636-93fd-4b80-81b1-48177346b887@Eagle, 2026-10-11T16:30:56Z, for #98

    Logged in lanes/log/openRepoTools-4.md at 79c469894c7ea0560cc77469d5b22d5359a3b776.

    The three reads (lane-collision-protocol Rule 1):

    1. existing `CLAIMED —` comments on opensoft/openRepoTools#98:
       none
    2. `gh pr list --repo opensoft/openRepoTools --state all --search "#98"`, kept where the row or its body names `#98`:
       none
    3. `git ls-remote --heads git@github.com:opensoft/openRepoTools` branches naming `98` as a whole token:
       none
    
  2. brettheap commented on Oct 19, 2026

    @brettheap
    ContributorAuthor

    RELEASED — lane openRepoTools-4, session e545e636-93fd-4b80-81b1-48177346b887@Eagle, 2026-10-19T11:56:27Z, for #98 — #98 is closed by PR #207 (235c68a); lane 4's claim ends

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions