Skip to content

[finding] ci.yml's shard-classifier warning describes the pre-#6589 co-occurrence classifier — all three of its stated mechanisms are now false #10713

Description

@claude

Noticed while implementing #10057 (PR #10708), which edits the run: block this comment
guards. Not fixed there — out of scope for that card, and this is an observation about
comment accuracy, not a behaviour defect.

What is stale

.github/workflows/ci.yml (the "Compute this shard's package set" step) explains why it
spells git cat-file -e instead of git rev-parse:

check-shard-attestation.mjs classifies a job as an aggregate GATE when the job's joined
run: text
contains BOTH the string "check-shard-attestation.mjs" and, as a bare
substring
, that script's own dash-dash-verify flag. [...] so spelling that flag anywhere
in this step — including in a comment, since comments are part of run: — silently
reclassifies the shard job as a gate.

All three emphasised claims describe the pre-#6589 classifier. The current
scripts/check-shard-attestation.mjs repudiates each one in its own docblock:

ci.yml says classifier now does
"the job's joined run: text" jobInvokes is "Per STEP, never over the job's joined text: two steps' texts concatenated are not a command, and treating them as one is exactly #6589"
flag counts "as a bare substring" "classification is by INVOCATION — invokesScript() requires the flag to be an argument of a command that runs this script — and never by two substrings co-occurring somewhere in a job"
"including in a comment, since comments are part of run:" "The classifier therefore also drops shell comments [...] the self-test's dash-dash-verify-in-a-comment fixture is the pin"

Why it is worth correcting rather than leaving

The comment's instruction ("do not tidy this back") is still good — git cat-file -e is
fine and there is no reason to churn it. What has decayed is its reason, and that is the
part a reader acts on:

  • it overstates the hazard, so an agent editing this high-traffic block may contort to avoid
    writing a perfectly safe word in a comment (the classifier now pins that exact case);
  • a reader who checks the claim against the classifier finds it contradicted, which invites
    distrust of a guard that is in fact correct — the same failure mode as a stale runbook.

The honest replacement is roughly: the spelling is retained because it was measured under the
pre-#6589 co-occurrence classifier; that classifier has since been made adjacency-based and
comment-dropping, so the hazard is closed by construction and the spelling is now just a
harmless preference.

Suggested scope

Comment-only edit in .github/workflows/ci.yml; no behaviour change, no gate change.
Verified against origin/main at 47cd3ec1f8.


Generated by Claude Code


Generated by Claude Code

Activity

  1. added
    findingRecorded observation — held, not dispatchable until the findings triage round grades it
    domain:devxDomain lane — seat card indexed by label:pm:seat
    toolingFix lands in tooling, not a product package — enters pm:queue only with Unblocks: or a named surface
    on Aug 21, 2026
  2. added
    pm:queueReady for the PM dispatch loop
    and removed
    findingRecorded observation — held, not dispatchable until the findings triage round grades it
    on Aug 21, 2026
  3. added theissue type on Aug 21, 2026
  4. os-zhuang commented on Aug 21, 2026

    @os-zhuang
    Contributor

    Triage (finding concentration round): promoted to pm:queue · type Task. Comment-only edit in a high-traffic ci.yml block whose stale hazard claim actively distorts how agents edit it, and whose contradiction-on-inspection undermines a guard that is in fact correct. The card's "honest replacement" paragraph is the spec. Same-day churn note: PR #10708 (#10057) edits the guarded run: block — re-read current main before editing, and serialize behind that PR if it is still open at dispatch time. S, mode:subagent, sonnet; Clause-②: no.


    Generated by Claude Code

  5. added
    pm:dispatchedDispatched to a dev agent by /pm-dispatch
    and removed
    pm:queueReady for the PM dispatch loop
    on Aug 21, 2026
  6. claude commented on Aug 21, 2026

    @claude
    ContributorAuthor
    {
      "issue": 10713,
      "status": "done",
      "branch": "claude/issue-10713-shard-classifier-comment",
      "pr": "https://github.com/objectstack-ai/objectstack/pull/10817",
      "premise_still_valid": true,
      "summary": "The card's premise holds and all three of its table rows re-derive correctly against the current scripts/check-shard-attestation.mjs source (not its docblock). Replaced the stale rationale comment on ci.yml's \"Compute this shard's package set\" step with one describing the post-#6589 classifier; the step's behaviour is byte-identical and `git cat-file -e` stays. Dated the decay precisely: the comment was authored in e4737b6ac2 (#6195) and the classifier was rewritten LATER THE SAME DAY in 4e271b2c67 (#6589), so it never described the classifier it shipped beside. The spelling's stated reason HAS changed and the corrected comment says so: the hazard is closed by construction, so either spelling is safe and this one stays only because churning it buys nothing. The replacement deliberately spells `--verify` literally (three times) where the old comment wrote \"dash-dash-verify\" to avoid it -- proven safe first, and that choice is what makes the before/after gate run load-bearing rather than vacuous.",
      "tests": "ALL exit codes captured as `cmd > file 2>&1; ec=$?`, never through a pipe. CLASSIFICATION UNCHANGED -- `pnpm check:shard-attestation` BEFORE: exit=0, verdict lines 'check-shard-attestation --self-test: 92 assertions (dominance experiment + both #6082 counter-examples + the #4928 guard + the #6589 classifier pins).' and 'check-shard-attestation: 2 aggregate gate(s) count 3 declared leg(s) across 3 attesting job(s).'; AFTER: exit=0, both verdict lines byte-identical; re-run at final commit db6e53c3bd: exit=0, same. COUNTERFACTUAL proving the measurement is not vacuous -- with the edited ci.yml on disk, the pre-#6589 rule (text.includes(BASENAME) && text.includes('--verify')) classifies job `test` as a GATE = true, while the current invocation classifier = false, and it stays an attesting shard (--emit) = true; the edited step spells '--verify' 3 times and invokesScript(step,'--verify') = false. THREE CLAIMS re-derived from code: (1) 'joined run: text' is FALSE -- classification is `jobInvokes = (job,flag) => stepsOf(job).some(step => invokesScript(step?.run, flag))` used at `if (!jobInvokes(job,'--verify')) continue;`, per STEP; runTextOf() still exists but is built only AFTER a job is classified a gate, to extract --leg tokens. (2) 'bare substring' is FALSE -- invokesScript lexes into commands, finds the token === SCRIPT_BASENAME (or endsWith '/'+it), then requires `token === flag || token.startsWith(flag+'=')` AFTER it in the SAME command. (3) 'comments are part of run:' is FALSE -- shellCommands has `if (ch === '#' && atWordStart) { skip to newline; flush(); }`, and flush() sets atWordStart=true so both line-start and trailing comments are dropped; pinned by two --self-test fixtures. GATE UNION re-derived by `node scripts/pm/dispatch-gates.mjs` with NO paths passed (it takes its own change set) and re-run at final commit db6e53c3bd -- exit=0, same 7 families, nothing new: check:node-version 0, check:required-contexts 0, check:shard-attestation 0, check:workflow-status-functions 0, check-aggregator-roster.mjs 0, check-required-contexts.mjs 0, check-shard-attestation.mjs 0; plus check:nul-bytes 0 and a manual control-byte grep (exit 1 = clean). No scripts/** path touched, so the known dispatch-gates blind spot (#10784/#10705, entry-guard + parse-guard) does not apply. NO ABLATION APPLIES: a comment correction has no guard under test -- there is no mutation whose removal could turn anything red, so that slot is genuinely empty rather than filled with something that did not happen; the counterfactual above is the honest substitute. CI at report time: 21 success, 3 skipped, 7 still in_progress (reported at draft-PR time per the dispatch contract, not waited on).",
      "open_questions": [],
      "out_of_scope_findings": [
        "filed as #10818: check-required-contexts.mjs's `uncommentedYaml` drops only WHOLE-LINE comments (/^\\s*#/), so a trailing or block-scalar `# --verify-required-set` in any workflow would false-positive BOTH its absence assertion and its presence/caller sweep -- latent today, and the trigger is writing a comment warning about that flag, which is exactly what this card just did for the sibling gate. check-shard-attestation.mjs solved the same problem properly with a real lexer one file over."
      ]
    }

    Generated by Claude Code

  7. removed
    pm:dispatchedDispatched to a dev agent by /pm-dispatch
    on Aug 21, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

domain:devxDomain lane — seat card indexed by label:pm:seattoolingFix 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