Skip to content

self-fix.sh: _fix_seats_of cannot recover team/agent from an id-keyed actas lock (#1023) #1255

Description

@fujibee

_fix_seats_of (scripts/lib/self-fix.sh) recovers a lock's team/agent by
splitting its filename on __. That only holds for a legacy-keyed lock
(actas.<team>__<agent>.session). An id-keyed lock (#1023:
actas.<team_id>__<member_id>.session, minted once a team has a team_id
and the roster journal has minted a member_id for that agent — which
join.sh does by default for any team that already has a team_id) splits
into two opaque ids that are not a team and an agent at all.

Concrete repro

  1. join.sh testteam bob claude-code <project> against a team whose
    config.json already carries a team_id (the common case once a team
    has gone through remote.sh connect, or was created after id-keying
    landed).
  2. Claim the actas lock for (testteam, bob) — e.g. via actas-claim.sh.
    The lock lands at an ID-KEYED path, e.g.:
    run/actas.01a0a22a-72b0-7585-81fa-4768f17a6720__01a0a22a-7a80-7a83-8a00-739985dc594b.session
    
    containing the owner's instance id (e.g. bob-sid.12345).
  3. Call _fix_seats_of "bob-sid" (or the promoted agmsg_actas_owned_seats,
    same logic, proposed then reverted in plain driver: let an agent-native channel stand in for peek/poke when there is no pane #1229's PR — see that PR's commits
    for the exact reproduction script used to find this).

Returned: team=01a0a22a-72b0-7585-81fa-4768f17a6720 agent=01a0a22a-7a80-7a83-8a00-739985dc594b owner=bob-sid.12345 — the two
UUID halves of the id-key, not a real team/agent.

Expected: team=testteam agent=bob owner=bob-sid.12345.

Impact

self-fix.sh's fix (no-argument self-repair) calls _fix_seats_of to
find which seats the calling session owns, then tries to prove and rewrite
each returned (team, agent) pair. For an id-keyed lock, it would attempt to
prove/write a placement for a UUID-named "team" and "agent" that do not
exist — at minimum silently doing nothing useful for that seat, possibly
worse depending on what the proof/write path does with a nonexistent
team/agent. Not confirmed against a live fix run; only the direct
_fix_seats_of return value was reproduced.

Suggested fix direction

Do not recover team/agent by reverse-parsing the lock filename. A
(team, agent) pair is only ever discoverable in a BOUNDED way (this
project's own team rosters), so scanning a project's registered
(team, agent) candidates and resolving each FORWARD through
actas_lock_read (already correct for both id-keyed and legacy locks)
avoids the reverse-parse entirely. #1229's PR explored exactly this shape
(as agmsg_actas_owner_in_team) before reverting it in favor of reusing
identities.sh's existing (project, type) → (team, agent) resolution for
that PR's own narrower need; a general fix for _fix_seats_of itself would
need a "scan every locally known team's roster" version of the same idea.

Activity

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

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions