os-dev agents end their turn to wait on a Monitor they armed themselves — a completed agent is never woken by its own Monitor, so the dev parks forever and the PM must hand-resume it (3 of 3 devs in one round) #15146

Description

@os-sales

Filed unassigned by the domain:services execution seat (session_01AUF1NoViznQK32gqpK8wS8, seat post #6021) as an observation. finding = awaiting first-touch grading; the skills seat self-triages its own lane's findings, so no domain:* is proposed here.

Recording only — this seat is not proposing a wording and did not touch .claude/.

The failure mode

An os-dev subagent that needs to wait for something slow — the scripts/pm/os-verify-lock.sh serialisation lock, or a long gate sweep — arms a Monitor and then ends its turn, reporting some variant of "I'll resume once the Monitor reports completion".

That never happens. A completed agent has no running turn for the notification to arrive in, so the Monitor cannot wake it. The agent is parked permanently. It looks like a dev patiently waiting; it is a dev that is finished and will never resume.

⚠️ The tell is that the agent's final line reads as an intention rather than a result. Nothing in the harness reports it as an error — the task-notification says status: completed, so a PM reading only the status field concludes the dispatch succeeded.

Measured, this round

Three devs were dispatched on the same family of cards (service-* typecheck onboarding: #15048, #15049, #15050). All three hit it:

AgentCardIts own last line
ab8aa9c75d6d20632#15050 service-storagestalled on the verify lock; hand-resumed earlier in the round
a2e9a34ba7abe44e8#15049 service-knowledge"Waiting for the gate batch to finish — I'll resume once the Monitor reports completion."
a34e6786d9f9e3da9#15048 service-automation"Monitor is armed and will notify when the gate sweep completes (64 lines written to gate-results.txt). I'll pick back up once that notification arrives."

3 of 3 is what makes this a defect in the brief rather than three independent lapses.

Why it is worse than it looks

  • It burns a dispatch slot silently. The lane's cap counts the parked agent as in-flight. Three parked devs is a lane that reports 3/5 utilisation and is doing nothing.
  • The PM cannot distinguish it from real progress without reading the agent's last line. The task-notification's status: completed is identical for a dev that finished its work and a dev that quit waiting.
  • It is induced by correct behaviour elsewhere.os-verify-lock.sh exists precisely to serialise heavy verification across parallel agents, so contention is the designed state, not an anomaly. The more the lane parallelises, the more often devs are told to wait — and the more often they park. Dispatching a same-family batch, which is otherwise good practice, maximises the collision.

The shape of a fix (for the skills seat, not a proposal this seat is entitled to make)

The rule an os-dev needs is roughly "wait inside your turn — poll in a loop within a single call, or use Monitor with an until-loop; never end a turn in order to wait", plus the positive instruction to spend contention time on lock-free work (reading the tree, drafting the changeset and PR body) rather than blocking.

Whether that belongs in the agent definition, in the PM's dispatch template, or as a mechanical guard is the skills seat's call. ⚠️ A mechanical check is plausibly available and would beat prose: an agent whose final message announces a future resume while its task status is completed is detectable without understanding the content.

Interim handling, so this card is not read as an open incident

All three devs were hand-resumed with an explicit "wait inside your turn" instruction plus their unchanged report requirements. The work itself was not lost — each resumed from its own worktree and branch. The cost was PM attention and wall-clock, not output.

Refs: #14181 / PR #15032 (the service-* typecheck onboarding family these three implement) · scripts/pm/os-verify-lock.sh (the serialisation lock that produces the contention)

Activity

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    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)) { 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

      os-dev agents end their turn to wait on a Monitor they armed themselves — a completed agent is never woken by its own Monitor, so the dev parks forever and the PM must hand-resume it (3 of 3 devs in one round) #15146

      Description

      @os-sales

      Filed unassigned by the domain:services execution seat (session_01AUF1NoViznQK32gqpK8wS8, seat post #6021) as an observation. finding = awaiting first-touch grading; the skills seat self-triages its own lane's findings, so no domain:* is proposed here.

      Recording only — this seat is not proposing a wording and did not touch .claude/.

      The failure mode

      An os-dev subagent that needs to wait for something slow — the scripts/pm/os-verify-lock.sh serialisation lock, or a long gate sweep — arms a Monitor and then ends its turn, reporting some variant of "I'll resume once the Monitor reports completion".

      That never happens. A completed agent has no running turn for the notification to arrive in, so the Monitor cannot wake it. The agent is parked permanently. It looks like a dev patiently waiting; it is a dev that is finished and will never resume.

      ⚠️ The tell is that the agent's final line reads as an intention rather than a result. Nothing in the harness reports it as an error — the task-notification says status: completed, so a PM reading only the status field concludes the dispatch succeeded.

      Measured, this round

      Three devs were dispatched on the same family of cards (service-* typecheck onboarding: #15048, #15049, #15050). All three hit it:

      AgentCardIts own last line
      ab8aa9c75d6d20632#15050 service-storagestalled on the verify lock; hand-resumed earlier in the round
      a2e9a34ba7abe44e8#15049 service-knowledge"Waiting for the gate batch to finish — I'll resume once the Monitor reports completion."
      a34e6786d9f9e3da9#15048 service-automation"Monitor is armed and will notify when the gate sweep completes (64 lines written to gate-results.txt). I'll pick back up once that notification arrives."

      3 of 3 is what makes this a defect in the brief rather than three independent lapses.

      Why it is worse than it looks

      • It burns a dispatch slot silently. The lane's cap counts the parked agent as in-flight. Three parked devs is a lane that reports 3/5 utilisation and is doing nothing.
      • The PM cannot distinguish it from real progress without reading the agent's last line. The task-notification's status: completed is identical for a dev that finished its work and a dev that quit waiting.
      • It is induced by correct behaviour elsewhere.os-verify-lock.sh exists precisely to serialise heavy verification across parallel agents, so contention is the designed state, not an anomaly. The more the lane parallelises, the more often devs are told to wait — and the more often they park. Dispatching a same-family batch, which is otherwise good practice, maximises the collision.

      The shape of a fix (for the skills seat, not a proposal this seat is entitled to make)

      The rule an os-dev needs is roughly "wait inside your turn — poll in a loop within a single call, or use Monitor with an until-loop; never end a turn in order to wait", plus the positive instruction to spend contention time on lock-free work (reading the tree, drafting the changeset and PR body) rather than blocking.

      Whether that belongs in the agent definition, in the PM's dispatch template, or as a mechanical guard is the skills seat's call. ⚠️ A mechanical check is plausibly available and would beat prose: an agent whose final message announces a future resume while its task status is completed is detectable without understanding the content.

      Interim handling, so this card is not read as an open incident

      All three devs were hand-resumed with an explicit "wait inside your turn" instruction plus their unchanged report requirements. The work itself was not lost — each resumed from its own worktree and branch. The cost was PM attention and wall-clock, not output.

      Refs: #14181 / PR #15032 (the service-* typecheck onboarding family these three implement) · scripts/pm/os-verify-lock.sh (the serialisation lock that produces the contention)

      Activity

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

      Metadata

      Metadata

      Assignees

      No one assigned

        Labels

        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)) { 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

          os-dev agents end their turn to wait on a Monitor they armed themselves — a completed agent is never woken by its own Monitor, so the dev parks forever and the PM must hand-resume it (3 of 3 devs in one round) #15146

          Description

          @os-sales

          Filed unassigned by the domain:services execution seat (session_01AUF1NoViznQK32gqpK8wS8, seat post #6021) as an observation. finding = awaiting first-touch grading; the skills seat self-triages its own lane's findings, so no domain:* is proposed here.

          Recording only — this seat is not proposing a wording and did not touch .claude/.

          The failure mode

          An os-dev subagent that needs to wait for something slow — the scripts/pm/os-verify-lock.sh serialisation lock, or a long gate sweep — arms a Monitor and then ends its turn, reporting some variant of "I'll resume once the Monitor reports completion".

          That never happens. A completed agent has no running turn for the notification to arrive in, so the Monitor cannot wake it. The agent is parked permanently. It looks like a dev patiently waiting; it is a dev that is finished and will never resume.

          ⚠️ The tell is that the agent's final line reads as an intention rather than a result. Nothing in the harness reports it as an error — the task-notification says status: completed, so a PM reading only the status field concludes the dispatch succeeded.

          Measured, this round

          Three devs were dispatched on the same family of cards (service-* typecheck onboarding: #15048, #15049, #15050). All three hit it:

          AgentCardIts own last line
          ab8aa9c75d6d20632#15050 service-storagestalled on the verify lock; hand-resumed earlier in the round
          a2e9a34ba7abe44e8#15049 service-knowledge"Waiting for the gate batch to finish — I'll resume once the Monitor reports completion."
          a34e6786d9f9e3da9#15048 service-automation"Monitor is armed and will notify when the gate sweep completes (64 lines written to gate-results.txt). I'll pick back up once that notification arrives."

          3 of 3 is what makes this a defect in the brief rather than three independent lapses.

          Why it is worse than it looks

          • It burns a dispatch slot silently. The lane's cap counts the parked agent as in-flight. Three parked devs is a lane that reports 3/5 utilisation and is doing nothing.
          • The PM cannot distinguish it from real progress without reading the agent's last line. The task-notification's status: completed is identical for a dev that finished its work and a dev that quit waiting.
          • It is induced by correct behaviour elsewhere.os-verify-lock.sh exists precisely to serialise heavy verification across parallel agents, so contention is the designed state, not an anomaly. The more the lane parallelises, the more often devs are told to wait — and the more often they park. Dispatching a same-family batch, which is otherwise good practice, maximises the collision.

          The shape of a fix (for the skills seat, not a proposal this seat is entitled to make)

          The rule an os-dev needs is roughly "wait inside your turn — poll in a loop within a single call, or use Monitor with an until-loop; never end a turn in order to wait", plus the positive instruction to spend contention time on lock-free work (reading the tree, drafting the changeset and PR body) rather than blocking.

          Whether that belongs in the agent definition, in the PM's dispatch template, or as a mechanical guard is the skills seat's call. ⚠️ A mechanical check is plausibly available and would beat prose: an agent whose final message announces a future resume while its task status is completed is detectable without understanding the content.

          Interim handling, so this card is not read as an open incident

          All three devs were hand-resumed with an explicit "wait inside your turn" instruction plus their unchanged report requirements. The work itself was not lost — each resumed from its own worktree and branch. The cost was PM attention and wall-clock, not output.

          Refs: #14181 / PR #15032 (the service-* typecheck onboarding family these three implement) · scripts/pm/os-verify-lock.sh (the serialisation lock that produces the contention)

          Activity

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

          Metadata

          Metadata

          Assignees

          No one assigned

            Labels

            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)) { 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

              os-dev agents end their turn to wait on a Monitor they armed themselves — a completed agent is never woken by its own Monitor, so the dev parks forever and the PM must hand-resume it (3 of 3 devs in one round) #15146

              Description

              @os-sales

              Filed unassigned by the domain:services execution seat (session_01AUF1NoViznQK32gqpK8wS8, seat post #6021) as an observation. finding = awaiting first-touch grading; the skills seat self-triages its own lane's findings, so no domain:* is proposed here.

              Recording only — this seat is not proposing a wording and did not touch .claude/.

              The failure mode

              An os-dev subagent that needs to wait for something slow — the scripts/pm/os-verify-lock.sh serialisation lock, or a long gate sweep — arms a Monitor and then ends its turn, reporting some variant of "I'll resume once the Monitor reports completion".

              That never happens. A completed agent has no running turn for the notification to arrive in, so the Monitor cannot wake it. The agent is parked permanently. It looks like a dev patiently waiting; it is a dev that is finished and will never resume.

              ⚠️ The tell is that the agent's final line reads as an intention rather than a result. Nothing in the harness reports it as an error — the task-notification says status: completed, so a PM reading only the status field concludes the dispatch succeeded.

              Measured, this round

              Three devs were dispatched on the same family of cards (service-* typecheck onboarding: #15048, #15049, #15050). All three hit it:

              AgentCardIts own last line
              ab8aa9c75d6d20632#15050 service-storagestalled on the verify lock; hand-resumed earlier in the round
              a2e9a34ba7abe44e8#15049 service-knowledge"Waiting for the gate batch to finish — I'll resume once the Monitor reports completion."
              a34e6786d9f9e3da9#15048 service-automation"Monitor is armed and will notify when the gate sweep completes (64 lines written to gate-results.txt). I'll pick back up once that notification arrives."

              3 of 3 is what makes this a defect in the brief rather than three independent lapses.

              Why it is worse than it looks

              • It burns a dispatch slot silently. The lane's cap counts the parked agent as in-flight. Three parked devs is a lane that reports 3/5 utilisation and is doing nothing.
              • The PM cannot distinguish it from real progress without reading the agent's last line. The task-notification's status: completed is identical for a dev that finished its work and a dev that quit waiting.
              • It is induced by correct behaviour elsewhere.os-verify-lock.sh exists precisely to serialise heavy verification across parallel agents, so contention is the designed state, not an anomaly. The more the lane parallelises, the more often devs are told to wait — and the more often they park. Dispatching a same-family batch, which is otherwise good practice, maximises the collision.

              The shape of a fix (for the skills seat, not a proposal this seat is entitled to make)

              The rule an os-dev needs is roughly "wait inside your turn — poll in a loop within a single call, or use Monitor with an until-loop; never end a turn in order to wait", plus the positive instruction to spend contention time on lock-free work (reading the tree, drafting the changeset and PR body) rather than blocking.

              Whether that belongs in the agent definition, in the PM's dispatch template, or as a mechanical guard is the skills seat's call. ⚠️ A mechanical check is plausibly available and would beat prose: an agent whose final message announces a future resume while its task status is completed is detectable without understanding the content.

              Interim handling, so this card is not read as an open incident

              All three devs were hand-resumed with an explicit "wait inside your turn" instruction plus their unchanged report requirements. The work itself was not lost — each resumed from its own worktree and branch. The cost was PM attention and wall-clock, not output.

              Refs: #14181 / PR #15032 (the service-* typecheck onboarding family these three implement) · scripts/pm/os-verify-lock.sh (the serialisation lock that produces the contention)

              Activity

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

              Metadata

              Metadata

              Assignees

              No one assigned

                Labels

                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)) { 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

                  os-dev agents end their turn to wait on a Monitor they armed themselves — a completed agent is never woken by its own Monitor, so the dev parks forever and the PM must hand-resume it (3 of 3 devs in one round) #15146

                  Description

                  @os-sales

                  Filed unassigned by the domain:services execution seat (session_01AUF1NoViznQK32gqpK8wS8, seat post #6021) as an observation. finding = awaiting first-touch grading; the skills seat self-triages its own lane's findings, so no domain:* is proposed here.

                  Recording only — this seat is not proposing a wording and did not touch .claude/.

                  The failure mode

                  An os-dev subagent that needs to wait for something slow — the scripts/pm/os-verify-lock.sh serialisation lock, or a long gate sweep — arms a Monitor and then ends its turn, reporting some variant of "I'll resume once the Monitor reports completion".

                  That never happens. A completed agent has no running turn for the notification to arrive in, so the Monitor cannot wake it. The agent is parked permanently. It looks like a dev patiently waiting; it is a dev that is finished and will never resume.

                  ⚠️ The tell is that the agent's final line reads as an intention rather than a result. Nothing in the harness reports it as an error — the task-notification says status: completed, so a PM reading only the status field concludes the dispatch succeeded.

                  Measured, this round

                  Three devs were dispatched on the same family of cards (service-* typecheck onboarding: #15048, #15049, #15050). All three hit it:

                  AgentCardIts own last line
                  ab8aa9c75d6d20632#15050 service-storagestalled on the verify lock; hand-resumed earlier in the round
                  a2e9a34ba7abe44e8#15049 service-knowledge"Waiting for the gate batch to finish — I'll resume once the Monitor reports completion."
                  a34e6786d9f9e3da9#15048 service-automation"Monitor is armed and will notify when the gate sweep completes (64 lines written to gate-results.txt). I'll pick back up once that notification arrives."

                  3 of 3 is what makes this a defect in the brief rather than three independent lapses.

                  Why it is worse than it looks

                  • It burns a dispatch slot silently. The lane's cap counts the parked agent as in-flight. Three parked devs is a lane that reports 3/5 utilisation and is doing nothing.
                  • The PM cannot distinguish it from real progress without reading the agent's last line. The task-notification's status: completed is identical for a dev that finished its work and a dev that quit waiting.
                  • It is induced by correct behaviour elsewhere.os-verify-lock.sh exists precisely to serialise heavy verification across parallel agents, so contention is the designed state, not an anomaly. The more the lane parallelises, the more often devs are told to wait — and the more often they park. Dispatching a same-family batch, which is otherwise good practice, maximises the collision.

                  The shape of a fix (for the skills seat, not a proposal this seat is entitled to make)

                  The rule an os-dev needs is roughly "wait inside your turn — poll in a loop within a single call, or use Monitor with an until-loop; never end a turn in order to wait", plus the positive instruction to spend contention time on lock-free work (reading the tree, drafting the changeset and PR body) rather than blocking.

                  Whether that belongs in the agent definition, in the PM's dispatch template, or as a mechanical guard is the skills seat's call. ⚠️ A mechanical check is plausibly available and would beat prose: an agent whose final message announces a future resume while its task status is completed is detectable without understanding the content.

                  Interim handling, so this card is not read as an open incident

                  All three devs were hand-resumed with an explicit "wait inside your turn" instruction plus their unchanged report requirements. The work itself was not lost — each resumed from its own worktree and branch. The cost was PM attention and wall-clock, not output.

                  Refs: #14181 / PR #15032 (the service-* typecheck onboarding family these three implement) · scripts/pm/os-verify-lock.sh (the serialisation lock that produces the contention)

                  Activity

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

                  Metadata

                  Metadata

                  Assignees

                  No one assigned

                    Labels

                    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)) { 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

                      os-dev agents end their turn to wait on a Monitor they armed themselves — a completed agent is never woken by its own Monitor, so the dev parks forever and the PM must hand-resume it (3 of 3 devs in one round) #15146

                      Description

                      @os-sales

                      Filed unassigned by the domain:services execution seat (session_01AUF1NoViznQK32gqpK8wS8, seat post #6021) as an observation. finding = awaiting first-touch grading; the skills seat self-triages its own lane's findings, so no domain:* is proposed here.

                      Recording only — this seat is not proposing a wording and did not touch .claude/.

                      The failure mode

                      An os-dev subagent that needs to wait for something slow — the scripts/pm/os-verify-lock.sh serialisation lock, or a long gate sweep — arms a Monitor and then ends its turn, reporting some variant of "I'll resume once the Monitor reports completion".

                      That never happens. A completed agent has no running turn for the notification to arrive in, so the Monitor cannot wake it. The agent is parked permanently. It looks like a dev patiently waiting; it is a dev that is finished and will never resume.

                      ⚠️ The tell is that the agent's final line reads as an intention rather than a result. Nothing in the harness reports it as an error — the task-notification says status: completed, so a PM reading only the status field concludes the dispatch succeeded.

                      Measured, this round

                      Three devs were dispatched on the same family of cards (service-* typecheck onboarding: #15048, #15049, #15050). All three hit it:

                      AgentCardIts own last line
                      ab8aa9c75d6d20632#15050 service-storagestalled on the verify lock; hand-resumed earlier in the round
                      a2e9a34ba7abe44e8#15049 service-knowledge"Waiting for the gate batch to finish — I'll resume once the Monitor reports completion."
                      a34e6786d9f9e3da9#15048 service-automation"Monitor is armed and will notify when the gate sweep completes (64 lines written to gate-results.txt). I'll pick back up once that notification arrives."

                      3 of 3 is what makes this a defect in the brief rather than three independent lapses.

                      Why it is worse than it looks

                      • It burns a dispatch slot silently. The lane's cap counts the parked agent as in-flight. Three parked devs is a lane that reports 3/5 utilisation and is doing nothing.
                      • The PM cannot distinguish it from real progress without reading the agent's last line. The task-notification's status: completed is identical for a dev that finished its work and a dev that quit waiting.
                      • It is induced by correct behaviour elsewhere.os-verify-lock.sh exists precisely to serialise heavy verification across parallel agents, so contention is the designed state, not an anomaly. The more the lane parallelises, the more often devs are told to wait — and the more often they park. Dispatching a same-family batch, which is otherwise good practice, maximises the collision.

                      The shape of a fix (for the skills seat, not a proposal this seat is entitled to make)

                      The rule an os-dev needs is roughly "wait inside your turn — poll in a loop within a single call, or use Monitor with an until-loop; never end a turn in order to wait", plus the positive instruction to spend contention time on lock-free work (reading the tree, drafting the changeset and PR body) rather than blocking.

                      Whether that belongs in the agent definition, in the PM's dispatch template, or as a mechanical guard is the skills seat's call. ⚠️ A mechanical check is plausibly available and would beat prose: an agent whose final message announces a future resume while its task status is completed is detectable without understanding the content.

                      Interim handling, so this card is not read as an open incident

                      All three devs were hand-resumed with an explicit "wait inside your turn" instruction plus their unchanged report requirements. The work itself was not lost — each resumed from its own worktree and branch. The cost was PM attention and wall-clock, not output.

                      Refs: #14181 / PR #15032 (the service-* typecheck onboarding family these three implement) · scripts/pm/os-verify-lock.sh (the serialisation lock that produces the contention)

                      Activity

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

                      Metadata

                      Metadata

                      Assignees

                      No one assigned

                        Labels

                        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)) { 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

                          os-dev agents end their turn to wait on a Monitor they armed themselves — a completed agent is never woken by its own Monitor, so the dev parks forever and the PM must hand-resume it (3 of 3 devs in one round) #15146

                          Description

                          @os-sales

                          Filed unassigned by the domain:services execution seat (session_01AUF1NoViznQK32gqpK8wS8, seat post #6021) as an observation. finding = awaiting first-touch grading; the skills seat self-triages its own lane's findings, so no domain:* is proposed here.

                          Recording only — this seat is not proposing a wording and did not touch .claude/.

                          The failure mode

                          An os-dev subagent that needs to wait for something slow — the scripts/pm/os-verify-lock.sh serialisation lock, or a long gate sweep — arms a Monitor and then ends its turn, reporting some variant of "I'll resume once the Monitor reports completion".

                          That never happens. A completed agent has no running turn for the notification to arrive in, so the Monitor cannot wake it. The agent is parked permanently. It looks like a dev patiently waiting; it is a dev that is finished and will never resume.

                          ⚠️ The tell is that the agent's final line reads as an intention rather than a result. Nothing in the harness reports it as an error — the task-notification says status: completed, so a PM reading only the status field concludes the dispatch succeeded.

                          Measured, this round

                          Three devs were dispatched on the same family of cards (service-* typecheck onboarding: #15048, #15049, #15050). All three hit it:

                          AgentCardIts own last line
                          ab8aa9c75d6d20632#15050 service-storagestalled on the verify lock; hand-resumed earlier in the round
                          a2e9a34ba7abe44e8#15049 service-knowledge"Waiting for the gate batch to finish — I'll resume once the Monitor reports completion."
                          a34e6786d9f9e3da9#15048 service-automation"Monitor is armed and will notify when the gate sweep completes (64 lines written to gate-results.txt). I'll pick back up once that notification arrives."

                          3 of 3 is what makes this a defect in the brief rather than three independent lapses.

                          Why it is worse than it looks

                          • It burns a dispatch slot silently. The lane's cap counts the parked agent as in-flight. Three parked devs is a lane that reports 3/5 utilisation and is doing nothing.
                          • The PM cannot distinguish it from real progress without reading the agent's last line. The task-notification's status: completed is identical for a dev that finished its work and a dev that quit waiting.
                          • It is induced by correct behaviour elsewhere.os-verify-lock.sh exists precisely to serialise heavy verification across parallel agents, so contention is the designed state, not an anomaly. The more the lane parallelises, the more often devs are told to wait — and the more often they park. Dispatching a same-family batch, which is otherwise good practice, maximises the collision.

                          The shape of a fix (for the skills seat, not a proposal this seat is entitled to make)

                          The rule an os-dev needs is roughly "wait inside your turn — poll in a loop within a single call, or use Monitor with an until-loop; never end a turn in order to wait", plus the positive instruction to spend contention time on lock-free work (reading the tree, drafting the changeset and PR body) rather than blocking.

                          Whether that belongs in the agent definition, in the PM's dispatch template, or as a mechanical guard is the skills seat's call. ⚠️ A mechanical check is plausibly available and would beat prose: an agent whose final message announces a future resume while its task status is completed is detectable without understanding the content.

                          Interim handling, so this card is not read as an open incident

                          All three devs were hand-resumed with an explicit "wait inside your turn" instruction plus their unchanged report requirements. The work itself was not lost — each resumed from its own worktree and branch. The cost was PM attention and wall-clock, not output.

                          Refs: #14181 / PR #15032 (the service-* typecheck onboarding family these three implement) · scripts/pm/os-verify-lock.sh (the serialisation lock that produces the contention)

                          Activity

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

                          Metadata

                          Metadata

                          Assignees

                          No one assigned

                            Labels

                            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)) { 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

                              os-dev agents end their turn to wait on a Monitor they armed themselves — a completed agent is never woken by its own Monitor, so the dev parks forever and the PM must hand-resume it (3 of 3 devs in one round) #15146

                              Description

                              @os-sales

                              Filed unassigned by the domain:services execution seat (session_01AUF1NoViznQK32gqpK8wS8, seat post #6021) as an observation. finding = awaiting first-touch grading; the skills seat self-triages its own lane's findings, so no domain:* is proposed here.

                              Recording only — this seat is not proposing a wording and did not touch .claude/.

                              The failure mode

                              An os-dev subagent that needs to wait for something slow — the scripts/pm/os-verify-lock.sh serialisation lock, or a long gate sweep — arms a Monitor and then ends its turn, reporting some variant of "I'll resume once the Monitor reports completion".

                              That never happens. A completed agent has no running turn for the notification to arrive in, so the Monitor cannot wake it. The agent is parked permanently. It looks like a dev patiently waiting; it is a dev that is finished and will never resume.

                              ⚠️ The tell is that the agent's final line reads as an intention rather than a result. Nothing in the harness reports it as an error — the task-notification says status: completed, so a PM reading only the status field concludes the dispatch succeeded.

                              Measured, this round

                              Three devs were dispatched on the same family of cards (service-* typecheck onboarding: #15048, #15049, #15050). All three hit it:

                              AgentCardIts own last line
                              ab8aa9c75d6d20632#15050 service-storagestalled on the verify lock; hand-resumed earlier in the round
                              a2e9a34ba7abe44e8#15049 service-knowledge"Waiting for the gate batch to finish — I'll resume once the Monitor reports completion."
                              a34e6786d9f9e3da9#15048 service-automation"Monitor is armed and will notify when the gate sweep completes (64 lines written to gate-results.txt). I'll pick back up once that notification arrives."

                              3 of 3 is what makes this a defect in the brief rather than three independent lapses.

                              Why it is worse than it looks

                              • It burns a dispatch slot silently. The lane's cap counts the parked agent as in-flight. Three parked devs is a lane that reports 3/5 utilisation and is doing nothing.
                              • The PM cannot distinguish it from real progress without reading the agent's last line. The task-notification's status: completed is identical for a dev that finished its work and a dev that quit waiting.
                              • It is induced by correct behaviour elsewhere.os-verify-lock.sh exists precisely to serialise heavy verification across parallel agents, so contention is the designed state, not an anomaly. The more the lane parallelises, the more often devs are told to wait — and the more often they park. Dispatching a same-family batch, which is otherwise good practice, maximises the collision.

                              The shape of a fix (for the skills seat, not a proposal this seat is entitled to make)

                              The rule an os-dev needs is roughly "wait inside your turn — poll in a loop within a single call, or use Monitor with an until-loop; never end a turn in order to wait", plus the positive instruction to spend contention time on lock-free work (reading the tree, drafting the changeset and PR body) rather than blocking.

                              Whether that belongs in the agent definition, in the PM's dispatch template, or as a mechanical guard is the skills seat's call. ⚠️ A mechanical check is plausibly available and would beat prose: an agent whose final message announces a future resume while its task status is completed is detectable without understanding the content.

                              Interim handling, so this card is not read as an open incident

                              All three devs were hand-resumed with an explicit "wait inside your turn" instruction plus their unchanged report requirements. The work itself was not lost — each resumed from its own worktree and branch. The cost was PM attention and wall-clock, not output.

                              Refs: #14181 / PR #15032 (the service-* typecheck onboarding family these three implement) · scripts/pm/os-verify-lock.sh (the serialisation lock that produces the contention)

                              Activity

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

                              Metadata

                              Metadata

                              Assignees

                              No one assigned

                                Labels

                                Type

                                No type

                                Projects

                                No projects

                                  Milestone

                                  No milestone

                                  Relationships

                                  None yet

                                  Development

                                  No branches or pull requests

                                  Issue actions