Skip to content

(claim): Green runs strand org-repo claims — author_association #477

Description

@evanharmon1

Invariant

When claim-release.yml reports success, the claim is actually released — or the job goes red. A green run must never leave the assignee and claim:* label in place, because nothing downstream re-checks a run that said it succeeded.

Current violation (observed 2026-08-16, first org-repo field failure)

ponderousdev/lawnomator-site#100 was closed COMPLETED by merging PR #110. claim-release.yml ran, concluded success, and left both markers on the issue:

assignees=evanharmon1  labels=claim:claude

The run log (31920664204) says:

ponderousdev/lawnomator-site#100 has no trusted claim comment — nothing to release

That is exit 3, which the workflow deliberately treats as benign ([ "$rc" -eq 0 ] || [ "$rc" -eq 3 ] || exit "$rc") — correct for a genuinely unclaimed issue, and exactly what makes this failure silent.

A trusted claim comment did exist, posted by the claimant:

author=evanharmon1  type=User  author_association=MEMBER  created=2026-08-15T21:38:07Z

…with a well-formed v1 claim record naming claim:claude and assignee added by this claim: yes.

The same script, with the workflow's exact flags, releases it correctly when run locally:

./.claude/skills/track-work/assets/release-claim.sh --repo ponderousdev/lawnomator-site --issue 100 \
  --reason "issue closed (completed)" --not-after "2026-08-16T01:55:16Z" --require-closed --dry-run
# → DRY-RUN: gh issue edit ... --remove-label claim:claude
# → DRY-RUN: gh issue edit ... --remove-assignee evanharmon1
# → ponderousdev/lawnomator-site#100: claim released      (exit 0)

Same file (.agents/skills/track-work is a symlink to .claude/skills/track-work; md5 173443cc0e059da4adf77132d5c396ba both). Same flags. Opposite verdict. The only difference is the token.

Root cause (strong hypothesis — the one thing I could not mint a token to prove)

The trust predicate requires write-shaped author_association:

def writeauth:
    (.author_association // "") as $a
    | (["OWNER", "MEMBER", "COLLABORATOR"] | index($a)) != null;

author_association is not absolute — GitHub computes it against what the requesting token may see. evanharmon1's membership in the ponderousdev org is private:

gh api orgs/ponderousdev/public_members/evanharmon1
# → HTTP 404: not a public member

A PAT with read:org therefore sees MEMBER (verified above). A bare secrets.GITHUB_TOKEN has no org-membership visibility, so it sees NONE, writeauth fails, the comment is filtered out, and the script correctly concludes there is no trusted claim.

On an org repo the owner prong (ponderousdev) never matches a user, so trust rests entirely on the assignee prong — and that prong is silently disarmed for every private org member. That is every claim this repo will ever make.

Relationship to #217

217 documents the org-repo trust gate stranding claims when the claimant is unassigned. This is a different trigger of the same gate: the claimant was a current assignee the whole time, and the trust still failed because the association degraded under the workflow's token

217's stated prerequisite — "an org repo actually adopting claim-release.yml" — is now met: ponderousdev/lawnomator-site has adopted it, and this is its first real close event. Distinct from #434 (markers with no claim record), since here the record is present and well-formed

Acceptance criteria

Verify

# The predicate that filters the comment out:
grep -n -A3 "def writeauth" .claude/skills/track-work/assets/release-claim.sh

# Is the claimant's org membership private (so a bare GITHUB_TOKEN sees NONE)?
gh api orgs/<org>/public_members/<claimant> --silent && echo public || echo private

# The end-to-end symptom, on any org repo that adopted the workflow:
gh issue list --repo <org>/<repo> --state closed --label claim:claude --limit 50

Any closed issue still carrying claim:claude means claims are being stranded under green runs.


Found while shipping ponderousdev/lawnomator-site#100. That claim was released by hand; the underlying gate is unchanged.

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

    area:session-flowThe session lifecycle skills: kickoff, breakdown, claim, implement, retro, wrapbugSomething isn't workingdomain:agent-workflowAI-delegated dev sessions: the universal skill suite (kickoff→wrap) and shared subagentslayer:integrationExternal boundary: webhooks, API clients, credentials

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions