Skip to content

ci(console-pin): conclude on every PR and enrol Console Pin Gate in REQUIRED_CONTEXTS - #19793

Closed
os-warren wants to merge 7 commits into
mainfrom
claude/issue-17673-console-pin-conclusion-every-pr
Closed

os-warren wants to merge 7 commits into
mainfrom
claude/issue-17673-console-pin-conclusion-every-pr

Conversation

@os-warren

Copy link
Copy Markdown
Collaborator

Part of #17673
Clause-②: no

Step 1 of ruling #18900 item ⑤ (comment 5727134555): Console Pin Gate reports a conclusion on every PR (a success on an unaffected one), and it is enrolled in REQUIRED_CONTEXTS. Step 2 is adding it to the required set in Settings → Rulesets. That is the maintainer's click after this lands, and nothing here does it.

Design: the filter term moves from the job onto its steps

  • console-pin's own if: is now !cancelled() alone, so the job always runs and concludes. A job-level if: that is false concludes skipped, and branch protection counts skipped as passing. That was the tombstone's cause.
  • Every step carries the filter term in the contract's own spelling, needs.filter.outputs.console != 'false'. Only an exact 'false' skips a step, so a dead filter job still builds. Both halves of THE FILTER CONTRACT are kept, and merge_group still widens the output to 'true'.
  • On an unaffected run, only one step runs. Its if: is the complement (== 'false'), and it writes a NOT BUILT notice and a step summary. That success is the filter's verdict, not a build.
  • One change from round 1's design: round 1 passed the verdict through a shell step output (steps.scope.outputs.affected). The repo's declaration readers cannot read that without trusting the shell, and that is what broke the dispatch-gates derivation. Each step's if: now reads the filter output directly. The rest of round 1's design is kept.

The three required-path reds round 1 found, and how each is addressed

  1. check:required-contexts: the set-naming census needs platform-readings.md to name the eighth context. It now does (see below).
  2. check:pm-expected-skips: Console Pin Gate is removed from the skip-by-design roster, so a skipped one now exits 4. The measured 39-run head is kept verbatim, and its Console Pin Gate skip is now its one unexpected skip. A derived copy, with that one row concluding success, carries the OK-path cases. Two new cases tie the roster's absence to the live job's own if:.
  3. dispatch-gates: a job's path population was read only from its job-level if:, so a pin-only diff stopped deriving check:console-sha / check:console-injection. The new rule (stepFilterPopulations): a job whose own if: is absent or !cancelled() alone is read step by step. When a step's if: passes the unchanged job-level whitelist, that step's checks get the population. The job-filtered tail walks the same steps. The 4 live console cases are unchanged. 12 new fixture cases and 1 live case pin the step-level shape.

The instruction files stay true on both sides of the click

  • AGENTS.md: "seven block (eight once Settings adds Console Pin Gate)". Where the sentence means the names the registry pins, "those seven" becomes "those eight".
  • platform-readings.md: "objectstack 七个(Console Pin Gate 已登记,入 Settings 即第八)".
  • Both files are at a zero-headroom line ceiling. The new words fill slack in an existing line, and no text moved between lines, so the files stay at 1116 and 469 lines.

CI on this PR

ci.yml is in the console filter, so this PR gets an AFFECTED run: Console Pin Gate builds. ⛔ This PR does not exercise the unaffected leg (NOT BUILT, success) live. The conclusion read on this head is recorded in the os-dev-report on #17673.

Verification (head d134f4c, after one merge of origin/main at 2cf9db7)

  • node scripts/check-required-contexts.mjs: exit 0, 8 names pinned. Its --self-test: exit 0, 169 assertions.
  • check-expected-skips --self-test: exit 0, 107 cases. Before this change it was 1 of 99 red.
  • check-skill-line-ratchet: exit 0. AGENTS.md is 1116 lines against a ceiling of 1116, and platform-readings.md is 469 against 469.
  • dispatch-gates .objectui-sha: base 43e17b8 derives both console gates. Round 1's head fb32a5e derives neither. This head derives both again, via "CI job filter for 'Console Pin Gate'".
  • check:workflow-status-functions, check:workflow-step-name-quoting, check-step-collectors, check-self-test-workflow-commands, check-ci-filter-parity, check:pm-skill-id-lint, check:pm-governed-prose and check:nul-bytes all exit 0. actionlint is not installed here (NOT MEASURED).
  • These were still running when this PR opened: the full dispatch-gates --self-test, the ablation that shows the new cases red on the job-level-only derivation, and the --commands sweep with --ran reconciliation. Their readings are in the os-dev-report on Console Pin Gate never runs on a packages/** change — so the one instrument AGENTS.md names for "did this removal break the pinned sibling?" is structurally absent on exactly the diffs that rule governs #17673.

Landing

This PR touches governed surfaces: AGENTS.md (Tier H) and .claude/** (Tier S). It lands only by the maintainer's hand or after an authorized approval, and it stays draft. There is no changeset because no published package changes (ci.yml, scripts/** and two instruction files).


Generated by Claude Code

…in REQUIRED_CONTEXTS

The console-pin job no longer carries the console filter term in its
job-level if: a first step reads the filter verdict once, every step
that costs anything is step-gated on it, and an unaffected run concludes
success with a NOT BUILT notice and step summary instead of skipped.
The filter contract is kept one level down (anything but an explicit
'false' builds; merge_group widens to 'true').

The registry row returns ahead of its Settings half, with an authorized
field that says approved-not-applied, and the tombstone is rewritten.

Claude-Session: https://claude.ai/code/session_01UDXER3sdqfeVYpEWZs5mZx
Co-authored-by: Claude <noreply@anthropic.com>
Round 1 moved the filter verdict from the job-level if into a first
step that wrote it to a step output (steps.scope.outputs.affected). That
verdict is shell-computed, so no declaration reader in the repo can
follow it without trusting the shell, and a pin-only diff stopped
deriving check:console-sha / check:console-injection.

Every step now carries the filter term in the contract's own spelling
(needs.filter.outputs.console != 'false'); the one step an unaffected
run executes has the exact complement and writes the NOT BUILT notice
and step summary. The job-level if stays !cancelled() alone, so the job
still concludes on every run.

Claude-Session: https://claude.ai/code/session_01UDXER3sdqfeVYpEWZs5mZx
Co-authored-by: Claude <noreply@anthropic.com>
A job that must conclude on every run cannot carry its filter term in
its job-level if (a false job if concludes skipped), so it carries it on
each step instead. Read only at job level, such a job resolved to no
population, and a pin-only diff derived neither check:console-sha nor
check:console-injection.

stepFilterPopulations reads a job whose own if is absent or
!cancelled() alone step by step: each step whose if passes the same
job-level whitelist (jobFilterOutputRefs, unchanged) contributes that
population to the checks that step runs. The job-filtered tail walks
the gated steps plus the job's other conditional ones, so a step whose
if restates the population's own term is not counted as conditional,
and the rest are still sized.

Claude-Session: https://claude.ai/code/session_01UDXER3sdqfeVYpEWZs5mZx
Co-authored-by: Claude <noreply@anthropic.com>
Fixture cases for a job whose filter term sits on its steps: the
population resolves and reaches only the gated step's check; a step with
no if, an inverted step, an AND with a refused term and a job-level if
carrying another term are all refused; the job-filtered tail lists a
step that restates the population term and sizes the rest. A live case
pins that the Console Pin Gate population is read off its steps. The
four live console cases are unchanged.

Claude-Session: https://claude.ai/code/session_01UDXER3sdqfeVYpEWZs5mZx
Co-authored-by: Claude <noreply@anthropic.com>
…ster

Its job now concludes on every run (own if: !cancelled() alone, the
console filter term on each step), so a skipped Console Pin Gate is no
longer by design and reads as exit 4 like any other unrostered name.

The measured 39-run head stays verbatim: its skipped Console Pin Gate
is now the one unexpected skip (18 expected, exit 4). A derived copy with
that one row concluding success carries the OK-path cases and the CLI
exit-0 case. Two roster cases pin the absence and tie it to the live
job's own if: carrying no filter output.

Claude-Session: https://claude.ai/code/session_01UDXER3sdqfeVYpEWZs5mZx
Co-authored-by: Claude <noreply@anthropic.com>
…sides of the click

AGENTS.md's merge-queue sentence and the pm-dispatch readings ledger both
state the required set. Console Pin Gate is registered in
REQUIRED_CONTEXTS and blocks only once the maintainer adds it in
Settings, so both now say seven block and an eighth joins on that click;
"those seven" becomes "those eight" where the sentence means the names
the registry pins. Both files stay at their line ceilings: the new words
fill slack in an existing line and no text moved between lines.

check-required-contexts: two comments re-worded for the step-level
filter term and for the whole-file literal-scan residual.

Claude-Session: https://claude.ai/code/session_01UDXER3sdqfeVYpEWZs5mZx
Co-authored-by: Claude <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ci/cd documentation Improvements or additions to documentation size/m skip-changeset PR has no user-facing published change; bypasses the changeset gate

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants