Skip to content

session selector: creation-attach BOTH .github and .github-private — measured, sessions currently trade one for the other #420

Description

@bdelanghe

Filed as a durable record of a measured result. The session that measured it could not write it to its own hand-off (.github-private#964) — see "The swap" below, which is exactly why.

Measured: creation-time attachment lifts the dot-name wall

A session created with bounded-systems/.github as an explicit creation source reaches it fully, including workflow_dispatch. Every prior session in this lineage failed at this wall.

Probe Result
Checkout on disk /home/user/.github, full clone, remote bounded-systems/.github, HEAD 5e180d1
GitHub MCP get_file_contents.github/workflows/claim-ticket.yml 200, full file
GET api.github.com/repos/bounded-systems/.github 200
POST .../actions/workflows/claim-ticket.yml/dispatches authorized

Mid-session add_repo still refuses it, re-tested this session:

add_repo: repository name ".github-private" begins with '.', so its clone directory would be a hidden path under this session's working directory and could collide with configuration directories (e.g. ~/.claude). Repositories whose names begin with '.' cannot be attached to this session.

So the wall is specifically on mid-session attach. Creation-time attach is a separate path and it works.

Three of these four probes are weaker evidence than they look

Recording the method, because the naive reading of each is wrong:

  • .github is a public repo. A 200 read proves nothing about session scope. What establishes scope: GET /user returns a real identity at 15000 req/hr (the proxy injects credentials), while .github-private, infra and desk return 403 "GitHub access to this repository is not enabled for this session". The wall is real, and .github is inside it.
  • The repo object reports permissions: {admin, maintain, push, triage, pull} all false, which reads as read-only. It is not a reliable signal here.
  • 403s on collaborators, actions/secrets, hooks are proxy path-filter responses, not GitHub permission denials — the body is "Access to this GitHub API path is not permitted through this proxy." They carry no permission signal. Anyone reading them as authorization evidence (as this session's first pass did) will get the wrong answer.

The one discriminating probe — dispatch at a nonexistent ref. Authorized → 422 No ref found; unauthorized → 403. Neither creates a run, so it is effect-free:

POST /repos/bounded-systems/.github/actions/workflows/claim-ticket.yml/dispatches
  ref = refs/heads/zz-nonexistent-probe-ref
→ 422 "No ref found for: refs/heads/zz-nonexistent-probe-ref"

The permission check passed before ref resolution. Claim door 1 is dispatchable.

The swap — the part that needs fixing

This is not a net gain. It is a trade, and nobody priced it.

  • Sessions before this one: .github-private attached, .github not. Door 1 unreachable.
  • This session: .github attached, .github-private not. Door 1 reachable; .github-private unreachable.
  • No session has had both. Neither can be added after creation.

Concrete cost incurred this session: .github-private#964 was this session's hand-off document and could not be read (403). Two of its four assigned work items live in .github-private and were impossible. The finding above had nowhere to be written, which is why it is filed here.

Ask

The session selector (claude/session-repos.json and whatever consumes it) should creation-attach both .github and .github-private. Since dot-prefixed names cannot be repaired mid-session with add_repo, creation time is the only opportunity — a selector that supplies one of the two produces a session that is silently missing half its context with no in-session remedy.

Related: .github-private#967 already proposes correcting that file's comment, which claims the list is "only the two repos the selector reliably provides". This is a second, independent falsification of that claim.

Note for infra#654

infra#654's premise reads: "add_repo refuses dot-prefixed names, so .github cannot be attached mid-session and its door is unreachable to such a session." The first half is confirmed. The conclusion is narrower than written — a session created with .github attached does reach that door. #654 remains valid (desk's door still serves sessions created without .github), but its motivation is now one route among two rather than the only one.

Status

Unclaimed. Filed as a record, not as started work — no ceremony was minted for it.

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

    Type

    No type

    Projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions