DashboardcraftSession 1IwF6F9erLuY

Session 1IwF6F9erLuY

Full ID: 1IwF6F9erLuYXPVGe
Messages: 35
Distillations: 1
Time range: 2026-09-02 13:18:08 — 2026-09-02 13:23:37

Conversation (35 messages)

Perform a strict read-only final adversarial review of the CURRENT uncommitted compact workspace publish-contract changes in BOTH worktrees:

  • /home/byk/Code/getsentry/craft-workspace-action-propagation
  • /home/byk/Code/getsentry/publish-workspace-acceptance

Do not modify files. Inspect complete diffs and relevant current source/tests/workflows. Validate specifically:

  1. Legacy and compact title handling including optional getsentry prefix and JSON legacy workspace paths.
  2. CI poller now uses the generated parser and fails closed on exactly one canonical Quick links View check runs entry, no same-repo decoys or duplicate links; controller source checkout is present.
  3. Exact CI revision flows to checkout, discovery, resolved location, state, and craft publish --rev.
  4. '.'/'..' workspace names are rejected consistently in Craft schema/action and Publish discovery.
  5. State parity tests exercise a feasible resolved compact location.
  6. Generated parser drift test, YAML/expression validity, action ordering, no repository-local state, and commit hygiene. Confirm untracked pnpm-lock.yaml is absent/excluded and identify any unrelated changes.

Return only prioritized file:line findings with PASS/FAIL and conclude MERGE or DO-NOT-MERGE. No generic summary.

gateway · 2026-09-02 13:18:08
result
<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>
gateway · 2026-09-02 13:18:56
result
<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>
gateway · 2026-09-02 13:19:00
result
 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/__tests__/publish.test.ts
 M src/commands/publish.ts
 M src/config.ts
 M src/index.ts
 M src/schemas/project_config.ts
?? src/commands/workspace.ts
?? src/commands/workspace_cmds/
 action.yml                              |  18 ++---
 docs/src/content/docs/targets/github.md |  36 ++++++++-
 src/__tests__/action.test.ts            | 135 ++++++++++++++++++++++++++++---
 src/__tests__/config.test.ts            | 136 +++++++++++++++++++++++---------
 src/commands/__tests__/publish.test.ts  |  27 +++++++
 src/commands/publish.ts                 |  18 ++++-
 src/config.ts                           |  48 ++++++++---
 src/index.ts                            |   2 +
 src/schemas/project_config.ts           |  66 +++++++++++-----
 9 files changed, 389 insertions(+), 97 deletions(-)
diff --git a/action.yml b/action.yml
index 6344db2..b2de7f1 100644
--- ...
gateway · 2026-09-02 13:19:04
result
 M .github/workflows/ci-poller.yml
 M .github/workflows/publish.yml
 M docs/publish-issue-format.md
 M package.json
 M src/modules/__tests__/details-from-context.js
 M src/modules/__tests__/publish-workflow.js
 M src/modules/details-from-context.js
 M src/modules/post-workflow-details.js
 M src/publish/inputs.js
 M yarn.lock
?? scripts/
?? src/modules/__tests__/ci-poller-input.js
?? src/modules/__tests__/publish-location.js
?? src/modules/__tests__/release-revision.js
?? src/modules/ci-poller-input.js
?? src/modules/publish-issue-title.js
?? src/modules/publish-issue-title.peggy
?? src/modules/publish-location.js
?? src/modules/release-revision.js
?? src/publish/resolve-ci-poller-input.js
?? src/publish/resolve-location.js
?? src/publish/resolve-release-revision.js
 .github/workflows/ci-poller.yml               | 32 ++++++--------
 .github/workflows/publish.yml                 | 59 +++++++++++++------------
 docs/publish-issue-format.md                  | 62 ...
gateway · 2026-09-02 13:19:09
result
/home/byk/Code/getsentry/craft-workspace-action-propagation/src/commands/workspace.ts
gateway · 2026-09-02 13:19:14
result
/home/byk/Code/getsentry/craft-workspace-action-propagation/src/commands/workspace_cmds/__tests__/list.test.ts
/home/byk/Code/getsentry/craft-workspace-action-propagation/src/commands/workspace_cmds/list.ts
gateway · 2026-09-02 13:19:22
result
/home/byk/Code/getsentry/publish-workspace-acceptance/scripts/generate-publish-issue-title-parser.js
gateway · 2026-09-02 13:19:28
result
/home/byk/Code/getsentry/publish-workspace-acceptance/src/modules/ci-poller-input.js
/home/byk/Code/getsentry/publish-workspace-acceptance/src/modules/release-revision.js
/home/byk/Code/getsentry/publish-workspace-acceptance/src/modules/publish-location.js
/home/byk/Code/getsentry/publish-workspace-acceptance/src/modules/publish-issue-title.js
/home/byk/Code/getsentry/publish-workspace-acceptance/src/modules/publish-issue-title.peggy
/home/byk/Code/getsentry/publish-workspace-acceptance/src/modules/__tests__/ci-poller-input.js
/home/byk/Code/getsentry/publish-workspace-acceptance/src/modules/__tests__/release-revision.js
/home/byk/Code/getsentry/publish-workspace-acceptance/src/modules/__tests__/publish-location.js
gateway · 2026-09-02 13:19:32
result
<path>/home/byk/Code/getsentry/craft-workspace-action-propagation/src/commands/workspace.ts</path>
<type>file</type>
<content>
1: import { Argv, CommandBuilder } from 'yargs';
2: 
3: import * as list from './workspace_cmds/list';
4: 
5: export const command = ['workspace <command>'];
6: export const description = 'Manage release workspaces';
7: 
8: export const builder: CommandBuilder = (yargs: Argv) =>
9:   yargs.demandCommand().command(list);
10: 
11: export const handler = (): void => {
12:   /* pass */
13: };

(End of file - total 13 lines)
</content>

<system-reminder>
Instructions from: /home/byk/Code/getsentry/craft-workspace-action-propagation/AGENTS.md
# AGENTS.md

This file provides guidance for AI coding assistants working with the Craft codebase.

## Package Management

- **Always use `pnpm`** for package management. Never use `npm` or `yarn`.
- Node.js version is managed by [Volta](https://volta.sh/) (currently v22.12.0). ...
gateway · 2026-09-02 13:19:38
result
<path>/home/byk/Code/getsentry/craft-workspace-action-propagation/src/commands/workspace_cmds/list.ts</path>
<type>file</type>
<content>
1: import { getWorkspaceNames } from '../../config';
2: import { formatJson } from '../../utils/strings';
3: 
4: export const command = ['list'];
5: export const description = 'List defined release workspaces as a JSON array';
6: 
7: export function handler(): void {
8:   console.log(formatJson(getWorkspaceNames()));
9: }

(End of file - total 9 lines)
</content>
gateway · 2026-09-02 13:19:42
result
<path>/home/byk/Code/getsentry/craft-workspace-action-propagation/src/commands/workspace_cmds/__tests__/list.test.ts</path>
<type>file</type>
<content>
1: import { describe, expect, test, vi } from 'vitest';
2: 
3: vi.mock('../../../config', () => ({
4:   getWorkspaceNames: vi.fn(),
5: }));
6: vi.mock('../../../utils/strings', () => ({
7:   formatJson: vi.fn(value => JSON.stringify(value)),
8: }));
9: 
10: import { getWorkspaceNames } from '../../../config';
11: import { handler } from '../list';
12: 
13: describe('workspace list command', () => {
14:   test('prints exact configured workspace names', () => {
15:     vi.mocked(getWorkspaceNames).mockReturnValue(['cli', 'mcp.v2']);
16:     const log = vi.spyOn(console, 'log').mockImplementation(() => {});
17: 
18:     handler();
19: 
20:     expect(log).toHaveBeenCalledWith('["cli","mcp.v2"]');
21:   });
22: 
23:   test('prints an empty array when no workspaces are configured', () => {
24:     ...
gateway · 2026-09-02 13:19:46
result
<path>/home/byk/Code/getsentry/publish-workspace-acceptance/src/modules/publish-issue-title.peggy</path>
<type>file</type>
<content>
1: {
2:   function join(characters) {
3:     return characters.join("");
4:   }
5: }
6: 
7: // Canonical grammar for publish issue titles. A path suffix is syntactic only:
8: // the controller resolves a single segment as a workspace after checking out
9: // the CI-approved revision.
10: PublishIssueTitle
11:   = "publish: " "getsentry/"? repo:Repository path:Path? workspace:LegacyWorkspace? "@" version:Version !. {
12:       return {
13:         repo,
14:         path: path || "",
15:         version,
16:         ...(workspace ? { workspace } : {}),
17:       };
18:     }
19: 
20: Repository
21:   = characters:RepositoryCharacter+ { return join(characters); }
22: 
23: RepositoryCharacter
24:   = [A-Za-z0-9_.-]
25: 
26: Path
27:   = segments:("/" segment:PathSegment { return `/${segment}`; })+ { return join(segments); }
28: 
29: PathSegment
30:   = ...
gateway · 2026-09-02 13:19:49
result
<path>/home/byk/Code/getsentry/publish-workspace-acceptance/src/modules/publish-issue-title.js</path>
<type>file</type>
<content>
1: /* eslint-disable */
2: // @generated by Peggy 5.1.0.
3: //
4: // https://peggyjs.org/
5: 
6: "use strict";
7: 
8: class peg$SyntaxError extends SyntaxError {
9:   constructor(message, expected, found, location) {
10:     super(message);
11:     this.expected = expected;
12:     this.found = found;
13:     this.location = location;
14:     this.name = "SyntaxError";
15:   }
16: 
17:   format(sources) {
18:     let str = "Error: " + this.message;
19:     if (this.location) {
20:       let src = null;
21:       const st = sources.find((s) => s.source === this.location.source);
22:       if (st) {
23:         src = st.text.split(/\r\n|\n|\r/g);
24:       }
25:       const s = this.location.start;
26:       const offset_s =
27:         this.location.source &&
28:         typeof this.location.source.offset === "function"
29:           ? ...
gateway · 2026-09-02 13:19:56
result
<path>/home/byk/Code/getsentry/publish-workspace-acceptance/src/modules/publish-location.js</path>
<type>file</type>
<content>
1: function needsWorkspaceDiscovery({ path, workspace }) {
2:   return !workspace && /^\.\/[A-Za-z0-9_.-]+$/.test(path);
3: }
4: 
5: function resolvePublishLocation({ path, workspace, workspaceNames }) {
6:   if (workspace) {
7:     if (path !== ".") {
8:       throw new Error("A publish workspace must use the repository root path.");
9:     }
10:     return { path, workspace };
11:   }
12: 
13:   if (!needsWorkspaceDiscovery({ path, workspace })) {
14:     return { path };
15:   }
16: 
17:   if (!workspaceNames.every(isWorkspaceName)) {
18:     throw new Error(
19:       "Craft workspace discovery returned an invalid workspace list."
20:     );
21:   }
22: 
23:   const segments = path.slice(2).split("/");
24:   if (
25:     path.startsWith("./") &&
26:     segments.length === 1 &&
27:     workspaceNames.includes(segments[0])
28:   ) {
29:     return { path: ...
gateway · 2026-09-02 13:20:00
result
<path>/home/byk/Code/getsentry/publish-workspace-acceptance/src/modules/ci-poller-input.js</path>
<type>file</type>
<content>
1: const { parse: parsePublishIssueTitle } = require("./publish-issue-title");
2: const {
3:   getReleaseRevision,
4:   updateReleaseRevision,
5: } = require("./release-revision");
6: 
7: function getCiPollerInput({ title, issueBody, revision }) {
8:   let parsedTitle;
9:   try {
10:     parsedTitle = parsePublishIssueTitle(title);
11:   } catch {
12:     throw new Error(`Invalid publish issue title: '${title}'`);
13:   }
14:   const { repo, version } = parsedTitle;
15:   const currentRevision = getReleaseRevision({ issueBody, repo });
16: 
17:   return {
18:     ...(revision
19:       ? { issueBody: updateReleaseRevision({ issueBody, repo, revision }) }
20:       : {}),
21:     repo: `getsentry/${repo}`,
22:     revision: currentRevision,
23:     version,
24:   };
25: }
26: 
27: module.exports = { getCiPollerInput };

(End of file - total 27 lines)
</content>
gateway · 2026-09-02 13:20:04
result
<path>/home/byk/Code/getsentry/publish-workspace-acceptance/src/modules/release-revision.js</path>
<type>file</type>
<content>
1: const CHECK_RUNS_LINK =
2:   /^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?$/m;
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 for getsentry/${repo} in the publish issue body.`
16:     );
17:   }
18: 
19:   return ...
gateway · 2026-09-02 13:20:10
result
<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>
gateway · 2026-09-02 13:20:17
result
<path>/home/byk/Code/getsentry/publish-workspace-acceptance/src/publish/resolve-release-revision.js</path>
<type>file</type>
<content>
1: const core = require("@actions/core");
2: const { getReleaseRevision } = require("../modules/release-revision");
3: 
4: function resolveReleaseRevision() {
5:   const { repo } = JSON.parse(process.env.PUBLISH_ARGS || "");
6:   core.setOutput(
7:     "revision",
8:     getReleaseRevision({
9:       issueBody: process.env.PUBLISH_ISSUE_BODY || "",
10:       repo,
11:     })
12:   );
13: }
14: 
15: resolveReleaseRevision();

(End of file - total 15 lines)
</content>
gateway · 2026-09-02 13:20:20
result
<path>/home/byk/Code/getsentry/publish-workspace-acceptance/src/publish/resolve-location.js</path>
<type>file</type>
<content>
1: const core = require("@actions/core");
2: const {
3:   needsWorkspaceDiscovery,
4:   resolvePublishLocation,
5: } = require("../modules/publish-location");
6: 
7: function resolveLocation() {
8:   const input = JSON.parse(process.env.PUBLISH_ARGS || "");
9:   const workspaceNames = needsWorkspaceDiscovery(input)
10:     ? JSON.parse(process.env.CRAFT_WORKSPACE_NAMES || "")
11:     : [];
12: 
13:   if (!Array.isArray(workspaceNames)) {
14:     throw new Error(
15:       "Craft workspace discovery returned an invalid workspace list."
16:     );
17:   }
18: 
19:   core.setOutput(
20:     "result",
21:     resolvePublishLocation({
22:       path: input.path,
23:       workspace: input.workspace,
24:       workspaceNames,
25:     })
26:   );
27: }
28: 
29: resolveLocation();

(End of file - total 29 lines)
</content>
gateway · 2026-09-02 13:20:23
result
<path>/home/byk/Code/getsentry/publish-workspace-acceptance/src/modules/__tests__/ci-poller-input.js</path>
<type>file</type>
<content>
1: import { readFileSync } from "fs";
2: import { join } from "path";
3: 
4: import { expect, test } from "vitest";
5: 
6: const { getCiPollerInput } = require("../ci-poller-input.js");
7: 
8: const REVISION = "7e5ca7ed5581552de066e2a8bc295b8306be38ac";
9: const issueBody = `Quick links:
10: - [View changes](https://github.com/getsentry/toolkit/compare/1.2.2...release/1.2.3)
11: - [View check runs](https://github.com/getsentry/toolkit/commit/${REVISION}/checks/)`;
12: 
13: test("parses compact and legacy workspace publish titles", () => {
14:   expect(
15:     getCiPollerInput({
16:       issueBody,
17:       title: "publish: getsentry/toolkit/cli@1.2.3",
18:     })
19:   ).toEqual({
20:     repo: "getsentry/toolkit",
21:     revision: REVISION,
22:     version: "1.2.3",
23:   });
24: 
25:   expect(
26:     getCiPollerInput({
27:       issueBody,
28:  ...
gateway · 2026-09-02 13:20:27
result
<path>/home/byk/Code/getsentry/publish-workspace-acceptance/src/modules/__tests__/release-revision.js</path>
<type>file</type>
<content>
1: import { expect, test } from "vitest";
2: 
3: const {
4:   getReleaseRevision,
5:   updateReleaseRevision,
6: } = require("../release-revision.js");
7: 
8: const REVISION = "7e5ca7ed5581552de066e2a8bc295b8306be38ac";
9: 
10: test("gets the CI-approved revision for the publish repository", () => {
11:   expect(
12:     getReleaseRevision({
13:       repo: "toolkit",
14:       issueBody: `Quick links:
15: - [View changes](https://github.com/getsentry/toolkit/compare/1.2.2...release/1.2.3)
16: - [View check runs](https://github.com/getsentry/toolkit/commit/${REVISION}/checks/)`,
17:     })
18:   ).toBe(REVISION);
19: });
20: 
21: test("gets the CI-approved revision from a CRLF issue body", () => {
22:   expect(
23:     getReleaseRevision({
24:       repo: "toolkit",
25:       issueBody: `Quick links:\r\n- [View ...
gateway · 2026-09-02 13:20:37
result
<path>/home/byk/Code/getsentry/publish-workspace-acceptance/src/modules/__tests__/publish-location.js</path>
<type>file</type>
<content>
1: import { expect, test } from "vitest";
2: 
3: const {
4:   needsWorkspaceDiscovery,
5:   resolvePublishLocation,
6: } = require("../publish-location.js");
7: 
8: test.each([
9:   [{ path: "./cli" }, true],
10:   [{ path: "./packages/cli" }, false],
11:   [{ path: "." }, false],
12:   [{ path: "./cli", workspace: "cli" }, false],
13: ])("workspace discovery is %s for %j", (input, expected) => {
14:   expect(needsWorkspaceDiscovery(input)).toBe(expected);
15: });
16: 
17: test("classifies an exact one-segment workspace without normalizing it", () => {
18:   expect(
19:     resolvePublishLocation({
20:       path: "./CLI",
21:       workspaceNames: ["cli", "CLI"],
22:     })
23:   ).toStrictEqual({ path: ".", workspace: "CLI" });
24: });
25: 
26: test("keeps a non-workspace suffix as a checkout path", () => {
27:   expect(
28:     ...
gateway · 2026-09-02 13:20:41
result
<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 ...
gateway · 2026-09-02 13:20:48
result
<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 ...
gateway · 2026-09-02 13:20:58
result
<path>/home/byk/Code/getsentry/publish-workspace-acceptance/src/modules/__tests__/details-from-context.js</path>
<type>file</type>
<content>
1: import { test, expect } from "vitest";
2: 
3: const { detailsFromContext } = require("../details-from-context.js");
4: 
5: const inputsArgs = {
6:   context: {
7:     repo: { owner: "getsentry", repo: "publish" },
8:     payload: {
9:       issue: {
10:         number: "223",
11:         title: "publish: getsentry/sentry@21.3.1",
12:         body: `
13: Requested by: @BYK
14: 
15: Merge target: custom-branch
16: 
17: Quick links:
18: - [View changes](https://github.com/getsentry/sentry/compare/21.3.0...refs/heads/releases/21.3.1)
19: - [View check runs](https://github.com/getsentry/sentry/commit/7e5ca7ed5581552de066e2a8bc295b8306be38ac/checks/)
20: 
21: Assign the **accepted** label to this issue to approve the release. ...
gateway · 2026-09-02 13:21:12
result
> @sentry/craft@2.31.0-dev.0 test /home/byk/Code/getsentry/craft-workspace-action-propagation
> vitest run -- --runInBand


 RUN  v4.1.8 /home/byk/Code/getsentry/craft-workspace-action-propagation

[info] [[target/github]] No previous release found
[info] [[target/github]] Deleted orphaned draft release: v1.0.0
[info] [[target/github]] No previous release found
[warn] [[target/github]] Failed to clean up release "v1.0.0": Error: Cleanup failed
[info] [[target/github]] No previous release found
[info] [[target/github]] No previous release found
[info] [[target/github]] Release for tag "1.0.0" already exists and is published. Skipping GitHub release creation (likely from a previous run).
[info] [[target/github]] No previous release found
[info] [[target/github]] createRelease returned 422 for tag "1.0.0". Looking for a leftover draft release to clean up...
[info] [[target/github]] Deleting leftover draft release (id=789) for tag "1.0.0"... ...
gateway · 2026-09-02 13:21:45
result
yarn run v1.22.22
$ yarn check:generated && vitest run
$ node scripts/generate-publish-issue-title-parser.js --check

 RUN  v4.1.0 /home/byk/Code/getsentry/publish-workspace-acceptance


 Test Files  9 passed (9)
      Tests  54 passed (54)
   Start at  13:21:46
   Duration  1.73s (transform 266ms, setup 0ms, import 1.28s, tests 294ms, environment 1ms)

Done in 2.93s.
gateway · 2026-09-02 13:21:53
result
Found 1 matches
/home/byk/Code/getsentry/publish-workspace-acceptance/src/modules/__tests__/ci-poller-input.js:
  Line 13: test("parses compact and legacy workspace publish titles", () => {
gateway · 2026-09-02 13:22:26
result
Found 18 matches
/home/byk/Code/getsentry/craft-workspace-action-propagation/src/utils/publishState.ts:
  Line 34:  * `scripts/print-publish-state-path.ts` if present) that needs to

  Line 71:  *   `publish-state-<owner>-<repo>-<sha1(cwd)[:12]>-<version>.json`

  Line 76:  *   `publish-state-<sha256(cwd)[:16]>-<version>.json`

  Line 90:     ? `workspace-${Buffer.from(workspace).toString('base64url')}-`

  Line 95:     return `publish-state-${owner}-${repo}-${shortCwdHash(cwd)}-${workspacePrefix}${safeVersion}.json`;

  Line 98:   return `publish-state-${cwdDigest}-${workspacePrefix}${safeVersion}.json`;


/home/byk/Code/getsentry/craft-workspace-action-propagation/src/utils/__tests__/publishState.test.ts:
  Line 52:         /^publish-state-getsentry-craft-[0-9a-f]{12}-1\.2\.3\.json$/,

  Line 84:       expect(cli).toMatch(/-workspace-Y2xp-1\.2\.3\.json$/);

  Line 85:       expect(mcp).toMatch(/-workspace-bWNw-1\.2\.3\.json$/);

  Line 107:       ...
gateway · 2026-09-02 13:22:30
result
<path>/home/byk/Code/getsentry/craft-workspace-action-propagation/src/utils/publishState.ts</path>
<type>file</type>
<content>
60:  * disambiguate monorepo subpaths so `packages/foo` and `packages/bar`
61:  * get separate state files even at the same version.
62:  */
63: function shortCwdHash(cwd: string): string {
64:   return createHash('sha1').update(cwd).digest('hex').slice(0, 12);
65: }
66: 
67: /**
68:  * Builds the filename for the publish-state file.
69:  *
70:  * With a resolvable GitHub config:
71:  *   `publish-state-<owner>-<repo>-<sha1(cwd)[:12]>-<version>.json`
72:  *
73:  * Without GitHub config (offline / non-GitHub test harnesses) the
74:  * filename falls back to a cwd-hash-only form so Craft still refuses
75:  * to write into the repo itself:
76:  *   `publish-state-<sha256(cwd)[:16]>-<version>.json`
77:  *
78:  * When a release workspace is selected, its losslessly encoded name is
79:  * included before the version so independent release units in the same
80:  * ...
gateway · 2026-09-02 13:22:38
result
 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/__tests__/publish.test.ts
 M src/commands/publish.ts
 M src/config.ts
 M src/index.ts
 M src/schemas/project_config.ts
?? src/commands/workspace.ts
?? src/commands/workspace_cmds/
src/commands/workspace.ts
src/commands/workspace_cmds/__tests__/list.test.ts
src/commands/workspace_cmds/list.ts
action.yml
docs/src/content/docs/targets/github.md
src/__tests__/action.test.ts
src/__tests__/config.test.ts
src/commands/__tests__/publish.test.ts
src/commands/publish.ts
src/config.ts
src/index.ts
src/schemas/project_config.ts
gateway · 2026-09-02 13:22:48
result
 M .github/workflows/ci-poller.yml
 M .github/workflows/publish.yml
 M docs/publish-issue-format.md
 M package.json
 M src/modules/__tests__/details-from-context.js
 M src/modules/__tests__/publish-workflow.js
 M src/modules/details-from-context.js
 M src/modules/post-workflow-details.js
 M src/publish/inputs.js
 M yarn.lock
?? scripts/
?? src/modules/__tests__/ci-poller-input.js
?? src/modules/__tests__/publish-location.js
?? src/modules/__tests__/release-revision.js
?? src/modules/ci-poller-input.js
?? src/modules/publish-issue-title.js
?? src/modules/publish-issue-title.peggy
?? src/modules/publish-location.js
?? src/modules/release-revision.js
?? src/publish/resolve-ci-poller-input.js
?? src/publish/resolve-location.js
?? ...
gateway · 2026-09-02 13:23:00
result
<path>/home/byk/Code/getsentry/publish-workspace-acceptance/src/modules/post-workflow-details.js</path>
<type>file</type>
<content>
1: async function postWorkflowDetails({context, octokit}) {
2:   const { repo: publishRepo, runId: run_id } = context;
3:   const { number: issue_number } = context.payload.issue;
4: 
5:   const workflowInfo = (
6:     await octokit.rest.actions.getWorkflowRun({
7:       ...publishRepo,
8:       run_id,
9:     })
10:   ).data;
11: 
12:   return octokit.rest.issues.createComment({
13:     ...publishRepo,
14:     issue_number,
15:     body: `Publishing: [run#${run_id}](${workflowInfo.html_url})`,
16:   });
17: }
18: 
19: module.exports = postWorkflowDetails;

(End of file - total 19 lines)
</content>
gateway · 2026-09-02 13:23:37
  • MUST-FIX — FAIL: Legacy JSON workspace paths are accepted by Publish but rejected by Craft. src/modules/publish-location.js:53-60 preserves workspace: "cli/v2", while Craft rejects that configured key at src/schemas/project_config.ts:221-232 and action input at action.yml:82-85. Existing legacy title requests cannot complete.

  • MUST-FIX — FAIL: The controller posts “Publishing” before validating the canonical CI revision. .github/workflows/publish.yml:138-149 runs post-workflow-details.js before resolve-release-revision.js; malformed or decoy Quick links cause a side effect before failure.

  • FAIL (commit hygiene): Unrelated newline-only changes exist in src/modules/post-workflow-details.js:18 and src/publish/inputs.js:10.

  • PASS: Title grammar supports optional getsentry/, compact suffixes, and legacy JSON workspace values: src/modules/publish-issue-title.peggy:10-45; exercised at src/modules/__tests__/ci-poller-input.js:13-35.

  • PASS: CI poller checks out controller code and uses the generated parser: .github/workflows/ci-poller.yml:51-54,100-107.

  • PASS: Canonical Quick links validation rejects duplicate and decoy check-runs links and requires the title repository: src/modules/release-revision.js:1-27; tests at src/modules/__tests__/release-revision.js:42-117.

  • PASS: The approved revision flows through checkout, discovery, resolved location, state, and craft publish --rev: .github/workflows/publish.yml:144-248; ordering test at src/modules/__tests__/publish-workflow.js:63-96.

  • PASS: Compact discovery rejects . and ..: src/modules/publish-location.js:35-42; regression coverage at src/modules/__tests__/publish-location.js:92-99. Craft schema/action also reject them at src/schemas/project_config.ts:221-232 and action.yml:82-85.

  • PASS: State parity uses a feasible resolved compact location: src/modules/__tests__/publish-workflow.js:105-123. ...

gpt-5.6-terra · 2026-09-02 13:23:37 · ~554 tokens

Distillations (1)

Gen 0 2026-09-02 13:19:48 · 412 tokens

Date: Sep 2, 2026 * 🔴 [requested-read-only-review] (13:18) User requested a strict read-only final adversarial review of current uncommitted compact workspace publish-contract changes in both worktrees: `/home/byk/Code/getsentry/craft-workspace-action-propagation` and `/home/byk/Code/getsentry/publish-workspace-acceptance`; instructed not to modify files. * 🔴 (13:18) User required inspection of…