Dashboard › craft › Distillation
c774a447-9a27-4b91-a47a-8eebab0bc851["lore_tm_v1_Gv-DAZvkr_jUuSlmbjImX6Ie1avHyFYh2nBncpiEgZE","lore_tm_v1_FU7qOUdYeRAD4cU_Xx2nkkX6EXfOwi8bDKpbQBZDldI","lore_tm_v1_YMf6J7_3QOD1QJiXOalQqqKhXtHSl2O04chKYaAD1qs","lore_tm_v1_A_W8Emm47aS5cOjUXnFLrRW3xrLEHL4J5SMxkla9fP0","lore_tm_v1_dEQEMMwZFECQGSffmjixBJwDWVPEvWtUzBKd5RRhO00","lore_tm_v1_rldQ8E9qpfZAGeiLN9eRa32fk6H5H6Z8gLigmAaI5nc","lore_tm_v1_YvBiYuZ-pkGdkd0rvWib79xPSlFqZH7J7gWU1iqdyEg","lore_tm_v1_G4Qyudd0TsYbHUxDU9KncbQxjAHw8ZRqeojK_5_m47c","lore_tm_v1_6MW-H2qZLHajKHPcBFy2QFTigMJav5jsizax9-81NRk","lore_tm_v1_A92zbXMflUHMnevtj6nklTaisTQJqsLDOMf1bYieZaM","lore_tm_v1_7rLvAOb5TziouUA8y5TVV88qvxSOkOChP0lyt0Dzw9o","lore_tm_v1_48p1AzJ6akQoviJz__FkHw9vWXGDDMrefU5eUp4WV6c","lore_tm_v1_c6I6hg5CK4c2Qk4MIAOEj6fr8N_bMMc_HcDI1_wUaI0","lore_tm_v1_NGK2ji5qcKkZ-0P7KZQYpNeQvNMeUfzVSd4V9QQHQHU","lore_tm_v1_db37Pm2Q3fYuJ2bmgxRc02BBBjoqezfDbMShfB4s9gs","lore_tm_v1_A0CPV6SCJkD-_6iqKWVgRiGXUCB-3Qq1YGzHUgE9v-o","lore_tm_v1_--eo0bJuDB-QADdOo7mnwW8X4zbfULRnqmGt45PdAhQ","lore_tm_v1_b9SGK-bSWnF1Ly1wM67Fk0cTmcXwZbcNT6RmXzWUj3s","lore_tm_v1_KQGt4ThQ5C31RjKXd3f-1L9kNKXmGJQcKyGT8Qhk_a0","lore_tm_v1_bFl2VfnvKqMeHYcvUqIimwjBx9H7qf69jgyMuCZAH_8","lore_tm_v1_Ju7m3oOSQzYScw6nRelSmkLTA8lestgk9tLpIY80ais","lore_tm_v1_RMW4WduPVPV99bVf_gRhYoMBVWKnQn_DlsLJqvloKFE","lore_tm_v1_E7mOEwdbKHVjovO9wyDK3Q4K_vwYUxzpXdOzeZajZ0M","lore_tm_v1_4F-R5uleL7OazCEzVZsAegKulgkWhAwrtAm4c1Rtlig","lore_tm_v1_6SO4BmMtXZOyn0HUodeavw4rBehazSH6MbJpvLU_cyA","lore_tm_v1_bDH8M8h6lhAV9pjh8vSGhCCgLXMSpF-Fl5w1zzNkt3o","lore_tm_v1_I_buHqd8Z4-DBTNWYdCEzDckcvSMCO5aMrrmSdRf13M","lore_tm_v1_ru9fT6T_NhbIV9O16yiUFZKv__VSaBYljjQqZkI-bJ4","lore_tm_v1_zoai4MIkv8GFgDlqaCPDdIzz9dzIFq-fprH9pER6gpg","lore_tm_v1_llHVKIT1ZQ9mm5zvNksZ7J3aUZ04VRieIw1DIIkDP30","lore_tm_v1_g4XWbWh2aViOubL56MWQ3FNDnAJMQjM4wrR0gmd7b2s","lore_tm_v1_ww7AfySb2LPsUwxjhcn4svL4j9mpziwhc9wlwzLvsYE","lore_tm_v1_E_htZbI6JUx9w1IHfskZIDrvRME-upbp6hSaPwGKvQY","lore_tm_v1_7qSJgPSkWk5NHTxkp8JcFsnnUEC1RvGUMyYjakpZVxA","lore_tm_v1_SaCIks-cuWaRTkIMQZJ7ff2x_0ArICWsuzc1-gkvQvQ","lore_tm_v1_sNmMIhHihLLIWDgfOt_venFJOcjSHWRi4NkEgazq_UE","lore_tm_v1_-5hFZbdXVBl4lQLGTo-v3otB-hL_qLo74YXP9VjecD8","lore_tm_v1_m4BD-Im1eUp9e_P0pht0USSFAaLsE_GlF9537qTmlvI","lore_tm_v1_zxx9qedPkkxNb_2ufdhOBtL_9p2Cwmp5-CG4LMIumXs","lore_tm_v1_OkEAfoujJ5Op3VVQT6nTNxOSax2GiBHPGawRyPXZP-A","lore_tm_v1_phqQazFamb_zFnMa4ZQImH9dl8OAnM_9kb1QGH3G-tM","lore_tm_v1_u-SPqsnpq3GOIywtioqli5wXs0QwM1kJUPLBm0YKia8","lore_tm_v1_oOkpKFmaZejJc1rtl051y-o6ujzFljkJ6TXsAr-U6eA","lore_tm_v1_5mPr42GW_X7pR1aV3ztolD3S_YDwMmJAVYBgXo2wq-I","lore_tm_v1_bnPSLevowXvBm87_plroTE20ZVXBpApItWwTq7dP37o","lore_tm_v1_5M6bZZc3rA6-y2v-kHMoNNMYb2rI6H9xdb-M9U4X_oY","lore_tm_v1_sgE82_XRNXnAE73KToyWuDbtdMhqrK0aSKcQc_YMvLU","lore_tm_v1_W6iXKKMLFKcPeigUXVfBMTHMqqrn8AnozXViY705rXo","lore_tm_v1_DtSk9-eKFbQbe-uRGq3UjkP0NqY9j-OR1DhLixR0oN0","lore_tm_v1_5Hj6nOsJwbJzsn5izTABR85epOpX2TBouOLdJ1Z4fEY","lore_tm_v1_QlbuPLRtuKT8aGkeAM-COLhHG8wu0J9PxeIO-_49fNo","lore_tm_v1_O8P9ERU2JZBdUf4MxYK9NJKX8VQocdrEINihtZl6-Co","lore_tm_v1_ZrH5h4Y-4TD4EQWqs1_rLZsKb9AQ9vX7J7tC6JlmwXY","lore_tm_v1_FN-1TSZITRVlEc3ir7auG75ZIf6lsIN3pMJhPWq54TE","lore_tm_v1_X7fmCdw7Ncz9Grxz1qyg6YypOm_uUtLfnwGVWUNUTV0","lore_tm_v1_7UbpKcXot7HbuTEjNMLm2Na3mQPnS-JzjzIsVD7uAD8","lore_tm_v1_FIupCHQISoaYjyzodI5HPparmi7j1cWOujjx-AaaILY","lore_tm_v1_NYShtXAZApX3Iiu7DCDI5vZpM6p5GX5t-Mff_xM-4QI","lore_tm_v1_CdMbO912Xth3OgyQhSBAytFomXW43NDoZUM0NDtjXcc","lore_tm_v1_zCiSeDpPd-kQai3ESNn0SgbOOWvsEiQXwrP72NZpUVc","lore_tm_v1_0Gkr_8zggmNxri-8BFDMpXPQ9uMGKiUaLIpLezb7OYE","lore_tm_v1_3z2jO8aKW9YBNy7gizxO3ExI0DVskiVOjGgsE8-AOWQ","lore_tm_v1_Kx5PEvhK2k4w_kPabz1TSRm_XaGm1k27bTiBP-eIaYU","lore_tm_v1_BuJYYmsZYoRs7Nf1yKBq-FJcOSMb38kYsiQ14ZqH1Hs","lore_tm_v1_ANXzGcIAwQvXpsM848kN0JSY_93YwokS_Ct6lNXB9gQ","lore_tm_v1_qDxeXX8yNtgeQRYx8VcU5IpDwPn_AMMw9c0p0uL-mnU","lore_tm_v1_fX0dgR2WvaDiMAJ4Nd006JPGGEX0I2tfb1k5vU0isvw","lore_tm_v1_RSwxzxlYnOWz7o-Yqt2oIRLQIr8f1Fib4ZP2hPToNFk","lore_tm_v1_s72jUiwnKI21oRkhGWlgw-POiPZyNsdRj9GOwyR0Yrw","lore_tm_v1_D0QkPYm-dUC4_L2YTEHb1hn8uMm-ZYdsOhhBlu2z5Ig","lore_tm_v1_gFb-fknMBQkTf7v_uiedu2FeVvQ32OL-nFPR4TWzH-Q","lore_tm_v1_jFSxGV-OQ9O2LtEnvvY2Ne5sPTwz6dzb2BQgI0rqIU4","lore_tm_v1_WbG1N8lTdOYHe1dkWTqtcxaXT-f1ZcBR7FjR33-7YDI","lore_tm_v1_Oe9cluSMb4IZvDm8SotGl8cFaB8leEarLNJCVK2thIo","lore_tm_v1_bxijYKTFIvf5Jq62Tz4nTgSt_IkT9TH0jBeTr1DlxNI","lore_tm_v1_31nhV5dPLleyewE4OLThjkgrQid9vcS72grfL9NT37Y","lore_tm_v1_z6C3KQ_38ypAlL684i1VzV1H7IudfSHmWnYnjgD_L3o","lore_tm_v1_NU3bbjuaJA6yxXPPh6z-AQ0sa39A6wTcbEa9OENQRog","lore_tm_v1_2hugS1o6UbMhtJhtbh12uv-EZHFLVky50JSlfe2mggA"]
feat/workspace-acceptance in /home/byk/Code/getsentry/publish-workspace-acceptancefd1e1156ae878a12a276af401a15a656bfff8127 (fd1e115 fix: address publish workspace review feedback)7c60ddb7f43040fe8fbfea70efc833f689c04e75 (7c60ddb).HTTP 422: Review Can not approve your own pull request); user explicitly authorized admin merges when ready.feat/workspace-action-propagation in /home/byk/Code/getsentry/craft-workspace-action-propagationfb1a705a01277570bf8564477b37eb4d561d1967 (fb1a705 fix: ignore broken workspace symlinks)2026-09-08T17:39:00Z as commit c8a878c53d937a62124796b39ac00f4d73212fe0 (c8a878c).REVIEW_REQUIRED solely because self-approval is prohibited.master using the repository’s established self-release flow. Inspect the release workflow and current master version before releasing. Do not infer or manually improvise release steps.repo-setup before situation skills..sentryclirc resolution must always check global locations as fallback after walking upward from cwd.--workspace --dry-run as a workspace name.node_modules must never be opened; default walks must not re-enter directories, including via symlinks when following them.ses_f7ecc9434ffeledouaoJSXmmtQ, started Sep 8 13:28 for CLI discovery inspection, completed Sep 8 13:49 with no directly reusable findings.ses_f7e3cf790ffean2YR8MT3hLull, started Sep 8 16:04 for independent Craft audit, completed Sep 8 16:59 with MERGE.ses_f7dfd0a94ffeFo9yAHzdIeQDqO, started Sep 8 17:14 for initial broken-symlink repair audit, completed Sep 8 17:17 with DO-NOT-MERGE; its two MUST-FIX findings were repaired.ses_f7df4b4a4ffeQoqF7rJr5Uz3FG, started Sep 8 17:23 for hardened broken-symlink repair audit, completed Sep 8 17:25 with MERGE and no material findings.lncluebd (created Sep 8 17:27) and gip4peqt (created Sep 8 17:29) were superseded by final Craft checks/merge.AGENTS.md directs autonomous GitHub coding work in /workspace/repo, pipeline: triage → explore → plan → implement → review → ship; worker is a deprecated alias of implement.AGENTS.md / CONTRIBUTING.md first; long-term Outpost knowledge is in .lore.md if present..agents/skills/, generated from canonical skills/ by scripts/sync-skills.mjs.grok-build-0.1.publish: getsentry/<checkout-repository>/<full-concrete-workspace-path>@<version>.getsentry/ remains optional only for parsing existing issues.cli/v2 is a valid concrete multi-segment workspace directory path, not legacy compatibility syntax. Removing support would violate the full-path title/selection contract and break valid paths such as packages/CLI.[A-Za-z0-9_.-]+, excluding ., .., __proto__, and segments beginning -; versions are Craft-compatible semantic versions and may contain + build metadata.src/modules/publish-issue-validation.js; Peggy remains syntactic, and poller/controller validation remains required."." remains root; only exact ./<workspace> discovery matches are workspaces; otherwise suffix remains safe checkout path.workspaces: keys may be literal concrete paths or glob patterns. Patterns expand to concrete directories relative to .craft.yml; selected release runs require one concrete path through --workspace <path> or CRAFT_WORKSPACE.craft workspace list outputs concrete workspace paths as a JSON array for automation.., _, and -; no ., .., __proto__, leading -, backslashes, absolute paths, unsafe glob syntax, or matching files. Overlapping workspace keys/patterns are rejected.github.projectPath; workflows cannot provide both path and a workspace.prepare --config-from resolves relative config against git rev-parse --show-toplevel.*, ?, character classes/negated classes, globstar, finite balanced braces; extglob is rejected.realpathSync() fails with ENOENT is skipped, covering broken symlinks and candidates removed between globbing and resolution. All other realpath failures—including ELOOP, EACCES, EPERM, and unexpected I/O errors—must propagate. This preserves fail-closed filesystem/error behavior while avoiding ENOENT failure for a vanished candidate.glob emits packages/broken, verifies the broken candidate is ignored, and separately verifies an unexpected ELOOP resolution error propagates. Explicit EACCES test coverage is not needed because the guard is explicitly code === 'ENOENT'.minVersion: 2.29.0, global GitHub { owner: getsentry, repo: toolkit }, packages/* configured with releaseBranchPrefix: release/cli and GitHub tagPrefix: "cli@", and tools/mcp with releaseBranchPrefix: release/mcp and GitHub tagPrefix: "mcp@".tagPrefix values, Craft uses the first prefix for read-path operations and logs a warning. Independent products should use separate release workspaces.isLatestRelease uses the repository current Latest, so Latest may move between monorepo products; tags, changelogs, release branches, and version detection remain per-product..craft.yml workspace discovery → full-suffix classification → craft publish <version> --rev <revision>.$GITHUB_WORKSPACE/.craft-state/craft; state identity uses physical container cwd SHA-1, lossless base64url workspace identity, and conditional lossless version identity to avoid case/build-metadata collisions.CRAFT_PUBLISH_STATE_GITHUB_REPO identifies checkout repository, never workspace release-repository override.getsentry/craft:latest because it must understand formats in the exact checked-out revision. CI-approved SHA plus craft publish --rev bind the actual release revision; a fixed image cannot safely support all historical/configured workspace formats.getsentry/craft:2.31.0.workspace list and --rev; when root .craft.yml exists, discovery failure remains fail-closed because compact fallback could silently misroute a workspace request.@actions/core.setOutput() cannot safely transmit plain objects to fromJSON(): object outputs must use JSON.stringify.PUBLISH_ARGS absent/empty parses as "{}"; workspace-list input as "[]". Required repo and path checks provide contextual errors instead of raw JSON.parse syntax errors.resolve-release-revision.js missing repo error: Publish input must define a repository.discover-location.js missing path error: Publish input must define a path.src/modules/publish-issue-title.peggy is canonical for PublishIssueTitle, ReleaseRevision, and CheckRunsLinkCount; generated parser start rules are exactly ["PublishIssueTitle", "ReleaseRevision", "CheckRunsLinkCount"].ReleaseRevision requires canonical body-start header: requester, required Merge target, Quick links, View changes, then one repository-bound checks URL.{ repo, mergeTarget, revision }; details-from-context.js gets Merge target solely through getReleaseRevisionDetails(), not arbitrary body regex scanning.(default) becomes empty Craft merge_target; appended/decoy Merge target: fields cannot override canonical header.(default) or documented branch-token characters: letters, digits, _, ., /, and -; unrestricted arbitrary non-newline values such as main; not-a-branch are rejected.CheckRunsLinkCount counts all literal - [View check runs]( occurrences across body to reject inline/blockquote/trailing decoys.Expected exactly one View check runs link in Quick links for getsentry/${repo}.Expected a View check runs link for getsentry/${repo} in the publish issue body.Release revision must be a lowercase 40-character SHA.updateReleaseRevision() accepts only /^[0-9a-f]{40}$/, then replaces parser-recorded [start,end) SHA offsets only.jq -jr/jq -ejr file-backed body input/output and gh issue edit --body-file..issueBody must be a nonempty string; only then can the body file be submitted to gh issue edit. Invalid/malformed JSON, top-level non-object/scalar values, missing property, non-string (null, boolean, number), empty string, JSON failure, and resolver failure skip without edit.EXIT trap for body_file, resolver_output_file, and updated_body_file; failure/skip paths use exit 0 inside the subshell rather than invalid continue, so cleanup occurs before outer while advances.// BEGIN TITLE GRAMMAR / // END TITLE GRAMMAR; docs use <!-- BEGIN GENERATED TITLE GRAMMAR --> / <!-- END GENERATED TITLE GRAMMAR -->..github/workflows/publish.yml and controller checkout in .github/workflows/ci-poller.yml use actions/checkout@v7..github/workflows/test.yml or .github/workflows/auto-approve.yml in this PR; that is unrelated scope expansion.packages/cli/AGENTS.md and .cursor/rules/ultracite.mdc.packages/cli of a pnpm workspace; it is Node.js/pnpm/Stricli, with docs at apps/cli-docs.pnpm add -D <package> and remain in devDependencies; CI enforces this with pnpm run check:deps.Bun.*, bun:test, or Bun CLI. Use node:fs/promises read/write APIs, node:fs existsSync, child-process spawn/execFile/execSync, src/lib/which.ts, src/lib/scan/, and node:timers/promises.mkdirSync(dir, { recursive: true, mode: 0o700 }); prefer array-argument execFileSync for user-controlled values to avoid shell injection.@sentry/api API-response types rather than redundant Valibot schemas in src/types/sentry.ts.buildCommand from ../../lib/command.js, use async *func() generators, yield new CommandOutput(data), return { hint }, and let shared output rendering serialize the same data. Do not add custom JSON flags, write stdout manually, branch on flags.json, or write stderr from command files; use logger diagnostics and formatter modules.buildRouteMap from ../../lib/route-map.js, which supplies aliases such as list→ls, view→show, delete→remove/rm, and create→new..sentryclirc resolution already walks upward from cwd then applies global fallback locations afterward, using getGlobalPaths(), applyGlobalFallbacks(), tryApplyFile(), walkUpFrom(cwd), and loadSentryCliRc(). Global paths are cached in globalPaths, and tests reset it when SENTRY_CONFIG_DIR changes.packages/cli/src/lib/walk-up.ts provides async function* walkUpFrom(startDir: string), resolving the start path, yielding absolute ancestors, and using realpath() plus a seen set to stop on broken/denied paths or symlink cycles.packages/cli/src/lib/scan/walker.ts is a streaming DFS file scanner, not workspace discovery. It applies IgnoreMatcher before descent, ignores node_modules-like directories without opening them, emits sorted POSIX-normalized regular files only, skips symlinks unless enabled, and seeds visited inodes with root when following symlinks to prevent subtree re-entry. It supports deterministic serial walking and bounded parallel exhaustive scanning./home/byk/Code/getsentry/craft-workspace-action-propagationfeat/workspace-action-propagationd48b906 feat: support concrete release workspaces4862056..d48b906action.ymldocs/src/content/docs/targets/github.mdsrc/__tests__/action.test.tssrc/__tests__/config.test.tssrc/commands/prepare.tssrc/config.tssrc/schemas/project_config.tssrc/utils/__tests__/publishState.test.tssrc/utils/publishState.tsf174cea test: describe workspace paths accuratelyd48b906..f174cea.src/__tests__/config.test.ts only: one insertion/one deletion, rename from allows legacy workspace names to allows multi-segment workspace paths.validateConfiguration({ workspaces: { 'cli/v2': {} } }) does not throw.src/config.ts#L249-L260 (initially cited around line 252): realpathSync(resolvedMatch) ran before directory filtering and threw ENOENT for a broken symlink matched by a glob such as packages/*.workspaces > ignores broken symlinks matched by workspace globs; failure was ENOENT from /tmp/craft-workspaces-EYzONj/packages/broken, stack getWorkspaceGlobMatches (src/config.ts:250) → getWorkspaceNamesFromConfig (src/config.ts:210) → getWorkspaceNames (src/config.ts:622) → test (src/__tests__/config.test.ts:522).catch { return false; } passed tests but was rejected by audit at Sep 8 17:17 because it swallowed EACCES, EPERM, ELOOP, and unexpected I/O errors, and the fixture had not proven globSync emitted the symlink.fb1a705 fix: ignore broken workspace symlinks
f174cea..fb1a705.fb1a705a01277570bf8564477b37eb4d561d1967.src/config.ts and src/__tests__/config.test.ts, with 53 insertions / 1 deletion.getWorkspaceGlobMatches() now catches only realpathSync(resolvedMatch) errors where error.code === 'ENOENT' and returns false for that candidate; it rethrows all other resolution errors..sort() are preserved.ignores broken symlinks matched by workspace globs creates temporary packages/cli and broken packages/broken symlink targeting missing-workspace, writes .craft.yml with minVersion: ${WORKSPACES_MIN_VERSION} and workspaces: packages/*, proves globSync emits the broken candidate, and expects getWorkspaceNames() to yield only ['packages/cli'].ELOOP realpath failure propagates.src/__tests__/config.test.ts:523-525, ENOENT-only skip at src/config.ts:253-259, non-ENOENT rethrow at src/config.ts:260, safety checks at src/config.ts:263-271, and clean exact diff from f174ce….c8a878c53d937a62124796b39ac00f4d73212fe0.loadConfigurationFromString(configContent, workspaceDirectory = process.cwd()); config-from resolves against Git top-level.src/config.ts:210-229: a concrete workspace matching multiple configured patterns throws ConfigurationError: Workspace "${workspaceName}" matches multiple workspace patterns: ${matchingKeys.join(', ')}.src/config.ts:231-271/final shifted lines: getWorkspaceGlobMatches() validates glob safety, uses globSync(... { absolute: false, cwd: root, dot: true, ignore: ['**/node_modules/**'], posix: true }), skips only ENOENT-unresolvable candidates, and admits sorted safe lexical/realpath-contained directories.src/config.ts:269-390 originally contained path/glob safety and balanced-brace helpers duplicating analogous project_config.ts helpers. isWorkspacePattern() uses hasMagic(... { magicalBraces: true }).src/config.ts:392-409: isVersionGteMinVersion() is a pure config-resolution-safe check and returns false for absent/unparseable versions.src/schemas/project_config.ts:208-215: WorkspaceSchema accepts release-unit fields and partial GitHub config but rejects workspace github.projectPath with Workspace github.projectPath is not supported.src/schemas/project_config.ts:219-334: workspace glob safety rejects unsafe empty/dot/parent/prototype/leading-dash segments; supports safe glob magic and finite balanced brace alternatives; unsafe paths raise Workspace paths must use safe ASCII segments.src/schemas/project_config.ts:322-334: literal multi-segment paths are accepted without normalization.src/commands/prepare.ts:806-812 resolves remote config workspace globs relative to Git top-level; src/config.ts:597-606 accepts the explicit root for string config.action.yml:74-92: validate before side effects; :191-224: clear inherited CRAFT_WORKSPACE; :245-275: emit complete exact titles.src/utils/publishState.ts:51-105: preserve workspace/version identities losslessly.CalVerConfigSchema: optional offset: z.number() (default documented as 14) and optional format: z.string() (default %y.%-m; supports %y, %m, %-m).VersioningConfigSchema: optional policy of auto, manual, or calver, plus optional calver.ChangelogConfigSchema: string or object with optional filePath, policy (auto, simple, none), and scopeGrouping.releaseUnitFields: optional github, targets, preReleaseCommand, postReleaseCommand, releaseBranchPrefix, changelog, changelogPolicy, requireNames, statusProvider, artifactProvider, versioning, and noMerge; noMerge defaults to true for compiled GitHub Actions with dist/.WorkspaceSchema uses all optional release-unit fields, with partial workspace GitHub settings that inherit missing top-level values.WorkspaceNameSchema errors:
Workspace name "__proto__" is not supported.Workspace names cannot be "." or "..".Workspace paths must use safe ASCII segments.CraftProjectConfigSchema.superRefine() rejects top-level github.projectPath when workspaces exist with Workspace configurations cannot use github.projectPath..tsc --noEmit, format, build, and git diff --check passed.vitest run -- src/__tests__/config.test.ts actually ran the full suite: 61 test files passed, 1,197 tests passed, 1 skipped (1,198 total), duration 62.99s.pnpm vitest run src/__tests__/config.test.ts --printConsoleTrace, with 69 focused tests, plus pnpm typecheck.eslint --cache --cache-strategy content consistently had 0 errors and 7 established @typescript-eslint/no-unused-vars warnings: src/commands/publish.ts _abortError at lines 482, 499, and 527; _statusError at 515; _diffError at 521; src/utils/git.ts _err at lines 241 and 249.prettier --check ., typecheck, node build.mjs, and git diff --check passed. Build skipped source-map upload because SENTRY_AUTH_TOKEN was absent.src/targets/__tests__/symbolCollector.test.ts:58-60,68-70 that assignments to imported checkExecutableIsPresent will throw, and remote-ref/branch fetch failures that used cached refs.pnpm exec tsc --noEmit --incremental false; Prettier on every changed file; focused Vitest across 5 files with 141 passing; full Vitest across 61 files with 1,197 passing / 1 skipped; ESLint 0 errors. Five unchanged no-unused-vars warnings in publish.ts also exist on origin/master.prepareMain mock assertion that --config-from passes git rev-parse --show-toplevel into workspace resolution; existing loadConfigurationFromString coverage verifies equivalent root contract.docs/src/content/docs/targets/github.md:89, original line 87, comment PRRC_kwDOCDHbwM7pfr4E, created Sep 2 18:33:13 UTC.src/__tests__/config.test.ts:164, original line 163, comment PRRC_kwDOCDHbwM7pftIQ, created Sep 2 18:33:53 UTC. Reply/resolve occurred Sep 8 17:00 at https://github.com/getsentry/craft/pull/872#discussion_r3960329900.294d500e-a01e-4627-af9f-b3d497c9b290, original discussion https://github.com/getsentry/craft/pull/872#discussion_r3960382720. It was addressed by fb1a705; a response documenting the constrained ENOENT fix and regressions was posted Sep 8 17:28 at https://github.com/getsentry/craft/pull/872#discussion_r3960550044.fb1a705 with no new finding; Seer completed successfully at Sep 8 17:30:08; Warden was last to complete and was green by Sep 8 17:38./home/byk/Code/getsentry/craft: b06435e4f20ff8cb0470de98ee113051978b3d63, byk/fix/commit-on-repo/home/byk/.local/share/opencode/worktree/55fa901aca64a01fa4b5c2abce1c85c1c27475e7/calm-circuit: 5d533c854ad481c31162c4e003cabe23ac5e900a, feat/ci-ready-signal.../calm-squid: 347ade0345dc9f46bce480600ca2beef66100c8f, fix/postcss-security-alert.../stellar-falcon: fc4c1d00d721eb76d9ccc46f841cb2b4b03ed665, byk/fix/dependabot-alerts-865.../swift-squid: 752a693b6ddc3d9b855ddb921e3f91d6e3a847b8, fix/flaky-zip-test/home/byk/Code/getsentry/craft-vercel-prebuilt-output: 3f701f5458f5dee92c730b9c7352d1e5b6ef2b56, fix/vercel-prebuilt-output/home/byk/Code/getsentry/craft-vercel-project-config: 3cceffbf4d6e697c535ec11f83652bcb11800a06, fix/vercel-project-config/home/byk/Code/getsentry/craft-workspaces-schema: ab635721cdaee8a3fe5ec853505e68ff76f8b9c5, feat/workspaces-schema/tmp/opencode/pr865: 51cab289873990824bcfc9c17e7309c430ea2059, byk/pr865-fixes; marked prunable because its gitdir points to a nonexistent location./home/byk/Code/getsentry/publish-workspace-acceptancefeat/workspace-acceptance.fd1e1156ae878a12a276af401a15a656bfff8127.83d210b29553ea6f4d97508821724a834c43856e.7c60ddb7f43040fe8fbfea70efc833f689c04e75.b658ffa fix: validate publish workspace JSON, 52ef600 feat: resolve compact workspace publish requests, a81ab03 feat: resolve workspace publish paths.a81ab03 was pushed Sep 5 03:46 (52ef600..a81ab03), with 13 files / 308 insertions / 539 deletions and new src/modules/publish-issue-validation.js.fd1e115 fix: address publish workspace review feedbacka81ab03..fd1e115.src/modules/__tests__/ci-poller-workflow.jssrc/modules/__tests__/generate-publish-issue-title-parser.jssrc/publish/__tests__/discover-location.jssrc/publish/__tests__/resolve-location.jssrc/publish/__tests__/resolve-release-revision.jssrc/publish/discover-location.js.github/workflows/ci-poller.yml.github/workflows/publish.ymldocs/publish-issue-format.mdscripts/generate-publish-issue-title-parser.jssrc/modules/__tests__/details-from-context.jssrc/modules/__tests__/publish-workflow.jssrc/modules/__tests__/release-revision.jssrc/modules/details-from-context.jssrc/modules/publish-issue-title.jssrc/modules/publish-issue-title.peggysrc/modules/release-revision.jssrc/publish/inputs.jssrc/publish/resolve-ci-poller-input.jssrc/publish/resolve-location.jssrc/publish/resolve-release-revision.jssrc/modules/publish-location.js validates safe paths/workspace names; discovery-invalid error: Craft workspace discovery returned an invalid workspace list. Exact matching is case-sensitive.details-from-context.js and ci-poller-input.js validate title fields before state, checkout, Craft, network, or cross-repository API work.ci-ready, accepted + ci-ready, open issue, no pending/failed labels, 90-minute timeout.ref: ${{ steps.release-revision.outputs.revision }}, path __repo__, Release Bot token, fetch-depth: 0; craft publish ... --rev and state behavior remain preserved.workflow_dispatch remains in ci-poller.yml, optional internal attempt default "0".src/publish/inputs.js: core.setOutput("result", JSON.stringify(result)).src/publish/resolve-location.js: parses PUBLISH_ARGS || "{}" and CRAFT_WORKSPACE_NAMES || "[]", serializes location output.src/publish/resolve-release-revision.js: parses PUBLISH_ARGS || "{}" and requires repo.src/publish/discover-location.js exports getWorkspaceNames({ repositoryDirectory, exists = existsSync, execFile = execFileSync }) and discoverLocation(...); missing root .craft.yml returns []; root config invokes Docker/Craft workspace list; blank/malformed/non-array/unsafe lists fail closed; serialized output..github/workflows/publish.yml invokes node .__publish__/src/publish/discover-location.js with PUBLISH_ARGS and PUBLISH_REPOSITORY_DIRECTORY: __repo__..github/workflows/publish.yml:120 and :159, plus .github/workflows/ci-poller.yml:52, use actions/checkout@v7; unrelated test.yml:19 and auto-approve.yml:16 remain unchanged.src/modules/publish-issue-title.peggy:7-34 contains title grammar markers; :36-85 contains canonical strict release header/merge-target parsing.checks URL with a lowercase SHA; supports LF/CRLF and optional terminal /checks/ slash; starts at body byte zero.NonNewline yielded merge-target character arrays) was fixed via string capture conversion; parser regenerated.src/modules/release-revision.js:7-45 uses generated parser, globally counts duplicate check-runs link prefixes, validates repository binding, and indexed-replaces only canonical SHA offsets.src/modules/details-from-context.js:54-75 draws Merge target only from canonical parser output.src/publish/resolve-ci-poller-input.js reads UTF-8 PUBLISH_ISSUE_BODY_FILE when set, otherwise PUBLISH_ISSUE_BODY || ""..github/workflows/ci-poller.yml:157-162 rejects invalid rewrite shapes and requires a nonempty string .issueBody.src/modules/__tests__/ci-poller-workflow.js executes extracted actual workflow shell with fake node, mktemp, and gh..issueBody, resolver failure, exact valid-body preservation, no issue edit on failures, and temporary-file cleanup. It covers six error/body-preservation paths.scripts/generate-publish-issue-title-parser.js:26-49 rejects missing, duplicate, and malformed marker-like generated documentation regions.src/modules/publish-issue-title.peggy:7-34 and docs/publish-issue-format.md:12-41.git diff --check passed.git diff --check a81ab03, generated check, lint), but full test was intentionally not run under read-only constraint.yarn vitest run src/modules/__tests__/ci-poller-workflow.js passed 1 file/6 tests in 704 ms. Full verification then passed: ESLint, generated check, Vitest 14 files/94 tests in 3.86s, and git diff --check.src/modules/__tests__/ci-poller-workflow.js:40-49,146-150 creates/deletes temp files, contrary to read-only audit constraints.warden and warden: security-review), Cursor Bugbot, Seer Code Review, Socket Security Project Report/Pull Request Alerts, and semgrep-cloud-platform/scan.24.0.0, Yarn 1.22.22.generate, check:generated, test = yarn check:generated && vitest run, lint = eslint src .github --ignore-pattern '!.github'.Error: There is no jj repo in "."; use Git.d48b906 feat: support concrete release workspaces created Sep 5 03:34, pushed 03:43.a81ab03 feat: resolve workspace publish paths created Sep 5 03:40, pushed 03:46.a81ab03 and required review.fd1e115 (21 files, +1,509/-96) and pushed successfully.fd1e1156ae878a12a276af401a15a656bfff8127; review decision remained REVIEW_REQUIRED, with CI beginning.repo-setup before situation skills; Outpost AGENTS.md instructions were read.cli/v2 is a valid concrete path, not legacy syntax; user explicitly requested test renaming instead of removal..sentryclirc upward/global resolution, walk-up.ts, and scan walker.it(...); actual test used test('allows legacy workspace names', ...).allows multi-segment workspace paths.globSync discovery; recommended against introducing async walker complexity unless profiling proves a workspace-expansion bottleneck.f174cea at 16:03; exact PR head became f174ceafa57355e71617f32ba1b0a030953be0a2.NEUTRAL and opened valid medium-severity finding 294d500e-a01e-4627-af9f-b3d497c9b290: broken symlink workspace glob candidates threw from realpathSync before directory filtering.realpathSync threw ENOENT for a broken /tmp/craft-workspaces-EYzONj/packages/broken candidate. Full suite had 60 passed/1 failed test file; 1,197 passed/1 failed/1 skipped tests.ses_f7dfd0a94ffeFo9yAHzdIeQDqO returned DO-NOT-MERGE.src/config.ts plus src/__tests__/config.test.ts.ENOENT, rethrows other realpath errors, proves glob emits the broken symlink, and adds ELOOP propagation coverage.ses_f7df4b4a4ffeQoqF7rJr5Uz3FG returned MERGE at 17:25.fb1a705 fix: ignore broken workspace symlinks; PR #872 head advanced from f174cea to exact fb1a705a01277570bf8564477b37eb4d561d1967.HTTP 422: Review Can not approve your own pull request.7c60ddb7f43040fe8fbfea70efc833f689c04e75.2026-09-08T17:39:00Z as c8a878c53d937a62124796b39ac00f4d73212fe0.master version, then release Craft through its self-release path.