Dashboard › craft › Distillation
e12bd823-3811-4f7b-9350-cc7fea7401a1["lore_tm_v1_T4eB08ysL8z8SyvXJCZVGwXnRoHs7RRjUmojKzTDdRQ","lore_tm_v1_4qcUQnm8JVteClCoiHAYkeRlVT7ZsIoJI6PwmqIDQqo","lore_tm_v1_zv3ZfWp2CL6tiyb6LMPKXMr22f3o-m_ElgO4Km_PWaM","lore_tm_v1_S7DREU-ILUVtgc7zsYG7S5xZah5AomK8aoJbd1cfYFg","lore_tm_v1_ywEI51FbueO2jFiqwqfARpsQbDz9e0BYXYco_JOamUE","lore_tm_v1_QRxyFdpp6OhO3jpLcaq7nDo6LrgnmEv5uy-HZwZ7VHg","lore_tm_v1_zEjDTWEKIcfU-iLXsKbe5zlpYvRYITY4vWONTDUpeL8"]
Date: Aug 25, 2026
yarn run v1.22.22 / vitest run src/modules/__tests__/details-from-context.js; failed because /bin/sh: 1: vitest: not found, exiting with code 127.SyntaxError: missing ) after argument list / Expected unicode escape under Node.js v24.0.0; the attempted command tested detailsFromContext with a quoted workspace containing escaped quotes, malformed \q, and \u0000./home/byk/Code/getsentry/craft-workspace-action-propagation/src/commands/publish.ts, including import of getPublishStatePath at line 51; publish-state construction, migration warning, state restoration, skipped-target handling, target success recording, and publish completion logic./home/byk/Code/getsentry/craft-workspace-action-propagation/src/commands/publish.ts:660-794. targetsToPublish is initialized from argv.target or [SpecialTarget.All]; combinations of all/none with other targets log an error and return.publish.ts expands workspace targets with expandWorkspaceTargets(config.targets || []), resolves getGlobalGitHubConfig() into publishStateGithubConfig, and deliberately catches resolution errors so getPublishStatePath() falls back to a cwd-hash-only filename under $XDG_STATE_HOME/craft/.publish.ts:697-702 calls getPublishStatePath(newVersion, publishStateGithubConfig, process.cwd(), getActiveWorkspace()); this is Craft’s authoritative state-file identity and includes the active workspace.publish.ts:707-720 detects legacy .craft-publish-${newVersion}.json in the current project directory but never reads it, warning that repository contents are attacker-influenceable via PRs and could pre-populate the “already published” target set; users/workflows must migrate pre-seeded state to $XDG_STATE_HOME/craft/.publish.ts:722-736 resumes from publishStateFile when it exists: reads/parses JSON, resets targetsToPublish to all configured target IDs, then deletes every key in publishState.published, logging each skipped successful target. Without prior state it initializes publishState = { published: Object.create(null) }.publish.ts:765-775 creates dirname(publishStateFile) via idempotent mkdirSync(..., { recursive: true }); after each publishToTarget(target, newVersion, revision), sets publishState.published[BaseTarget.getId(target.config)] = true and writes JSON synchronously with safeFs.writeFileSync(publishStateFile, JSON.stringify(publishState))..github/workflows/publish.yml:199-233 writes state to Craft’s secure XDG location, but failure handling at .github/workflows/publish.yml:293-298 invokes src/modules/update-issue.js, which reads attacker-controlled legacy __repo__/.craft-publish-<version>.json at src/modules/update-issue.js:8-11.publish.ts:707-718) and reads/resumes from the XDG getPublishStatePath() filename (publish.ts:697-702; publishState.ts:89-95), while acceptance action update-issue.js and its test (src/modules/__tests__/update-issue.js:73-81) still use the obsolete legacy path.src/modules/details-from-context.js:25 permits noncanonical workspace paths including . and ..; .github/workflows/publish.yml:213-220 hashes the unnormalized constructed path, while Craft hashes process.cwd() at publish.ts:697-701 / publishState.ts:63-64, after Node canonicalizes the path following workflow cd at publish.yml:244-245./packages/../cli leads workflow hashing /github/workspace/__repo__/packages/../cli, whereas Craft uses /github/workspace/__repo__/cli; the pre-seeded state file is therefore ignored and checked-target resume breaks. This issue also exists on origin/main. Verdict for full filename parity: FAIL.base64 -w 0 | tr '+/' '-_' | tr -d '=' at publish.yml:226-229 matches Buffer.from(workspace).toString('base64url') at publishState.ts:89-91 for tested ASCII, punctuation, and Unicode workspace samples.src/modules/details-from-context.js:25 accepts JSON-escaped controls, but validation at :35-40 rejects only CR/LF. Example [workspace: "\u0000"] parses successfully; NUL/control values are unsafe as GitHub Actions environment values or Craft workspace identifiers. Verdict: FAIL dangerous-string fail-closed requirement.[^/@]+, whereas new parser at src/modules/details-from-context.js:25 accepts only [A-Za-z0-9_.-]+. This is safer and covers valid GitHub repository names but is not exact accepted-language compatibility for legacy titles. Verdict: FAIL literal legacy grammar compatibility.publish: repo/path [workspace: <JSON string>] @version at craft .../action.yml:258-265, parser accepts that grammar at details-from-context.js:25, absent workspace emits no workspace property at :71, and an empty workspace prefix preserves the old state filename at publish.yml:225-231.JSON.parse and malformed/missing wrappers fail regex; FAIL dangerous workspace strings; PASS shell/YAML injection because workspace is supplied via env rather than interpolated run (publish.yml:193,255), Bash expands it quoted at :226-228, and filenames Base64URL-encode it.publish.yml:108-114 and still requiring ci-ready, accepted, and no pending/failed label; PASS issue concurrency identity because the complete issue title remains the concurrency group (publish.yml:6-10) and workspace titles differ; PASS dry run because propagation to CRAFT_DRY_RUN remains at publish.yml:254 and Craft treats "1" as true; FAIL workspace resume isolation due to obsolete failure-state reader and noncanonical path hashing.yarn test src/modules/__tests__/details-from-context.js could not run because vitest was unavailable; git diff --check passed; manual parser and Base64URL parity checks passed.