finding(check-governed-merges): the merge queue's build-to-land skew can put a governed landing BELOW a round's --since boundary, where it is silently absent from the audit list #12633

Description

@os-litant

Turned up while measuring #11996 (whether the audit sees a governed-surface PR that lands through a merge-queue batch). That question measured YES — every batch topology lists the governed file. This is a different, adjacent property: not the batch topology, but the sweep's window. Filed separately rather than fixed on #11996, whose disposition rule fires only on a blind-to-the-topology verdict.

The mechanism, measured

GitHub's merge queue writes a queue entry's commit when the batch is built, and main receives it when the batch lands. Those are not the same moment. Measured on this repo, on two governed PRs from one batch:

PRmainline commit committer datePR merged_atskew
#12440 (.claude/agents/os-dev.md + 2 references)04600d939 @ 2026-08-26T05:00:27Z2026-08-26T05:25:22Z~25 min
#12443 (.claude/skills/pm-dispatch/SKILL.md + 1 reference)ade757fb3 @ 2026-08-26T05:00:49Z2026-08-26T05:33:08Z~32 min

Consequence: a commit can sit above another on main's first-parent chain (so it landed later) while carrying an earlier committer date. That is not hypothetical — over the last 3612 first-parent pairs on main:

inversions: 10 of 3612 pairs; max 874 s; median 539 s
max skew as a fraction of a 24h window: 1.012%

Two of those ten inverted commits are governed:

git merge-base --is-ancestor 98eec7e248 01a7337fc0 exits 0, so the ancestry direction is not an inference.

The measured miss, on real history

mainlineCommits() windows with git log --first-parent --since=DATE, which cuts on committer date. Set the boundary to the parent's date — exactly what --since-ref ROUND_TIP yields, and what "since the last round" yields whenever the last round ended between the two:

node scripts/pm/check-governed-merges.mjs --repos objectstack --since 2026-08-14T05:55:02Z --json
scanned=1719 governed_entries=190 01a7337fc0 listed? False
node scripts/pm/check-governed-merges.mjs --repos objectstack --since 2026-08-14T05:44:52Z --json
scanned=1721 governed_entries=191 01a7337fc0 listed? True
-> 01a7337fc0 PR #8620 surfaces: docs/adr/0029-kernel-object-ownership-and-platform-objects-decomposition.md

Same tree, same landed set. The only difference is a boundary ten minutes earlier. A governed ADR landing that reached main after the boundary is absent from the first list, and nothing in the output marks the gap — no warning, no incomplete classification on that account. In the degenerate case where it is the only governed landing in the window, the sweep prints a clean window and exits 0 = "swept COMPLETELY", which is precisely the reading #4690 and #9902 say must never be producible.

Reproduced as a constructed signature too (queue chain whose governed entry is dated 874 s — the measured maximum — before its own first parent):

QS-7 build-land skew, --since at the previous round tip
BLIND — governed file absent from the list [exit 0, 0 entries, 0 mainline commits scanned]
QS-7c same tree, --since backed off by the measured 874 s max skew
SEES — listed, attributed to the governed PR [exit 2, 1 entry, 2 mainline commits scanned]

What is NOT broken

The hole opens only when the window start falls between the governed commit's committer date and its landing time. The documented default invocation is safe by a wide margin: the largest measured skew is 874 s = 1.012% of a --since 24h window, and consecutive default rounds overlap by nearly a full day. The exposure is the knife-edge boundary — --since-ref ROUND_TIP, or an exact previous-round timestamp, which is what "实跑 --since 上轮" invites.

Also worth stating plainly: this is queue-specific. A direct merge writes its commit at merge time, so it produces no skew and no inversion.

Options (not taken here; this needs a ruling on windowing semantics)

  • A. Widen by a stated margin. Subtract a skew budget from any operator-supplied --since (and from --since-ref), and say so in the report line. Cheap, mechanical; costs some re-listing of already-recognised entries at each boundary, which the audit tolerates by design (a re-listed entry is recognised again; a dropped one is never seen).
  • B. Window on landing order, not on dates. Take --since-ref topologically: enumerate REF..origin/main instead of --since on the ref's date. That is exactly right for the round-to-round question and immune to any date skew, but it needs the previous round's ref to be recorded, which today it is not.
  • C. Detect and refuse. Notice a committer-date inversion crossing the boundary and classify the sweep INCOMPLETE rather than clean. Smallest behaviour change, keeps the check:react-declaration-parity 是唯一没接进任何 workflow 的源码审计门禁,且无 MANIFEST 时静默 skip 退出 0 —— 它现在永远不可能红 #4690 posture, but reports a problem instead of answering the question.
  • D. Accept and document. State in the header that --since is a date window, not a landing window, and pin the default-invocation margin.

Recommendation: B for --since-ref, A for --since — B is the only one that makes the round-to-round reading exact, and A covers the operator who passes a bare timestamp. Both keep the audit's report-only posture and neither weakens any judgment.

Measured on tree 0043c9224 (plus 4be2e880e, which main fast-forwarded to mid-measurement). Gate baseline is untouched: node scripts/pm/check-governed-merges.mjs --self-test prints "157 assertions" and the lock's VERDICT line reads command-exit 0.

Back-link: #11996 (the measurement this came out of), #11831 (the ruling that chartered it).


Generated by Claude Code

Metadata

Metadata

Assignees

Type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions

    , 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
     blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
    }
    } catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
    })();
    (function(){
    try {
    var __m = "github.com";
    var __re = new RegExp('^' + "github\\.com" + '
    
    Skip to content

    finding(check-governed-merges): the merge queue's build-to-land skew can put a governed landing BELOW a round's --since boundary, where it is silently absent from the audit list #12633

    Description

    @os-litant

    Turned up while measuring #11996 (whether the audit sees a governed-surface PR that lands through a merge-queue batch). That question measured YES — every batch topology lists the governed file. This is a different, adjacent property: not the batch topology, but the sweep's window. Filed separately rather than fixed on #11996, whose disposition rule fires only on a blind-to-the-topology verdict.

    The mechanism, measured

    GitHub's merge queue writes a queue entry's commit when the batch is built, and main receives it when the batch lands. Those are not the same moment. Measured on this repo, on two governed PRs from one batch:

    PRmainline commit committer datePR merged_atskew
    #12440 (.claude/agents/os-dev.md + 2 references)04600d939 @ 2026-08-26T05:00:27Z2026-08-26T05:25:22Z~25 min
    #12443 (.claude/skills/pm-dispatch/SKILL.md + 1 reference)ade757fb3 @ 2026-08-26T05:00:49Z2026-08-26T05:33:08Z~32 min

    Consequence: a commit can sit above another on main's first-parent chain (so it landed later) while carrying an earlier committer date. That is not hypothetical — over the last 3612 first-parent pairs on main:

    inversions: 10 of 3612 pairs; max 874 s; median 539 s
    max skew as a fraction of a 24h window: 1.012%
    

    Two of those ten inverted commits are governed:

    git merge-base --is-ancestor 98eec7e248 01a7337fc0 exits 0, so the ancestry direction is not an inference.

    The measured miss, on real history

    mainlineCommits() windows with git log --first-parent --since=DATE, which cuts on committer date. Set the boundary to the parent's date — exactly what --since-ref ROUND_TIP yields, and what "since the last round" yields whenever the last round ended between the two:

    node scripts/pm/check-governed-merges.mjs --repos objectstack --since 2026-08-14T05:55:02Z --json
    scanned=1719 governed_entries=190 01a7337fc0 listed? False
    node scripts/pm/check-governed-merges.mjs --repos objectstack --since 2026-08-14T05:44:52Z --json
    scanned=1721 governed_entries=191 01a7337fc0 listed? True
    -> 01a7337fc0 PR #8620 surfaces: docs/adr/0029-kernel-object-ownership-and-platform-objects-decomposition.md
    

    Same tree, same landed set. The only difference is a boundary ten minutes earlier. A governed ADR landing that reached main after the boundary is absent from the first list, and nothing in the output marks the gap — no warning, no incomplete classification on that account. In the degenerate case where it is the only governed landing in the window, the sweep prints a clean window and exits 0 = "swept COMPLETELY", which is precisely the reading #4690 and #9902 say must never be producible.

    Reproduced as a constructed signature too (queue chain whose governed entry is dated 874 s — the measured maximum — before its own first parent):

    QS-7 build-land skew, --since at the previous round tip
    BLIND — governed file absent from the list [exit 0, 0 entries, 0 mainline commits scanned]
    QS-7c same tree, --since backed off by the measured 874 s max skew
    SEES — listed, attributed to the governed PR [exit 2, 1 entry, 2 mainline commits scanned]
    

    What is NOT broken

    The hole opens only when the window start falls between the governed commit's committer date and its landing time. The documented default invocation is safe by a wide margin: the largest measured skew is 874 s = 1.012% of a --since 24h window, and consecutive default rounds overlap by nearly a full day. The exposure is the knife-edge boundary — --since-ref ROUND_TIP, or an exact previous-round timestamp, which is what "实跑 --since 上轮" invites.

    Also worth stating plainly: this is queue-specific. A direct merge writes its commit at merge time, so it produces no skew and no inversion.

    Options (not taken here; this needs a ruling on windowing semantics)

    • A. Widen by a stated margin. Subtract a skew budget from any operator-supplied --since (and from --since-ref), and say so in the report line. Cheap, mechanical; costs some re-listing of already-recognised entries at each boundary, which the audit tolerates by design (a re-listed entry is recognised again; a dropped one is never seen).
    • B. Window on landing order, not on dates. Take --since-ref topologically: enumerate REF..origin/main instead of --since on the ref's date. That is exactly right for the round-to-round question and immune to any date skew, but it needs the previous round's ref to be recorded, which today it is not.
    • C. Detect and refuse. Notice a committer-date inversion crossing the boundary and classify the sweep INCOMPLETE rather than clean. Smallest behaviour change, keeps the check:react-declaration-parity 是唯一没接进任何 workflow 的源码审计门禁,且无 MANIFEST 时静默 skip 退出 0 —— 它现在永远不可能红 #4690 posture, but reports a problem instead of answering the question.
    • D. Accept and document. State in the header that --since is a date window, not a landing window, and pin the default-invocation margin.

    Recommendation: B for --since-ref, A for --since — B is the only one that makes the round-to-round reading exact, and A covers the operator who passes a bare timestamp. Both keep the audit's report-only posture and neither weakens any judgment.

    Measured on tree 0043c9224 (plus 4be2e880e, which main fast-forwarded to mid-measurement). Gate baseline is untouched: node scripts/pm/check-governed-merges.mjs --self-test prints "157 assertions" and the lock's VERDICT line reads command-exit 0.

    Back-link: #11996 (the measurement this came out of), #11831 (the ruling that chartered it).


    Generated by Claude Code

    Metadata

    Metadata

    Assignees

    Type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions

      , 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
      Skip to content

      finding(check-governed-merges): the merge queue's build-to-land skew can put a governed landing BELOW a round's --since boundary, where it is silently absent from the audit list #12633

      Description

      @os-litant

      Turned up while measuring #11996 (whether the audit sees a governed-surface PR that lands through a merge-queue batch). That question measured YES — every batch topology lists the governed file. This is a different, adjacent property: not the batch topology, but the sweep's window. Filed separately rather than fixed on #11996, whose disposition rule fires only on a blind-to-the-topology verdict.

      The mechanism, measured

      GitHub's merge queue writes a queue entry's commit when the batch is built, and main receives it when the batch lands. Those are not the same moment. Measured on this repo, on two governed PRs from one batch:

      PRmainline commit committer datePR merged_atskew
      #12440 (.claude/agents/os-dev.md + 2 references)04600d939 @ 2026-08-26T05:00:27Z2026-08-26T05:25:22Z~25 min
      #12443 (.claude/skills/pm-dispatch/SKILL.md + 1 reference)ade757fb3 @ 2026-08-26T05:00:49Z2026-08-26T05:33:08Z~32 min

      Consequence: a commit can sit above another on main's first-parent chain (so it landed later) while carrying an earlier committer date. That is not hypothetical — over the last 3612 first-parent pairs on main:

      inversions: 10 of 3612 pairs; max 874 s; median 539 s
      max skew as a fraction of a 24h window: 1.012%
      

      Two of those ten inverted commits are governed:

      git merge-base --is-ancestor 98eec7e248 01a7337fc0 exits 0, so the ancestry direction is not an inference.

      The measured miss, on real history

      mainlineCommits() windows with git log --first-parent --since=DATE, which cuts on committer date. Set the boundary to the parent's date — exactly what --since-ref ROUND_TIP yields, and what "since the last round" yields whenever the last round ended between the two:

      node scripts/pm/check-governed-merges.mjs --repos objectstack --since 2026-08-14T05:55:02Z --json
      scanned=1719 governed_entries=190 01a7337fc0 listed? False
      node scripts/pm/check-governed-merges.mjs --repos objectstack --since 2026-08-14T05:44:52Z --json
      scanned=1721 governed_entries=191 01a7337fc0 listed? True
      -> 01a7337fc0 PR #8620 surfaces: docs/adr/0029-kernel-object-ownership-and-platform-objects-decomposition.md
      

      Same tree, same landed set. The only difference is a boundary ten minutes earlier. A governed ADR landing that reached main after the boundary is absent from the first list, and nothing in the output marks the gap — no warning, no incomplete classification on that account. In the degenerate case where it is the only governed landing in the window, the sweep prints a clean window and exits 0 = "swept COMPLETELY", which is precisely the reading #4690 and #9902 say must never be producible.

      Reproduced as a constructed signature too (queue chain whose governed entry is dated 874 s — the measured maximum — before its own first parent):

      QS-7 build-land skew, --since at the previous round tip
      BLIND — governed file absent from the list [exit 0, 0 entries, 0 mainline commits scanned]
      QS-7c same tree, --since backed off by the measured 874 s max skew
      SEES — listed, attributed to the governed PR [exit 2, 1 entry, 2 mainline commits scanned]
      

      What is NOT broken

      The hole opens only when the window start falls between the governed commit's committer date and its landing time. The documented default invocation is safe by a wide margin: the largest measured skew is 874 s = 1.012% of a --since 24h window, and consecutive default rounds overlap by nearly a full day. The exposure is the knife-edge boundary — --since-ref ROUND_TIP, or an exact previous-round timestamp, which is what "实跑 --since 上轮" invites.

      Also worth stating plainly: this is queue-specific. A direct merge writes its commit at merge time, so it produces no skew and no inversion.

      Options (not taken here; this needs a ruling on windowing semantics)

      • A. Widen by a stated margin. Subtract a skew budget from any operator-supplied --since (and from --since-ref), and say so in the report line. Cheap, mechanical; costs some re-listing of already-recognised entries at each boundary, which the audit tolerates by design (a re-listed entry is recognised again; a dropped one is never seen).
      • B. Window on landing order, not on dates. Take --since-ref topologically: enumerate REF..origin/main instead of --since on the ref's date. That is exactly right for the round-to-round question and immune to any date skew, but it needs the previous round's ref to be recorded, which today it is not.
      • C. Detect and refuse. Notice a committer-date inversion crossing the boundary and classify the sweep INCOMPLETE rather than clean. Smallest behaviour change, keeps the check:react-declaration-parity 是唯一没接进任何 workflow 的源码审计门禁,且无 MANIFEST 时静默 skip 退出 0 —— 它现在永远不可能红 #4690 posture, but reports a problem instead of answering the question.
      • D. Accept and document. State in the header that --since is a date window, not a landing window, and pin the default-invocation margin.

      Recommendation: B for --since-ref, A for --since — B is the only one that makes the round-to-round reading exact, and A covers the operator who passes a bare timestamp. Both keep the audit's report-only posture and neither weakens any judgment.

      Measured on tree 0043c9224 (plus 4be2e880e, which main fast-forwarded to mid-measurement). Gate baseline is untouched: node scripts/pm/check-governed-merges.mjs --self-test prints "157 assertions" and the lock's VERDICT line reads command-exit 0.

      Back-link: #11996 (the measurement this came out of), #11831 (the ruling that chartered it).


      Generated by Claude Code

      Metadata

      Metadata

      Assignees

      Type

      Projects

      No projects

        Milestone

        No milestone

        Relationships

        None yet

        Development

        No branches or pull requests

        Issue actions

        , 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
        Skip to content

        finding(check-governed-merges): the merge queue's build-to-land skew can put a governed landing BELOW a round's --since boundary, where it is silently absent from the audit list #12633

        Description

        @os-litant

        Turned up while measuring #11996 (whether the audit sees a governed-surface PR that lands through a merge-queue batch). That question measured YES — every batch topology lists the governed file. This is a different, adjacent property: not the batch topology, but the sweep's window. Filed separately rather than fixed on #11996, whose disposition rule fires only on a blind-to-the-topology verdict.

        The mechanism, measured

        GitHub's merge queue writes a queue entry's commit when the batch is built, and main receives it when the batch lands. Those are not the same moment. Measured on this repo, on two governed PRs from one batch:

        PRmainline commit committer datePR merged_atskew
        #12440 (.claude/agents/os-dev.md + 2 references)04600d939 @ 2026-08-26T05:00:27Z2026-08-26T05:25:22Z~25 min
        #12443 (.claude/skills/pm-dispatch/SKILL.md + 1 reference)ade757fb3 @ 2026-08-26T05:00:49Z2026-08-26T05:33:08Z~32 min

        Consequence: a commit can sit above another on main's first-parent chain (so it landed later) while carrying an earlier committer date. That is not hypothetical — over the last 3612 first-parent pairs on main:

        inversions: 10 of 3612 pairs; max 874 s; median 539 s
        max skew as a fraction of a 24h window: 1.012%
        

        Two of those ten inverted commits are governed:

        git merge-base --is-ancestor 98eec7e248 01a7337fc0 exits 0, so the ancestry direction is not an inference.

        The measured miss, on real history

        mainlineCommits() windows with git log --first-parent --since=DATE, which cuts on committer date. Set the boundary to the parent's date — exactly what --since-ref ROUND_TIP yields, and what "since the last round" yields whenever the last round ended between the two:

        node scripts/pm/check-governed-merges.mjs --repos objectstack --since 2026-08-14T05:55:02Z --json
        scanned=1719 governed_entries=190 01a7337fc0 listed? False
        node scripts/pm/check-governed-merges.mjs --repos objectstack --since 2026-08-14T05:44:52Z --json
        scanned=1721 governed_entries=191 01a7337fc0 listed? True
        -> 01a7337fc0 PR #8620 surfaces: docs/adr/0029-kernel-object-ownership-and-platform-objects-decomposition.md
        

        Same tree, same landed set. The only difference is a boundary ten minutes earlier. A governed ADR landing that reached main after the boundary is absent from the first list, and nothing in the output marks the gap — no warning, no incomplete classification on that account. In the degenerate case where it is the only governed landing in the window, the sweep prints a clean window and exits 0 = "swept COMPLETELY", which is precisely the reading #4690 and #9902 say must never be producible.

        Reproduced as a constructed signature too (queue chain whose governed entry is dated 874 s — the measured maximum — before its own first parent):

        QS-7 build-land skew, --since at the previous round tip
        BLIND — governed file absent from the list [exit 0, 0 entries, 0 mainline commits scanned]
        QS-7c same tree, --since backed off by the measured 874 s max skew
        SEES — listed, attributed to the governed PR [exit 2, 1 entry, 2 mainline commits scanned]
        

        What is NOT broken

        The hole opens only when the window start falls between the governed commit's committer date and its landing time. The documented default invocation is safe by a wide margin: the largest measured skew is 874 s = 1.012% of a --since 24h window, and consecutive default rounds overlap by nearly a full day. The exposure is the knife-edge boundary — --since-ref ROUND_TIP, or an exact previous-round timestamp, which is what "实跑 --since 上轮" invites.

        Also worth stating plainly: this is queue-specific. A direct merge writes its commit at merge time, so it produces no skew and no inversion.

        Options (not taken here; this needs a ruling on windowing semantics)

        • A. Widen by a stated margin. Subtract a skew budget from any operator-supplied --since (and from --since-ref), and say so in the report line. Cheap, mechanical; costs some re-listing of already-recognised entries at each boundary, which the audit tolerates by design (a re-listed entry is recognised again; a dropped one is never seen).
        • B. Window on landing order, not on dates. Take --since-ref topologically: enumerate REF..origin/main instead of --since on the ref's date. That is exactly right for the round-to-round question and immune to any date skew, but it needs the previous round's ref to be recorded, which today it is not.
        • C. Detect and refuse. Notice a committer-date inversion crossing the boundary and classify the sweep INCOMPLETE rather than clean. Smallest behaviour change, keeps the check:react-declaration-parity 是唯一没接进任何 workflow 的源码审计门禁,且无 MANIFEST 时静默 skip 退出 0 —— 它现在永远不可能红 #4690 posture, but reports a problem instead of answering the question.
        • D. Accept and document. State in the header that --since is a date window, not a landing window, and pin the default-invocation margin.

        Recommendation: B for --since-ref, A for --since — B is the only one that makes the round-to-round reading exact, and A covers the operator who passes a bare timestamp. Both keep the audit's report-only posture and neither weakens any judgment.

        Measured on tree 0043c9224 (plus 4be2e880e, which main fast-forwarded to mid-measurement). Gate baseline is untouched: node scripts/pm/check-governed-merges.mjs --self-test prints "157 assertions" and the lock's VERDICT line reads command-exit 0.

        Back-link: #11996 (the measurement this came out of), #11831 (the ruling that chartered it).


        Generated by Claude Code

        Metadata

        Metadata

        Assignees

        Type

        Projects

        No projects

          Milestone

          No milestone

          Relationships

          None yet

          Development

          No branches or pull requests

          Issue actions

          , 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
          Skip to content

          finding(check-governed-merges): the merge queue's build-to-land skew can put a governed landing BELOW a round's --since boundary, where it is silently absent from the audit list #12633

          Description

          @os-litant

          Turned up while measuring #11996 (whether the audit sees a governed-surface PR that lands through a merge-queue batch). That question measured YES — every batch topology lists the governed file. This is a different, adjacent property: not the batch topology, but the sweep's window. Filed separately rather than fixed on #11996, whose disposition rule fires only on a blind-to-the-topology verdict.

          The mechanism, measured

          GitHub's merge queue writes a queue entry's commit when the batch is built, and main receives it when the batch lands. Those are not the same moment. Measured on this repo, on two governed PRs from one batch:

          PRmainline commit committer datePR merged_atskew
          #12440 (.claude/agents/os-dev.md + 2 references)04600d939 @ 2026-08-26T05:00:27Z2026-08-26T05:25:22Z~25 min
          #12443 (.claude/skills/pm-dispatch/SKILL.md + 1 reference)ade757fb3 @ 2026-08-26T05:00:49Z2026-08-26T05:33:08Z~32 min

          Consequence: a commit can sit above another on main's first-parent chain (so it landed later) while carrying an earlier committer date. That is not hypothetical — over the last 3612 first-parent pairs on main:

          inversions: 10 of 3612 pairs; max 874 s; median 539 s
          max skew as a fraction of a 24h window: 1.012%
          

          Two of those ten inverted commits are governed:

          git merge-base --is-ancestor 98eec7e248 01a7337fc0 exits 0, so the ancestry direction is not an inference.

          The measured miss, on real history

          mainlineCommits() windows with git log --first-parent --since=DATE, which cuts on committer date. Set the boundary to the parent's date — exactly what --since-ref ROUND_TIP yields, and what "since the last round" yields whenever the last round ended between the two:

          node scripts/pm/check-governed-merges.mjs --repos objectstack --since 2026-08-14T05:55:02Z --json
          scanned=1719 governed_entries=190 01a7337fc0 listed? False
          node scripts/pm/check-governed-merges.mjs --repos objectstack --since 2026-08-14T05:44:52Z --json
          scanned=1721 governed_entries=191 01a7337fc0 listed? True
          -> 01a7337fc0 PR #8620 surfaces: docs/adr/0029-kernel-object-ownership-and-platform-objects-decomposition.md
          

          Same tree, same landed set. The only difference is a boundary ten minutes earlier. A governed ADR landing that reached main after the boundary is absent from the first list, and nothing in the output marks the gap — no warning, no incomplete classification on that account. In the degenerate case where it is the only governed landing in the window, the sweep prints a clean window and exits 0 = "swept COMPLETELY", which is precisely the reading #4690 and #9902 say must never be producible.

          Reproduced as a constructed signature too (queue chain whose governed entry is dated 874 s — the measured maximum — before its own first parent):

          QS-7 build-land skew, --since at the previous round tip
          BLIND — governed file absent from the list [exit 0, 0 entries, 0 mainline commits scanned]
          QS-7c same tree, --since backed off by the measured 874 s max skew
          SEES — listed, attributed to the governed PR [exit 2, 1 entry, 2 mainline commits scanned]
          

          What is NOT broken

          The hole opens only when the window start falls between the governed commit's committer date and its landing time. The documented default invocation is safe by a wide margin: the largest measured skew is 874 s = 1.012% of a --since 24h window, and consecutive default rounds overlap by nearly a full day. The exposure is the knife-edge boundary — --since-ref ROUND_TIP, or an exact previous-round timestamp, which is what "实跑 --since 上轮" invites.

          Also worth stating plainly: this is queue-specific. A direct merge writes its commit at merge time, so it produces no skew and no inversion.

          Options (not taken here; this needs a ruling on windowing semantics)

          • A. Widen by a stated margin. Subtract a skew budget from any operator-supplied --since (and from --since-ref), and say so in the report line. Cheap, mechanical; costs some re-listing of already-recognised entries at each boundary, which the audit tolerates by design (a re-listed entry is recognised again; a dropped one is never seen).
          • B. Window on landing order, not on dates. Take --since-ref topologically: enumerate REF..origin/main instead of --since on the ref's date. That is exactly right for the round-to-round question and immune to any date skew, but it needs the previous round's ref to be recorded, which today it is not.
          • C. Detect and refuse. Notice a committer-date inversion crossing the boundary and classify the sweep INCOMPLETE rather than clean. Smallest behaviour change, keeps the check:react-declaration-parity 是唯一没接进任何 workflow 的源码审计门禁,且无 MANIFEST 时静默 skip 退出 0 —— 它现在永远不可能红 #4690 posture, but reports a problem instead of answering the question.
          • D. Accept and document. State in the header that --since is a date window, not a landing window, and pin the default-invocation margin.

          Recommendation: B for --since-ref, A for --since — B is the only one that makes the round-to-round reading exact, and A covers the operator who passes a bare timestamp. Both keep the audit's report-only posture and neither weakens any judgment.

          Measured on tree 0043c9224 (plus 4be2e880e, which main fast-forwarded to mid-measurement). Gate baseline is untouched: node scripts/pm/check-governed-merges.mjs --self-test prints "157 assertions" and the lock's VERDICT line reads command-exit 0.

          Back-link: #11996 (the measurement this came out of), #11831 (the ruling that chartered it).


          Generated by Claude Code

          Metadata

          Metadata

          Assignees

          Type

          Projects

          No projects

            Milestone

            No milestone

            Relationships

            None yet

            Development

            No branches or pull requests

            Issue actions

            , 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
            Skip to content

            finding(check-governed-merges): the merge queue's build-to-land skew can put a governed landing BELOW a round's --since boundary, where it is silently absent from the audit list #12633

            Description

            @os-litant

            Turned up while measuring #11996 (whether the audit sees a governed-surface PR that lands through a merge-queue batch). That question measured YES — every batch topology lists the governed file. This is a different, adjacent property: not the batch topology, but the sweep's window. Filed separately rather than fixed on #11996, whose disposition rule fires only on a blind-to-the-topology verdict.

            The mechanism, measured

            GitHub's merge queue writes a queue entry's commit when the batch is built, and main receives it when the batch lands. Those are not the same moment. Measured on this repo, on two governed PRs from one batch:

            PRmainline commit committer datePR merged_atskew
            #12440 (.claude/agents/os-dev.md + 2 references)04600d939 @ 2026-08-26T05:00:27Z2026-08-26T05:25:22Z~25 min
            #12443 (.claude/skills/pm-dispatch/SKILL.md + 1 reference)ade757fb3 @ 2026-08-26T05:00:49Z2026-08-26T05:33:08Z~32 min

            Consequence: a commit can sit above another on main's first-parent chain (so it landed later) while carrying an earlier committer date. That is not hypothetical — over the last 3612 first-parent pairs on main:

            inversions: 10 of 3612 pairs; max 874 s; median 539 s
            max skew as a fraction of a 24h window: 1.012%
            

            Two of those ten inverted commits are governed:

            git merge-base --is-ancestor 98eec7e248 01a7337fc0 exits 0, so the ancestry direction is not an inference.

            The measured miss, on real history

            mainlineCommits() windows with git log --first-parent --since=DATE, which cuts on committer date. Set the boundary to the parent's date — exactly what --since-ref ROUND_TIP yields, and what "since the last round" yields whenever the last round ended between the two:

            node scripts/pm/check-governed-merges.mjs --repos objectstack --since 2026-08-14T05:55:02Z --json
            scanned=1719 governed_entries=190 01a7337fc0 listed? False
            node scripts/pm/check-governed-merges.mjs --repos objectstack --since 2026-08-14T05:44:52Z --json
            scanned=1721 governed_entries=191 01a7337fc0 listed? True
            -> 01a7337fc0 PR #8620 surfaces: docs/adr/0029-kernel-object-ownership-and-platform-objects-decomposition.md
            

            Same tree, same landed set. The only difference is a boundary ten minutes earlier. A governed ADR landing that reached main after the boundary is absent from the first list, and nothing in the output marks the gap — no warning, no incomplete classification on that account. In the degenerate case where it is the only governed landing in the window, the sweep prints a clean window and exits 0 = "swept COMPLETELY", which is precisely the reading #4690 and #9902 say must never be producible.

            Reproduced as a constructed signature too (queue chain whose governed entry is dated 874 s — the measured maximum — before its own first parent):

            QS-7 build-land skew, --since at the previous round tip
            BLIND — governed file absent from the list [exit 0, 0 entries, 0 mainline commits scanned]
            QS-7c same tree, --since backed off by the measured 874 s max skew
            SEES — listed, attributed to the governed PR [exit 2, 1 entry, 2 mainline commits scanned]
            

            What is NOT broken

            The hole opens only when the window start falls between the governed commit's committer date and its landing time. The documented default invocation is safe by a wide margin: the largest measured skew is 874 s = 1.012% of a --since 24h window, and consecutive default rounds overlap by nearly a full day. The exposure is the knife-edge boundary — --since-ref ROUND_TIP, or an exact previous-round timestamp, which is what "实跑 --since 上轮" invites.

            Also worth stating plainly: this is queue-specific. A direct merge writes its commit at merge time, so it produces no skew and no inversion.

            Options (not taken here; this needs a ruling on windowing semantics)

            • A. Widen by a stated margin. Subtract a skew budget from any operator-supplied --since (and from --since-ref), and say so in the report line. Cheap, mechanical; costs some re-listing of already-recognised entries at each boundary, which the audit tolerates by design (a re-listed entry is recognised again; a dropped one is never seen).
            • B. Window on landing order, not on dates. Take --since-ref topologically: enumerate REF..origin/main instead of --since on the ref's date. That is exactly right for the round-to-round question and immune to any date skew, but it needs the previous round's ref to be recorded, which today it is not.
            • C. Detect and refuse. Notice a committer-date inversion crossing the boundary and classify the sweep INCOMPLETE rather than clean. Smallest behaviour change, keeps the check:react-declaration-parity 是唯一没接进任何 workflow 的源码审计门禁,且无 MANIFEST 时静默 skip 退出 0 —— 它现在永远不可能红 #4690 posture, but reports a problem instead of answering the question.
            • D. Accept and document. State in the header that --since is a date window, not a landing window, and pin the default-invocation margin.

            Recommendation: B for --since-ref, A for --since — B is the only one that makes the round-to-round reading exact, and A covers the operator who passes a bare timestamp. Both keep the audit's report-only posture and neither weakens any judgment.

            Measured on tree 0043c9224 (plus 4be2e880e, which main fast-forwarded to mid-measurement). Gate baseline is untouched: node scripts/pm/check-governed-merges.mjs --self-test prints "157 assertions" and the lock's VERDICT line reads command-exit 0.

            Back-link: #11996 (the measurement this came out of), #11831 (the ruling that chartered it).


            Generated by Claude Code

            Metadata

            Metadata

            Assignees

            Type

            Projects

            No projects

              Milestone

              No milestone

              Relationships

              None yet

              Development

              No branches or pull requests

              Issue actions

              , 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
              Skip to content

              finding(check-governed-merges): the merge queue's build-to-land skew can put a governed landing BELOW a round's --since boundary, where it is silently absent from the audit list #12633

              Description

              @os-litant

              Turned up while measuring #11996 (whether the audit sees a governed-surface PR that lands through a merge-queue batch). That question measured YES — every batch topology lists the governed file. This is a different, adjacent property: not the batch topology, but the sweep's window. Filed separately rather than fixed on #11996, whose disposition rule fires only on a blind-to-the-topology verdict.

              The mechanism, measured

              GitHub's merge queue writes a queue entry's commit when the batch is built, and main receives it when the batch lands. Those are not the same moment. Measured on this repo, on two governed PRs from one batch:

              PRmainline commit committer datePR merged_atskew
              #12440 (.claude/agents/os-dev.md + 2 references)04600d939 @ 2026-08-26T05:00:27Z2026-08-26T05:25:22Z~25 min
              #12443 (.claude/skills/pm-dispatch/SKILL.md + 1 reference)ade757fb3 @ 2026-08-26T05:00:49Z2026-08-26T05:33:08Z~32 min

              Consequence: a commit can sit above another on main's first-parent chain (so it landed later) while carrying an earlier committer date. That is not hypothetical — over the last 3612 first-parent pairs on main:

              inversions: 10 of 3612 pairs; max 874 s; median 539 s
              max skew as a fraction of a 24h window: 1.012%
              

              Two of those ten inverted commits are governed:

              git merge-base --is-ancestor 98eec7e248 01a7337fc0 exits 0, so the ancestry direction is not an inference.

              The measured miss, on real history

              mainlineCommits() windows with git log --first-parent --since=DATE, which cuts on committer date. Set the boundary to the parent's date — exactly what --since-ref ROUND_TIP yields, and what "since the last round" yields whenever the last round ended between the two:

              node scripts/pm/check-governed-merges.mjs --repos objectstack --since 2026-08-14T05:55:02Z --json
              scanned=1719 governed_entries=190 01a7337fc0 listed? False
              node scripts/pm/check-governed-merges.mjs --repos objectstack --since 2026-08-14T05:44:52Z --json
              scanned=1721 governed_entries=191 01a7337fc0 listed? True
              -> 01a7337fc0 PR #8620 surfaces: docs/adr/0029-kernel-object-ownership-and-platform-objects-decomposition.md
              

              Same tree, same landed set. The only difference is a boundary ten minutes earlier. A governed ADR landing that reached main after the boundary is absent from the first list, and nothing in the output marks the gap — no warning, no incomplete classification on that account. In the degenerate case where it is the only governed landing in the window, the sweep prints a clean window and exits 0 = "swept COMPLETELY", which is precisely the reading #4690 and #9902 say must never be producible.

              Reproduced as a constructed signature too (queue chain whose governed entry is dated 874 s — the measured maximum — before its own first parent):

              QS-7 build-land skew, --since at the previous round tip
              BLIND — governed file absent from the list [exit 0, 0 entries, 0 mainline commits scanned]
              QS-7c same tree, --since backed off by the measured 874 s max skew
              SEES — listed, attributed to the governed PR [exit 2, 1 entry, 2 mainline commits scanned]
              

              What is NOT broken

              The hole opens only when the window start falls between the governed commit's committer date and its landing time. The documented default invocation is safe by a wide margin: the largest measured skew is 874 s = 1.012% of a --since 24h window, and consecutive default rounds overlap by nearly a full day. The exposure is the knife-edge boundary — --since-ref ROUND_TIP, or an exact previous-round timestamp, which is what "实跑 --since 上轮" invites.

              Also worth stating plainly: this is queue-specific. A direct merge writes its commit at merge time, so it produces no skew and no inversion.

              Options (not taken here; this needs a ruling on windowing semantics)

              • A. Widen by a stated margin. Subtract a skew budget from any operator-supplied --since (and from --since-ref), and say so in the report line. Cheap, mechanical; costs some re-listing of already-recognised entries at each boundary, which the audit tolerates by design (a re-listed entry is recognised again; a dropped one is never seen).
              • B. Window on landing order, not on dates. Take --since-ref topologically: enumerate REF..origin/main instead of --since on the ref's date. That is exactly right for the round-to-round question and immune to any date skew, but it needs the previous round's ref to be recorded, which today it is not.
              • C. Detect and refuse. Notice a committer-date inversion crossing the boundary and classify the sweep INCOMPLETE rather than clean. Smallest behaviour change, keeps the check:react-declaration-parity 是唯一没接进任何 workflow 的源码审计门禁,且无 MANIFEST 时静默 skip 退出 0 —— 它现在永远不可能红 #4690 posture, but reports a problem instead of answering the question.
              • D. Accept and document. State in the header that --since is a date window, not a landing window, and pin the default-invocation margin.

              Recommendation: B for --since-ref, A for --since — B is the only one that makes the round-to-round reading exact, and A covers the operator who passes a bare timestamp. Both keep the audit's report-only posture and neither weakens any judgment.

              Measured on tree 0043c9224 (plus 4be2e880e, which main fast-forwarded to mid-measurement). Gate baseline is untouched: node scripts/pm/check-governed-merges.mjs --self-test prints "157 assertions" and the lock's VERDICT line reads command-exit 0.

              Back-link: #11996 (the measurement this came out of), #11831 (the ruling that chartered it).


              Generated by Claude Code

              Metadata

              Metadata

              Assignees

              Type

              Projects

              No projects

                Milestone

                No milestone

                Relationships

                None yet

                Development

                No branches or pull requests

                Issue actions

                , 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
                Skip to content

                finding(check-governed-merges): the merge queue's build-to-land skew can put a governed landing BELOW a round's --since boundary, where it is silently absent from the audit list #12633

                Description

                @os-litant

                Turned up while measuring #11996 (whether the audit sees a governed-surface PR that lands through a merge-queue batch). That question measured YES — every batch topology lists the governed file. This is a different, adjacent property: not the batch topology, but the sweep's window. Filed separately rather than fixed on #11996, whose disposition rule fires only on a blind-to-the-topology verdict.

                The mechanism, measured

                GitHub's merge queue writes a queue entry's commit when the batch is built, and main receives it when the batch lands. Those are not the same moment. Measured on this repo, on two governed PRs from one batch:

                PRmainline commit committer datePR merged_atskew
                #12440 (.claude/agents/os-dev.md + 2 references)04600d939 @ 2026-08-26T05:00:27Z2026-08-26T05:25:22Z~25 min
                #12443 (.claude/skills/pm-dispatch/SKILL.md + 1 reference)ade757fb3 @ 2026-08-26T05:00:49Z2026-08-26T05:33:08Z~32 min

                Consequence: a commit can sit above another on main's first-parent chain (so it landed later) while carrying an earlier committer date. That is not hypothetical — over the last 3612 first-parent pairs on main:

                inversions: 10 of 3612 pairs; max 874 s; median 539 s
                max skew as a fraction of a 24h window: 1.012%
                

                Two of those ten inverted commits are governed:

                git merge-base --is-ancestor 98eec7e248 01a7337fc0 exits 0, so the ancestry direction is not an inference.

                The measured miss, on real history

                mainlineCommits() windows with git log --first-parent --since=DATE, which cuts on committer date. Set the boundary to the parent's date — exactly what --since-ref ROUND_TIP yields, and what "since the last round" yields whenever the last round ended between the two:

                node scripts/pm/check-governed-merges.mjs --repos objectstack --since 2026-08-14T05:55:02Z --json
                scanned=1719 governed_entries=190 01a7337fc0 listed? False
                node scripts/pm/check-governed-merges.mjs --repos objectstack --since 2026-08-14T05:44:52Z --json
                scanned=1721 governed_entries=191 01a7337fc0 listed? True
                -> 01a7337fc0 PR #8620 surfaces: docs/adr/0029-kernel-object-ownership-and-platform-objects-decomposition.md
                

                Same tree, same landed set. The only difference is a boundary ten minutes earlier. A governed ADR landing that reached main after the boundary is absent from the first list, and nothing in the output marks the gap — no warning, no incomplete classification on that account. In the degenerate case where it is the only governed landing in the window, the sweep prints a clean window and exits 0 = "swept COMPLETELY", which is precisely the reading #4690 and #9902 say must never be producible.

                Reproduced as a constructed signature too (queue chain whose governed entry is dated 874 s — the measured maximum — before its own first parent):

                QS-7 build-land skew, --since at the previous round tip
                BLIND — governed file absent from the list [exit 0, 0 entries, 0 mainline commits scanned]
                QS-7c same tree, --since backed off by the measured 874 s max skew
                SEES — listed, attributed to the governed PR [exit 2, 1 entry, 2 mainline commits scanned]
                

                What is NOT broken

                The hole opens only when the window start falls between the governed commit's committer date and its landing time. The documented default invocation is safe by a wide margin: the largest measured skew is 874 s = 1.012% of a --since 24h window, and consecutive default rounds overlap by nearly a full day. The exposure is the knife-edge boundary — --since-ref ROUND_TIP, or an exact previous-round timestamp, which is what "实跑 --since 上轮" invites.

                Also worth stating plainly: this is queue-specific. A direct merge writes its commit at merge time, so it produces no skew and no inversion.

                Options (not taken here; this needs a ruling on windowing semantics)

                • A. Widen by a stated margin. Subtract a skew budget from any operator-supplied --since (and from --since-ref), and say so in the report line. Cheap, mechanical; costs some re-listing of already-recognised entries at each boundary, which the audit tolerates by design (a re-listed entry is recognised again; a dropped one is never seen).
                • B. Window on landing order, not on dates. Take --since-ref topologically: enumerate REF..origin/main instead of --since on the ref's date. That is exactly right for the round-to-round question and immune to any date skew, but it needs the previous round's ref to be recorded, which today it is not.
                • C. Detect and refuse. Notice a committer-date inversion crossing the boundary and classify the sweep INCOMPLETE rather than clean. Smallest behaviour change, keeps the check:react-declaration-parity 是唯一没接进任何 workflow 的源码审计门禁,且无 MANIFEST 时静默 skip 退出 0 —— 它现在永远不可能红 #4690 posture, but reports a problem instead of answering the question.
                • D. Accept and document. State in the header that --since is a date window, not a landing window, and pin the default-invocation margin.

                Recommendation: B for --since-ref, A for --since — B is the only one that makes the round-to-round reading exact, and A covers the operator who passes a bare timestamp. Both keep the audit's report-only posture and neither weakens any judgment.

                Measured on tree 0043c9224 (plus 4be2e880e, which main fast-forwarded to mid-measurement). Gate baseline is untouched: node scripts/pm/check-governed-merges.mjs --self-test prints "157 assertions" and the lock's VERDICT line reads command-exit 0.

                Back-link: #11996 (the measurement this came out of), #11831 (the ruling that chartered it).


                Generated by Claude Code

                Metadata

                Metadata

                Assignees

                Type

                Projects

                No projects

                  Milestone

                  No milestone

                  Relationships

                  None yet

                  Development

                  No branches or pull requests

                  Issue actions