Repository navigation
finding: lint.yml 的两个 required context 名(ESLint / TypeScript Type Check)在仓内无任何断言 —— 改名即静默丢门,而 ci.yml 的同类名字有 check:shard-attestation 守着 #6865
Description
Activity
os-project-manager commented
on Aug 9, 2026 CollaboratorAuthorMore actionsTriage (maintainer-authorized one-off pass, 2026-08-09, registered on #6015): promoted
finding→pm:queue(domain:devxkept). A rename of either jobname:silently detaches a branch-protection contract carrying the wholecheck:*gate family — the exact #5617 incident shape — while ci.yml's equivalent names are machine-asserted. Deliverable: extend thecheck:shard-attestationidiom (or a sibling script) to pin lint.yml's required context names. Scope update from #5617's closure (2026-08-09): the maintainer approved a second batch of required contexts —Build Core,Build Docs,Console Pin Gate,Temporal Conformance (live PG + MySQL)— so the guard should enroll those names in the same assertion, not just the original two.
Generated by Claude Code
os-project-manager commented
on Aug 9, 2026 CollaboratorAuthorMore actionsClaiming this issue.
- Session:
session_01F8q5J1MQyocgtNspb15fSn - Branch:
claude/issue-6865-lint-required-context-pin
Scope per the 2026-08-09 triage comment: pin all six required-context job names (
ESLint,TypeScript Type Check,Build Core,Build Docs,Console Pin Gate,Temporal Conformance (live PG + MySQL)), following the existingcheck:shard-attestationidiom. Each name will be re-verified againstorigin/mainbefore pinning.
Generated by Claude Code
- Session:
os-project-manager commented
on Aug 9, 2026 CollaboratorAuthorMore actionsScope update — the pinned name set is now FINAL, from the maintainer's saved configuration (2026-08-09), superseding both this card's original two and the #5617 closing comment's planned four-item second batch.
The maintainer configured and saved the
mainruleset's required set as exactly five contexts:ESLint TypeScript Type Check Test Core Dogfood Regression Gate Build CoreThe guard pins these five names — no more, no fewer. The rest of the #5617-approved second batch was deliberately narrowed at settings time (marginal-value review with the maintainer):
Build DocsandTemporal Conformance (live PG + MySQL)stay advisory (the latter's live-DB flake exposure outweighs its solo-red catch rate), andConsole Pin Gateis a v17-window option the maintainer may add temporarily — the guard should treat it as allowed-if-present, not required-to-exist, so adding or removing it around the release window never reds the guard.Implementation note carried over: the guard asserts that each pinned name exists as a job-level
name:in the workflow files (ESLint / TypeScript Type Check inlint.yml; Test Core / Dogfood Regression Gate / Build Core inci.yml), in thecheck:shard-attestationidiom — a rename or deletion reds CI naming the detached branch-protection contract.
Generated by Claude Code
os-project-manager commented
on Aug 9, 2026 CollaboratorAuthorMore actionsScope update #2 (maintainer settings action, 2026-08-09 ~12:0xZ): the pinned set gains a sixth name.
The maintainer added
ADR maintainer approval(the job-level name from.github/workflows/adr-merge-approval.yml— NOT the workflow-level "ADR Merge Approval", which was explicitly checked and avoided) to themainruleset's required set, closing the #7022 gap (two ADR files landed unapproved earlier today because the gate was advisory).Final pinned set for the guard — six required names plus one allowed-if-present:
ESLint (lint.yml) TypeScript Type Check (lint.yml) Test Core (ci.yml) Dogfood Regression Gate (ci.yml) Build Core (ci.yml) ADR maintainer approval (adr-merge-approval.yml)plus
Console Pin Gateas allowed-if-present (v17-window option, never required-to-exist).The adr-merge-approval workflow deliberately reports on every PR (no paths filter, merge_group trigger, review-triggered re-run), so it is deadlock-safe as a required context — the guard should also assert that the workflow keeps all three triggers, since losing any one of them re-opens either the #7022 bypass (merge_group) or a stuck-red-after-approval state (pull_request_review).
Generated by Claude Code
- added a commit that references this issue
on Aug 17, 2026
观察级发现(observation-class:今天没人被咬,是一条潜伏的改名陷阱)。核 #5617 时量到,单独立案不夹带在任何 PR 里。
事实
#5617 的设置面已于 2026-08-07 落地:
ESLint与TypeScript Type Check现在是main分支保护的 required context。这两个名字是 job 级name:的值,不是 workflow 名、也不是 rollup:.github/workflows/lint.yml:24-25— job idlint→name: ESLint(承载 25 条check:*门禁族).github/workflows/lint.yml:506-507— job idtypecheck→name: TypeScript Type Check也就是说这两行字面量就是分支保护的契约。改掉任意一行,GitHub 上报的 check-run 名字随之改变,而分支保护里那条 required context 从此永不上报 —— 表现为永久 pending(与红等效地卡住 PR),或者(若同时把该 context 从设置里摘掉)整个门禁族静默降级为 advisory,即 #5617 事故的原始形状。
为什么说这是缺口:同类风险在 ci.yml 那侧是有守的
ci.yml 的两个聚合门禁名有机器断言:
scripts/check-shard-attestation.mjs:106-107:410-412在 job 消失/改名时判红:job '...' carries a branch-protection-required context but no longer counts shard attestations (#6082/#3622);:344另守聚合 job 的always()(「a gate that skips publishes no required context」)。self-test:655里有test-gate→test-gate-renamed的改名用例,方向明确。ci.yml 正文也把这条契约写了至少 8 处(
:123、:329-330、:423-424、:858-869、:1177-1178,原话「the NAME is the required check, so renaming it would silently drop the gate」)。lint.yml 的两个名字享受不到其中任何一条:
check:shard-attestation只读 ci.yml 的分片/聚合拓扑,check:workflow-status-functions管的是status()函数用法,两者都不断言ESLint/TypeScript Type Check这两个字面量存在。lint.yml 里也没有对应的契约注释(它只在:10-13说明了merge_group触发器的必要性,没说 job 名是契约)。可能的处置(留给分诊定,本人不预设)
check:*的字面量断言(最小改动:在check-shard-attestation.mjs之外新开或扩一条,断言lint.yml中 joblint的name恰为ESLint、jobtypecheck的name恰为TypeScript Type Check,且两者均无if:/matrix/continue-on-error,且on:含merge_group与不带paths:的pull_request)。GET /repos/objectstack-ai/objectstack/branches/main/protection返回 HTTP 403GitHub access is not enabled for this session),所以这类 check 只能断言「仓内这一侧的名字没变」,不能断言「它确实在 required 集里」。前者可测、有价值;后者只能靠维护者核对(#5617 的剩余项正是如此)。把它写成「断言 required 集」会是一道读不到自己声称要读的东西的门。关联:#5617(required 集缺口与审计表)、#6082 / #3622(同族的分片改名陷阱)。