From ded59ceec9fc3af7cf4fd0167e2c6e443917de9f Mon Sep 17 00:00:00 2001 From: Claude Date: Thu, 17 Sep 2026 23:21:33 +0000 Subject: [PATCH] docs(workflows): five 65536 restatements re-worded to the measured caps, each naming its record MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The five lines asserted "GitHub's 65536-character limit" as fact. The ISSUE-body half was falsified by bisection (objectstack#18793: 262,144 UTF-8 bytes stored, 262,145 refused); the COMMENT half is bisected here (objectstack#18826: the same boundary, on both createComment and updateComment, with a real 422 where the issue-body surface is silent). A github-script step cannot import ISSUE_BODY_LIMIT, so these five are restatements by construction — so each now NAMES the record it was read from, and the next falsification finds all five by grep. GitHub's own 422 text still claims "maximum is 65536 characters" and is false in both unit and value; every restatement says so, because that string is where the folklore comes back from. test-nightly-tiers.yml's BUDGET = 40000 is left at 40,000 and stated as what it is: a reading budget sized against the reader, not a platform bound inherited from the false cap. No behaviour changes: comments only. retry-exempt-status-codes is untouched on all four files that carry it. Claude-Session: https://claude.ai/code/session_01Gqi43smmqjJ5sUrhfoPeKu Co-authored-by: Claude --- .github/workflows/cross-repo-issue-closer.yml | 19 +++++++++++--- .github/workflows/docs-drift-check.yml | 14 ++++++++--- .github/workflows/merge-queue-triage.yml | 19 +++++++++++--- .github/workflows/scheduled-full-run-card.yml | 19 +++++++++++--- .github/workflows/test-nightly-tiers.yml | 25 +++++++++++++++++-- 5 files changed, 81 insertions(+), 15 deletions(-) diff --git a/.github/workflows/cross-repo-issue-closer.yml b/.github/workflows/cross-repo-issue-closer.yml index b82103bcb04..d6a4c4a5137 100644 --- a/.github/workflows/cross-repo-issue-closer.yml +++ b/.github/workflows/cross-repo-issue-closer.yml @@ -162,10 +162,21 @@ jobs: # to fail instead of one. It still fails, and the loop still names the # target it failed on. # - # 400/401/404/422 stay exempt: a malformed request, a wrong target, or a - # body past GitHub's 65536-character comment limit is this repo's own - # bug. It is answered correctly on the first try and asking again only - # spends runner minutes. + # 400/401/404/422 stay exempt: a malformed request, a wrong target, or + # an oversized body is this repo's own bug. It is answered correctly on + # the first try and asking again only spends runner minutes. + # + # Both caps this step can hit are MEASURED, in UTF-8 BYTES, and they are + # the same number — ⛔ neither is the 65,536 characters this comment used + # to name. A COMMENT (`issues.createComment` below) stores 262,144 bytes + # and refuses 262,145 with a real 422: objectstack#18826, bisected to one + # byte. An ISSUE BODY (`issues.update` below) stores 262,144 and refuses + # 262,145 SILENTLY — 200, old body kept, nothing reported: + # objectstack#18793, bisected to one byte, restated as + # `ISSUE_BODY_LIMIT` in scripts/pm/check-half-states.mjs. ⛔ Do not + # re-derive 65,536 from a refusal message: GitHub's own 422 text still + # says "maximum is 65536 characters" and #18826 falsified it in both unit + # and value by storing a 262,144-character comment. retries: 3 retry-exempt-status-codes: 400,401,404,422 script: | diff --git a/.github/workflows/docs-drift-check.yml b/.github/workflows/docs-drift-check.yml index 87f929eec9c..47175bbc9d3 100644 --- a/.github/workflows/docs-drift-check.yml +++ b/.github/workflows/docs-drift-check.yml @@ -554,9 +554,17 @@ jobs: // separates it from a genuine permission denial. // Everything else stays fatal on purpose: 401 / plain 403 (the `permissions:` // block above is wrong), 404 (wrong target), 422 (the body this workflow built - // is not postable — e.g. past GitHub's 65536-character comment limit), and any - // non-HTTP error such as a TypeError in the code above. Those are this repo's - // own bugs and must keep failing the job. + // is not postable — e.g. past the COMMENT cap), and any non-HTTP error such as + // a TypeError in the code above. Those are this repo's own bugs and must keep + // failing the job. + // + // That cap is MEASURED, in UTF-8 BYTES, ⛔ not the 65,536 characters this + // comment used to name: a comment stores 262,144 bytes and refuses 262,145 + // with a real 422, on BOTH `issues.createComment` and `issues.updateComment` + // below — objectstack#18826, bisected to one byte on each endpoint. ⛔ Do not + // re-derive 65,536 from the refusal itself: GitHub's own 422 text still reads + // "maximum is 65536 characters" and #18826 falsified it in both unit and + // value, storing a 262,144-CHARACTER comment. const TRANSIENT_NETWORK_CODES = new Set([ 'ECONNRESET', 'ECONNREFUSED', 'ETIMEDOUT', 'EAI_AGAIN', 'ENOTFOUND', 'EPIPE', 'EHOSTUNREACH', 'ENETUNREACH', 'UND_ERR_SOCKET', 'UND_ERR_CONNECT_TIMEOUT', diff --git a/.github/workflows/merge-queue-triage.yml b/.github/workflows/merge-queue-triage.yml index d649bb99613..60d87161a49 100644 --- a/.github/workflows/merge-queue-triage.yml +++ b/.github/workflows/merge-queue-triage.yml @@ -174,9 +174,22 @@ jobs: # wrong `permissions:` block) now takes four attempts to fail instead of # one. It still fails. # - # 400/401/404/422 stay exempt: a malformed request, a wrong target, or a - # body past GitHub's 65536-character comment limit is this repo's own bug, - # answered on the first try and not improved by asking again. + # 400/401/404/422 stay exempt: a malformed request, a wrong target, or + # an oversized body is this repo's own bug, answered on the first try and + # not improved by asking again. + # + # Both caps this workflow can hit are MEASURED, in UTF-8 BYTES, and they + # are the same number — ⛔ neither is the 65,536 characters this comment + # used to name. A COMMENT (`issues.createComment` below) stores 262,144 + # bytes and refuses 262,145 with a real 422: objectstack#18826, bisected + # to one byte. An ISSUE BODY (`issues.update` / `issues.create` below) + # stores 262,144 and refuses 262,145 — on `create` with a 422 (#18826), + # on `update` SILENTLY, 200 with the old body kept and nothing reported: + # objectstack#18793, bisected to one byte, restated as + # `ISSUE_BODY_LIMIT` in scripts/pm/check-half-states.mjs. ⛔ Do not + # re-derive 65,536 from a refusal message: GitHub's own 422 text still + # says "maximum is 65536 characters" and #18826 falsified it in both unit + # and value by storing a 262,144-character comment. retries: 3 retry-exempt-status-codes: 400,401,404,422 script: | diff --git a/.github/workflows/scheduled-full-run-card.yml b/.github/workflows/scheduled-full-run-card.yml index af34c81d8d2..1e3b9bfac60 100644 --- a/.github/workflows/scheduled-full-run-card.yml +++ b/.github/workflows/scheduled-full-run-card.yml @@ -121,9 +121,22 @@ jobs: # Same transient-retry posture as merge-queue-triage.yml, and for the # same reason: 403 is REMOVED from the exempt list because GitHub # answers a secondary rate limit with 403 as well as 429, and this job - # pages issues. 400/401/404/422 stay exempt — a malformed request or a - # body past the 65536-character limit is this repo's own bug and is - # not improved by asking again. + # pages issues. 400/401/404/422 stay exempt — a malformed request or + # an oversized body is this repo's own bug and is not improved by + # asking again. The size that makes a body oversized is MEASURED, in + # UTF-8 BYTES: this job writes an ISSUE BODY, which stores 262,144 + # bytes and refuses 262,145 (objectstack#18793, bisected to one byte; + # restated as `ISSUE_BODY_LIMIT` in scripts/pm/check-half-states.mjs). + # ⛔ Not the 65,536 characters this comment used to name, and ⛔ not + # the number in GitHub's own refusal text either — that string still + # reads "maximum is 65536 characters" and objectstack#18826 falsified + # it in both unit and value by storing a 262,144-character comment. + # ⚠️ On `issues.update` an oversized body is not a 422 at all: the + # platform answers 200, keeps the OLD body and reports nothing + # (#18793). The 422 exemption stays right for the malformed request it + # also covers, and `issues.create` DOES answer 422 on an oversized + # body (#18826) — but ⛔ a refresh that outgrows the cap never reaches + # it. retries: 3 retry-exempt-status-codes: 400,401,404,422 script: | diff --git a/.github/workflows/test-nightly-tiers.yml b/.github/workflows/test-nightly-tiers.yml index 2eb37dc1b65..75a166b715f 100644 --- a/.github/workflows/test-nightly-tiers.yml +++ b/.github/workflows/test-nightly-tiers.yml @@ -433,8 +433,19 @@ jobs: const failing = read('failing-files.txt').split('\n').map((s) => s.trim()).filter(Boolean); const extractorExit = process.env.FAILING_FILES_EXIT; - // The log tails, bounded: a GitHub issue body caps at 65536 chars, - // and the run link carries the whole log anyway. + // The log tails, bounded. ⛔ The bound below is NOT the platform + // cap, and the platform cap is not 65,536 of anything. This step + // posts an ISSUE BODY, and that surface is MEASURED, in UTF-8 + // BYTES: 262,144 bytes stored, 262,145 refused — bisected to one + // byte on objectstack#18793, and restated as `ISSUE_BODY_LIMIT` in + // scripts/pm/check-half-states.mjs. ⛔ Do not re-derive 65,536 from + // a refusal message: GitHub's own 422 text still says "maximum is + // 65536 characters" and is false in both unit and value — + // objectstack#18826 stored a 262,144-CHARACTER comment. ⚠️ And on + // this surface the refusal is not a 422 at all: an oversized issue + // body is answered 200 with the OLD body kept and nothing reported + // (#18793), so a body that outgrows the cap vanishes silently. + // The run link carries the whole log anyway. const tails = []; const reportsDir = path.join(process.env.RUNNER_TEMP, 'nightly-reports'); const walk = (dir) => { @@ -447,6 +458,16 @@ jobs: } }; walk(reportsDir); + // BUDGET is a READING budget, ⛔ not a platform bound, and it is + // deliberately NOT re-sized now that the cap above is known to be + // four times what this file used to assert. 40,000 is about as much + // log tail as a person reads off a card before clicking through, + // and the run link carries every byte elided here — so this number + // is sized against the reader, and a correction to the cap moves a + // reading, never a licence to print more. It is counted in the unit + // the slice below uses (JS string length, i.e. UTF-16 code units), + // because nothing judges it against the byte cap: even as bytes of + // CJK prose it stays far under 262,144. const BUDGET = 40000; const perTail = Math.max(2000, Math.floor(BUDGET / Math.max(1, tails.length))); const tailBlocks = tails.sort((a, b) => a.shard.localeCompare(b.shard)).flatMap(({ shard, text }) => [