🐛 <TempDir> turns <Output> failures into success and continues later effects #445

Description

@taras

Problem

A wrapping <TempDir> silently changes the failure semantics of an enclosing
<Output> region. An ordinary failure inside the temporary directory becomes a
printed error, expansion continues both inside and after <TempDir>, the content
rendered around the failure is discarded, and the document completes
successfully.

That defeats <Output>'s fail-closed contract. In an operational document, a
failed preview inside <TempDir> can therefore be followed by an elicitation or
an external mutation such as publish.

This blocks the Markdown-first npm bootstrap in #276 / #308. Nesting every later
step behind another <If> is not a safe substitute: a future sibling silently
reopens the path, and the failed stage's stdout and rendered refusal remain
unavailable.

Reproduction

Reproduced from source at main commit
a1c196c18cd766267a9398348422517abad08cb3:

<Output>
<TempDir>
```bash exec
echo FIRST >> /tmp/xmd-tempdir-trace
echo stdout-of-failing
exit 1
```
TEXT-AFTER-FAILURE
```bash exec
echo SECOND >> /tmp/xmd-tempdir-trace
```
</TempDir>
```bash exec
echo OUTER >> /tmp/xmd-tempdir-trace
```
</Output>

Run with:

deno task xmd run /tmp/tempdir-failure-repro.md --raw --no-secret-detection

Observed result:

  • exit status is 0;
  • rendered output is only one <!-- ERROR: Command failed (exit 1) ... -->;
  • stdout-of-failing and TEXT-AFTER-FAILURE are absent;
  • /tmp/xmd-tempdir-trace contains FIRST, SECOND, and OUTER.

Replacing <TempDir> with <If condition={true}> is the control. It exits 1,
preserves stdout-of-failing, and the trace contains only FIRST.

Contract conflict

#309 made continuation after an ordinary failure explicit and scope-local; the
current vocabulary is <PrintErrors> / printErrors(fn). <TempDir> declares
printErrors(...) internally, so merely asking for a working directory opts the
author into recovery without an explicit capture boundary.

The resulting behavior conflicts with specs/executable-mdx-spec.md §6.9:

  • an error in an <Output> region fails the run;
  • nothing after it begins; and
  • a failing visible region preserves what it rendered before the failure.

There is an uncovered interaction with §6.11 and TD14. They preserve the older
rule that an ordinary <TempDir> failure is printable under the root's default
printing mode, but do not cover <TempDir> inside <Output>. The fix must make
the precedence explicit and update §6.11 rather than leaving contradictory
general statements.

The implementation path is visible in
packages/core/src/components/TempDir.ts: wrapping form calls content() from a
component marked with printErrors. The projection runs to completion under
the printing boundary, then ContentExpansionFailure replaces the projection
with only its error segment, accounting for both continuation and lost output.

Required behavior

  • <TempDir> changes the contextual working directory and owns cleanup; it does
    not implicitly opt its content into failure recovery.
  • Inside <Output>, the first ordinary failure in a wrapping <TempDir>:
    • preserves visible output produced before and by the failing command;
    • fails the document;
    • prevents later content inside <TempDir> from starting; and
    • prevents siblings after <TempDir> from starting.
  • An author can still request continuation explicitly with <PrintErrors> at
    the intended scope.
  • Temporary-directory cleanup still completes on success, failure, and
    cancellation.
  • Root documents without <Output> retain their documented default printing
    behavior unless an explicit architecture amendment says otherwise.
  • Add a regression that asserts exit outcome, rendered prefix, an internal
    side-effect probe, an external sibling probe, and cleanup. Keep the <If>
    control or an equivalent discriminating case.
  • Update specs/executable-mdx-spec.md §6.9 and §6.11 together with the fix.

Related work

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

      🐛 <TempDir> turns <Output> failures into success and continues later effects #445

      Description

      @taras

      Problem

      A wrapping <TempDir> silently changes the failure semantics of an enclosing
      <Output> region. An ordinary failure inside the temporary directory becomes a
      printed error, expansion continues both inside and after <TempDir>, the content
      rendered around the failure is discarded, and the document completes
      successfully.

      That defeats <Output>'s fail-closed contract. In an operational document, a
      failed preview inside <TempDir> can therefore be followed by an elicitation or
      an external mutation such as publish.

      This blocks the Markdown-first npm bootstrap in #276 / #308. Nesting every later
      step behind another <If> is not a safe substitute: a future sibling silently
      reopens the path, and the failed stage's stdout and rendered refusal remain
      unavailable.

      Reproduction

      Reproduced from source at main commit
      a1c196c18cd766267a9398348422517abad08cb3:

      <Output>
      <TempDir>
      ```bash exec
      echo FIRST >> /tmp/xmd-tempdir-trace
      echo stdout-of-failing
      exit 1
      ```
      TEXT-AFTER-FAILURE
      ```bash exec
      echo SECOND >> /tmp/xmd-tempdir-trace
      ```
      </TempDir>
      ```bash exec
      echo OUTER >> /tmp/xmd-tempdir-trace
      ```
      </Output>

      Run with:

      deno task xmd run /tmp/tempdir-failure-repro.md --raw --no-secret-detection

      Observed result:

      • exit status is 0;
      • rendered output is only one <!-- ERROR: Command failed (exit 1) ... -->;
      • stdout-of-failing and TEXT-AFTER-FAILURE are absent;
      • /tmp/xmd-tempdir-trace contains FIRST, SECOND, and OUTER.

      Replacing <TempDir> with <If condition={true}> is the control. It exits 1,
      preserves stdout-of-failing, and the trace contains only FIRST.

      Contract conflict

      #309 made continuation after an ordinary failure explicit and scope-local; the
      current vocabulary is <PrintErrors> / printErrors(fn). <TempDir> declares
      printErrors(...) internally, so merely asking for a working directory opts the
      author into recovery without an explicit capture boundary.

      The resulting behavior conflicts with specs/executable-mdx-spec.md §6.9:

      • an error in an <Output> region fails the run;
      • nothing after it begins; and
      • a failing visible region preserves what it rendered before the failure.

      There is an uncovered interaction with §6.11 and TD14. They preserve the older
      rule that an ordinary <TempDir> failure is printable under the root's default
      printing mode, but do not cover <TempDir> inside <Output>. The fix must make
      the precedence explicit and update §6.11 rather than leaving contradictory
      general statements.

      The implementation path is visible in
      packages/core/src/components/TempDir.ts: wrapping form calls content() from a
      component marked with printErrors. The projection runs to completion under
      the printing boundary, then ContentExpansionFailure replaces the projection
      with only its error segment, accounting for both continuation and lost output.

      Required behavior

      • <TempDir> changes the contextual working directory and owns cleanup; it does
        not implicitly opt its content into failure recovery.
      • Inside <Output>, the first ordinary failure in a wrapping <TempDir>:
        • preserves visible output produced before and by the failing command;
        • fails the document;
        • prevents later content inside <TempDir> from starting; and
        • prevents siblings after <TempDir> from starting.
      • An author can still request continuation explicitly with <PrintErrors> at
        the intended scope.
      • Temporary-directory cleanup still completes on success, failure, and
        cancellation.
      • Root documents without <Output> retain their documented default printing
        behavior unless an explicit architecture amendment says otherwise.
      • Add a regression that asserts exit outcome, rendered prefix, an internal
        side-effect probe, an external sibling probe, and cleanup. Keep the <If>
        control or an equivalent discriminating case.
      • Update specs/executable-mdx-spec.md §6.9 and §6.11 together with the fix.

      Related work

      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

          🐛 <TempDir> turns <Output> failures into success and continues later effects #445

          Description

          @taras

          Problem

          A wrapping <TempDir> silently changes the failure semantics of an enclosing
          <Output> region. An ordinary failure inside the temporary directory becomes a
          printed error, expansion continues both inside and after <TempDir>, the content
          rendered around the failure is discarded, and the document completes
          successfully.

          That defeats <Output>'s fail-closed contract. In an operational document, a
          failed preview inside <TempDir> can therefore be followed by an elicitation or
          an external mutation such as publish.

          This blocks the Markdown-first npm bootstrap in #276 / #308. Nesting every later
          step behind another <If> is not a safe substitute: a future sibling silently
          reopens the path, and the failed stage's stdout and rendered refusal remain
          unavailable.

          Reproduction

          Reproduced from source at main commit
          a1c196c18cd766267a9398348422517abad08cb3:

          <Output>
          <TempDir>
          ```bash exec
          echo FIRST >> /tmp/xmd-tempdir-trace
          echo stdout-of-failing
          exit 1
          ```
          TEXT-AFTER-FAILURE
          ```bash exec
          echo SECOND >> /tmp/xmd-tempdir-trace
          ```
          </TempDir>
          ```bash exec
          echo OUTER >> /tmp/xmd-tempdir-trace
          ```
          </Output>

          Run with:

          deno task xmd run /tmp/tempdir-failure-repro.md --raw --no-secret-detection

          Observed result:

          • exit status is 0;
          • rendered output is only one <!-- ERROR: Command failed (exit 1) ... -->;
          • stdout-of-failing and TEXT-AFTER-FAILURE are absent;
          • /tmp/xmd-tempdir-trace contains FIRST, SECOND, and OUTER.

          Replacing <TempDir> with <If condition={true}> is the control. It exits 1,
          preserves stdout-of-failing, and the trace contains only FIRST.

          Contract conflict

          #309 made continuation after an ordinary failure explicit and scope-local; the
          current vocabulary is <PrintErrors> / printErrors(fn). <TempDir> declares
          printErrors(...) internally, so merely asking for a working directory opts the
          author into recovery without an explicit capture boundary.

          The resulting behavior conflicts with specs/executable-mdx-spec.md §6.9:

          • an error in an <Output> region fails the run;
          • nothing after it begins; and
          • a failing visible region preserves what it rendered before the failure.

          There is an uncovered interaction with §6.11 and TD14. They preserve the older
          rule that an ordinary <TempDir> failure is printable under the root's default
          printing mode, but do not cover <TempDir> inside <Output>. The fix must make
          the precedence explicit and update §6.11 rather than leaving contradictory
          general statements.

          The implementation path is visible in
          packages/core/src/components/TempDir.ts: wrapping form calls content() from a
          component marked with printErrors. The projection runs to completion under
          the printing boundary, then ContentExpansionFailure replaces the projection
          with only its error segment, accounting for both continuation and lost output.

          Required behavior

          • <TempDir> changes the contextual working directory and owns cleanup; it does
            not implicitly opt its content into failure recovery.
          • Inside <Output>, the first ordinary failure in a wrapping <TempDir>:
            • preserves visible output produced before and by the failing command;
            • fails the document;
            • prevents later content inside <TempDir> from starting; and
            • prevents siblings after <TempDir> from starting.
          • An author can still request continuation explicitly with <PrintErrors> at
            the intended scope.
          • Temporary-directory cleanup still completes on success, failure, and
            cancellation.
          • Root documents without <Output> retain their documented default printing
            behavior unless an explicit architecture amendment says otherwise.
          • Add a regression that asserts exit outcome, rendered prefix, an internal
            side-effect probe, an external sibling probe, and cleanup. Keep the <If>
            control or an equivalent discriminating case.
          • Update specs/executable-mdx-spec.md §6.9 and §6.11 together with the fix.

          Related work

          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

              🐛 <TempDir> turns <Output> failures into success and continues later effects #445

              Description

              @taras

              Problem

              A wrapping <TempDir> silently changes the failure semantics of an enclosing
              <Output> region. An ordinary failure inside the temporary directory becomes a
              printed error, expansion continues both inside and after <TempDir>, the content
              rendered around the failure is discarded, and the document completes
              successfully.

              That defeats <Output>'s fail-closed contract. In an operational document, a
              failed preview inside <TempDir> can therefore be followed by an elicitation or
              an external mutation such as publish.

              This blocks the Markdown-first npm bootstrap in #276 / #308. Nesting every later
              step behind another <If> is not a safe substitute: a future sibling silently
              reopens the path, and the failed stage's stdout and rendered refusal remain
              unavailable.

              Reproduction

              Reproduced from source at main commit
              a1c196c18cd766267a9398348422517abad08cb3:

              <Output>
              <TempDir>
              ```bash exec
              echo FIRST >> /tmp/xmd-tempdir-trace
              echo stdout-of-failing
              exit 1
              ```
              TEXT-AFTER-FAILURE
              ```bash exec
              echo SECOND >> /tmp/xmd-tempdir-trace
              ```
              </TempDir>
              ```bash exec
              echo OUTER >> /tmp/xmd-tempdir-trace
              ```
              </Output>

              Run with:

              deno task xmd run /tmp/tempdir-failure-repro.md --raw --no-secret-detection

              Observed result:

              • exit status is 0;
              • rendered output is only one <!-- ERROR: Command failed (exit 1) ... -->;
              • stdout-of-failing and TEXT-AFTER-FAILURE are absent;
              • /tmp/xmd-tempdir-trace contains FIRST, SECOND, and OUTER.

              Replacing <TempDir> with <If condition={true}> is the control. It exits 1,
              preserves stdout-of-failing, and the trace contains only FIRST.

              Contract conflict

              #309 made continuation after an ordinary failure explicit and scope-local; the
              current vocabulary is <PrintErrors> / printErrors(fn). <TempDir> declares
              printErrors(...) internally, so merely asking for a working directory opts the
              author into recovery without an explicit capture boundary.

              The resulting behavior conflicts with specs/executable-mdx-spec.md §6.9:

              • an error in an <Output> region fails the run;
              • nothing after it begins; and
              • a failing visible region preserves what it rendered before the failure.

              There is an uncovered interaction with §6.11 and TD14. They preserve the older
              rule that an ordinary <TempDir> failure is printable under the root's default
              printing mode, but do not cover <TempDir> inside <Output>. The fix must make
              the precedence explicit and update §6.11 rather than leaving contradictory
              general statements.

              The implementation path is visible in
              packages/core/src/components/TempDir.ts: wrapping form calls content() from a
              component marked with printErrors. The projection runs to completion under
              the printing boundary, then ContentExpansionFailure replaces the projection
              with only its error segment, accounting for both continuation and lost output.

              Required behavior

              • <TempDir> changes the contextual working directory and owns cleanup; it does
                not implicitly opt its content into failure recovery.
              • Inside <Output>, the first ordinary failure in a wrapping <TempDir>:
                • preserves visible output produced before and by the failing command;
                • fails the document;
                • prevents later content inside <TempDir> from starting; and
                • prevents siblings after <TempDir> from starting.
              • An author can still request continuation explicitly with <PrintErrors> at
                the intended scope.
              • Temporary-directory cleanup still completes on success, failure, and
                cancellation.
              • Root documents without <Output> retain their documented default printing
                behavior unless an explicit architecture amendment says otherwise.
              • Add a regression that asserts exit outcome, rendered prefix, an internal
                side-effect probe, an external sibling probe, and cleanup. Keep the <If>
                control or an equivalent discriminating case.
              • Update specs/executable-mdx-spec.md §6.9 and §6.11 together with the fix.

              Related work

              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

                  🐛 <TempDir> turns <Output> failures into success and continues later effects #445

                  Description

                  @taras

                  Problem

                  A wrapping <TempDir> silently changes the failure semantics of an enclosing
                  <Output> region. An ordinary failure inside the temporary directory becomes a
                  printed error, expansion continues both inside and after <TempDir>, the content
                  rendered around the failure is discarded, and the document completes
                  successfully.

                  That defeats <Output>'s fail-closed contract. In an operational document, a
                  failed preview inside <TempDir> can therefore be followed by an elicitation or
                  an external mutation such as publish.

                  This blocks the Markdown-first npm bootstrap in #276 / #308. Nesting every later
                  step behind another <If> is not a safe substitute: a future sibling silently
                  reopens the path, and the failed stage's stdout and rendered refusal remain
                  unavailable.

                  Reproduction

                  Reproduced from source at main commit
                  a1c196c18cd766267a9398348422517abad08cb3:

                  <Output>
                  <TempDir>
                  ```bash exec
                  echo FIRST >> /tmp/xmd-tempdir-trace
                  echo stdout-of-failing
                  exit 1
                  ```
                  TEXT-AFTER-FAILURE
                  ```bash exec
                  echo SECOND >> /tmp/xmd-tempdir-trace
                  ```
                  </TempDir>
                  ```bash exec
                  echo OUTER >> /tmp/xmd-tempdir-trace
                  ```
                  </Output>

                  Run with:

                  deno task xmd run /tmp/tempdir-failure-repro.md --raw --no-secret-detection

                  Observed result:

                  • exit status is 0;
                  • rendered output is only one <!-- ERROR: Command failed (exit 1) ... -->;
                  • stdout-of-failing and TEXT-AFTER-FAILURE are absent;
                  • /tmp/xmd-tempdir-trace contains FIRST, SECOND, and OUTER.

                  Replacing <TempDir> with <If condition={true}> is the control. It exits 1,
                  preserves stdout-of-failing, and the trace contains only FIRST.

                  Contract conflict

                  #309 made continuation after an ordinary failure explicit and scope-local; the
                  current vocabulary is <PrintErrors> / printErrors(fn). <TempDir> declares
                  printErrors(...) internally, so merely asking for a working directory opts the
                  author into recovery without an explicit capture boundary.

                  The resulting behavior conflicts with specs/executable-mdx-spec.md §6.9:

                  • an error in an <Output> region fails the run;
                  • nothing after it begins; and
                  • a failing visible region preserves what it rendered before the failure.

                  There is an uncovered interaction with §6.11 and TD14. They preserve the older
                  rule that an ordinary <TempDir> failure is printable under the root's default
                  printing mode, but do not cover <TempDir> inside <Output>. The fix must make
                  the precedence explicit and update §6.11 rather than leaving contradictory
                  general statements.

                  The implementation path is visible in
                  packages/core/src/components/TempDir.ts: wrapping form calls content() from a
                  component marked with printErrors. The projection runs to completion under
                  the printing boundary, then ContentExpansionFailure replaces the projection
                  with only its error segment, accounting for both continuation and lost output.

                  Required behavior

                  • <TempDir> changes the contextual working directory and owns cleanup; it does
                    not implicitly opt its content into failure recovery.
                  • Inside <Output>, the first ordinary failure in a wrapping <TempDir>:
                    • preserves visible output produced before and by the failing command;
                    • fails the document;
                    • prevents later content inside <TempDir> from starting; and
                    • prevents siblings after <TempDir> from starting.
                  • An author can still request continuation explicitly with <PrintErrors> at
                    the intended scope.
                  • Temporary-directory cleanup still completes on success, failure, and
                    cancellation.
                  • Root documents without <Output> retain their documented default printing
                    behavior unless an explicit architecture amendment says otherwise.
                  • Add a regression that asserts exit outcome, rendered prefix, an internal
                    side-effect probe, an external sibling probe, and cleanup. Keep the <If>
                    control or an equivalent discriminating case.
                  • Update specs/executable-mdx-spec.md §6.9 and §6.11 together with the fix.

                  Related work

                  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

                      🐛 <TempDir> turns <Output> failures into success and continues later effects #445

                      Description

                      @taras

                      Problem

                      A wrapping <TempDir> silently changes the failure semantics of an enclosing
                      <Output> region. An ordinary failure inside the temporary directory becomes a
                      printed error, expansion continues both inside and after <TempDir>, the content
                      rendered around the failure is discarded, and the document completes
                      successfully.

                      That defeats <Output>'s fail-closed contract. In an operational document, a
                      failed preview inside <TempDir> can therefore be followed by an elicitation or
                      an external mutation such as publish.

                      This blocks the Markdown-first npm bootstrap in #276 / #308. Nesting every later
                      step behind another <If> is not a safe substitute: a future sibling silently
                      reopens the path, and the failed stage's stdout and rendered refusal remain
                      unavailable.

                      Reproduction

                      Reproduced from source at main commit
                      a1c196c18cd766267a9398348422517abad08cb3:

                      <Output>
                      <TempDir>
                      ```bash exec
                      echo FIRST >> /tmp/xmd-tempdir-trace
                      echo stdout-of-failing
                      exit 1
                      ```
                      TEXT-AFTER-FAILURE
                      ```bash exec
                      echo SECOND >> /tmp/xmd-tempdir-trace
                      ```
                      </TempDir>
                      ```bash exec
                      echo OUTER >> /tmp/xmd-tempdir-trace
                      ```
                      </Output>

                      Run with:

                      deno task xmd run /tmp/tempdir-failure-repro.md --raw --no-secret-detection

                      Observed result:

                      • exit status is 0;
                      • rendered output is only one <!-- ERROR: Command failed (exit 1) ... -->;
                      • stdout-of-failing and TEXT-AFTER-FAILURE are absent;
                      • /tmp/xmd-tempdir-trace contains FIRST, SECOND, and OUTER.

                      Replacing <TempDir> with <If condition={true}> is the control. It exits 1,
                      preserves stdout-of-failing, and the trace contains only FIRST.

                      Contract conflict

                      #309 made continuation after an ordinary failure explicit and scope-local; the
                      current vocabulary is <PrintErrors> / printErrors(fn). <TempDir> declares
                      printErrors(...) internally, so merely asking for a working directory opts the
                      author into recovery without an explicit capture boundary.

                      The resulting behavior conflicts with specs/executable-mdx-spec.md §6.9:

                      • an error in an <Output> region fails the run;
                      • nothing after it begins; and
                      • a failing visible region preserves what it rendered before the failure.

                      There is an uncovered interaction with §6.11 and TD14. They preserve the older
                      rule that an ordinary <TempDir> failure is printable under the root's default
                      printing mode, but do not cover <TempDir> inside <Output>. The fix must make
                      the precedence explicit and update §6.11 rather than leaving contradictory
                      general statements.

                      The implementation path is visible in
                      packages/core/src/components/TempDir.ts: wrapping form calls content() from a
                      component marked with printErrors. The projection runs to completion under
                      the printing boundary, then ContentExpansionFailure replaces the projection
                      with only its error segment, accounting for both continuation and lost output.

                      Required behavior

                      • <TempDir> changes the contextual working directory and owns cleanup; it does
                        not implicitly opt its content into failure recovery.
                      • Inside <Output>, the first ordinary failure in a wrapping <TempDir>:
                        • preserves visible output produced before and by the failing command;
                        • fails the document;
                        • prevents later content inside <TempDir> from starting; and
                        • prevents siblings after <TempDir> from starting.
                      • An author can still request continuation explicitly with <PrintErrors> at
                        the intended scope.
                      • Temporary-directory cleanup still completes on success, failure, and
                        cancellation.
                      • Root documents without <Output> retain their documented default printing
                        behavior unless an explicit architecture amendment says otherwise.
                      • Add a regression that asserts exit outcome, rendered prefix, an internal
                        side-effect probe, an external sibling probe, and cleanup. Keep the <If>
                        control or an equivalent discriminating case.
                      • Update specs/executable-mdx-spec.md §6.9 and §6.11 together with the fix.

                      Related work

                      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

                          🐛 <TempDir> turns <Output> failures into success and continues later effects #445

                          Description

                          @taras

                          Problem

                          A wrapping <TempDir> silently changes the failure semantics of an enclosing
                          <Output> region. An ordinary failure inside the temporary directory becomes a
                          printed error, expansion continues both inside and after <TempDir>, the content
                          rendered around the failure is discarded, and the document completes
                          successfully.

                          That defeats <Output>'s fail-closed contract. In an operational document, a
                          failed preview inside <TempDir> can therefore be followed by an elicitation or
                          an external mutation such as publish.

                          This blocks the Markdown-first npm bootstrap in #276 / #308. Nesting every later
                          step behind another <If> is not a safe substitute: a future sibling silently
                          reopens the path, and the failed stage's stdout and rendered refusal remain
                          unavailable.

                          Reproduction

                          Reproduced from source at main commit
                          a1c196c18cd766267a9398348422517abad08cb3:

                          <Output>
                          <TempDir>
                          ```bash exec
                          echo FIRST >> /tmp/xmd-tempdir-trace
                          echo stdout-of-failing
                          exit 1
                          ```
                          TEXT-AFTER-FAILURE
                          ```bash exec
                          echo SECOND >> /tmp/xmd-tempdir-trace
                          ```
                          </TempDir>
                          ```bash exec
                          echo OUTER >> /tmp/xmd-tempdir-trace
                          ```
                          </Output>

                          Run with:

                          deno task xmd run /tmp/tempdir-failure-repro.md --raw --no-secret-detection

                          Observed result:

                          • exit status is 0;
                          • rendered output is only one <!-- ERROR: Command failed (exit 1) ... -->;
                          • stdout-of-failing and TEXT-AFTER-FAILURE are absent;
                          • /tmp/xmd-tempdir-trace contains FIRST, SECOND, and OUTER.

                          Replacing <TempDir> with <If condition={true}> is the control. It exits 1,
                          preserves stdout-of-failing, and the trace contains only FIRST.

                          Contract conflict

                          #309 made continuation after an ordinary failure explicit and scope-local; the
                          current vocabulary is <PrintErrors> / printErrors(fn). <TempDir> declares
                          printErrors(...) internally, so merely asking for a working directory opts the
                          author into recovery without an explicit capture boundary.

                          The resulting behavior conflicts with specs/executable-mdx-spec.md §6.9:

                          • an error in an <Output> region fails the run;
                          • nothing after it begins; and
                          • a failing visible region preserves what it rendered before the failure.

                          There is an uncovered interaction with §6.11 and TD14. They preserve the older
                          rule that an ordinary <TempDir> failure is printable under the root's default
                          printing mode, but do not cover <TempDir> inside <Output>. The fix must make
                          the precedence explicit and update §6.11 rather than leaving contradictory
                          general statements.

                          The implementation path is visible in
                          packages/core/src/components/TempDir.ts: wrapping form calls content() from a
                          component marked with printErrors. The projection runs to completion under
                          the printing boundary, then ContentExpansionFailure replaces the projection
                          with only its error segment, accounting for both continuation and lost output.

                          Required behavior

                          • <TempDir> changes the contextual working directory and owns cleanup; it does
                            not implicitly opt its content into failure recovery.
                          • Inside <Output>, the first ordinary failure in a wrapping <TempDir>:
                            • preserves visible output produced before and by the failing command;
                            • fails the document;
                            • prevents later content inside <TempDir> from starting; and
                            • prevents siblings after <TempDir> from starting.
                          • An author can still request continuation explicitly with <PrintErrors> at
                            the intended scope.
                          • Temporary-directory cleanup still completes on success, failure, and
                            cancellation.
                          • Root documents without <Output> retain their documented default printing
                            behavior unless an explicit architecture amendment says otherwise.
                          • Add a regression that asserts exit outcome, rendered prefix, an internal
                            side-effect probe, an external sibling probe, and cleanup. Keep the <If>
                            control or an equivalent discriminating case.
                          • Update specs/executable-mdx-spec.md §6.9 and §6.11 together with the fix.

                          Related work

                          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

                              🐛 <TempDir> turns <Output> failures into success and continues later effects #445

                              Description

                              @taras

                              Problem

                              A wrapping <TempDir> silently changes the failure semantics of an enclosing
                              <Output> region. An ordinary failure inside the temporary directory becomes a
                              printed error, expansion continues both inside and after <TempDir>, the content
                              rendered around the failure is discarded, and the document completes
                              successfully.

                              That defeats <Output>'s fail-closed contract. In an operational document, a
                              failed preview inside <TempDir> can therefore be followed by an elicitation or
                              an external mutation such as publish.

                              This blocks the Markdown-first npm bootstrap in #276 / #308. Nesting every later
                              step behind another <If> is not a safe substitute: a future sibling silently
                              reopens the path, and the failed stage's stdout and rendered refusal remain
                              unavailable.

                              Reproduction

                              Reproduced from source at main commit
                              a1c196c18cd766267a9398348422517abad08cb3:

                              <Output>
                              <TempDir>
                              ```bash exec
                              echo FIRST >> /tmp/xmd-tempdir-trace
                              echo stdout-of-failing
                              exit 1
                              ```
                              TEXT-AFTER-FAILURE
                              ```bash exec
                              echo SECOND >> /tmp/xmd-tempdir-trace
                              ```
                              </TempDir>
                              ```bash exec
                              echo OUTER >> /tmp/xmd-tempdir-trace
                              ```
                              </Output>

                              Run with:

                              deno task xmd run /tmp/tempdir-failure-repro.md --raw --no-secret-detection

                              Observed result:

                              • exit status is 0;
                              • rendered output is only one <!-- ERROR: Command failed (exit 1) ... -->;
                              • stdout-of-failing and TEXT-AFTER-FAILURE are absent;
                              • /tmp/xmd-tempdir-trace contains FIRST, SECOND, and OUTER.

                              Replacing <TempDir> with <If condition={true}> is the control. It exits 1,
                              preserves stdout-of-failing, and the trace contains only FIRST.

                              Contract conflict

                              #309 made continuation after an ordinary failure explicit and scope-local; the
                              current vocabulary is <PrintErrors> / printErrors(fn). <TempDir> declares
                              printErrors(...) internally, so merely asking for a working directory opts the
                              author into recovery without an explicit capture boundary.

                              The resulting behavior conflicts with specs/executable-mdx-spec.md §6.9:

                              • an error in an <Output> region fails the run;
                              • nothing after it begins; and
                              • a failing visible region preserves what it rendered before the failure.

                              There is an uncovered interaction with §6.11 and TD14. They preserve the older
                              rule that an ordinary <TempDir> failure is printable under the root's default
                              printing mode, but do not cover <TempDir> inside <Output>. The fix must make
                              the precedence explicit and update §6.11 rather than leaving contradictory
                              general statements.

                              The implementation path is visible in
                              packages/core/src/components/TempDir.ts: wrapping form calls content() from a
                              component marked with printErrors. The projection runs to completion under
                              the printing boundary, then ContentExpansionFailure replaces the projection
                              with only its error segment, accounting for both continuation and lost output.

                              Required behavior

                              • <TempDir> changes the contextual working directory and owns cleanup; it does
                                not implicitly opt its content into failure recovery.
                              • Inside <Output>, the first ordinary failure in a wrapping <TempDir>:
                                • preserves visible output produced before and by the failing command;
                                • fails the document;
                                • prevents later content inside <TempDir> from starting; and
                                • prevents siblings after <TempDir> from starting.
                              • An author can still request continuation explicitly with <PrintErrors> at
                                the intended scope.
                              • Temporary-directory cleanup still completes on success, failure, and
                                cancellation.
                              • Root documents without <Output> retain their documented default printing
                                behavior unless an explicit architecture amendment says otherwise.
                              • Add a regression that asserts exit outcome, rendered prefix, an internal
                                side-effect probe, an external sibling probe, and cleanup. Keep the <If>
                                control or an equivalent discriminating case.
                              • Update specs/executable-mdx-spec.md §6.9 and §6.11 together with the fix.

                              Related work

                              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