Make the full verification battery safe to run concurrently #279

Description

@taras

Motivation

The repository's verification battery is logically independent, but it is not safe to run concurrently in one worktree. That forces local verification to serialize long Deno, Node, and Bun suites even though CI runs them in parallel on separate checkouts.

Owner ruling (2026-08-02): the entire applicable verification battery must be safe to launch concurrently in one worktree after setup. This is a repository rule, not an optimization that individual implementors may opt out of.

Reproduced failure

The current setup is:

deno task build:web
pnpm install

A concurrent local run of the pinned Deno suite with the Node and Bun suites then produced false failures such as:

ERR_MODULE_NOT_FOUND: Cannot find package '@effectionx/context-api'
ENOENT reading node_modules/@effectionx/converge

The same PR head is green in CI because the runtime jobs use separate checkouts.

The collision is structural:

  • The root deno.json uses "nodeModulesDir": "auto".
  • scripts/build-web-client.ts calls deno install --frozen in the repository root.
  • deno task test executes scripts/tests/build-web-client.test.ts, which calls buildWebClient() repeatedly.
  • That Deno install replaces the pnpm-shaped root node_modules while pnpm exec tsc, the Node suite, the Bun suite, lint tools, and spawned tsx processes resolve through it.
  • buildWebClient() also temporarily patches the fixed path node_modules/@rjsf/validator-ajv8/package.json and writes the fixed generated path packages/web/generated/client-bundle.ts. Concurrent builders can therefore observe one another's temporary manifest state or race restoration/output writes.
  • The Deno install follows the workspace CLI bin target and changes the tracked mode of packages/cli/src/node.ts from 100644 to 100755, so verification can leave a clean tree dirty even without another runtime running.

The first concurrent Node/Bun results are not product failures: they were caused by this shared-state race. Pinned Deno 2.9.1 completed independently with 320 passed and 0 failed.

Contract

After one documented setup, all applicable commands in the verification battery can be started concurrently from the same worktree:

deno task lint
deno task check
deno task test
deno task check:jsr
pnpm exec tsc --project tsconfig.node.json --noEmit
pnpm test:node
bun run test:bun
deno task xmd test packages/core/src --raw
(cd site && deno task check)
(cd site && deno task build)

The site commands are applicable when site/ changes, as today. Deno commands run with CI-pinned Deno 2.9.1 on PATH.

The invariant is stronger than "the commands usually pass together":

  • No verification command may install into, remove, relink, patch, chmod, or clean the repository dependency tree or another command's owned paths.
  • Temporary mutations are isolated per command/process; cleanup from one command cannot overwrite another command's state.
  • Generated outputs needed by verification remain deterministic, but a fixed generated path must not become a cross-command race.
  • A successful battery leaves tracked files byte-for-byte and mode-for-mode unchanged.
  • Failures and cancellation also restore or remove only the invoking command's own temporary state.
  • CI keeps its independent jobs; this issue fixes local composability rather than collapsing CI into one job.

Dependency-cache boundary

Owner ruling (2026-08-04): verification does not have a Deno global-cache purity requirement. The runtime-owned cache may gain or refresh locked npm/JSR package content and registry metadata while checks run. Verification must not fingerprint that cache or require it to remain byte-identical.

The protected repository state remains strict: verification cannot change node_modules, deno.lock, tracked content or modes, or another invocation's temporary state. Build and release phases retain the separate #304 guarantee: after preparation they run offline and leave both dependency layouts and the lock unchanged. verify:clean continues checking cache purity around those build/release phases, but not around the verification battery.

Repository rule

Update AGENTS.md so future changes preserve this invariant. The rule must say that the full verification battery is designed to run concurrently after setup and that tests/build helpers must not rely on repository-wide mutable state that conflicts with another check.

The rule supplements the existing command list; it does not weaken any required check or permit skipping a command.

Plan gate

This is a nontrivial mechanism change. Before code, submit a short plan that identifies:

  1. the owner and lifetime of dependency layouts used by Deno, pnpm/Node, Bun, lint, and site checks;
  2. how buildWebClient() stops mutating shared dependency/package paths while preserving the real-bundle and deterministic-output tests;
  3. how generated bundle and site build outputs are isolated or coordinated without serializing the battery;
  4. how tracked file mode/content cleanliness is enforced; and
  5. the regression harness that launches the whole applicable battery concurrently and proves both results and post-run cleanliness.

Do not choose product behavior in the implementation plan. The product contract is the concurrent-safety invariant above; the mechanism remains open for review.

Acceptance criteria

  • From a clean checkout after the documented setup, one command or documented harness launches the full applicable battery concurrently and every command passes.
  • The regression fails against the current shared-node_modules behavior.
  • Repeated runs are deterministic and leave no tracked content or mode changes, no node_modules changes, and no deno.lock changes; Deno global-cache additions are permitted.
  • Failure/cancellation coverage proves temporary state is scoped to the invoking command.
  • Existing CI jobs remain green with Deno 2.9.1, Node 22, and the pinned Bun version.
  • AGENTS.md records the concurrent-verification rule.
  • The setup and local verification documentation show the parallel invocation.

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

    No labels
    No labels

    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 \u003cpre\u003e\u003ccode\u003e 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

      Make the full verification battery safe to run concurrently #279

      Description

      @taras

      Motivation

      The repository's verification battery is logically independent, but it is not safe to run concurrently in one worktree. That forces local verification to serialize long Deno, Node, and Bun suites even though CI runs them in parallel on separate checkouts.

      Owner ruling (2026-08-02): the entire applicable verification battery must be safe to launch concurrently in one worktree after setup. This is a repository rule, not an optimization that individual implementors may opt out of.

      Reproduced failure

      The current setup is:

      deno task build:web
      pnpm install

      A concurrent local run of the pinned Deno suite with the Node and Bun suites then produced false failures such as:

      ERR_MODULE_NOT_FOUND: Cannot find package '@effectionx/context-api'
      ENOENT reading node_modules/@effectionx/converge
      

      The same PR head is green in CI because the runtime jobs use separate checkouts.

      The collision is structural:

      • The root deno.json uses "nodeModulesDir": "auto".
      • scripts/build-web-client.ts calls deno install --frozen in the repository root.
      • deno task test executes scripts/tests/build-web-client.test.ts, which calls buildWebClient() repeatedly.
      • That Deno install replaces the pnpm-shaped root node_modules while pnpm exec tsc, the Node suite, the Bun suite, lint tools, and spawned tsx processes resolve through it.
      • buildWebClient() also temporarily patches the fixed path node_modules/@rjsf/validator-ajv8/package.json and writes the fixed generated path packages/web/generated/client-bundle.ts. Concurrent builders can therefore observe one another's temporary manifest state or race restoration/output writes.
      • The Deno install follows the workspace CLI bin target and changes the tracked mode of packages/cli/src/node.ts from 100644 to 100755, so verification can leave a clean tree dirty even without another runtime running.

      The first concurrent Node/Bun results are not product failures: they were caused by this shared-state race. Pinned Deno 2.9.1 completed independently with 320 passed and 0 failed.

      Contract

      After one documented setup, all applicable commands in the verification battery can be started concurrently from the same worktree:

      deno task lint
      deno task check
      deno task test
      deno task check:jsr
      pnpm exec tsc --project tsconfig.node.json --noEmit
      pnpm test:node
      bun run test:bun
      deno task xmd test packages/core/src --raw
      (cd site && deno task check)
      (cd site && deno task build)

      The site commands are applicable when site/ changes, as today. Deno commands run with CI-pinned Deno 2.9.1 on PATH.

      The invariant is stronger than "the commands usually pass together":

      • No verification command may install into, remove, relink, patch, chmod, or clean the repository dependency tree or another command's owned paths.
      • Temporary mutations are isolated per command/process; cleanup from one command cannot overwrite another command's state.
      • Generated outputs needed by verification remain deterministic, but a fixed generated path must not become a cross-command race.
      • A successful battery leaves tracked files byte-for-byte and mode-for-mode unchanged.
      • Failures and cancellation also restore or remove only the invoking command's own temporary state.
      • CI keeps its independent jobs; this issue fixes local composability rather than collapsing CI into one job.

      Dependency-cache boundary

      Owner ruling (2026-08-04): verification does not have a Deno global-cache purity requirement. The runtime-owned cache may gain or refresh locked npm/JSR package content and registry metadata while checks run. Verification must not fingerprint that cache or require it to remain byte-identical.

      The protected repository state remains strict: verification cannot change node_modules, deno.lock, tracked content or modes, or another invocation's temporary state. Build and release phases retain the separate #304 guarantee: after preparation they run offline and leave both dependency layouts and the lock unchanged. verify:clean continues checking cache purity around those build/release phases, but not around the verification battery.

      Repository rule

      Update AGENTS.md so future changes preserve this invariant. The rule must say that the full verification battery is designed to run concurrently after setup and that tests/build helpers must not rely on repository-wide mutable state that conflicts with another check.

      The rule supplements the existing command list; it does not weaken any required check or permit skipping a command.

      Plan gate

      This is a nontrivial mechanism change. Before code, submit a short plan that identifies:

      1. the owner and lifetime of dependency layouts used by Deno, pnpm/Node, Bun, lint, and site checks;
      2. how buildWebClient() stops mutating shared dependency/package paths while preserving the real-bundle and deterministic-output tests;
      3. how generated bundle and site build outputs are isolated or coordinated without serializing the battery;
      4. how tracked file mode/content cleanliness is enforced; and
      5. the regression harness that launches the whole applicable battery concurrently and proves both results and post-run cleanliness.

      Do not choose product behavior in the implementation plan. The product contract is the concurrent-safety invariant above; the mechanism remains open for review.

      Acceptance criteria

      • From a clean checkout after the documented setup, one command or documented harness launches the full applicable battery concurrently and every command passes.
      • The regression fails against the current shared-node_modules behavior.
      • Repeated runs are deterministic and leave no tracked content or mode changes, no node_modules changes, and no deno.lock changes; Deno global-cache additions are permitted.
      • Failure/cancellation coverage proves temporary state is scoped to the invoking command.
      • Existing CI jobs remain green with Deno 2.9.1, Node 22, and the pinned Bun version.
      • AGENTS.md records the concurrent-verification rule.
      • The setup and local verification documentation show the parallel invocation.

      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

        No labels
        No labels

        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

          Make the full verification battery safe to run concurrently #279

          Description

          @taras

          Motivation

          The repository's verification battery is logically independent, but it is not safe to run concurrently in one worktree. That forces local verification to serialize long Deno, Node, and Bun suites even though CI runs them in parallel on separate checkouts.

          Owner ruling (2026-08-02): the entire applicable verification battery must be safe to launch concurrently in one worktree after setup. This is a repository rule, not an optimization that individual implementors may opt out of.

          Reproduced failure

          The current setup is:

          deno task build:web
          pnpm install

          A concurrent local run of the pinned Deno suite with the Node and Bun suites then produced false failures such as:

          ERR_MODULE_NOT_FOUND: Cannot find package '@effectionx/context-api'
          ENOENT reading node_modules/@effectionx/converge
          

          The same PR head is green in CI because the runtime jobs use separate checkouts.

          The collision is structural:

          • The root deno.json uses "nodeModulesDir": "auto".
          • scripts/build-web-client.ts calls deno install --frozen in the repository root.
          • deno task test executes scripts/tests/build-web-client.test.ts, which calls buildWebClient() repeatedly.
          • That Deno install replaces the pnpm-shaped root node_modules while pnpm exec tsc, the Node suite, the Bun suite, lint tools, and spawned tsx processes resolve through it.
          • buildWebClient() also temporarily patches the fixed path node_modules/@rjsf/validator-ajv8/package.json and writes the fixed generated path packages/web/generated/client-bundle.ts. Concurrent builders can therefore observe one another's temporary manifest state or race restoration/output writes.
          • The Deno install follows the workspace CLI bin target and changes the tracked mode of packages/cli/src/node.ts from 100644 to 100755, so verification can leave a clean tree dirty even without another runtime running.

          The first concurrent Node/Bun results are not product failures: they were caused by this shared-state race. Pinned Deno 2.9.1 completed independently with 320 passed and 0 failed.

          Contract

          After one documented setup, all applicable commands in the verification battery can be started concurrently from the same worktree:

          deno task lint
          deno task check
          deno task test
          deno task check:jsr
          pnpm exec tsc --project tsconfig.node.json --noEmit
          pnpm test:node
          bun run test:bun
          deno task xmd test packages/core/src --raw
          (cd site && deno task check)
          (cd site && deno task build)

          The site commands are applicable when site/ changes, as today. Deno commands run with CI-pinned Deno 2.9.1 on PATH.

          The invariant is stronger than "the commands usually pass together":

          • No verification command may install into, remove, relink, patch, chmod, or clean the repository dependency tree or another command's owned paths.
          • Temporary mutations are isolated per command/process; cleanup from one command cannot overwrite another command's state.
          • Generated outputs needed by verification remain deterministic, but a fixed generated path must not become a cross-command race.
          • A successful battery leaves tracked files byte-for-byte and mode-for-mode unchanged.
          • Failures and cancellation also restore or remove only the invoking command's own temporary state.
          • CI keeps its independent jobs; this issue fixes local composability rather than collapsing CI into one job.

          Dependency-cache boundary

          Owner ruling (2026-08-04): verification does not have a Deno global-cache purity requirement. The runtime-owned cache may gain or refresh locked npm/JSR package content and registry metadata while checks run. Verification must not fingerprint that cache or require it to remain byte-identical.

          The protected repository state remains strict: verification cannot change node_modules, deno.lock, tracked content or modes, or another invocation's temporary state. Build and release phases retain the separate #304 guarantee: after preparation they run offline and leave both dependency layouts and the lock unchanged. verify:clean continues checking cache purity around those build/release phases, but not around the verification battery.

          Repository rule

          Update AGENTS.md so future changes preserve this invariant. The rule must say that the full verification battery is designed to run concurrently after setup and that tests/build helpers must not rely on repository-wide mutable state that conflicts with another check.

          The rule supplements the existing command list; it does not weaken any required check or permit skipping a command.

          Plan gate

          This is a nontrivial mechanism change. Before code, submit a short plan that identifies:

          1. the owner and lifetime of dependency layouts used by Deno, pnpm/Node, Bun, lint, and site checks;
          2. how buildWebClient() stops mutating shared dependency/package paths while preserving the real-bundle and deterministic-output tests;
          3. how generated bundle and site build outputs are isolated or coordinated without serializing the battery;
          4. how tracked file mode/content cleanliness is enforced; and
          5. the regression harness that launches the whole applicable battery concurrently and proves both results and post-run cleanliness.

          Do not choose product behavior in the implementation plan. The product contract is the concurrent-safety invariant above; the mechanism remains open for review.

          Acceptance criteria

          • From a clean checkout after the documented setup, one command or documented harness launches the full applicable battery concurrently and every command passes.
          • The regression fails against the current shared-node_modules behavior.
          • Repeated runs are deterministic and leave no tracked content or mode changes, no node_modules changes, and no deno.lock changes; Deno global-cache additions are permitted.
          • Failure/cancellation coverage proves temporary state is scoped to the invoking command.
          • Existing CI jobs remain green with Deno 2.9.1, Node 22, and the pinned Bun version.
          • AGENTS.md records the concurrent-verification rule.
          • The setup and local verification documentation show the parallel invocation.

          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

            No labels
            No labels

            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 \u003e 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

              Make the full verification battery safe to run concurrently #279

              Description

              @taras

              Motivation

              The repository's verification battery is logically independent, but it is not safe to run concurrently in one worktree. That forces local verification to serialize long Deno, Node, and Bun suites even though CI runs them in parallel on separate checkouts.

              Owner ruling (2026-08-02): the entire applicable verification battery must be safe to launch concurrently in one worktree after setup. This is a repository rule, not an optimization that individual implementors may opt out of.

              Reproduced failure

              The current setup is:

              deno task build:web
              pnpm install

              A concurrent local run of the pinned Deno suite with the Node and Bun suites then produced false failures such as:

              ERR_MODULE_NOT_FOUND: Cannot find package '@effectionx/context-api'
              ENOENT reading node_modules/@effectionx/converge
              

              The same PR head is green in CI because the runtime jobs use separate checkouts.

              The collision is structural:

              • The root deno.json uses "nodeModulesDir": "auto".
              • scripts/build-web-client.ts calls deno install --frozen in the repository root.
              • deno task test executes scripts/tests/build-web-client.test.ts, which calls buildWebClient() repeatedly.
              • That Deno install replaces the pnpm-shaped root node_modules while pnpm exec tsc, the Node suite, the Bun suite, lint tools, and spawned tsx processes resolve through it.
              • buildWebClient() also temporarily patches the fixed path node_modules/@rjsf/validator-ajv8/package.json and writes the fixed generated path packages/web/generated/client-bundle.ts. Concurrent builders can therefore observe one another's temporary manifest state or race restoration/output writes.
              • The Deno install follows the workspace CLI bin target and changes the tracked mode of packages/cli/src/node.ts from 100644 to 100755, so verification can leave a clean tree dirty even without another runtime running.

              The first concurrent Node/Bun results are not product failures: they were caused by this shared-state race. Pinned Deno 2.9.1 completed independently with 320 passed and 0 failed.

              Contract

              After one documented setup, all applicable commands in the verification battery can be started concurrently from the same worktree:

              deno task lint
              deno task check
              deno task test
              deno task check:jsr
              pnpm exec tsc --project tsconfig.node.json --noEmit
              pnpm test:node
              bun run test:bun
              deno task xmd test packages/core/src --raw
              (cd site && deno task check)
              (cd site && deno task build)

              The site commands are applicable when site/ changes, as today. Deno commands run with CI-pinned Deno 2.9.1 on PATH.

              The invariant is stronger than "the commands usually pass together":

              • No verification command may install into, remove, relink, patch, chmod, or clean the repository dependency tree or another command's owned paths.
              • Temporary mutations are isolated per command/process; cleanup from one command cannot overwrite another command's state.
              • Generated outputs needed by verification remain deterministic, but a fixed generated path must not become a cross-command race.
              • A successful battery leaves tracked files byte-for-byte and mode-for-mode unchanged.
              • Failures and cancellation also restore or remove only the invoking command's own temporary state.
              • CI keeps its independent jobs; this issue fixes local composability rather than collapsing CI into one job.

              Dependency-cache boundary

              Owner ruling (2026-08-04): verification does not have a Deno global-cache purity requirement. The runtime-owned cache may gain or refresh locked npm/JSR package content and registry metadata while checks run. Verification must not fingerprint that cache or require it to remain byte-identical.

              The protected repository state remains strict: verification cannot change node_modules, deno.lock, tracked content or modes, or another invocation's temporary state. Build and release phases retain the separate #304 guarantee: after preparation they run offline and leave both dependency layouts and the lock unchanged. verify:clean continues checking cache purity around those build/release phases, but not around the verification battery.

              Repository rule

              Update AGENTS.md so future changes preserve this invariant. The rule must say that the full verification battery is designed to run concurrently after setup and that tests/build helpers must not rely on repository-wide mutable state that conflicts with another check.

              The rule supplements the existing command list; it does not weaken any required check or permit skipping a command.

              Plan gate

              This is a nontrivial mechanism change. Before code, submit a short plan that identifies:

              1. the owner and lifetime of dependency layouts used by Deno, pnpm/Node, Bun, lint, and site checks;
              2. how buildWebClient() stops mutating shared dependency/package paths while preserving the real-bundle and deterministic-output tests;
              3. how generated bundle and site build outputs are isolated or coordinated without serializing the battery;
              4. how tracked file mode/content cleanliness is enforced; and
              5. the regression harness that launches the whole applicable battery concurrently and proves both results and post-run cleanliness.

              Do not choose product behavior in the implementation plan. The product contract is the concurrent-safety invariant above; the mechanism remains open for review.

              Acceptance criteria

              • From a clean checkout after the documented setup, one command or documented harness launches the full applicable battery concurrently and every command passes.
              • The regression fails against the current shared-node_modules behavior.
              • Repeated runs are deterministic and leave no tracked content or mode changes, no node_modules changes, and no deno.lock changes; Deno global-cache additions are permitted.
              • Failure/cancellation coverage proves temporary state is scoped to the invoking command.
              • Existing CI jobs remain green with Deno 2.9.1, Node 22, and the pinned Bun version.
              • AGENTS.md records the concurrent-verification rule.
              • The setup and local verification documentation show the parallel invocation.

              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

                No labels
                No labels

                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

                  Make the full verification battery safe to run concurrently #279

                  Description

                  @taras

                  Motivation

                  The repository's verification battery is logically independent, but it is not safe to run concurrently in one worktree. That forces local verification to serialize long Deno, Node, and Bun suites even though CI runs them in parallel on separate checkouts.

                  Owner ruling (2026-08-02): the entire applicable verification battery must be safe to launch concurrently in one worktree after setup. This is a repository rule, not an optimization that individual implementors may opt out of.

                  Reproduced failure

                  The current setup is:

                  deno task build:web
                  pnpm install

                  A concurrent local run of the pinned Deno suite with the Node and Bun suites then produced false failures such as:

                  ERR_MODULE_NOT_FOUND: Cannot find package '@effectionx/context-api'
                  ENOENT reading node_modules/@effectionx/converge
                  

                  The same PR head is green in CI because the runtime jobs use separate checkouts.

                  The collision is structural:

                  • The root deno.json uses "nodeModulesDir": "auto".
                  • scripts/build-web-client.ts calls deno install --frozen in the repository root.
                  • deno task test executes scripts/tests/build-web-client.test.ts, which calls buildWebClient() repeatedly.
                  • That Deno install replaces the pnpm-shaped root node_modules while pnpm exec tsc, the Node suite, the Bun suite, lint tools, and spawned tsx processes resolve through it.
                  • buildWebClient() also temporarily patches the fixed path node_modules/@rjsf/validator-ajv8/package.json and writes the fixed generated path packages/web/generated/client-bundle.ts. Concurrent builders can therefore observe one another's temporary manifest state or race restoration/output writes.
                  • The Deno install follows the workspace CLI bin target and changes the tracked mode of packages/cli/src/node.ts from 100644 to 100755, so verification can leave a clean tree dirty even without another runtime running.

                  The first concurrent Node/Bun results are not product failures: they were caused by this shared-state race. Pinned Deno 2.9.1 completed independently with 320 passed and 0 failed.

                  Contract

                  After one documented setup, all applicable commands in the verification battery can be started concurrently from the same worktree:

                  deno task lint
                  deno task check
                  deno task test
                  deno task check:jsr
                  pnpm exec tsc --project tsconfig.node.json --noEmit
                  pnpm test:node
                  bun run test:bun
                  deno task xmd test packages/core/src --raw
                  (cd site && deno task check)
                  (cd site && deno task build)

                  The site commands are applicable when site/ changes, as today. Deno commands run with CI-pinned Deno 2.9.1 on PATH.

                  The invariant is stronger than "the commands usually pass together":

                  • No verification command may install into, remove, relink, patch, chmod, or clean the repository dependency tree or another command's owned paths.
                  • Temporary mutations are isolated per command/process; cleanup from one command cannot overwrite another command's state.
                  • Generated outputs needed by verification remain deterministic, but a fixed generated path must not become a cross-command race.
                  • A successful battery leaves tracked files byte-for-byte and mode-for-mode unchanged.
                  • Failures and cancellation also restore or remove only the invoking command's own temporary state.
                  • CI keeps its independent jobs; this issue fixes local composability rather than collapsing CI into one job.

                  Dependency-cache boundary

                  Owner ruling (2026-08-04): verification does not have a Deno global-cache purity requirement. The runtime-owned cache may gain or refresh locked npm/JSR package content and registry metadata while checks run. Verification must not fingerprint that cache or require it to remain byte-identical.

                  The protected repository state remains strict: verification cannot change node_modules, deno.lock, tracked content or modes, or another invocation's temporary state. Build and release phases retain the separate #304 guarantee: after preparation they run offline and leave both dependency layouts and the lock unchanged. verify:clean continues checking cache purity around those build/release phases, but not around the verification battery.

                  Repository rule

                  Update AGENTS.md so future changes preserve this invariant. The rule must say that the full verification battery is designed to run concurrently after setup and that tests/build helpers must not rely on repository-wide mutable state that conflicts with another check.

                  The rule supplements the existing command list; it does not weaken any required check or permit skipping a command.

                  Plan gate

                  This is a nontrivial mechanism change. Before code, submit a short plan that identifies:

                  1. the owner and lifetime of dependency layouts used by Deno, pnpm/Node, Bun, lint, and site checks;
                  2. how buildWebClient() stops mutating shared dependency/package paths while preserving the real-bundle and deterministic-output tests;
                  3. how generated bundle and site build outputs are isolated or coordinated without serializing the battery;
                  4. how tracked file mode/content cleanliness is enforced; and
                  5. the regression harness that launches the whole applicable battery concurrently and proves both results and post-run cleanliness.

                  Do not choose product behavior in the implementation plan. The product contract is the concurrent-safety invariant above; the mechanism remains open for review.

                  Acceptance criteria

                  • From a clean checkout after the documented setup, one command or documented harness launches the full applicable battery concurrently and every command passes.
                  • The regression fails against the current shared-node_modules behavior.
                  • Repeated runs are deterministic and leave no tracked content or mode changes, no node_modules changes, and no deno.lock changes; Deno global-cache additions are permitted.
                  • Failure/cancellation coverage proves temporary state is scoped to the invoking command.
                  • Existing CI jobs remain green with Deno 2.9.1, Node 22, and the pinned Bun version.
                  • AGENTS.md records the concurrent-verification rule.
                  • The setup and local verification documentation show the parallel invocation.

                  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

                    No labels
                    No labels

                    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

                      Make the full verification battery safe to run concurrently #279

                      Description

                      @taras

                      Motivation

                      The repository's verification battery is logically independent, but it is not safe to run concurrently in one worktree. That forces local verification to serialize long Deno, Node, and Bun suites even though CI runs them in parallel on separate checkouts.

                      Owner ruling (2026-08-02): the entire applicable verification battery must be safe to launch concurrently in one worktree after setup. This is a repository rule, not an optimization that individual implementors may opt out of.

                      Reproduced failure

                      The current setup is:

                      deno task build:web
                      pnpm install

                      A concurrent local run of the pinned Deno suite with the Node and Bun suites then produced false failures such as:

                      ERR_MODULE_NOT_FOUND: Cannot find package '@effectionx/context-api'
                      ENOENT reading node_modules/@effectionx/converge
                      

                      The same PR head is green in CI because the runtime jobs use separate checkouts.

                      The collision is structural:

                      • The root deno.json uses "nodeModulesDir": "auto".
                      • scripts/build-web-client.ts calls deno install --frozen in the repository root.
                      • deno task test executes scripts/tests/build-web-client.test.ts, which calls buildWebClient() repeatedly.
                      • That Deno install replaces the pnpm-shaped root node_modules while pnpm exec tsc, the Node suite, the Bun suite, lint tools, and spawned tsx processes resolve through it.
                      • buildWebClient() also temporarily patches the fixed path node_modules/@rjsf/validator-ajv8/package.json and writes the fixed generated path packages/web/generated/client-bundle.ts. Concurrent builders can therefore observe one another's temporary manifest state or race restoration/output writes.
                      • The Deno install follows the workspace CLI bin target and changes the tracked mode of packages/cli/src/node.ts from 100644 to 100755, so verification can leave a clean tree dirty even without another runtime running.

                      The first concurrent Node/Bun results are not product failures: they were caused by this shared-state race. Pinned Deno 2.9.1 completed independently with 320 passed and 0 failed.

                      Contract

                      After one documented setup, all applicable commands in the verification battery can be started concurrently from the same worktree:

                      deno task lint
                      deno task check
                      deno task test
                      deno task check:jsr
                      pnpm exec tsc --project tsconfig.node.json --noEmit
                      pnpm test:node
                      bun run test:bun
                      deno task xmd test packages/core/src --raw
                      (cd site && deno task check)
                      (cd site && deno task build)

                      The site commands are applicable when site/ changes, as today. Deno commands run with CI-pinned Deno 2.9.1 on PATH.

                      The invariant is stronger than "the commands usually pass together":

                      • No verification command may install into, remove, relink, patch, chmod, or clean the repository dependency tree or another command's owned paths.
                      • Temporary mutations are isolated per command/process; cleanup from one command cannot overwrite another command's state.
                      • Generated outputs needed by verification remain deterministic, but a fixed generated path must not become a cross-command race.
                      • A successful battery leaves tracked files byte-for-byte and mode-for-mode unchanged.
                      • Failures and cancellation also restore or remove only the invoking command's own temporary state.
                      • CI keeps its independent jobs; this issue fixes local composability rather than collapsing CI into one job.

                      Dependency-cache boundary

                      Owner ruling (2026-08-04): verification does not have a Deno global-cache purity requirement. The runtime-owned cache may gain or refresh locked npm/JSR package content and registry metadata while checks run. Verification must not fingerprint that cache or require it to remain byte-identical.

                      The protected repository state remains strict: verification cannot change node_modules, deno.lock, tracked content or modes, or another invocation's temporary state. Build and release phases retain the separate #304 guarantee: after preparation they run offline and leave both dependency layouts and the lock unchanged. verify:clean continues checking cache purity around those build/release phases, but not around the verification battery.

                      Repository rule

                      Update AGENTS.md so future changes preserve this invariant. The rule must say that the full verification battery is designed to run concurrently after setup and that tests/build helpers must not rely on repository-wide mutable state that conflicts with another check.

                      The rule supplements the existing command list; it does not weaken any required check or permit skipping a command.

                      Plan gate

                      This is a nontrivial mechanism change. Before code, submit a short plan that identifies:

                      1. the owner and lifetime of dependency layouts used by Deno, pnpm/Node, Bun, lint, and site checks;
                      2. how buildWebClient() stops mutating shared dependency/package paths while preserving the real-bundle and deterministic-output tests;
                      3. how generated bundle and site build outputs are isolated or coordinated without serializing the battery;
                      4. how tracked file mode/content cleanliness is enforced; and
                      5. the regression harness that launches the whole applicable battery concurrently and proves both results and post-run cleanliness.

                      Do not choose product behavior in the implementation plan. The product contract is the concurrent-safety invariant above; the mechanism remains open for review.

                      Acceptance criteria

                      • From a clean checkout after the documented setup, one command or documented harness launches the full applicable battery concurrently and every command passes.
                      • The regression fails against the current shared-node_modules behavior.
                      • Repeated runs are deterministic and leave no tracked content or mode changes, no node_modules changes, and no deno.lock changes; Deno global-cache additions are permitted.
                      • Failure/cancellation coverage proves temporary state is scoped to the invoking command.
                      • Existing CI jobs remain green with Deno 2.9.1, Node 22, and the pinned Bun version.
                      • AGENTS.md records the concurrent-verification rule.
                      • The setup and local verification documentation show the parallel invocation.

                      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

                        No labels
                        No labels

                        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

                          Make the full verification battery safe to run concurrently #279

                          Description

                          @taras

                          Motivation

                          The repository's verification battery is logically independent, but it is not safe to run concurrently in one worktree. That forces local verification to serialize long Deno, Node, and Bun suites even though CI runs them in parallel on separate checkouts.

                          Owner ruling (2026-08-02): the entire applicable verification battery must be safe to launch concurrently in one worktree after setup. This is a repository rule, not an optimization that individual implementors may opt out of.

                          Reproduced failure

                          The current setup is:

                          deno task build:web
                          pnpm install

                          A concurrent local run of the pinned Deno suite with the Node and Bun suites then produced false failures such as:

                          ERR_MODULE_NOT_FOUND: Cannot find package '@effectionx/context-api'
                          ENOENT reading node_modules/@effectionx/converge
                          

                          The same PR head is green in CI because the runtime jobs use separate checkouts.

                          The collision is structural:

                          • The root deno.json uses "nodeModulesDir": "auto".
                          • scripts/build-web-client.ts calls deno install --frozen in the repository root.
                          • deno task test executes scripts/tests/build-web-client.test.ts, which calls buildWebClient() repeatedly.
                          • That Deno install replaces the pnpm-shaped root node_modules while pnpm exec tsc, the Node suite, the Bun suite, lint tools, and spawned tsx processes resolve through it.
                          • buildWebClient() also temporarily patches the fixed path node_modules/@rjsf/validator-ajv8/package.json and writes the fixed generated path packages/web/generated/client-bundle.ts. Concurrent builders can therefore observe one another's temporary manifest state or race restoration/output writes.
                          • The Deno install follows the workspace CLI bin target and changes the tracked mode of packages/cli/src/node.ts from 100644 to 100755, so verification can leave a clean tree dirty even without another runtime running.

                          The first concurrent Node/Bun results are not product failures: they were caused by this shared-state race. Pinned Deno 2.9.1 completed independently with 320 passed and 0 failed.

                          Contract

                          After one documented setup, all applicable commands in the verification battery can be started concurrently from the same worktree:

                          deno task lint
                          deno task check
                          deno task test
                          deno task check:jsr
                          pnpm exec tsc --project tsconfig.node.json --noEmit
                          pnpm test:node
                          bun run test:bun
                          deno task xmd test packages/core/src --raw
                          (cd site && deno task check)
                          (cd site && deno task build)

                          The site commands are applicable when site/ changes, as today. Deno commands run with CI-pinned Deno 2.9.1 on PATH.

                          The invariant is stronger than "the commands usually pass together":

                          • No verification command may install into, remove, relink, patch, chmod, or clean the repository dependency tree or another command's owned paths.
                          • Temporary mutations are isolated per command/process; cleanup from one command cannot overwrite another command's state.
                          • Generated outputs needed by verification remain deterministic, but a fixed generated path must not become a cross-command race.
                          • A successful battery leaves tracked files byte-for-byte and mode-for-mode unchanged.
                          • Failures and cancellation also restore or remove only the invoking command's own temporary state.
                          • CI keeps its independent jobs; this issue fixes local composability rather than collapsing CI into one job.

                          Dependency-cache boundary

                          Owner ruling (2026-08-04): verification does not have a Deno global-cache purity requirement. The runtime-owned cache may gain or refresh locked npm/JSR package content and registry metadata while checks run. Verification must not fingerprint that cache or require it to remain byte-identical.

                          The protected repository state remains strict: verification cannot change node_modules, deno.lock, tracked content or modes, or another invocation's temporary state. Build and release phases retain the separate #304 guarantee: after preparation they run offline and leave both dependency layouts and the lock unchanged. verify:clean continues checking cache purity around those build/release phases, but not around the verification battery.

                          Repository rule

                          Update AGENTS.md so future changes preserve this invariant. The rule must say that the full verification battery is designed to run concurrently after setup and that tests/build helpers must not rely on repository-wide mutable state that conflicts with another check.

                          The rule supplements the existing command list; it does not weaken any required check or permit skipping a command.

                          Plan gate

                          This is a nontrivial mechanism change. Before code, submit a short plan that identifies:

                          1. the owner and lifetime of dependency layouts used by Deno, pnpm/Node, Bun, lint, and site checks;
                          2. how buildWebClient() stops mutating shared dependency/package paths while preserving the real-bundle and deterministic-output tests;
                          3. how generated bundle and site build outputs are isolated or coordinated without serializing the battery;
                          4. how tracked file mode/content cleanliness is enforced; and
                          5. the regression harness that launches the whole applicable battery concurrently and proves both results and post-run cleanliness.

                          Do not choose product behavior in the implementation plan. The product contract is the concurrent-safety invariant above; the mechanism remains open for review.

                          Acceptance criteria

                          • From a clean checkout after the documented setup, one command or documented harness launches the full applicable battery concurrently and every command passes.
                          • The regression fails against the current shared-node_modules behavior.
                          • Repeated runs are deterministic and leave no tracked content or mode changes, no node_modules changes, and no deno.lock changes; Deno global-cache additions are permitted.
                          • Failure/cancellation coverage proves temporary state is scoped to the invoking command.
                          • Existing CI jobs remain green with Deno 2.9.1, Node 22, and the pinned Bun version.
                          • AGENTS.md records the concurrent-verification rule.
                          • The setup and local verification documentation show the parallel invocation.

                          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

                            No labels
                            No labels

                            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

                              Make the full verification battery safe to run concurrently #279

                              Description

                              @taras

                              Motivation

                              The repository's verification battery is logically independent, but it is not safe to run concurrently in one worktree. That forces local verification to serialize long Deno, Node, and Bun suites even though CI runs them in parallel on separate checkouts.

                              Owner ruling (2026-08-02): the entire applicable verification battery must be safe to launch concurrently in one worktree after setup. This is a repository rule, not an optimization that individual implementors may opt out of.

                              Reproduced failure

                              The current setup is:

                              deno task build:web
                              pnpm install

                              A concurrent local run of the pinned Deno suite with the Node and Bun suites then produced false failures such as:

                              ERR_MODULE_NOT_FOUND: Cannot find package '@effectionx/context-api'
                              ENOENT reading node_modules/@effectionx/converge
                              

                              The same PR head is green in CI because the runtime jobs use separate checkouts.

                              The collision is structural:

                              • The root deno.json uses "nodeModulesDir": "auto".
                              • scripts/build-web-client.ts calls deno install --frozen in the repository root.
                              • deno task test executes scripts/tests/build-web-client.test.ts, which calls buildWebClient() repeatedly.
                              • That Deno install replaces the pnpm-shaped root node_modules while pnpm exec tsc, the Node suite, the Bun suite, lint tools, and spawned tsx processes resolve through it.
                              • buildWebClient() also temporarily patches the fixed path node_modules/@rjsf/validator-ajv8/package.json and writes the fixed generated path packages/web/generated/client-bundle.ts. Concurrent builders can therefore observe one another's temporary manifest state or race restoration/output writes.
                              • The Deno install follows the workspace CLI bin target and changes the tracked mode of packages/cli/src/node.ts from 100644 to 100755, so verification can leave a clean tree dirty even without another runtime running.

                              The first concurrent Node/Bun results are not product failures: they were caused by this shared-state race. Pinned Deno 2.9.1 completed independently with 320 passed and 0 failed.

                              Contract

                              After one documented setup, all applicable commands in the verification battery can be started concurrently from the same worktree:

                              deno task lint
                              deno task check
                              deno task test
                              deno task check:jsr
                              pnpm exec tsc --project tsconfig.node.json --noEmit
                              pnpm test:node
                              bun run test:bun
                              deno task xmd test packages/core/src --raw
                              (cd site && deno task check)
                              (cd site && deno task build)

                              The site commands are applicable when site/ changes, as today. Deno commands run with CI-pinned Deno 2.9.1 on PATH.

                              The invariant is stronger than "the commands usually pass together":

                              • No verification command may install into, remove, relink, patch, chmod, or clean the repository dependency tree or another command's owned paths.
                              • Temporary mutations are isolated per command/process; cleanup from one command cannot overwrite another command's state.
                              • Generated outputs needed by verification remain deterministic, but a fixed generated path must not become a cross-command race.
                              • A successful battery leaves tracked files byte-for-byte and mode-for-mode unchanged.
                              • Failures and cancellation also restore or remove only the invoking command's own temporary state.
                              • CI keeps its independent jobs; this issue fixes local composability rather than collapsing CI into one job.

                              Dependency-cache boundary

                              Owner ruling (2026-08-04): verification does not have a Deno global-cache purity requirement. The runtime-owned cache may gain or refresh locked npm/JSR package content and registry metadata while checks run. Verification must not fingerprint that cache or require it to remain byte-identical.

                              The protected repository state remains strict: verification cannot change node_modules, deno.lock, tracked content or modes, or another invocation's temporary state. Build and release phases retain the separate #304 guarantee: after preparation they run offline and leave both dependency layouts and the lock unchanged. verify:clean continues checking cache purity around those build/release phases, but not around the verification battery.

                              Repository rule

                              Update AGENTS.md so future changes preserve this invariant. The rule must say that the full verification battery is designed to run concurrently after setup and that tests/build helpers must not rely on repository-wide mutable state that conflicts with another check.

                              The rule supplements the existing command list; it does not weaken any required check or permit skipping a command.

                              Plan gate

                              This is a nontrivial mechanism change. Before code, submit a short plan that identifies:

                              1. the owner and lifetime of dependency layouts used by Deno, pnpm/Node, Bun, lint, and site checks;
                              2. how buildWebClient() stops mutating shared dependency/package paths while preserving the real-bundle and deterministic-output tests;
                              3. how generated bundle and site build outputs are isolated or coordinated without serializing the battery;
                              4. how tracked file mode/content cleanliness is enforced; and
                              5. the regression harness that launches the whole applicable battery concurrently and proves both results and post-run cleanliness.

                              Do not choose product behavior in the implementation plan. The product contract is the concurrent-safety invariant above; the mechanism remains open for review.

                              Acceptance criteria

                              • From a clean checkout after the documented setup, one command or documented harness launches the full applicable battery concurrently and every command passes.
                              • The regression fails against the current shared-node_modules behavior.
                              • Repeated runs are deterministic and leave no tracked content or mode changes, no node_modules changes, and no deno.lock changes; Deno global-cache additions are permitted.
                              • Failure/cancellation coverage proves temporary state is scoped to the invoking command.
                              • Existing CI jobs remain green with Deno 2.9.1, Node 22, and the pinned Bun version.
                              • AGENTS.md records the concurrent-verification rule.
                              • The setup and local verification documentation show the parallel invocation.

                              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

                                No labels
                                No labels

                                Projects

                                No projects

                                  Milestone

                                  No milestone

                                  Relationships

                                  None yet

                                  Development

                                  No branches or pull requests

                                  Issue actions