Skip to content

patch explainer: patched pages embed a relative path to the deleted temp patched-draft.json (user name on Windows, not reproducible) #1085

Closed

Description

@MBrekhof

What happens

archify patch explainer writes a patched page whose embedded prepared bundle carries inputPath pointing at the temporary patched-draft.json that commandPatch creates and then deletes. The path is stored relative to the output page, so for a page saved outside the temp directory it climbs to the OS temp folder, which on Windows includes the user's profile name. A page delivered without patching carries only sourcePath.

Side effects:

  • the patched page publishes the author's local user name and temp directory layout;
  • the temp directory name is random, so patching the same page with the same replacement twice gives different bytes (the bundle digest covers inputPath).

Reproduced on v3.2.0 (main 25cf370 has the same commandPatch). Windows 11, Node 24.

Minimal repro

In a project directory outside the temp folder, with any formal explainer draft (here branches.archify.md, one panel {#q}):

node archify/bin/archify.mjs deliver explainer branches.archify.md page.html --quality standard
printf '## How does a release branch? {#q}\n\nIt branches on the build result.\n' > repl.md
node archify/bin/archify.mjs patch explainer page.html q repl.md patched.html

The archify-explainer-prepared payload of page.html has "sourcePath":"branches.archify.md". The one in patched.html has the same sourcePath plus:

"inputPath":"..\\..\\..\\..\\..\\..\\Users\\<user>\\AppData\\Local\\Temp\\archify-explainer-patch-0zV7G0\\patched-draft.json"

Expected

The patched page's bundle has the same shape as a delivered page: bound to the original draft (sourcePath), with no reference to the temporary file, so patching is reproducible and publishes no local paths.

Cause

archify/bin/archify.mjs:5333-5334 (commandPatch): the bundle is rebound with inputPath set to the temporary patched-draft.json so that the child deliver accepts it (readPreparedBundle compares bundle.inputPath || bundle.sourcePath with the delivered input). That binding is then written into the page as is. Dropping inputPath (and recomputing the digest) before the page is written, or letting the child accept a bundle bound to the original draft, avoids it.

🤖 Generated with Claude Code

Activity

  1. BlueboxC commented on Oct 24, 2026

    @BlueboxC

    Reproduced on our Archify 3.2.0-based fork at 897cbbf04351bfc75749544cc50eadedfb1e9521. Fixed, packaged and installed in 8b1b702.

    The fix excludes the execution-only inputPath at page serialization and recomputes the published bundle digest. The private temporary-input binding, source identity, byte/digest checks and resource validation remain in place. It also handles pages without a usable original directory without mutating the private bundle.

    Verified:

    • Both new regressions fail before the fix and pass afterward. Repeating the same patch at the same destination produces identical HTML; original inputs remain unchanged.
    • Source/resource origins and frozen assets survive patching after the original files have disappeared. Strict artifact/provenance checking passes.
    • Windows path and missing-origin simulations exclude the temporary profile path; these are simulations, not a native Windows run.
    • 3,477 general-suite passes / 133 conditional skips. The browser gate passed 314 cases; the ten opt-in Explainer cases were then explicitly enabled and all passed, covering 324 distinct Chrome checks.
    • Extracted package and actual installed Skill pass Node 22.23.2 / Node 26.0.0 probes, including real Chrome checks of the patched page and the constrained Workflow case. All 213 managed file hashes/modes were checked; 209 files remain identical.

    Reproduction tests: node --test test/explainer-patch.test.mjs test/explainer-renderer.test.mjs test/explainer-input-publication.test.mjs.

    Existing user HTML is not rewritten. These are local automated results; no human visual review, native Windows qualification or upstream merge approval is implied. No final-head remote CI ran on the fork branch.

    BlueboxC

  2. tt-a1i commented on Oct 25, 2026

    @tt-a1i
    Owner

    Completed on dev through #1090, integrated by #1102 at commit 10b4dd5. Original contribution history is retained.

    Published patched pages omit the private temporary input binding while preserving original origins and recomputing the bundle digest.

    The exact integrated candidate 98efbfc passed CI run 40177166414: 19 successful jobs, no failures, two deployment-only skips. Closing as completed in the development branch; this does not announce a release or a live installation.

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