Skip to content

[Decision] Fleet writes leave the free user accounts: a GitHub App identity for every seat's GitHub writes (reads stay on user tokens), and no new free accounts #17392

Closed as not planned

Description

@os-litant

Filed by the skills seat (session session_01YKEjmbYNvYWJvWGSWx26zK, GitHub os-litant) from the maintainer's discussion of #17374 in this seat's chat, 2026-09-10T10:3xZ–10:5xZ. The maintainer's readings, verbatim and untranslated: 「最近两个月已经封了三个github账户了。封号之后代码都在,最麻烦的是之前的issue都没了。」 · 「申诉过,10天没回复了;账号都是免费的」. ⛔ Not a triage grading; needs-user-decision because the choice moves credentials, cost and the fleet's identity model — the 人工地板.

维护者速读

事情 —— 两个月封了三个账号,申诉十天无回复,而这些账号全是免费账号。GitHub 的条款只允许一个实体持有一个免费账号(机器账号要么占付费席位,要么不被允许);一批一个月内新建、同一基础设施、高频自动化写入的免费账号,正是它反滥用系统识别的「账号舰队」形态。封号时该账号写的 issue、PR、评论全部对他人不可见,分支与提交不受影响(#17374 F3 实测)。快照(#17390)能把每次损失封顶在几小时,但挡不住下一次封号。

选项 —— A:席位的所有 GitHub 写入改走一个 GitHub App(免费;内容归属 xxx[bot];installation token 由仓库私钥签发,配额按 installation 计;席位账号只做读)。B:保留每席一账号,但改为付费 org 席位上的机器账号(合规,按席收费;仍是人类账号形态,封号风险降低但不归零)。C:维持现状,只写限流纪律(#17374 的 1–4 项)。

推荐 A。理由按四轴在下方四棱块。代价:你要建一个 App、装到 org、把私钥放进会话环境的 secret;本席加一个铸 token 的脚本并把 post-stamped.mjs 与 REST 写通道切过去;draft 翻转与 auto-merge 这两个 GraphQL-only 动作要按 App 权限重验一遍;App 一个 installation 共用一池配额(比现在每席各一池少),但写入本就该少而慢。回滚:切回用户 token 只是改一个环境变量。

你要做的 —— 回一个字:A / B / C。

Governing text

Options × real cost

what customer-visible / fleet-visible consequence
A One GitHub App installed on the org; every seat WRITES (comments, labels, PR create, body edits) with an installation token minted from the App's private key; READS keep using the existing user tokens (MCP + REST) Records are authored by <app>[bot] — a seat account's suspension destroys nothing; write quota stops being a human account's; no new free accounts ever. Costs: App setup (maintainer, once), a token-minting script (scripts/pm/), channel switch in post-stamped.mjs and the REST write path; GraphQL-only actions (draft flip, auto-merge) re-verified under App permissions; one shared installation pool instead of one pool per seat
B Paid org seats for machine users, one per seat, no new free accounts ToS-compliant; still human-account shaped (suspension risk lower, not zero; records still die with the account); recurring cost per seat
C Status quo + the discipline text from #17374 (asks 1–4) Nothing structural changes; the next suspension is a matter of time and destroys another author face

四维分析

  • 实际业务需求 —— 实测:三次封号、六张卡与四条 PR 已销毁、一张 p1 安全决策卡在内;申诉无回音。需求不是假设的。
  • 项目长远合理性 —— A 把「记录归属」从可封的人类账号挪到仓库自己的 App 身份,是结构性答案;B 是同一形态花钱降风险;C 是散文。长远权重 ≥50% 指向 A。
  • 防 AI 犯错 —— A 让「多个客户端压同一身份翻倍速率」这种形状在结构上消失(写只有一条通道),比一句「限流绑定身份」的纪律更难写错;C 依赖记忆,条款②声明载体是一扇单向门:席位能把自己写进一个自己出不去的状态 —— 一个会话里同一个坑被踩了 5 次 #17366 已实测记忆不是补救。
  • 创业阶段不扩散 —— A 不新增任何能力面,减少账号数;B 增加经常性支出;C 零成本但零效果。

os-decision-facets

  • ① 项目长远合理性:A 结构性(App 身份归仓库),B 花钱降风险,C 不改形态。
  • ② 实际业务拉动:三次封号、记录销毁、申诉无回音 —— 实测拉动。
  • ③ 防 AI 犯错:A 写通道唯一,速率翻倍形状消失;C 靠记忆。
  • ④ 创业阶段不扩散:A 减账号数不增面;B 增支出。
    推荐 A;置信缺口:App installation token 能否执行 draft 翻转与 auto-merge 未测;org 一池配额是否够全队写(写入本就应少)。

裁后执行(A)

Maintainer: create the App (permissions: issues write, pull requests write, contents read, metadata), install on objectstack-ai, store the App id + private key as environment secrets for the seat sessions. Skills seat: scripts/pm/app-token.mjs (mint + cache an installation token, refuse when the key is absent), switch post-stamped.mjs and the documented REST write path to it, record the channel facts in references/platform-readings.md, keep MCP for reads; one card, one PR, governed only where .claude/** is touched. Then #17374's discipline text lands on top (the identity rule holds under any architecture).

Re-check

# the fleet identity in this container is a user, not an App (control: the login is a person-shaped account)
curl -sS -H "Authorization: token $GH_TOKEN" https://api.github.com/user | python3 -c 'import json,sys; d=json.load(sys.stdin); print(d["login"], d["type"])'   # expect: <login> User

Refs: #17374 (incident), #17390 (board snapshot — the loss cap, independent of this decision), #17366 (memory is not a remedy).


Generated by Claude Code

Activity

  1. added
    toolingFix lands in tooling, not a product package — enters pm:queue only with Unblocks: or a named surface
    priority:p1High: required for production / M2
    needs-user-decisionBlocked on a maintainer decision — do not dispatch; decision cards only, never on a PR
    domain:skillsDomain lane — seat card indexed by label:pm:seat
    on Sep 10, 2026
  2. added theissue type on Sep 10, 2026
  3. os-litant commented on Sep 10, 2026

    @os-litant
    ContributorAuthor

    席位推荐 —— 总监席第 21 场 · 批 #114 · 1/3(session_01QVMnxyWBx8cAQMsV6akDV9,2026-09-10T11:1xZ)

    卡面四棱与速读由 skills 席写就,本席复核同意;人工地板项(凭据、花费、舰队形态)恒交维护者,本席只补三条读数与推荐。

    推荐 A(一个 GitHub App,写归 App、读留用户 token;不再新建免费账号)。回退 B(付费席位机器账号)。⛔ 不推荐 C。执行顺序按卡面:您建 App 与 secret 在先,skills 席的铸 token 脚本与写通道切换在后(governed 面 draft + 人合)。

    os-decision-facets

    • ① 项目长远合理性:A 把记录归属挪到仓库自己的 App 身份,结构性;B 花钱降风险;C 不改形态。
    • ② 实际业务拉动:三次封号、六卡四 PR 销毁、申诉无回音;本场 60+ 条记录同形状暴露。
    • ③ 防 AI 犯错:A 写通道唯一,多客户端压同一身份的形状消失;C 靠纪律。
    • ④ 创业阶段不扩散:A 减账号数、零新能力面;B 增经常性支出。
      推荐 A;置信缺口:App token 对 draft 翻转 / auto-merge 端点未实测;一池配额峰值未量。

    Generated by Claude Code

  4. os-litant commented on Sep 11, 2026

    @os-litant
    ContributorAuthor

    关闭 —— 批 #114 第 1 项:维护者裁「关」(总监席第 21 场 session_01QVMnxyWBx8cAQMsV6akDV9,2026-09-11T04:3xZ)

    出处(谁 / 原话 / 在哪):维护者 · 维护者本场对话逐字:「17392 关; 其他同意,然后你可以下班了」(2026-09-11T04:3xZ,对批 #114 的回批) · 总监席对话。鲜度门:本卡在分析 5617657469 之后无他人评论。

    裁定:不做 A / B / C 中的任何结构改动,本卡关闭 not_planned。⛔ 本席不代维护者补理由;卡面的读数(三次封号、记录销毁)与 #17374 的限流纪律项(1–4)、#17390 的看板快照不受本关闭影响,各自按自己的卡走。若形态再变(新的封号、或 GitHub 侧对机器账号的条款变化),由 skills 席重开并引本评论。

    标签:needs-user-decision 摘;domain:skills · priority:p1 · tooling 留(归属不是状态)。


    Generated by Claude Code

  5. removed
    needs-user-decisionBlocked on a maintainer decision — do not dispatch; decision cards only, never on a PR
    on Sep 11, 2026
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

    domain:skillsDomain lane — seat card indexed by label:pm:seatpriority:p1High: required for production / M2toolingFix lands in tooling, not a product package — enters pm:queue only with Unblocks: or a named surface

    Type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions