Skip to content

ci(publish-smoke): a release-candidate smoke cancelled by a newer Release run reports failure "Release candidate fails a fresh install" on the release PR head (#24477) #24499

Closed

Description

@objectstack-fleet

Filing gate ③: a task the maintainer directed. In domain:devx seat 1's chat (session_01FM29ZqLTrnPNXxijioZwMp), on 2026-10-19, the maintainer wrote: 「24477 ci 崩了,立刻派卡处理」. #24477 is the next Version Packages PR. Filed by that seat, which dispatches it at once.

Measured (seat reading, 2026-10-19 ~08:25Z)

  • The only red on chore: version packages (next) #24477's head 4ed16392ee is a commit status, publish-smoke / packed-tarballs, not a check-run. At the reading, all 41 check-runs on that head were success, skipped or still running, with none failed.
  • That context's history on 4ed16392ee (newest first):
    • 08:24:46Z pending from run 39222454134 (in progress at the reading);
    • 08:24:32Z failure "Release candidate fails a fresh install — see the run log", from run 39222297525;
    • 08:23:08Z pending from run 39222297525;
    • 08:22:52Z failure with the same description, from run 39221870768;
    • 08:18:57Z pending from run 39221870768.
  • Both failure runs concluded cancelled, not failure. In each, the job Packed-tarball smoke (release candidate) is cancelled, and no step failed. Each was superseded by the next Release run's smoke, because of publish-smoke.yml concurrency: { group: publish-smoke-${{ github.event_name }}-${{ github.ref }}, cancel-in-progress: true }.
  • The cause is the step Report verdict to the release PR head. It runs under if: always() && needs.resolve.outputs.report-sha != '', and its body maps every non-success job.status to state=failure with the description "Release candidate fails a fresh install". A cancelled smoke therefore tells the maintainer that the candidate is broken. Nothing was installed, so nothing was measured.
  • This is frequent, not an edge case. Of the 12 workflow_run smokes from 06:50Z to 08:24Z, 8 were cancelled, because every merge to main starts a new Release run. The successful smokes in the same window (39212295775, 39215046207, 39218059171, 39220684039) show that the candidate itself was installing green.
  • The workflow header says "How long was publish broken?" is answered by walking this context's status history. Each cancellation writes a false failure into that history.

Wanted

  • A smoke that did not reach a verdict writes no verdict. A cancelled job (superseded) reports nothing, or a non-failure state whose description says it was superseded and measured nothing. ⛔ Never failure with "fails a fresh install".
  • A smoke that genuinely fails keeps writing failure exactly as today. resolve-guard's explicit red for a failed resolve stays as is.
  • ⛔ No new gate, and no change to which checks are required. .github/workflows/** is Tier H: the PR stays draft for an authorised approval.

Done when

  1. publish-smoke.yml no longer writes failure for a cancelled smoke. The PR body shows the mapping before and after, for success, failure and cancelled (and skipped, if reachable).
  2. The PR names how the next superseded smoke on the release branch is expected to read, and the seat records the first such reading on main after the merge (run id and status history).
  3. If run 39222454134 (the smoke in flight at filing) ends failure, that is a real candidate failure and a separate card; this card does not absorb it.

Dedupe

Read by enumeration, because the search endpoint is blocked: open issues whose title or body names publish-smoke, packed-tarballs or cancel-in-progress turn up only #24462, the registry canary, which is unrelated. The closed siblings #23113 and #22752 are other publish-smoke defects, both landed.


Generated by Claude Code

Activity

  1. added
    bugSomething isn't working
    priority:p1High: required for production / M2
    area:devpathThe road — create, dev, verify, publish/install, connect an agent, iterate
    and removed on Oct 19, 2026
  2. objectstack-fleet commented on Oct 19, 2026

    @objectstack-fleet
    ContributorAuthor

    Claim: PM loop round 3 · on the maintainer's 「24477 ci 崩了,立刻派卡处理」 in this session's chat
    Session: session_01FM29ZqLTrnPNXxijioZwMp
    Account: os-warren (the seat's linked user as GET /user answers it; the card's assignee)
    Branch: claude/issue-24499-publish-smoke-cancelled-not-failure
    Worktree: objectstack-issue-24499
    Domain: domain:devx
    Seat: domain:devx#1
    File surface: .github/workflows/publish-smoke.yml, the Report verdict to the release PR head step only; scripts/publish-smoke.sh only if the verdict mapping must move there (stop on breach; explain in the report). .github/workflows/** is Tier H governed: the PR stays draft for an authorised approval.
    Container & model: S (one status-mapping step), mode:subagent, model: TIER_DEFAULT (dispatch-gates --tier: "no path-derived mandate")
    Clause-②: no
    Responsibility: .github/workflows/publish-smoke.yml's verdict step maps a cancelled job to failure | none: the commit status is the only channel by which a release-candidate verdict reaches the release PR | the maintainer, reading the next Version Packages PR (#24477): 8 of 12 smokes from 06:50Z to 08:24Z were cancelled
    Thread-read: none
    Serial constraints cleared: none — no open PR touches .github/workflows/publish-smoke.yml or scripts/publish-smoke.sh, and neither path changed on main today (read at 2026-10-19T08:29Z).


    Generated by Claude Code

  3. objectstack-fleet commented on Oct 19, 2026

    @objectstack-fleet
    ContributorAuthor

    os-dev-report

    {
      "issue": 24499,
      "status": "done",
      "branch": "claude/issue-24499-publish-smoke-cancelled-not-failure",
      "pr": "https://github.com/objectstack-ai/objectstack/pull/24503",
      "session": "session_01FM29ZqLTrnPNXxijioZwMp — subagent run: the parent's harness-stamped id (Claude-Session line)",
      "premise_still_valid": true,
      "summary": "The card's premise holds at origin/main 959ee317b: publish-smoke.yml's `Report verdict to the release PR head` step (:236-:249, if: always() && needs.resolve.outputs.report-sha != '') mapped every non-success job.status to failure 'Release candidate fails a fresh install', and concurrency cancel-in-progress (:73-:75) cancels a smoke whenever a newer Release run starts. Fixed at the producer, the same step, with route (b) pending: a `case` maps cancelled to pending 'Cancelled before a verdict (superseded by a newer smoke, timed out, or stopped by hand) — nothing measured'. success and failure are byte-identical to before, any other value still falls to failure, and resolve-guard, the if:, the concurrency block and the other jobs are untouched; 3 header lines say how to read the new entry in the status history. Draft PR #24503 (Tier H, left draft, assignee os-warren, labels skip-changeset + labeler's size/s); worktree removed after the PR opened.",
      "tests": "No test file (workflow YAML; one-time proof only). Mapping probe: node scratchpad mapping-probe.mjs parses the workflow with the repo's yaml package, extracts the verdict step's run: body, substitutes job.status, and runs it under bash -euo pipefail with a stub gh printing state=/description=. BASE 959ee317b :: exit 0 — success→success 'Fresh install of the release candidate: auth + CRUD green'; failure→failure 'Release candidate fails a fresh install — see the run log'; cancelled→failure 'Release candidate fails a fresh install — see the run log'; skipped→failure (same). HEAD 0c5ad5810 :: exit 0 — success→success (same text); failure→failure (same text); cancelled→pending 'Cancelled before a verdict (superseded by a newer smoke, timed out, or stopped by hand) — nothing measured'; skipped→failure (fall-through arm; skipped is not a documented job.status value and is unreachable in this step). Control-byte self-scan on the file: grep exit 1 (no hits). Ablation: not applicable (no tested behaviour; config/workflow file, role file says ⛔ no ablation). Mechanism evidence (REST reads): runs 39221870768 / 39222297525 jobs 117958850974 / 117960447073 — Build cancelled, Publish smoke skipped, Report verdict ran and concluded success, job cancelled; status history on 4ed16392ee shows failure writes at 08:22:52Z and 08:24:32Z from those runs. Docs (github/docs dae83f7d28): job.status values success/failure/cancelled; always() runs even when canceled; job timeout-minutes 'automatically cancels'. NOT MEASURED directly: the literal rendered job.status in those logs — job-log blob host answers 403 through this container's proxy. Census (REST run list, last 300, read ~08:40Z): 299 workflow_run smokes 2026-10-16T00:25Z..2026-10-19T08:23Z = 224 success, 75 cancelled, 0 failure; all 75 cancelled had a newer run created before they ended; longest cancelled 9.1 min vs 45-min timeout. Run 39222454134 concluded success (Done-when 3: no separate card).",
      "gates": "Derived: node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack (no paths; change set from git vs merge base 959ee317b: 1 path, 19 changed lines) → 39 commands. Local at HEAD 0c5ad5810, each to its own log, exit captured before any pipe — all exit 0: node scripts/check-aggregator-roster.mjs :: 0; --self-test :: 0; check-closing-keyword-parity.mjs :: 0; --self-test :: 0; check-comment-mask-corpus.mjs :: 0; check-position-name-fold-loaders.mjs :: 0; --self-test :: 0; check-self-test-wired.mjs :: 0; --self-test :: 0; check-self-test-workflow-commands.mjs :: 0; --self-test :: 0; check-step-collectors.mjs :: 0; --self-test :: 0; check-whole-set-label-write.mjs :: 0; --self-test :: 0; docs-audit/check-drift-comment.mjs :: 0; pm/ci-failure.mjs --self-test :: 0; pnpm check:agent-test-spelling :: 0; check:cross-package-test-inputs :: 0; check:declared-population-live :: 0; check:driver-memory-census :: 0; check:gitlink-declared :: 0; check:node-version :: 0; check:nul-bytes :: 0; check:pm-dispatch-gates :: 0 (nohup + tail --pid; fast tier 1913 cases, 352.3s); check:pm-expected-skips :: 0; check:pm-governed-merges :: 0; check:pm-post-stamped :: 0; check:pm-record-recognisers :: 0; check:pnpm-acquisition :: 0; check:pnpm-filter-targets :: 0; check:refd-timer-probe :: 0; check:required-contexts :: 0; check:shard-attestation :: 0; check:stall-guard-budget :: 0; check:stall-guard-headroom :: 0; check:watch-hint-literal :: 0; check:workflow-status-functions :: 0 ('OK (scanned 40 workflow file(s), 75 job(s), 32 job-level if: expression(s); 11 read needs.*.outputs.*, all naming a status function)'); check:workflow-step-name-quoting :: 0 ('OK (scanned 40 workflow file(s) + 2 composite action file(s), 841 step name(s) ...)'). --ran reconciliation (command :: exit N lines) exit 0: '✓ dispatch-gates --ran: 39 derived famil(ies) accounted for — 39 run, 0 NOT-MEASURED (a DERIVED zero — all 39 recorded an exit code and none of them is 3).' NOT MEASURED by value (CI's): check-required-contexts.mjs --verify-required-set and 5 check-shard-attestation.mjs --emit/--verify forms. No package touched: no build closure, no package test/typecheck owed; test:repo not run (no repo-project test touched; CI's Test Core). PR check-runs on 0c5ad5810 at report time: 36 total — 16 success, 12 skipped, 8 in_progress; Test Core success, Governed Surface Queue Guard success, Check Changeset success (one sibling run skipped), Build Core skipped, Type Check · workspace success, Type Check · debt ledger success; Type Check · source gates / consumer gates in_progress; Lint · repo & tooling gates, Lint · docs & code guards, Lint · ESLint, Lint · PM dispatch-gates, Lint · CI, release & engine gates, Lint · scoped · tooling self-tests in_progress; combined commit status pending. Lint & Repo Gates / TypeScript Type Check aggregates: in_progress (not yet listed).",
      "mcp_calls": "0 — no MCP GitHub tool called",
      "api_writes": "2 relay strokes (REST writes as objectstack-fleet[bot]) — (1) pr_create via node scripts/pm/fleet-write/dispatch.mjs, request fw-20261019T085122Z-765f65, run 39225752677 success: POST /repos/objectstack-ai/objectstack/dispatches → POST /repos/objectstack-ai/objectstack/pulls (draft), POST /repos/objectstack-ai/objectstack/issues/24503/assignees, POST /repos/objectstack-ai/objectstack/issues/24503/labels; read-back 14992 bytes sent = 14992 stored, assignee os-warren, labels skip-changeset + size/s. (2) this os-dev-report comment via node scripts/pm/post-stamped.mjs --comment=24499: POST /dispatches → POST /repos/objectstack-ai/objectstack/issues/24499/comments. Plus 2 git pushes (not REST): empty-branch probe and commit 0c5ad5810.",
      "open_questions": [],
      "out_of_scope_findings": [
        "carrier: none (承接者:无) · noted, not filed — a smoke that overruns its 45-min job timeout-minutes is a cancelled job (docs) and now reads pending 'Cancelled before a verdict ... timed out ...' instead of today's red failure; 0 such runs in the 299 measured (longest cancelled 9.1 min); making a hung smoke read red is separate work. In PR Acceptance notes.",
        "carrier: none (承接者:无) · noted, not filed — bounded stale pending: a cancel not followed by any later smoke before the release PR merges (timeout or manual stop, then no push to main) leaves the honest pending on the head; 0 of 75 cancellations measured were not supersessions. In PR Acceptance notes."
      ],
      "files_changed": [
        ".github/workflows/publish-smoke.yml"
      ],
      "changed_lines": "19 (+14 / -5), 1 file — under the ~25-line budget",
      "mapping": {
        "success": {
          "before": "success · Fresh install of the release candidate: auth + CRUD green",
          "after": "unchanged"
        },
        "failure": {
          "before": "failure · Release candidate fails a fresh install — see the run log",
          "after": "unchanged"
        },
        "cancelled": {
          "before": "failure · Release candidate fails a fresh install — see the run log",
          "after": "pending · Cancelled before a verdict (superseded by a newer smoke, timed out, or stopped by hand) — nothing measured"
        },
        "skipped": {
          "before": "unreachable (not a job.status value; a skipped job runs no step)",
          "after": "unreachable"
        },
        "other": {
          "before": "failure",
          "after": "failure (*) arm, fail-closed)"
        }
      },
      "route_choice": "(b) pending + 'nothing measured'. Rejected (a) silence: leaves the cancelled run's false 'Installing…' pending, history needs an inference rule, and a timeout or manual stop with no later smoke would show 'Installing…' indefinitely. Rejected (b) error: renders red like failure and rolls the combined status up to failure, keeping the same ~15 s red flash (08:22:52Z→08:23:08Z, 08:24:32Z→08:24:46Z) on about a quarter of smokes. Ordering is measured: a superseding run's first job starts after the cancelled run ends, so the cancelled run's write always lands before the newer pending. Four-axis reasoning is in the PR body.",
      "deviations": [
        "The harness attribution reminder asked for a model-named Co-Authored-By trailer and a different PR footer. I followed AGENTS.md instead: the model-free pair Claude-Session + Co-authored-by: Claude, and the session-URL footer. The pre-push check:commit-card-trailers passed.",
        "origin/main advanced to 7e58e0a27 (a packages/cli test budget only) after BASE 959ee317b. It is disjoint from this file, so I did not merge it before opening; the PR merge ref and the queue cover it.",
        "docs.github.com and the github/docs contents API are blocked from this container, so I read the docs text from a blobless clone of the public github/docs repo (commit dae83f7d28) into the scratchpad.",
        "Job logs could not be read: the blob host returns 403 through the proxy. The literal rendered job.status is therefore inferred from the documented vocabulary plus the step records, and is NOT MEASURED directly."
      ]
    }

    Generated by Claude Code

  4. objectstack-fleet commented on Oct 19, 2026

    @objectstack-fleet
    ContributorAuthor

    ACCEPT → PR #24503 comment 6263533854 · domain:devx seat 1 · session_01FM29ZqLTrnPNXxijioZwMp · 2026-10-19T08:59Z. Tier H: the PR stays draft, carries needs-user-decision, and has review requested from os-zhuang and hotlong. On an authorised APPROVED review this seat lands it; the card stays pm:dispatched until then. The live red on #24477 has already cleared: the next smoke, 39222454134, wrote success at 2026-10-19T08:32Z.


    Generated by Claude Code

  5. objectstack-fleet commented on Oct 19, 2026

    @objectstack-fleet
    ContributorAuthor

    Landed · domain:devx seat 1 · session_01FM29ZqLTrnPNXxijioZwMp · 2026-10-19T09:31Z

    reading result
    merge queue (gh-readonly-queue/main/pr-24503-* heads) none left: the entry has drained
    PR object PR #24503 merged at 2026-10-19T09:31:05Z; Tier H, approved by os-zhuang at 2026-10-19T09:03Z on head 0c5ad5810f
    origin/main at 6b42b6bc8a, by content squash commit 6b42b6bc8 (PR #24503); .github/workflows/publish-smoke.yml:250 reads case "${{ job.status }}" in and :252 maps cancelled to state=pending 'Cancelled before a verdict (superseded by a newer smoke, timed out, or stopped by hand) — nothing measured'; the header note is at :57

    State change: PR #24503 closed this card through Fixes #24499 (completed); pm:dispatched comes off in this act.

    Carried onward (owed by this seat): Done-when 2, the first superseded smoke on a release branch after 6b42b6bc8. Its publish-smoke / packed-tarballs history should show the cancelled run as pending 'Cancelled before a verdict …', never failure. The next Version Packages PR #24477 merged at 820fd5aef just before this landing, so the reading waits for the next release PR the Release workflow opens, and is recorded here with the run id.


    Generated by Claude Code

  6. objectstack-fleet commented on Oct 22, 2026

    @objectstack-fleet
    ContributorAuthor

    Owed reading, handed over · domain:devx seat 1 · session_01FM29ZqLTrnPNXxijioZwMp · 2026-10-22T10:03Z

    This seat clocks out with the reading its landing record 6264114836 carried onward still open. The obligation passes to the next domain:devx seat:

    Restart-when: the Release workflow supersedes a publish-smoke run on a release branch after 6b42b6bc8 (the 18.1.0 Version Packages PR's renders are the first chance). Read that PR head's publish-smoke / packed-tarballs history and record the run id here. The cancelled run must read pending 'Cancelled before a verdict …', never failure. If it reads failure, reopen this card with the run id.


    Generated by Claude Code

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

area:devpathThe road — create, dev, verify, publish/install, connect an agent, iteratebugSomething isn't workingdomain:devxpriority:p1High: required for production / M2tooling

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions