Dashboard › craft › Session 0hgDoTjtoxAE
0hgDoTjtoxAEltIn7Perform a final strict READ-ONLY adversarial audit of the complete CURRENT uncommitted diffs and relevant source in BOTH worktrees. Do not edit, format, generate, run mutating commands, or modify git state.
The prior audit returned DO-NOT-MERGE. Recheck these claimed fixed blockers exhaustively:
getReleaseRevision / any API-oriented work. . root allowed; unsafe .., ., __proto__, option-like/empty path segments rejected. Confirm shared validator use and tests.packages/{cli,mcp} must expand; unsafe brace alternatives including relative traversal and absolute paths must fail before filesystem globbing. Audit manual brace-validation parsing for nested/malformed braces, character classes, globstar, negated classes, commas, POSIX consistency, and fail-closed behavior. Verify exact actual glob semantics and schema/runtime alignment.Then audit entire final system: action full workspace title and path/workspace mutual exclusion, pre-side-effect untrusted input validation, ambient workspace clearing, exact post-checkout resolution and missing-root fallback, physical symlink containment, remote config root, CI revision order/fresh ready event, external state isolation/--rev, canonical path-only parser/generation/docs, all regression coverage, no unrelated churn. Be adversarial: failures are blockers. ...
<path>/home/byk/Code/getsentry/craft-workspace-action-propagation</path> <type>directory</type> <entries> .craft.yml .dockerignore .eslintcache .git .github/ .gitignore .lore.md .nojekyll .npmignore .prettierignore .prettierrc.yml .tsbuildinfo .vscode/ action.yml AGENTS.md blog-post-draft.md build.mjs CHANGELOG.md CONTRIBUTING.md dist/ Dockerfile docs/ eslint.config.mjs img/ LICENSE node_modules/ package.json pnpm-lock.yaml README.md src/ tsconfig.build.json tsconfig.json vitest.config.mts (33 entries) </entries>
<path>/home/byk/Code/getsentry/publish-workspace-acceptance</path> <type>directory</type> <entries> .eslintrc.js .git .github/ .gitignore AGENTS.md auto-approve-repos.txt docs/ LICENSE node_modules/ package.json README.md scripts/ src/ vitest.config.js yarn.lock (15 entries) </entries>
## feat/workspace-action-propagation...origin/feat/workspace-action-propagation M action.yml M docs/src/content/docs/targets/github.md M src/__tests__/action.test.ts M src/__tests__/config.test.ts M src/commands/prepare.ts M src/config.ts M src/schemas/project_config.ts M src/utils/__tests__/publishState.test.ts M src/utils/publishState.ts M action.yml M docs/src/content/docs/targets/github.md M src/__tests__/action.test.ts M src/__tests__/config.test.ts M src/commands/prepare.ts M src/config.ts M src/schemas/project_config.ts M src/utils/__tests__/publishState.test.ts M src/utils/publishState.ts
## feat/workspace-acceptance...origin/feat/workspace-acceptance M .github/workflows/publish.yml M docs/publish-issue-format.md M src/modules/__tests__/ci-poller-input.js M src/modules/__tests__/details-from-context.js M src/modules/__tests__/publish-location.js M src/modules/__tests__/publish-workflow.js M src/modules/ci-poller-input.js M src/modules/details-from-context.js M src/modules/publish-issue-title.js M src/modules/publish-issue-title.peggy M src/modules/publish-location.js M src/publish/resolve-location.js ?? ...
<path>/home/byk/Code/getsentry/craft-workspace-action-propagation/AGENTS.md</path> <type>file</type> <content> 1: # AGENTS.md 2: 3: This file provides guidance for AI coding assistants working with the Craft codebase. 4: 5: ## Package Management 6: 7: - **Always use `pnpm`** for package management. Never use `npm` or `yarn`. 8: - Node.js version is managed by [Volta](https://volta.sh/) (currently v22.12.0). 9: - Install dependencies with `pnpm install --frozen-lockfile`. 10: 11: ## Development Commands 12: 13: | Command | Description | 14: | ------------ | ------------------------------------------- | 15: | `pnpm build` | Build the project (outputs to `dist/craft`) | 16: | `pnpm test` | Run tests | 17: | `pnpm lint` | Run ESLint | 18: | `pnpm fix` | Auto-fix lint issues | 19: 20: To manually test changes: 21: 22: ```bash 23: pnpm build && ...
<path>/home/byk/Code/getsentry/publish-workspace-acceptance/AGENTS.md</path> <type>file</type> <content> 1: # AGENTS.md - Coding Agent Guidelines 2: 3: This document provides guidelines for AI coding agents working in this repository. 4: 5: ## Project Overview 6: 7: This is the **Sentry Publish Repository** - a GitHub Actions-based approval system for publishing releases across multiple Sentry projects using [Craft](https://github.com/getsentry/craft). It's a pure JavaScript (Node.js 24.0.0) project using CommonJS modules. 8: 9: ## Build/Lint/Test Commands 10: 11: ### Package Manager 12: 13: - **Yarn 1.22.22** (classic) - Do NOT use npm 14: - Version management via Volta (pinned in package.json) 15: 16: ### Commands 17: 18: ```bash 19: # Install dependencies 20: yarn install 21: 22: # Run all tests 23: yarn test 24: 25: # Run tests in watch mode 26: yarn test:watch 27: 28: # Run a single test file 29: yarn test src/modules/__tests__/update-issue.js 30: 31: # Run tests ...
diff --git a/action.yml b/action.yml
index 94f3158..d160509 100644
--- a/action.yml
+++ b/action.yml
@@ -74,6 +74,7 @@ runs:
- name: Validate workspace
shell: bash
env:
+ LC_ALL: C
PATH_INPUT: ${{ inputs.path }}
WORKSPACE: ${{ inputs.workspace }}
run: |
@@ -81,8 +82,12 @@ runs:
echo "::error::The path and workspace inputs cannot be used together."
exit 1
fi
- if [[ -n "$WORKSPACE" ]] && ! node -e 'process.exit(/^(?!\.{1,2}$)(?!__proto__$)(?!-)[A-Za-z0-9_.-]+$/.test(process.env.WORKSPACE) ? 0 : 1)'; then
- echo "::error::Workspace names must use only ASCII letters, digits, periods, underscores, and hyphens."
+ if ! node -e 'const path = process.env.PATH_INPUT; const segment = /^[A-Za-z0-9_.-]+$/; process.exit(path === "." || (typeof path === "string" && path.split("/").every(name => segment.test(name) && ![".", "..", "__proto__"].includes(name) && !name.startsWith("-"))) ? ...
diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml
index f6dc96a..23c546e 100644
--- a/.github/workflows/publish.yml
+++ b/.github/workflows/publish.yml
@@ -172,12 +172,7 @@ jobs:
PUBLISH_ARGS: ${{ steps.inputs.outputs.result }}
run: |
workspace_names='[]'
- requires_workspace_discovery="$(node -e '
- const { needsWorkspaceDiscovery } = require("./.__publish__/src/modules/publish-location");
- const input = JSON.parse(process.env.PUBLISH_ARGS || "");
- process.stdout.write(String(needsWorkspaceDiscovery(input)));
- ')"
- if [[ "$requires_workspace_discovery" == "true" && -f __repo__/.craft.yml ]]; then
+ if [[ -f __repo__/.craft.yml ]]; then
workspace_names="$(docker run --rm \
--volume "$GITHUB_WORKSPACE/__repo__:/github/workspace/__repo__" \
--workdir /github/workspace/__repo__ \
@@ -224,13 +219,18 @@ jobs:
...
Found 75 matches
/home/byk/Code/getsentry/publish-workspace-acceptance/src/publish/resolve-ci-poller-input.js:
Line 1: const { getCiPollerInput } = require("../modules/ci-poller-input");
Line 5: getCiPollerInput({
/home/byk/Code/getsentry/publish-workspace-acceptance/src/publish/resolve-release-revision.js:
Line 2: const { getReleaseRevision } = require("../modules/release-revision");
Line 8: getReleaseRevision({
/home/byk/Code/getsentry/publish-workspace-acceptance/src/modules/ci-poller-input.js:
Line 3: getReleaseRevision,
Line 4: updateReleaseRevision,
Line 12: function getCiPollerInput({ title, issueBody, revision }) {
Line 30: const currentRevision = getReleaseRevision({ issueBody, repo });
Line 34: ? { issueBody: updateReleaseRevision({ issueBody, repo, revision }) }
Line 42: module.exports = { getCiPollerInput };
/home/byk/Code/getsentry/publish-workspace-acceptance/src/modules/release-revision.js:
Line 5: function ...
<path>/home/byk/Code/getsentry/publish-workspace-acceptance/.github/workflows/ci-poller.yml</path> <type>file</type> <content> 1: name: CI Status Poller 2: 3: on: 4: schedule: 5: - cron: "*/5 * * * *" 6: workflow_dispatch: 7: inputs: 8: attempt: 9: description: Self-dispatch attempt counter (internal use) 10: required: false 11: default: "0" 12: 13: permissions: 14: contents: read 15: issues: read 16: 17: jobs: 18: check-ci: 19: runs-on: ubuntu-latest 20: environment: production 21: # Skip entirely (no runner provisioned) when there's nothing to check. 22: # Set to "true" by ci-pending.yml, reset to "false" here when done. 23: # Always allow workflow_dispatch for manual recovery. 24: if: vars.CI_POLLER_HAS_PENDING == 'true' || github.event_name == 'workflow_dispatch' 25: concurrency: 26: group: ci-status-poller 27: cancel-in-progress: false 28: steps: 29: # sentry-internal-app token ...
<path>/home/byk/Code/getsentry/craft-workspace-action-propagation/action.yml</path>
<type>file</type>
<content>
1: name: 'Craft Prepare Release'
2: description: 'Prepare a new release using Craft'
3:
4: inputs:
5: version:
6: description: >
7: Version to release. Can be a semver string (e.g., "1.2.3"),
8: a bump type ("major", "minor", "patch"), or "auto" for automatic detection.
9: required: false
10: merge_target:
11: description: Target branch to merge into. Uses the default branch as a fallback. ...
<path>/home/byk/Code/getsentry/craft-workspace-action-propagation/action.yml</path>
<type>file</type>
<content>
321: # Build changelog section if available
322: if [[ -n "$CHANGELOG" ]]; then
323: CHANGELOG_SECTION="
324: ---
325:
326: <details open>
327: <summary>📋 Changelog</summary>
328:
329: ${CHANGELOG}
330:
331: </details>"
332: else
333: CHANGELOG_SECTION=""
334: fi
335:
336: body="Requested by: @${GITHUB_ACTOR}
337:
338: Merge target: ${MERGE_TARGET}
339:
340: Quick links:
341: - [View changes](https://github.com/${GITHUB_REPOSITORY}/compare/${RELEASE_PREVIOUS_TAG}...${RELEASE_BRANCH})
342: - [View check runs](https://github.com/${GITHUB_REPOSITORY}/commit/${RELEASE_SHA}/checks/)
343:
344: Assign the **accepted** label to this issue to approve the release. ...
<path>/home/byk/Code/getsentry/craft-workspace-action-propagation/src/utils/publishState.ts</path> <type>file</type> <content> 1: /** 2: * Helpers for locating Craft's publish-state file in a path that is NOT 3: * writable by the repository being published. 4: * 5: * Background: `craft publish` writes a small JSON file listing targets 6: * that have completed so a resumed run can skip them. Before this module 7: * existed, the file lived at `.craft-publish-<version>.json` in the 8: * project's cwd. That path is inside the repository checkout, so any 9: * committed file at the same path (or any earlier CI step) could 10: * pre-populate the "published" set and trick Craft into silently 11: * skipping targets. 12: * 13: * The file now lives under `$XDG_STATE_HOME/craft/` (falling back to 14: * `$HOME/.local/state/craft/`). The filename is keyed on 15: * owner, repo, a hash of cwd (to disambiguate monorepo subpaths), and 16: * the version being published. ...
<path>/home/byk/Code/getsentry/publish-workspace-acceptance/.github/workflows/publish.yml</path>
<type>file</type>
<content>
1: name: Publish
2: on:
3: issues:
4: types: [labeled]
5:
6: concurrency:
7: # Use the issue title (e.g. "publish: getsentry/foo@1.2.3") so duplicate
8: # issues for the same repo@version share a concurrency group.
9: group: ${{ github.event.issue.title }}
10: cancel-in-progress: false
11:
12: permissions:
13: contents: read
14: issues: write
15: packages: write
16:
17: jobs:
18: # When accepted is added to a publish issue:
19: # - Add ci-pending (and remove ci-failed if retrying)
20: # - Enable the poller via CI_POLLER_HAS_PENDING=true
21: # - Comment on the issue
22: # - Trigger the poller immediately so we don't wait for the next cron tick
23: # The publish job below requires ci-ready, so it will not fire until the
24: # poller flips ci-pending → ci-ready (which also prevents publishing without
25: # CI ...
<path>/home/byk/Code/getsentry/publish-workspace-acceptance/src/publish/inputs.js</path>
<type>file</type>
<content>
1: const github = require('@actions/github');
2: const core = require('@actions/core');
3: const { detailsFromContext } = require('../modules/details-from-context');
4:
5: async function inputs() {
6: const result = await detailsFromContext({
7: context: github.context,
8: });
9: core.setOutput('result', result);
10: }
11:
12:
13: inputs();
(End of file - total 13 lines)
</content>
<path>/home/byk/Code/getsentry/publish-workspace-acceptance/src/publish/resolve-ci-poller-input.js</path>
<type>file</type>
<content>
1: const { getCiPollerInput } = require("../modules/ci-poller-input");
2:
3: process.stdout.write(
4: JSON.stringify(
5: getCiPollerInput({
6: issueBody: process.env.PUBLISH_ISSUE_BODY || "",
7: title: process.env.PUBLISH_TITLE || "",
8: revision: process.env.PUBLISH_REVISION || "",
9: })
10: )
11: );
(End of file - total 11 lines)
</content>
<path>/home/byk/Code/getsentry/publish-workspace-acceptance/src/modules/release-revision.js</path>
<type>file</type>
<content>
1: const CHECK_RUNS_LINK =
2: /^Requested by: @[^\r\n]+\r?\n(?:[ \t]*\r?\n)?[ \t]*Merge target: [^\r\n]+\r?\n(?:[ \t]*\r?\n)?[ \t]*Quick links:\r?\n(?:[ \t]*\r?\n)?[ \t]*- \[View changes\]\([^\r\n]+\)\r?\n[ \t]*- \[View check runs\]\(https:\/\/github\.com\/getsentry\/(?<repo>[A-Za-z0-9_.-]+)\/commit\/(?<revision>[0-9a-f]{40})\/checks\/?\)(?=\r?\n|$)/;
3: const CHECK_RUNS_LINK_COUNT = /^[ \t]*- \[View check runs\]\(/gm;
4:
5: function getReleaseRevision({ issueBody, repo }) {
6: if ((issueBody.match(CHECK_RUNS_LINK_COUNT) || []).length !== 1) {
7: throw new Error(
8: `Expected exactly one View check runs link in Quick links for getsentry/${repo}.`
9: );
10: }
11:
12: const match = issueBody.match(CHECK_RUNS_LINK);
13: if (!match?.groups || match.groups.repo !== repo) {
14: throw new Error(
15: `Expected a View check runs link ...
{"pattern":"packages/{cli,mcp}","magic":true,"matches":[]}
{"pattern":"packages/{cli","magic":false,"matches":[]}
{"pattern":"packages/{cli,{mcp}","magic":false,"matches":[]}
{"pattern":"packages/{1..3}","magic":true,"matches":[]}
{"pattern":"packages/[!a]*","magic":true,"matches":[]}
{"pattern":"packages/[^a]*","magic":true,"matches":[]}
{"pattern":"packages/[!]*","magic":true,"matches":[]}
{"pattern":"packages/[a","magic":false,"matches":[]}
{"pattern":"packages/[{]","magic":false,"matches":[]}
{"pattern":"packages/**/cli","magic":true,"matches":[]}
11.1.0
{"pattern":"src/{commands,utils}","matches":["src/commands","src/utils"]}
{"pattern":"src/**/publishState.ts","matches":["src/utils/publishState.ts"]}
{"pattern":"src/[cu]*","matches":["src/commands","src/config.ts","src/utils"]}
node:internal/modules/cjs/loader:1520
throw err;
^
Error: Cannot find module 'minimatch'
Require stack:
- /home/byk/Code/getsentry/craft-workspace-action-propagation/[eval]
at Module._resolveFilename (node:internal/modules/cjs/loader:1517:15)
at wrapResolveFilename (node:internal/modules/cjs/loader:1071:27)
at defaultResolveImplForCJSLoading (node:internal/modules/cjs/loader:1095:10)
at resolveForCJSWithHooks (node:internal/modules/cjs/loader:1122:12)
at Module._load (node:internal/modules/cjs/loader:1294:5)
at wrapModuleLoad (node:internal/modules/cjs/loader:255:19)
at Module.require (node:internal/modules/cjs/loader:1617:12)
at require (node:internal/modules/helpers:153:16)
at [eval]:1:21
at runScriptInThisContext (node:internal/vm:219:10) {
code: 'MODULE_NOT_FOUND',
requireStack: [
'/home/byk/Code/getsentry/craft-workspace-action-propagation/[eval]'
]
}
Node.js v24.18.0
Date: Sep 4, 2026 * 🔴 (15:30) User stated that new Craft requests always include the checkout repository identity. * 🔴 (15:30) User stated that a missing root `.craft.yml` always means checkout-path behavior. * 🔴 (15:30) User stated that the controller never normalizes names. * 🟡 (15:30) Publish workflow change in `.github/workflows/publish.yml`: workspace discovery now runs whenever `__repo_…
Date: Sep 4, 2026 * 🔴 [requested-read-only-audit] (15:28) User requested a final strict read-only adversarial audit of complete current uncommitted diffs and relevant source in both worktrees: `/home/byk/Code/getsentry/craft-workspace-action-propagation` and `/home/byk/Code/getsentry/publish-workspace-acceptance`. User prohibited editing, formatting, generation, mutating commands, and git-state …