Skip to content

AGENTS.md's governed-surface section contradicts the shipped guard: it lists skills/** as NOT governed and asserts no mechanical backstop exists #6975

Description

@os-sam

Filed by the domain:ui execution seat. Surfaced by the dev on card #5704 (PR #6974) as an out-of-scope finding; it could not file it itself (GitHub search hit this seat's rate limit mid-task). I re-measured every claim below against the bytes on origin/main = fd8dacecc322e886986d86fdea8ddf139834241e before filing — none of it is forwarded phrasing.

Two contradictions, both checkable

AGENTS.md §"⛔ 受管面(governed surface):agent 起草,人类合并" (line 360 onward) and scripts/check-governed-queue-guard.mjs disagree about what the governed surface is and about whether it is enforced.

1. skills/** — the doc says not governed, the guard says governed

AGENTS.md:371 heads its list with "本仓的受管面 —— 四项" (four items). The shipped guard ships five:

// scripts/check-governed-queue-guard.mjsexportconstGOVERNED_SURFACES=Object.freeze([Object.freeze({id: 'adr',prefix: 'docs/adr/',glob: 'docs/adr/**',what: 'architecture decision records'}),Object.freeze({id: 'claude-tree',prefix: '.claude/',glob: '.claude/**',what: 'the agent instruction tree (skills, hooks, settings)'}),Object.freeze({id: 'skills-catalog',prefix: 'skills/',glob: 'skills/**',what: 'the published skills catalog'}),Object.freeze({id: 'agents-md',exact: 'AGENTS.md',glob: 'AGENTS.md',what: 'the repo-root agent instruction file'}),Object.freeze({id: 'claude-md',exact: 'CLAUDE.md',glob: 'CLAUDE.md',what: 'the repo-root Claude instruction file'}),]);

The count difference is exactly skills-catalog, and AGENTS.md:378 does not merely omit it — it rules the opposite way, in the ruling text's own words (quoted verbatim, untranslated):

  • skills/**(仓根,发布给使用者的那棵,如 skills/objectui/)—— 不在受管面上,按普通代码 PR 走:CI 全绿就照上面的常规路径自行入队合并。

Gloss: repo-root skills/** is not on the governed surface, and an agent should take the ordinary path — CI green, self-enqueue, merge.

2. The doc says no mechanical backstop exists; one is shipped and wired

AGENTS.md:392, verbatim:

本仓没有任何机械兜底,这一段就是全部。 … 受管面上没有 required check、没有钩子 … 本段没点名的兜底工具,就是不存在的工具;哪天本仓真有了检测,它会写在这里。

Gloss: this repo has no mechanical backstop at all, this section is the whole of it; there is no required check and no hook on the governed surface; a backstop tool not named in this section is a tool that does not exist.

But .github/workflows/governed-surface-guard.yml exists and is wired on two legs — pull_request: (line 24) and merge_group: (line 42) — and its own header states which leg does the work:

merge_group is the leg that REFUSES: the queue build is the last thing between a speculative merge and main, and it is the path #6183 took. pull_request is an EARLY WARNING that deliberately exits 0 …

The guard's header dates its mandate: objectui#6596, maintainer ruling 2026-08-27. AGENTS.md's section quotes a ruling of 2026-08-18. The guard's ruling is the later of the two, and the doc was never brought forward to it.

What in that paragraph still holds — do not over-correct

One claim at AGENTS.md:392 is still true and must survive the fix: this repo has no CODEOWNERS. Verified — .github/CODEOWNERS, CODEOWNERS, and docs/CODEOWNERS all absent. The stale parts are "no required check / no hook" and the closing "a tool not named here does not exist", not the CODEOWNERS sentence.

The failure mode this creates

An agent that follows AGENTS.md:378 literally on a skills/**-only PR does exactly what the line tells it to: waits for CI green, flips the PR ready, enqueues. The merge_group leg then refuses — so the trap costs a rejected queue build plus a ready-flip that, per the guard header's account of #6183, converting back to draft did not cleanly undo.

This is not hypothetical for the current batch: PR #6974 (card #5704) is a skills/**-only change. It stayed draft only because that dev read the guard source instead of trusting AGENTS.md's literal text. An agent doing the reverse — trusting the instruction file, which is the documented thing to do — walks into the refusal.

Proposed remedy

Sync AGENTS.md to the shipped mechanism: correct line 378 to place repo-root skills/** on the governed surface, correct the count at line 371 (four to five), and rewrite line 392 to name scripts/check-governed-queue-guard.mjs and .github/workflows/governed-surface-guard.yml as the backstop that now exists — while keeping the CODEOWNERS sentence, which is still accurate.

This PR edits AGENTS.md, which is itself a governed surface. It must be drafted and left as a draft for a human to merge — never marked ready, never enqueued, never auto-merged. GOVERNED_APPROVERS are os-zhuang and hotlong.

Note for the maintainer

I am not treating the direction of the fix as settled by me. The reading above — that the 2026-08-27 ruling behind the guard supersedes the 2026-08-18 ruling quoted in AGENTS.md — is the only reading consistent with both artifacts, but the governed-surface definition is the maintainer's to state. If the intent was instead that repo-root skills/** stay ungoverned, then the fix is in the guard's GOVERNED_SURFACES, not in the doc, and this card should be re-pointed there.


Seat session: https://claude.ai/code/session_013hfmP9hoMd3dJwTh85J4yB

Metadata

Metadata

Assignees

No one assigned

    Labels

    domain:uiobjectui ui stream: fix lands on the published library or apps — objectui execution seatfindingpm:dispatchedpriority:p1

    Type

    No 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)) { // Add copy buttons to all
       blocks
      (function() {
      function addCopyButtons() {
      document.querySelectorAll('pre code').forEach(function(codeBlock) {
      if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;
      codeBlock.parentElement.setAttribute('data-copy-added', 'true');
      var btn = document.createElement('button');
      btn.textContent = 'Copy';
      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;';
      btn.onmouseover = function() { this.style.opacity = '1'; };
      btn.onmouseout = function() { this.style.opacity = '0.7'; };
      btn.onclick = function() {
      navigator.clipboard.writeText(codeBlock.textContent).then(function() {
      btn.textContent = 'Copied!';
      setTimeout(function() { btn.textContent = 'Copy'; }, 1500);
      });
      };
      codeBlock.parentElement.style.position = 'relative';
      codeBlock.parentElement.appendChild(btn);
      });
      }
      addCopyButtons();
      // Re-run on dynamic content
      var observer = new MutationObserver(addCopyButtons);
      observer.observe(document.body, { childList: true, subtree: true });
      })();
      }
      } catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
      })();
      (function(){
      try {
      var __m = "github.com";
      var __re = new RegExp('^' + "github\\.com" + '
      AGENTS.md's governed-surface section contradicts the shipped guard: it lists `skills/**` as NOT governed and asserts no mechanical backstop exists · Issue #6975 · objectstack-ai/objectui · GitHub
      Skip to content

      AGENTS.md's governed-surface section contradicts the shipped guard: it lists skills/** as NOT governed and asserts no mechanical backstop exists #6975

      Description

      @os-sam

      Filed by the domain:ui execution seat. Surfaced by the dev on card #5704 (PR #6974) as an out-of-scope finding; it could not file it itself (GitHub search hit this seat's rate limit mid-task). I re-measured every claim below against the bytes on origin/main = fd8dacecc322e886986d86fdea8ddf139834241e before filing — none of it is forwarded phrasing.

      Two contradictions, both checkable

      AGENTS.md §"⛔ 受管面(governed surface):agent 起草,人类合并" (line 360 onward) and scripts/check-governed-queue-guard.mjs disagree about what the governed surface is and about whether it is enforced.

      1. skills/** — the doc says not governed, the guard says governed

      AGENTS.md:371 heads its list with "本仓的受管面 —— 四项" (four items). The shipped guard ships five:

      // scripts/check-governed-queue-guard.mjsexportconstGOVERNED_SURFACES=Object.freeze([Object.freeze({id: 'adr',prefix: 'docs/adr/',glob: 'docs/adr/**',what: 'architecture decision records'}),Object.freeze({id: 'claude-tree',prefix: '.claude/',glob: '.claude/**',what: 'the agent instruction tree (skills, hooks, settings)'}),Object.freeze({id: 'skills-catalog',prefix: 'skills/',glob: 'skills/**',what: 'the published skills catalog'}),Object.freeze({id: 'agents-md',exact: 'AGENTS.md',glob: 'AGENTS.md',what: 'the repo-root agent instruction file'}),Object.freeze({id: 'claude-md',exact: 'CLAUDE.md',glob: 'CLAUDE.md',what: 'the repo-root Claude instruction file'}),]);

      The count difference is exactly skills-catalog, and AGENTS.md:378 does not merely omit it — it rules the opposite way, in the ruling text's own words (quoted verbatim, untranslated):

      • skills/**(仓根,发布给使用者的那棵,如 skills/objectui/)—— 不在受管面上,按普通代码 PR 走:CI 全绿就照上面的常规路径自行入队合并。

      Gloss: repo-root skills/** is not on the governed surface, and an agent should take the ordinary path — CI green, self-enqueue, merge.

      2. The doc says no mechanical backstop exists; one is shipped and wired

      AGENTS.md:392, verbatim:

      本仓没有任何机械兜底,这一段就是全部。 … 受管面上没有 required check、没有钩子 … 本段没点名的兜底工具,就是不存在的工具;哪天本仓真有了检测,它会写在这里。

      Gloss: this repo has no mechanical backstop at all, this section is the whole of it; there is no required check and no hook on the governed surface; a backstop tool not named in this section is a tool that does not exist.

      But .github/workflows/governed-surface-guard.yml exists and is wired on two legs — pull_request: (line 24) and merge_group: (line 42) — and its own header states which leg does the work:

      merge_group is the leg that REFUSES: the queue build is the last thing between a speculative merge and main, and it is the path #6183 took. pull_request is an EARLY WARNING that deliberately exits 0 …

      The guard's header dates its mandate: objectui#6596, maintainer ruling 2026-08-27. AGENTS.md's section quotes a ruling of 2026-08-18. The guard's ruling is the later of the two, and the doc was never brought forward to it.

      What in that paragraph still holds — do not over-correct

      One claim at AGENTS.md:392 is still true and must survive the fix: this repo has no CODEOWNERS. Verified — .github/CODEOWNERS, CODEOWNERS, and docs/CODEOWNERS all absent. The stale parts are "no required check / no hook" and the closing "a tool not named here does not exist", not the CODEOWNERS sentence.

      The failure mode this creates

      An agent that follows AGENTS.md:378 literally on a skills/**-only PR does exactly what the line tells it to: waits for CI green, flips the PR ready, enqueues. The merge_group leg then refuses — so the trap costs a rejected queue build plus a ready-flip that, per the guard header's account of #6183, converting back to draft did not cleanly undo.

      This is not hypothetical for the current batch: PR #6974 (card #5704) is a skills/**-only change. It stayed draft only because that dev read the guard source instead of trusting AGENTS.md's literal text. An agent doing the reverse — trusting the instruction file, which is the documented thing to do — walks into the refusal.

      Proposed remedy

      Sync AGENTS.md to the shipped mechanism: correct line 378 to place repo-root skills/** on the governed surface, correct the count at line 371 (four to five), and rewrite line 392 to name scripts/check-governed-queue-guard.mjs and .github/workflows/governed-surface-guard.yml as the backstop that now exists — while keeping the CODEOWNERS sentence, which is still accurate.

      This PR edits AGENTS.md, which is itself a governed surface. It must be drafted and left as a draft for a human to merge — never marked ready, never enqueued, never auto-merged. GOVERNED_APPROVERS are os-zhuang and hotlong.

      Note for the maintainer

      I am not treating the direction of the fix as settled by me. The reading above — that the 2026-08-27 ruling behind the guard supersedes the 2026-08-18 ruling quoted in AGENTS.md — is the only reading consistent with both artifacts, but the governed-surface definition is the maintainer's to state. If the intent was instead that repo-root skills/** stay ungoverned, then the fix is in the guard's GOVERNED_SURFACES, not in the doc, and this card should be re-pointed there.


      Seat session: https://claude.ai/code/session_013hfmP9hoMd3dJwTh85J4yB

      Metadata

      Metadata

      Assignees

      No one assigned

        Labels

        domain:uiobjectui ui stream: fix lands on the published library or apps — objectui execution seatfindingpm:dispatchedpriority:p1

        Type

        No 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)) { // Force GitHub README to respect dark mode (function() { var style = document.createElement('style'); style.textContent = ' .markdown-body { color-scheme: dark light; } .markdown-body pre { background: #161b22 !important; } .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; } .markdown-body table th, .markdown-body table td { border-color: #30363d !important; } .markdown-body img { background: #0d1117; } .markdown-body blockquote { border-left-color: #8b949e; } .markdown-body hr { border-color: #30363d; } '; document.head.appendChild(style); })(); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' AGENTS.md's governed-surface section contradicts the shipped guard: it lists `skills/**` as NOT governed and asserts no mechanical backstop exists · Issue #6975 · objectstack-ai/objectui · GitHub
          Skip to content

          AGENTS.md's governed-surface section contradicts the shipped guard: it lists skills/** as NOT governed and asserts no mechanical backstop exists #6975

          Description

          @os-sam

          Filed by the domain:ui execution seat. Surfaced by the dev on card #5704 (PR #6974) as an out-of-scope finding; it could not file it itself (GitHub search hit this seat's rate limit mid-task). I re-measured every claim below against the bytes on origin/main = fd8dacecc322e886986d86fdea8ddf139834241e before filing — none of it is forwarded phrasing.

          Two contradictions, both checkable

          AGENTS.md §"⛔ 受管面(governed surface):agent 起草,人类合并" (line 360 onward) and scripts/check-governed-queue-guard.mjs disagree about what the governed surface is and about whether it is enforced.

          1. skills/** — the doc says not governed, the guard says governed

          AGENTS.md:371 heads its list with "本仓的受管面 —— 四项" (four items). The shipped guard ships five:

          // scripts/check-governed-queue-guard.mjsexportconstGOVERNED_SURFACES=Object.freeze([Object.freeze({id: 'adr',prefix: 'docs/adr/',glob: 'docs/adr/**',what: 'architecture decision records'}),Object.freeze({id: 'claude-tree',prefix: '.claude/',glob: '.claude/**',what: 'the agent instruction tree (skills, hooks, settings)'}),Object.freeze({id: 'skills-catalog',prefix: 'skills/',glob: 'skills/**',what: 'the published skills catalog'}),Object.freeze({id: 'agents-md',exact: 'AGENTS.md',glob: 'AGENTS.md',what: 'the repo-root agent instruction file'}),Object.freeze({id: 'claude-md',exact: 'CLAUDE.md',glob: 'CLAUDE.md',what: 'the repo-root Claude instruction file'}),]);

          The count difference is exactly skills-catalog, and AGENTS.md:378 does not merely omit it — it rules the opposite way, in the ruling text's own words (quoted verbatim, untranslated):

          • skills/**(仓根,发布给使用者的那棵,如 skills/objectui/)—— 不在受管面上,按普通代码 PR 走:CI 全绿就照上面的常规路径自行入队合并。

          Gloss: repo-root skills/** is not on the governed surface, and an agent should take the ordinary path — CI green, self-enqueue, merge.

          2. The doc says no mechanical backstop exists; one is shipped and wired

          AGENTS.md:392, verbatim:

          本仓没有任何机械兜底,这一段就是全部。 … 受管面上没有 required check、没有钩子 … 本段没点名的兜底工具,就是不存在的工具;哪天本仓真有了检测,它会写在这里。

          Gloss: this repo has no mechanical backstop at all, this section is the whole of it; there is no required check and no hook on the governed surface; a backstop tool not named in this section is a tool that does not exist.

          But .github/workflows/governed-surface-guard.yml exists and is wired on two legs — pull_request: (line 24) and merge_group: (line 42) — and its own header states which leg does the work:

          merge_group is the leg that REFUSES: the queue build is the last thing between a speculative merge and main, and it is the path #6183 took. pull_request is an EARLY WARNING that deliberately exits 0 …

          The guard's header dates its mandate: objectui#6596, maintainer ruling 2026-08-27. AGENTS.md's section quotes a ruling of 2026-08-18. The guard's ruling is the later of the two, and the doc was never brought forward to it.

          What in that paragraph still holds — do not over-correct

          One claim at AGENTS.md:392 is still true and must survive the fix: this repo has no CODEOWNERS. Verified — .github/CODEOWNERS, CODEOWNERS, and docs/CODEOWNERS all absent. The stale parts are "no required check / no hook" and the closing "a tool not named here does not exist", not the CODEOWNERS sentence.

          The failure mode this creates

          An agent that follows AGENTS.md:378 literally on a skills/**-only PR does exactly what the line tells it to: waits for CI green, flips the PR ready, enqueues. The merge_group leg then refuses — so the trap costs a rejected queue build plus a ready-flip that, per the guard header's account of #6183, converting back to draft did not cleanly undo.

          This is not hypothetical for the current batch: PR #6974 (card #5704) is a skills/**-only change. It stayed draft only because that dev read the guard source instead of trusting AGENTS.md's literal text. An agent doing the reverse — trusting the instruction file, which is the documented thing to do — walks into the refusal.

          Proposed remedy

          Sync AGENTS.md to the shipped mechanism: correct line 378 to place repo-root skills/** on the governed surface, correct the count at line 371 (four to five), and rewrite line 392 to name scripts/check-governed-queue-guard.mjs and .github/workflows/governed-surface-guard.yml as the backstop that now exists — while keeping the CODEOWNERS sentence, which is still accurate.

          This PR edits AGENTS.md, which is itself a governed surface. It must be drafted and left as a draft for a human to merge — never marked ready, never enqueued, never auto-merged. GOVERNED_APPROVERS are os-zhuang and hotlong.

          Note for the maintainer

          I am not treating the direction of the fix as settled by me. The reading above — that the 2026-08-27 ruling behind the guard supersedes the 2026-08-18 ruling quoted in AGENTS.md — is the only reading consistent with both artifacts, but the governed-surface definition is the maintainer's to state. If the intent was instead that repo-root skills/** stay ungoverned, then the fix is in the guard's GOVERNED_SURFACES, not in the doc, and this card should be re-pointed there.


          Seat session: https://claude.ai/code/session_013hfmP9hoMd3dJwTh85J4yB

          Metadata

          Metadata

          Assignees

          No one assigned

            Labels

            domain:uiobjectui ui stream: fix lands on the published library or apps — objectui execution seatfindingpm:dispatchedpriority:p1

            Type

            No 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)) { // Highlight search terms from Google/DuckDuckGo/Bing referrer (function() { var ref = document.referrer; var terms = []; if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) { var url = new URL(ref); var q = url.searchParams.get('q') || url.searchParams.get('p'); if (q) { terms = q.split(/\s+/).filter(function(t) { return t.length > 2; }); } } if (terms.length === 0) return; var style = document.createElement('style'); style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }'; document.head.appendChild(style); function highlight(node) { if (node.nodeType === 3) { // text node var text = node.textContent; var found = false; terms.forEach(function(term) { var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\]\\]/g, '\\') + ')', 'gi'); if (regex.test(text)) { found = true; var frag = document.createDocumentFragment(); var parts = text.split(regex); parts.forEach(function(part, i) { if (i % 2 === 0) { frag.appendChild(document.createTextNode(part)); } else { var span = document.createElement('span'); span.className = 'userscript-highlight'; span.textContent = part; frag.appendChild(span); } }); node.parentNode.replaceChild(frag, node); } }); } else if (node.nodeType === 1 && node.childNodes) { // element var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT']; if (!skipTags.includes(node.tagName)) { Array.from(node.childNodes).forEach(highlight); } } } highlight(document.body); // Re-highlight on dynamic content var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1 || node.nodeType === 3) highlight(node); }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' AGENTS.md's governed-surface section contradicts the shipped guard: it lists `skills/**` as NOT governed and asserts no mechanical backstop exists · Issue #6975 · objectstack-ai/objectui · GitHub
              Skip to content

              AGENTS.md's governed-surface section contradicts the shipped guard: it lists skills/** as NOT governed and asserts no mechanical backstop exists #6975

              Description

              @os-sam

              Filed by the domain:ui execution seat. Surfaced by the dev on card #5704 (PR #6974) as an out-of-scope finding; it could not file it itself (GitHub search hit this seat's rate limit mid-task). I re-measured every claim below against the bytes on origin/main = fd8dacecc322e886986d86fdea8ddf139834241e before filing — none of it is forwarded phrasing.

              Two contradictions, both checkable

              AGENTS.md §"⛔ 受管面(governed surface):agent 起草,人类合并" (line 360 onward) and scripts/check-governed-queue-guard.mjs disagree about what the governed surface is and about whether it is enforced.

              1. skills/** — the doc says not governed, the guard says governed

              AGENTS.md:371 heads its list with "本仓的受管面 —— 四项" (four items). The shipped guard ships five:

              // scripts/check-governed-queue-guard.mjsexportconstGOVERNED_SURFACES=Object.freeze([Object.freeze({id: 'adr',prefix: 'docs/adr/',glob: 'docs/adr/**',what: 'architecture decision records'}),Object.freeze({id: 'claude-tree',prefix: '.claude/',glob: '.claude/**',what: 'the agent instruction tree (skills, hooks, settings)'}),Object.freeze({id: 'skills-catalog',prefix: 'skills/',glob: 'skills/**',what: 'the published skills catalog'}),Object.freeze({id: 'agents-md',exact: 'AGENTS.md',glob: 'AGENTS.md',what: 'the repo-root agent instruction file'}),Object.freeze({id: 'claude-md',exact: 'CLAUDE.md',glob: 'CLAUDE.md',what: 'the repo-root Claude instruction file'}),]);

              The count difference is exactly skills-catalog, and AGENTS.md:378 does not merely omit it — it rules the opposite way, in the ruling text's own words (quoted verbatim, untranslated):

              • skills/**(仓根,发布给使用者的那棵,如 skills/objectui/)—— 不在受管面上,按普通代码 PR 走:CI 全绿就照上面的常规路径自行入队合并。

              Gloss: repo-root skills/** is not on the governed surface, and an agent should take the ordinary path — CI green, self-enqueue, merge.

              2. The doc says no mechanical backstop exists; one is shipped and wired

              AGENTS.md:392, verbatim:

              本仓没有任何机械兜底,这一段就是全部。 … 受管面上没有 required check、没有钩子 … 本段没点名的兜底工具,就是不存在的工具;哪天本仓真有了检测,它会写在这里。

              Gloss: this repo has no mechanical backstop at all, this section is the whole of it; there is no required check and no hook on the governed surface; a backstop tool not named in this section is a tool that does not exist.

              But .github/workflows/governed-surface-guard.yml exists and is wired on two legs — pull_request: (line 24) and merge_group: (line 42) — and its own header states which leg does the work:

              merge_group is the leg that REFUSES: the queue build is the last thing between a speculative merge and main, and it is the path #6183 took. pull_request is an EARLY WARNING that deliberately exits 0 …

              The guard's header dates its mandate: objectui#6596, maintainer ruling 2026-08-27. AGENTS.md's section quotes a ruling of 2026-08-18. The guard's ruling is the later of the two, and the doc was never brought forward to it.

              What in that paragraph still holds — do not over-correct

              One claim at AGENTS.md:392 is still true and must survive the fix: this repo has no CODEOWNERS. Verified — .github/CODEOWNERS, CODEOWNERS, and docs/CODEOWNERS all absent. The stale parts are "no required check / no hook" and the closing "a tool not named here does not exist", not the CODEOWNERS sentence.

              The failure mode this creates

              An agent that follows AGENTS.md:378 literally on a skills/**-only PR does exactly what the line tells it to: waits for CI green, flips the PR ready, enqueues. The merge_group leg then refuses — so the trap costs a rejected queue build plus a ready-flip that, per the guard header's account of #6183, converting back to draft did not cleanly undo.

              This is not hypothetical for the current batch: PR #6974 (card #5704) is a skills/**-only change. It stayed draft only because that dev read the guard source instead of trusting AGENTS.md's literal text. An agent doing the reverse — trusting the instruction file, which is the documented thing to do — walks into the refusal.

              Proposed remedy

              Sync AGENTS.md to the shipped mechanism: correct line 378 to place repo-root skills/** on the governed surface, correct the count at line 371 (four to five), and rewrite line 392 to name scripts/check-governed-queue-guard.mjs and .github/workflows/governed-surface-guard.yml as the backstop that now exists — while keeping the CODEOWNERS sentence, which is still accurate.

              This PR edits AGENTS.md, which is itself a governed surface. It must be drafted and left as a draft for a human to merge — never marked ready, never enqueued, never auto-merged. GOVERNED_APPROVERS are os-zhuang and hotlong.

              Note for the maintainer

              I am not treating the direction of the fix as settled by me. The reading above — that the 2026-08-27 ruling behind the guard supersedes the 2026-08-18 ruling quoted in AGENTS.md — is the only reading consistent with both artifacts, but the governed-surface definition is the maintainer's to state. If the intent was instead that repo-root skills/** stay ungoverned, then the fix is in the guard's GOVERNED_SURFACES, not in the doc, and this card should be re-pointed there.


              Seat session: https://claude.ai/code/session_013hfmP9hoMd3dJwTh85J4yB

              Metadata

              Metadata

              Assignees

              No one assigned

                Labels

                domain:uiobjectui ui stream: fix lands on the published library or apps — objectui execution seatfindingpm:dispatchedpriority:p1

                Type

                No 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)) { // Strip utm_, fbclid, gclid, etc. from all links on page (function() { var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content', 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid', 'ref', 'ref_src', 'source', 'medium', 'campaign']; function cleanUrl(url) { try { var u = new URL(url, window.location.origin); var changed = false; trackingParams.forEach(function(p) { if (u.searchParams.has(p)) { u.searchParams.delete(p); changed = true; } }); return changed ? u.toString() : url; } catch (e) { return url; } } function cleanLinks() { document.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } cleanLinks(); var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1) { if (node.tagName === 'A') cleanLinks(); node.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + ' AGENTS.md's governed-surface section contradicts the shipped guard: it lists `skills/**` as NOT governed and asserts no mechanical backstop exists · Issue #6975 · objectstack-ai/objectui · GitHub
                  Skip to content

                  AGENTS.md's governed-surface section contradicts the shipped guard: it lists skills/** as NOT governed and asserts no mechanical backstop exists #6975

                  Description

                  @os-sam

                  Filed by the domain:ui execution seat. Surfaced by the dev on card #5704 (PR #6974) as an out-of-scope finding; it could not file it itself (GitHub search hit this seat's rate limit mid-task). I re-measured every claim below against the bytes on origin/main = fd8dacecc322e886986d86fdea8ddf139834241e before filing — none of it is forwarded phrasing.

                  Two contradictions, both checkable

                  AGENTS.md §"⛔ 受管面(governed surface):agent 起草,人类合并" (line 360 onward) and scripts/check-governed-queue-guard.mjs disagree about what the governed surface is and about whether it is enforced.

                  1. skills/** — the doc says not governed, the guard says governed

                  AGENTS.md:371 heads its list with "本仓的受管面 —— 四项" (four items). The shipped guard ships five:

                  // scripts/check-governed-queue-guard.mjsexportconstGOVERNED_SURFACES=Object.freeze([Object.freeze({id: 'adr',prefix: 'docs/adr/',glob: 'docs/adr/**',what: 'architecture decision records'}),Object.freeze({id: 'claude-tree',prefix: '.claude/',glob: '.claude/**',what: 'the agent instruction tree (skills, hooks, settings)'}),Object.freeze({id: 'skills-catalog',prefix: 'skills/',glob: 'skills/**',what: 'the published skills catalog'}),Object.freeze({id: 'agents-md',exact: 'AGENTS.md',glob: 'AGENTS.md',what: 'the repo-root agent instruction file'}),Object.freeze({id: 'claude-md',exact: 'CLAUDE.md',glob: 'CLAUDE.md',what: 'the repo-root Claude instruction file'}),]);

                  The count difference is exactly skills-catalog, and AGENTS.md:378 does not merely omit it — it rules the opposite way, in the ruling text's own words (quoted verbatim, untranslated):

                  • skills/**(仓根,发布给使用者的那棵,如 skills/objectui/)—— 不在受管面上,按普通代码 PR 走:CI 全绿就照上面的常规路径自行入队合并。

                  Gloss: repo-root skills/** is not on the governed surface, and an agent should take the ordinary path — CI green, self-enqueue, merge.

                  2. The doc says no mechanical backstop exists; one is shipped and wired

                  AGENTS.md:392, verbatim:

                  本仓没有任何机械兜底,这一段就是全部。 … 受管面上没有 required check、没有钩子 … 本段没点名的兜底工具,就是不存在的工具;哪天本仓真有了检测,它会写在这里。

                  Gloss: this repo has no mechanical backstop at all, this section is the whole of it; there is no required check and no hook on the governed surface; a backstop tool not named in this section is a tool that does not exist.

                  But .github/workflows/governed-surface-guard.yml exists and is wired on two legs — pull_request: (line 24) and merge_group: (line 42) — and its own header states which leg does the work:

                  merge_group is the leg that REFUSES: the queue build is the last thing between a speculative merge and main, and it is the path #6183 took. pull_request is an EARLY WARNING that deliberately exits 0 …

                  The guard's header dates its mandate: objectui#6596, maintainer ruling 2026-08-27. AGENTS.md's section quotes a ruling of 2026-08-18. The guard's ruling is the later of the two, and the doc was never brought forward to it.

                  What in that paragraph still holds — do not over-correct

                  One claim at AGENTS.md:392 is still true and must survive the fix: this repo has no CODEOWNERS. Verified — .github/CODEOWNERS, CODEOWNERS, and docs/CODEOWNERS all absent. The stale parts are "no required check / no hook" and the closing "a tool not named here does not exist", not the CODEOWNERS sentence.

                  The failure mode this creates

                  An agent that follows AGENTS.md:378 literally on a skills/**-only PR does exactly what the line tells it to: waits for CI green, flips the PR ready, enqueues. The merge_group leg then refuses — so the trap costs a rejected queue build plus a ready-flip that, per the guard header's account of #6183, converting back to draft did not cleanly undo.

                  This is not hypothetical for the current batch: PR #6974 (card #5704) is a skills/**-only change. It stayed draft only because that dev read the guard source instead of trusting AGENTS.md's literal text. An agent doing the reverse — trusting the instruction file, which is the documented thing to do — walks into the refusal.

                  Proposed remedy

                  Sync AGENTS.md to the shipped mechanism: correct line 378 to place repo-root skills/** on the governed surface, correct the count at line 371 (four to five), and rewrite line 392 to name scripts/check-governed-queue-guard.mjs and .github/workflows/governed-surface-guard.yml as the backstop that now exists — while keeping the CODEOWNERS sentence, which is still accurate.

                  This PR edits AGENTS.md, which is itself a governed surface. It must be drafted and left as a draft for a human to merge — never marked ready, never enqueued, never auto-merged. GOVERNED_APPROVERS are os-zhuang and hotlong.

                  Note for the maintainer

                  I am not treating the direction of the fix as settled by me. The reading above — that the 2026-08-27 ruling behind the guard supersedes the 2026-08-18 ruling quoted in AGENTS.md — is the only reading consistent with both artifacts, but the governed-surface definition is the maintainer's to state. If the intent was instead that repo-root skills/** stay ungoverned, then the fix is in the guard's GOVERNED_SURFACES, not in the doc, and this card should be re-pointed there.


                  Seat session: https://claude.ai/code/session_013hfmP9hoMd3dJwTh85J4yB

                  Metadata

                  Metadata

                  Assignees

                  No one assigned

                    Labels

                    domain:uiobjectui ui stream: fix lands on the published library or apps — objectui execution seatfindingpm:dispatchedpriority:p1

                    Type

                    No 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)) { // Auto-enable theater mode on YouTube (function() { function tryTheater() { var btn = document.querySelector('button[aria-label="Theater mode"], ytd-player #player button[title="Theater mode"]'); if (btn && !btn.classList.contains('activated')) { btn.click(); } } // Try immediately tryTheater(); // Try after navigation (SPA) var lastUrl = location.href; setInterval(function() { if (location.href !== lastUrl) { lastUrl = location.href; setTimeout(tryTheater, 500); } }, 1000); // Also try on player load var observer = new MutationObserver(tryTheater); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' AGENTS.md's governed-surface section contradicts the shipped guard: it lists `skills/**` as NOT governed and asserts no mechanical backstop exists · Issue #6975 · objectstack-ai/objectui · GitHub
                      Skip to content

                      AGENTS.md's governed-surface section contradicts the shipped guard: it lists skills/** as NOT governed and asserts no mechanical backstop exists #6975

                      Description

                      @os-sam

                      Filed by the domain:ui execution seat. Surfaced by the dev on card #5704 (PR #6974) as an out-of-scope finding; it could not file it itself (GitHub search hit this seat's rate limit mid-task). I re-measured every claim below against the bytes on origin/main = fd8dacecc322e886986d86fdea8ddf139834241e before filing — none of it is forwarded phrasing.

                      Two contradictions, both checkable

                      AGENTS.md §"⛔ 受管面(governed surface):agent 起草,人类合并" (line 360 onward) and scripts/check-governed-queue-guard.mjs disagree about what the governed surface is and about whether it is enforced.

                      1. skills/** — the doc says not governed, the guard says governed

                      AGENTS.md:371 heads its list with "本仓的受管面 —— 四项" (four items). The shipped guard ships five:

                      // scripts/check-governed-queue-guard.mjsexportconstGOVERNED_SURFACES=Object.freeze([Object.freeze({id: 'adr',prefix: 'docs/adr/',glob: 'docs/adr/**',what: 'architecture decision records'}),Object.freeze({id: 'claude-tree',prefix: '.claude/',glob: '.claude/**',what: 'the agent instruction tree (skills, hooks, settings)'}),Object.freeze({id: 'skills-catalog',prefix: 'skills/',glob: 'skills/**',what: 'the published skills catalog'}),Object.freeze({id: 'agents-md',exact: 'AGENTS.md',glob: 'AGENTS.md',what: 'the repo-root agent instruction file'}),Object.freeze({id: 'claude-md',exact: 'CLAUDE.md',glob: 'CLAUDE.md',what: 'the repo-root Claude instruction file'}),]);

                      The count difference is exactly skills-catalog, and AGENTS.md:378 does not merely omit it — it rules the opposite way, in the ruling text's own words (quoted verbatim, untranslated):

                      • skills/**(仓根,发布给使用者的那棵,如 skills/objectui/)—— 不在受管面上,按普通代码 PR 走:CI 全绿就照上面的常规路径自行入队合并。

                      Gloss: repo-root skills/** is not on the governed surface, and an agent should take the ordinary path — CI green, self-enqueue, merge.

                      2. The doc says no mechanical backstop exists; one is shipped and wired

                      AGENTS.md:392, verbatim:

                      本仓没有任何机械兜底,这一段就是全部。 … 受管面上没有 required check、没有钩子 … 本段没点名的兜底工具,就是不存在的工具;哪天本仓真有了检测,它会写在这里。

                      Gloss: this repo has no mechanical backstop at all, this section is the whole of it; there is no required check and no hook on the governed surface; a backstop tool not named in this section is a tool that does not exist.

                      But .github/workflows/governed-surface-guard.yml exists and is wired on two legs — pull_request: (line 24) and merge_group: (line 42) — and its own header states which leg does the work:

                      merge_group is the leg that REFUSES: the queue build is the last thing between a speculative merge and main, and it is the path #6183 took. pull_request is an EARLY WARNING that deliberately exits 0 …

                      The guard's header dates its mandate: objectui#6596, maintainer ruling 2026-08-27. AGENTS.md's section quotes a ruling of 2026-08-18. The guard's ruling is the later of the two, and the doc was never brought forward to it.

                      What in that paragraph still holds — do not over-correct

                      One claim at AGENTS.md:392 is still true and must survive the fix: this repo has no CODEOWNERS. Verified — .github/CODEOWNERS, CODEOWNERS, and docs/CODEOWNERS all absent. The stale parts are "no required check / no hook" and the closing "a tool not named here does not exist", not the CODEOWNERS sentence.

                      The failure mode this creates

                      An agent that follows AGENTS.md:378 literally on a skills/**-only PR does exactly what the line tells it to: waits for CI green, flips the PR ready, enqueues. The merge_group leg then refuses — so the trap costs a rejected queue build plus a ready-flip that, per the guard header's account of #6183, converting back to draft did not cleanly undo.

                      This is not hypothetical for the current batch: PR #6974 (card #5704) is a skills/**-only change. It stayed draft only because that dev read the guard source instead of trusting AGENTS.md's literal text. An agent doing the reverse — trusting the instruction file, which is the documented thing to do — walks into the refusal.

                      Proposed remedy

                      Sync AGENTS.md to the shipped mechanism: correct line 378 to place repo-root skills/** on the governed surface, correct the count at line 371 (four to five), and rewrite line 392 to name scripts/check-governed-queue-guard.mjs and .github/workflows/governed-surface-guard.yml as the backstop that now exists — while keeping the CODEOWNERS sentence, which is still accurate.

                      This PR edits AGENTS.md, which is itself a governed surface. It must be drafted and left as a draft for a human to merge — never marked ready, never enqueued, never auto-merged. GOVERNED_APPROVERS are os-zhuang and hotlong.

                      Note for the maintainer

                      I am not treating the direction of the fix as settled by me. The reading above — that the 2026-08-27 ruling behind the guard supersedes the 2026-08-18 ruling quoted in AGENTS.md — is the only reading consistent with both artifacts, but the governed-surface definition is the maintainer's to state. If the intent was instead that repo-root skills/** stay ungoverned, then the fix is in the guard's GOVERNED_SURFACES, not in the doc, and this card should be re-pointed there.


                      Seat session: https://claude.ai/code/session_013hfmP9hoMd3dJwTh85J4yB

                      Metadata

                      Metadata

                      Assignees

                      No one assigned

                        Labels

                        domain:uiobjectui ui stream: fix lands on the published library or apps — objectui execution seatfindingpm:dispatchedpriority:p1

                        Type

                        No 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)) { // Remove or un-stick sticky/fixed headers that block content (function() { function unstick() { document.querySelectorAll('header, nav, [role="banner"], .header, .navbar, .sticky, .fixed-top, [style*="position: fixed"], [style*="position:sticky"]').forEach(function(el) { if (el.style.position === 'fixed' || el.style.position === 'sticky' || getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') { el.style.position = 'static'; el.style.top = 'auto'; el.style.zIndex = 'auto'; } }); } unstick(); var observer = new MutationObserver(unstick); observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] }); })(); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' AGENTS.md's governed-surface section contradicts the shipped guard: it lists `skills/**` as NOT governed and asserts no mechanical backstop exists · Issue #6975 · objectstack-ai/objectui · GitHub
                          Skip to content

                          AGENTS.md's governed-surface section contradicts the shipped guard: it lists skills/** as NOT governed and asserts no mechanical backstop exists #6975

                          Description

                          @os-sam

                          Filed by the domain:ui execution seat. Surfaced by the dev on card #5704 (PR #6974) as an out-of-scope finding; it could not file it itself (GitHub search hit this seat's rate limit mid-task). I re-measured every claim below against the bytes on origin/main = fd8dacecc322e886986d86fdea8ddf139834241e before filing — none of it is forwarded phrasing.

                          Two contradictions, both checkable

                          AGENTS.md §"⛔ 受管面(governed surface):agent 起草,人类合并" (line 360 onward) and scripts/check-governed-queue-guard.mjs disagree about what the governed surface is and about whether it is enforced.

                          1. skills/** — the doc says not governed, the guard says governed

                          AGENTS.md:371 heads its list with "本仓的受管面 —— 四项" (four items). The shipped guard ships five:

                          // scripts/check-governed-queue-guard.mjsexportconstGOVERNED_SURFACES=Object.freeze([Object.freeze({id: 'adr',prefix: 'docs/adr/',glob: 'docs/adr/**',what: 'architecture decision records'}),Object.freeze({id: 'claude-tree',prefix: '.claude/',glob: '.claude/**',what: 'the agent instruction tree (skills, hooks, settings)'}),Object.freeze({id: 'skills-catalog',prefix: 'skills/',glob: 'skills/**',what: 'the published skills catalog'}),Object.freeze({id: 'agents-md',exact: 'AGENTS.md',glob: 'AGENTS.md',what: 'the repo-root agent instruction file'}),Object.freeze({id: 'claude-md',exact: 'CLAUDE.md',glob: 'CLAUDE.md',what: 'the repo-root Claude instruction file'}),]);

                          The count difference is exactly skills-catalog, and AGENTS.md:378 does not merely omit it — it rules the opposite way, in the ruling text's own words (quoted verbatim, untranslated):

                          • skills/**(仓根,发布给使用者的那棵,如 skills/objectui/)—— 不在受管面上,按普通代码 PR 走:CI 全绿就照上面的常规路径自行入队合并。

                          Gloss: repo-root skills/** is not on the governed surface, and an agent should take the ordinary path — CI green, self-enqueue, merge.

                          2. The doc says no mechanical backstop exists; one is shipped and wired

                          AGENTS.md:392, verbatim:

                          本仓没有任何机械兜底,这一段就是全部。 … 受管面上没有 required check、没有钩子 … 本段没点名的兜底工具,就是不存在的工具;哪天本仓真有了检测,它会写在这里。

                          Gloss: this repo has no mechanical backstop at all, this section is the whole of it; there is no required check and no hook on the governed surface; a backstop tool not named in this section is a tool that does not exist.

                          But .github/workflows/governed-surface-guard.yml exists and is wired on two legs — pull_request: (line 24) and merge_group: (line 42) — and its own header states which leg does the work:

                          merge_group is the leg that REFUSES: the queue build is the last thing between a speculative merge and main, and it is the path #6183 took. pull_request is an EARLY WARNING that deliberately exits 0 …

                          The guard's header dates its mandate: objectui#6596, maintainer ruling 2026-08-27. AGENTS.md's section quotes a ruling of 2026-08-18. The guard's ruling is the later of the two, and the doc was never brought forward to it.

                          What in that paragraph still holds — do not over-correct

                          One claim at AGENTS.md:392 is still true and must survive the fix: this repo has no CODEOWNERS. Verified — .github/CODEOWNERS, CODEOWNERS, and docs/CODEOWNERS all absent. The stale parts are "no required check / no hook" and the closing "a tool not named here does not exist", not the CODEOWNERS sentence.

                          The failure mode this creates

                          An agent that follows AGENTS.md:378 literally on a skills/**-only PR does exactly what the line tells it to: waits for CI green, flips the PR ready, enqueues. The merge_group leg then refuses — so the trap costs a rejected queue build plus a ready-flip that, per the guard header's account of #6183, converting back to draft did not cleanly undo.

                          This is not hypothetical for the current batch: PR #6974 (card #5704) is a skills/**-only change. It stayed draft only because that dev read the guard source instead of trusting AGENTS.md's literal text. An agent doing the reverse — trusting the instruction file, which is the documented thing to do — walks into the refusal.

                          Proposed remedy

                          Sync AGENTS.md to the shipped mechanism: correct line 378 to place repo-root skills/** on the governed surface, correct the count at line 371 (four to five), and rewrite line 392 to name scripts/check-governed-queue-guard.mjs and .github/workflows/governed-surface-guard.yml as the backstop that now exists — while keeping the CODEOWNERS sentence, which is still accurate.

                          This PR edits AGENTS.md, which is itself a governed surface. It must be drafted and left as a draft for a human to merge — never marked ready, never enqueued, never auto-merged. GOVERNED_APPROVERS are os-zhuang and hotlong.

                          Note for the maintainer

                          I am not treating the direction of the fix as settled by me. The reading above — that the 2026-08-27 ruling behind the guard supersedes the 2026-08-18 ruling quoted in AGENTS.md — is the only reading consistent with both artifacts, but the governed-surface definition is the maintainer's to state. If the intent was instead that repo-root skills/** stay ungoverned, then the fix is in the guard's GOVERNED_SURFACES, not in the doc, and this card should be re-pointed there.


                          Seat session: https://claude.ai/code/session_013hfmP9hoMd3dJwTh85J4yB

                          Metadata

                          Metadata

                          Assignees

                          No one assigned

                            Labels

                            domain:uiobjectui ui stream: fix lands on the published library or apps — objectui execution seatfindingpm:dispatchedpriority:p1

                            Type

                            No 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)) { // Universal Dark Mode - works on any site (function() { var enabled = true; function applyDarkMode() { if (!enabled) return; // Create style element if it doesn't exist var style = document.getElementById('universal-dark-mode-style'); if (!style) { style = document.createElement('style'); style.id = 'universal-dark-mode-style'; document.head.appendChild(style); } // Dark mode CSS - inverts colors but preserves images/video style.textContent = ' /* Invert everything except media */ html { filter: invert(1) hue-rotate(180deg) !important; background: #1a1a2e !important; } /* Restore images, videos, iframes, canvas */ img, video, iframe, canvas, svg, picture, [style*="background-image"] { filter: invert(1) hue-rotate(180deg) !important; } /* Preserve specific elements that should not be inverted */ .no-dark-mode, .no-dark-mode *, [data-theme="light"], [data-theme="light"], .ace_editor, .ace_editor *, .CodeMirror, .CodeMirror *, .monaco-editor, .monaco-editor *, .markdown-body pre, .markdown-body pre *, .highlight, .highlight *, pre code, pre code * { filter: none !important; } /* Fix common UI elements */ .modal, .popup, .dropdown-menu, .tooltip, .popover { filter: invert(1) hue-rotate(180deg) !important; background: #2d2d44 !important; border-color: #444 !important; } /* Scrollbars */ ::-webkit-scrollbar { background: #1a1a2e !important; } ::-webkit-scrollbar-thumb { background: #444 !important; } ::-webkit-scrollbar-thumb:hover { background: #555 !important; } /* Selection */ ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; } ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; } '; } function removeDarkMode() { var style = document.getElementById('universal-dark-mode-style'); if (style) style.remove(); } // Toggle with Alt+Shift+D document.addEventListener('keydown', function(e) { if (e.altKey && e.shiftKey && e.key === 'D') { e.preventDefault(); enabled = !enabled; if (enabled) { applyDarkMode(); console.log('[Universal Dark Mode] Enabled'); } else { removeDarkMode(); console.log('[Universal Dark Mode] Disabled'); } } }); // Apply on load applyDarkMode(); // Re-apply on dynamic content var observer = new MutationObserver(function(mutations) { if (enabled && !document.getElementById('universal-dark-mode-style')) { applyDarkMode(); } }); observer.observe(document.head, { childList: true }); console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle'); })(); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })(); AGENTS.md's governed-surface section contradicts the shipped guard: it lists `skills/**` as NOT governed and asserts no mechanical backstop exists · Issue #6975 · objectstack-ai/objectui · GitHub
                              Skip to content

                              AGENTS.md's governed-surface section contradicts the shipped guard: it lists skills/** as NOT governed and asserts no mechanical backstop exists #6975

                              Description

                              @os-sam

                              Filed by the domain:ui execution seat. Surfaced by the dev on card #5704 (PR #6974) as an out-of-scope finding; it could not file it itself (GitHub search hit this seat's rate limit mid-task). I re-measured every claim below against the bytes on origin/main = fd8dacecc322e886986d86fdea8ddf139834241e before filing — none of it is forwarded phrasing.

                              Two contradictions, both checkable

                              AGENTS.md §"⛔ 受管面(governed surface):agent 起草,人类合并" (line 360 onward) and scripts/check-governed-queue-guard.mjs disagree about what the governed surface is and about whether it is enforced.

                              1. skills/** — the doc says not governed, the guard says governed

                              AGENTS.md:371 heads its list with "本仓的受管面 —— 四项" (four items). The shipped guard ships five:

                              // scripts/check-governed-queue-guard.mjsexportconstGOVERNED_SURFACES=Object.freeze([Object.freeze({id: 'adr',prefix: 'docs/adr/',glob: 'docs/adr/**',what: 'architecture decision records'}),Object.freeze({id: 'claude-tree',prefix: '.claude/',glob: '.claude/**',what: 'the agent instruction tree (skills, hooks, settings)'}),Object.freeze({id: 'skills-catalog',prefix: 'skills/',glob: 'skills/**',what: 'the published skills catalog'}),Object.freeze({id: 'agents-md',exact: 'AGENTS.md',glob: 'AGENTS.md',what: 'the repo-root agent instruction file'}),Object.freeze({id: 'claude-md',exact: 'CLAUDE.md',glob: 'CLAUDE.md',what: 'the repo-root Claude instruction file'}),]);

                              The count difference is exactly skills-catalog, and AGENTS.md:378 does not merely omit it — it rules the opposite way, in the ruling text's own words (quoted verbatim, untranslated):

                              • skills/**(仓根,发布给使用者的那棵,如 skills/objectui/)—— 不在受管面上,按普通代码 PR 走:CI 全绿就照上面的常规路径自行入队合并。

                              Gloss: repo-root skills/** is not on the governed surface, and an agent should take the ordinary path — CI green, self-enqueue, merge.

                              2. The doc says no mechanical backstop exists; one is shipped and wired

                              AGENTS.md:392, verbatim:

                              本仓没有任何机械兜底,这一段就是全部。 … 受管面上没有 required check、没有钩子 … 本段没点名的兜底工具,就是不存在的工具;哪天本仓真有了检测,它会写在这里。

                              Gloss: this repo has no mechanical backstop at all, this section is the whole of it; there is no required check and no hook on the governed surface; a backstop tool not named in this section is a tool that does not exist.

                              But .github/workflows/governed-surface-guard.yml exists and is wired on two legs — pull_request: (line 24) and merge_group: (line 42) — and its own header states which leg does the work:

                              merge_group is the leg that REFUSES: the queue build is the last thing between a speculative merge and main, and it is the path #6183 took. pull_request is an EARLY WARNING that deliberately exits 0 …

                              The guard's header dates its mandate: objectui#6596, maintainer ruling 2026-08-27. AGENTS.md's section quotes a ruling of 2026-08-18. The guard's ruling is the later of the two, and the doc was never brought forward to it.

                              What in that paragraph still holds — do not over-correct

                              One claim at AGENTS.md:392 is still true and must survive the fix: this repo has no CODEOWNERS. Verified — .github/CODEOWNERS, CODEOWNERS, and docs/CODEOWNERS all absent. The stale parts are "no required check / no hook" and the closing "a tool not named here does not exist", not the CODEOWNERS sentence.

                              The failure mode this creates

                              An agent that follows AGENTS.md:378 literally on a skills/**-only PR does exactly what the line tells it to: waits for CI green, flips the PR ready, enqueues. The merge_group leg then refuses — so the trap costs a rejected queue build plus a ready-flip that, per the guard header's account of #6183, converting back to draft did not cleanly undo.

                              This is not hypothetical for the current batch: PR #6974 (card #5704) is a skills/**-only change. It stayed draft only because that dev read the guard source instead of trusting AGENTS.md's literal text. An agent doing the reverse — trusting the instruction file, which is the documented thing to do — walks into the refusal.

                              Proposed remedy

                              Sync AGENTS.md to the shipped mechanism: correct line 378 to place repo-root skills/** on the governed surface, correct the count at line 371 (four to five), and rewrite line 392 to name scripts/check-governed-queue-guard.mjs and .github/workflows/governed-surface-guard.yml as the backstop that now exists — while keeping the CODEOWNERS sentence, which is still accurate.

                              This PR edits AGENTS.md, which is itself a governed surface. It must be drafted and left as a draft for a human to merge — never marked ready, never enqueued, never auto-merged. GOVERNED_APPROVERS are os-zhuang and hotlong.

                              Note for the maintainer

                              I am not treating the direction of the fix as settled by me. The reading above — that the 2026-08-27 ruling behind the guard supersedes the 2026-08-18 ruling quoted in AGENTS.md — is the only reading consistent with both artifacts, but the governed-surface definition is the maintainer's to state. If the intent was instead that repo-root skills/** stay ungoverned, then the fix is in the guard's GOVERNED_SURFACES, not in the doc, and this card should be re-pointed there.


                              Seat session: https://claude.ai/code/session_013hfmP9hoMd3dJwTh85J4yB

                              Metadata

                              Metadata

                              Assignees

                              No one assigned

                                Labels

                                domain:uiobjectui ui stream: fix lands on the published library or apps — objectui execution seatfindingpm:dispatchedpriority:p1

                                Type

                                No type

                                Projects

                                No projects

                                  Milestone

                                  No milestone

                                  Relationships

                                  None yet

                                  Development

                                  No branches or pull requests

                                  Issue actions