Repository navigation
ci: fleet-write relay workflow (repository_dispatch → App token → executor) and lint wiring for its self-tests - #19726
Conversation
The repository_dispatch listener that validates a seat's payload, mints a narrowed App token on the runner and executes the actions as the fleet; lint.yml runs the three fleet-write self-tests the way it runs the other pm tools'. Claude-Session: https://claude.ai/code/session_01VhatbEZCV5JJBoU579UBCG Co-authored-by: Claude <noreply@anthropic.com>
|
Standing-down note from the dispatching seat (director, summon #27,
Generated by Claude Code |
|
CI reading on the refreshed head
Fix, ruled by the seat and sent to the same dev: on this branch, Generated by Claude Code |
…as a slug
`check:declared-population-live` reds on main after PR B: the only path-shaped
literal `scripts/pm/fleet-write/validate.mjs` declares in its own body is the
fixture's `repo: 'objectstack-ai/objectstack'`, a slug that names no tracked
file, so the derivation reads the family as declaring a population that reaches
nothing. The fixture now spells the target as `${TARGET_OWNER}/objectstack`,
which the hint extractor admits nothing out of, so the family declares nothing
of its own and keeps the population it inherits from `RELAY_FILES` in ops.mjs.
No `no-path-population` marker: the family inherits four live leads through
the import channel, and `check:pm-dispatch-gates`' live self-test refuses a
family that carries the marker while naming paths.
Claude-Session: https://claude.ai/code/session_01VhatbEZCV5JJBoU579UBCG
Co-authored-by: Claude <noreply@anthropic.com>
维护者速读(终稿)席位:总监席(summon #27, 改了什么:新增 为什么改:云席位拿不到 App 身份(代理替换 风险与代价:私钥只在 runner 铸 token 时被 action 读取,token 按目标仓与三项权限收窄、单次运行即撤销;发送者门禁 = 能对 objectstack 仓发 dispatch 的人,无名单变量;回滚 = 删两个文件 + 撤 席位意见:通过。三轮 CI:第一轮红是落地顺序(B 未进 main),第二轮红是 你要做的:①合并本 PR(Squash);②组织变量 Generated by Claude Code |
Part of #19701 — the relay workflow (PR A of two). Depends on PR B (
claude/issue-19701-fleet-write-transport) landing first: the workflow'srun:lines executescripts/pm/fleet-write/validate.mjsandscripts/pm/fleet-write/execute.mjsfrommain, and the threelint.ymlsteps added here runcheck:pm-fleet-write-*rows that PR B adds topackage.json. Kept as a draft for the maintainer to merge by hand once PR B is onmain(.github/workflows/**— seat tokens cannot land workflow changes)..github/workflows/fleet-write.ymlrepository_dispatchwithtypes: [fleet-write]only.run-name: fleet-write REQUEST_IDso a seat's run-poller finds its run by name.permissions: {}for the workflow'sGITHUB_TOKEN; the job re-grantscontents: readalone (the checkout needs it;persist-credentials: false). The run's only write path is the App token of the mint step, which exists only inside the execute step's environment and is revoked by the action's post step.validate.mjs --from-env --github-output(the payload throughenv:, never interpolated into arun:line; a refusal fails the run with every reason in the step summary and zero writes; on success it outputsrepo_name) →actions/create-github-app-token@v2withapp-id: vars.OS_FLEET_APP_ID,private-key: secrets.OS_FLEET_PRIVATE_KEY,owner: objectstack-ai,repositories: STEPS.VALIDATE.OUTPUTS.REPO_NAME,permission-issues: write,permission-pull-requests: write,permission-metadata: read→execute.mjswith the payload,github.event.sender.loginand the minted token throughenv:.scripts/pm/fleet-write/(PR B); this file is the invocation..github/workflows/lint.ymlThree steps after the card-closure helper's, spelled like their neighbours:
pnpm check:pm-fleet-write-validate,pnpm check:pm-fleet-write-execute,pnpm check:pm-fleet-write-dispatch.check:self-test-wiredrequires the first two the momentfleet-write.ymlnames those scripts; the third is wired for the same reason its siblings are.Maintainer's prerequisites for the live probe (from the card, not for this code)
OS_FLEET_PRIVATE_KEY— done 2026-09-22.OS_FLEET_APP_ID=5028251, visible to objectstack.objectstack-fleet→ repository access All repositories.Live-probe plan (the director seat's, after this lands and 2–3 exist)
From a cloud seat with
OS_FLEET_SESSION=session_…set:node scripts/pm/post-stamped.mjs --comment=19701 --file=probe.md(transportauto→dispatch). Expected:POST …/dispatches → 204, a run namedfleet-write fw-…appears, completessuccess, the step summary carries onecommentrow, the read-back on the card finds the comment withuser.login == objectstack-fleet[bot]. Two readings to take: the run start latency (tuneOS_FLEET_DISPATCH_START_MS, default 90 s) and completion time (tuneOS_FLEET_DISPATCH_TIMEOUT_MS, default 5 min). If the probe withautomerge_enableis refused for permissions, addpermission-contents: writeto the mint step — deliberately not pre-granted.Verification
Run in the relay worktree at
690954b(this branch carries only the two workflow files; the gates below judge the workflow tree and the lint wiring): 43 families reconciled with--ran— 42 run, 1 NOT MEASURED (check:type-check-debt, exit 3, needs the workspace build), 0 unrun; two of the 42 are red on this branch ALONE and green on the combined tree, for the one reason stated at the top:check-self-test-wired --self-testkeys the threepnpm check:pm-fleet-write-*invocations to rows only PR B'spackage.jsoncarries, andcheck:pm-dispatch-gatesreports the same three as 'no root script'. Everything else green, includingcheck:workflow-status-functions,check:workflow-step-name-quoting,check-step-collectors,check-aggregator-roster,check:required-contexts,check:pm-widening-tells,check:nul-bytes.Round 2 at
dbc820c(one commit on top of theorigin/mainrefresh7bae5b5, after PR B merged as70dccce0):scripts/pm/fleet-write/validate.mjsnow rides this PR too — its fixture spells the target as${TARGET_OWNER}/objectstackinstead of the slug'objectstack-ai/objectstack', whichcheck:declared-population-liveread as a path declaration reaching no tracked file once the threelint.ymlsteps made the family a wired gate. Nono-path-populationmarker: the family inherits four live leads fromRELAY_FILESinops.mjs, andcheck:pm-dispatch-gates' live case refuses a family that carries the marker while naming paths. Dev's run on the pushed tree:check:declared-population-liveexit 0 (264 of 325 declaring families live),check:self-test-wired229 scripts,check:pm-dispatch-gates1905/1905, the threecheck:pm-fleet-write-*rows green; 60 families reconciled with--ranover the three changed paths, 59 green, 1 NOT MEASURED (check:type-check-debt, workspace build). Seat's reading of CI ondbc820cis in the final 速读 comment below.The
yamlparse offleet-write.ymlis exercised bycheck:workflow-status-functionsandcheck:workflow-step-name-quoting.check:self-test-wiredwas run against a tree carrying BOTH branches' changes (PR B's scripts plus this workflow) to prove the wiring holds once both land: production run green (229 scripts CI runs ship a--self-test, every one run by CI),--self-test73 cases across 11 batteries green;check:pm-dispatch-gateson that combined tree 1906/1906 with 0 unreachable families.维护者速读(草稿)
fleet-write.yml(repository_dispatch监听,四步:校验 → 铸造 App token → 执行),lint.yml加三个自测步骤。/app/**),只能发 dispatch;这个 workflow 就是「方案 1」的中继,让写入以objectstack-fleet[bot]落地。permissions: {}之下 job 单独给了contents: read供 checkout。OS_FLEET_APP_ID与 App 的仓库范围;之后由总监席发一次探针。Generated by Claude Code
Generated by Claude Code