Skip to content

feat: tag auto-moved lab issues with source="extensions"#58

Merged
stack72 merged 1 commit intomainfrom
feat/lab-issue-source-extensions
Apr 8, 2026
Merged

feat: tag auto-moved lab issues with source="extensions"#58
stack72 merged 1 commit intomainfrom
feat/lab-issue-source-extensions

Conversation

@stack72
Copy link
Copy Markdown
Contributor

@stack72 stack72 commented Apr 8, 2026

Summary

swamp-club#375 added a source field on lab issues so each one is attributed to its origin (swamp-club, swamp, extensions, UAT). This auto-responder was defaulting to swamp-club, which is wrong for issues filed against systeminit/swamp-extensions. Tag submissions with source: "extensions" so the Lab UI shows the correct chip and filter bucket.

Switches the endpoint from the admin-only /api/v1/lab/issues/ensure (which doesn't accept source) to the public /api/v1/lab/issues endpoint, and expands the footer to include the full GitHub issue URL (issue.html_url) so the back-link survives the loss of the structured githubRepoFullName / githubIssueNumber fields that the public endpoint doesn't accept.

Mirrors systeminit/swamp#1140, which makes the same change for the swamp repo (with source: "swamp").

Notes

  • The /issues endpoint accepts the same Bearer ${SWAMP_CLUB_API_KEY} header as /ensure, confirmed via swamp-club's routes/_middleware.ts which recognizes Bearer swamp_… API keys for any /api/* route.
  • /issues is not idempotent on (repo, issueNumber) like /ensure was, but this workflow only fires on issues.opened (one-shot per GitHub issue), so dedup behavior is unchanged in practice.
  • swamp-club's MAX_TITLE_LENGTH is 256 chars; GitHub titles can exceed this. The current workflow doesn't truncate — same as before. Failures keep the GitHub issue open via core.setFailed.

Test plan

  • Post-merge: open a throwaway issue on systeminit/swamp-extensions and verify the auto-responder produces a lab issue with the "Extensions" chip and a footer linking back to the GitHub URL

🤖 Generated with Claude Code

swamp-club#375 added a `source` field to lab issues so each one is
attributed to its origin (web app, CLI, extensions, UAT). The
auto-responder was defaulting to "swamp-club"; tag it with
`source: "extensions"` so the Lab UI shows the correct chip and
filter bucket.

Switches the endpoint from `/api/v1/lab/issues/ensure` (admin-only,
doesn't accept `source`) to the public `/api/v1/lab/issues` endpoint.
The footer is expanded to include the full GitHub issue URL so the
back-link survives the loss of the structured githubRepoFullName /
githubIssueNumber fields the public endpoint doesn't accept.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Copy link
Copy Markdown
Contributor

@github-actions github-actions bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

Blocking Issues

None.

Suggestions

  1. Title truncation: issue.title is sent without truncation; if swamp-club's MAX_TITLE_LENGTH is 256 chars and a GitHub title exceeds that, the API call will fail with core.setFailed. The PR notes acknowledge this is unchanged behavior — worth a follow-up to truncate client-side to avoid leaving GitHub issues unclosed on failure.

  2. githubAuthorLogin removed: The field was dropped since the public endpoint doesn't require it. If the lab UI uses author attribution, this will silently lose that data. Low risk given the PR description, but worth verifying against the swamp-club endpoint contract.

Changes look correct and well-reasoned. The switch to the public /issues endpoint with source: "extensions" is straightforward. Error handling, null-safety on response parsing, and secret handling are all appropriate.

Copy link
Copy Markdown
Contributor

@github-actions github-actions bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

CI Security Review

Critical / High

None.

Medium

None.

Low

None.

Analysis

Prompt Injection (N/A): No LLM invocations in this workflow.

Expression Injection: No run: blocks — all logic runs inside actions/github-script, which executes JavaScript (not shell). User-controlled fields (issue.title, issue.body, issue.html_url) are accessed as JS object properties and passed through JSON.stringify(), which properly escapes them before they reach the external API. No expression injection vector.

Dangerous Triggers: The issues: opened trigger is externally reachable, but the workflow only reads issue data via the JS context object and sends it to a hardcoded URL (https://swamp.club/api/v1/lab/issues) over HTTPS. An attacker opening an issue cannot redirect data flow or exfiltrate secrets.

Supply Chain: actions/github-script@v7 is a GitHub-owned action with a tag pin — acceptable per policy.

Permissions: issues: write + contents: read at the workflow level. Since there is only one job, workflow-level scoping is equivalent to job-level. Permissions are minimal for the job's needs (post comments, close issues).

Secret Exposure: SWAMP_CLUB_API_KEY is passed via env: (not interpolated in shell) and used only in an Authorization header sent to a hardcoded HTTPS endpoint. Error paths log the HTTP status and response body from the external API, not the secret itself.

Auto-merge: Not applicable — no merge behavior in this workflow.

Changes are security-neutral. The PR swaps the API endpoint from /ensure to /issues, adds a source field, and adjusts the footer text. All existing safe patterns (JSON.stringify for serialization, env-var for secrets, hardcoded target URL) are preserved.

Verdict

PASS — No security findings. The workflow changes maintain existing safe patterns and introduce no new attack surface.

@stack72 stack72 merged commit f4aed18 into main Apr 8, 2026
21 checks passed
@stack72 stack72 deleted the feat/lab-issue-source-extensions branch April 8, 2026 01:39
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant