feat: Reddit growth agent with Slack approval workflow#3142
Merged
Conversation
Adds an automated agent that scans Reddit for threads where Spawn solves someone's problem, qualifies the poster, and surfaces the best candidate to Slack for human review. Does not auto-reply. - growth.sh: service script (same pattern as refactor.sh) - growth-prompt.md: Claude prompt for Reddit scanning + Slack posting - growth.yml: GitHub Actions workflow (daily trigger) - start-growth.sh: gitignored template for VM secrets Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Simplifies the growth agent to just scan Reddit + score + qualify + output to stdout/log. Slack (via spa) and GH issue logging will be wired up separately. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Previous icon was a wrong GitHub avatar (Korean characters). Now uses the official Pi logo (pixelated P with dot) from the project website. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…gagent.ai" This reverts commit 43098b2.
Growth agent scans Reddit daily, extracts structured JSON from output, and POSTs candidates to SPA's new HTTP endpoint. SPA posts Block Kit cards to #proj-spawn with Approve/Edit/Skip buttons. Approve calls back to growth VM's /reply endpoint which posts the comment to Reddit. - growth-prompt.md: add json:candidate output format - growth.sh: extract JSON + POST to SPA_TRIGGER_URL - reply.sh: new script for Reddit comment posting via OAuth - trigger-server.ts: add POST /reply endpoint - SPA helpers.ts: add candidates table + CRUD - SPA main.ts: HTTP server, button handlers, edit modal - spa.test.ts: candidate DB operation tests Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
AhmedTMM
previously approved these changes
Apr 3, 2026
louisgv
previously requested changes
Apr 3, 2026
Member
louisgv
left a comment
There was a problem hiding this comment.
Security Review
Verdict: REQUEST_CHANGES — MEDIUM severity issues found
Commit: 9ae3f99
Findings
- [MEDIUM]
.claude/skills/setup-agent-team/growth.sh:162— Command injection:CANDIDATE_JSONvariable passed to curl-dflag without sanitization. If the agent outputs malicious JSON containing shell metacharacters, they will be expanded. Usecurl --data-binary @-with heredoc or temp file instead. - [MEDIUM]
.claude/skills/setup-agent-team/growth.sh:93-96— Credential exposure: Reddit credentials written to temp file/tmp/growth-prompt-XXXXXX.mdwith world-readable permissions. Usemktemp --mode=0600orchmod 0600after creation. - [LOW]
.claude/skills/setup-agent-team/growth.sh:101— Command substitution$(cat "${PROMPT_FILE}")expands prompt content in shell context. If prompt contains shell metacharacters, injection is possible. Useclaude -p "$PROMPT_FILE"(file path) instead of$(cat ...). - [LOW]
.claude/skills/setup-agent-team/reply.sh:31-96— Credentials visible in process list:bun -ewith inline script containing Reddit credentials appears inps auxoutput. Use heredoc or temp file instead.
Tests
bash -n: PASSbun test(packages/cli): PASSbun test(.claude/skills/setup-spa): PASS (100 tests)
-- security/pr-reviewer
- chmod 0600 temp prompt file to prevent credential exposure - Use stdin redirect instead of $(cat) for claude -p to avoid shell expansion - Use curl --data-binary @- heredoc instead of -d to prevent command injection - Move reply.sh bun script to temp file so credentials stay in env vars (not visible in ps) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
louisgv
approved these changes
Apr 3, 2026
Member
louisgv
left a comment
There was a problem hiding this comment.
Security Review
Verdict: APPROVED
Commit: a225ef6
Summary
All MEDIUM severity findings from the prior security review have been successfully addressed. The PR demonstrates strong security practices throughout:
Prior Findings (ALL FIXED):
- ✅ Command injection in
growth.sh:162— Fixed by using--data-binary @-instead of-d - ✅ Credential exposure in temp files — Fixed with
chmod 0600immediately aftermktemp - ✅ Command substitution injection — Fixed by using stdin redirect instead of
$(cat ...) - ✅ Credentials visible in ps output — Fixed by writing script to temp file with restricted perms
Current Findings (LOW severity only):
- [LOW]
.claude/skills/setup-agent-team/growth.sh:102— Uses--dangerously-skip-permissionsfor automated agent workflow. Acceptable since human approval happens downstream via Slack. - [LOW]
.claude/skills/setup-spa/main.ts:1280— User-controlled number interpolated into Slack message. Safe because valibot validates it as a number and Slack Block Kit escapes content.
Strong Security Patterns Observed:
- Timing-safe authentication using
timingSafeEqual() - Valibot schema validation for all JSON inputs
- Reddit post ID format validation with regex
- Path traversal prevention via allowlist
- Parameterized SQL queries throughout
- URL encoding for all external API parameters
- Secrets passed via env vars, not CLI args
- Temp files created with mode 0600
Tests
bash -n(shell scripts): PASSbun test(packages/cli): PASS (2002 tests)bun test(setup-spa): PASS (100 tests)- macOS bash 3.x compatibility: PASS
- curl|bash safety: N/A (not applicable to this feature)
-- security/pr-reviewer
All findings have been addressed in subsequent commits (a225ef6). Approving the updated PR.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Architecture
Files
Growth VM:
.claude/skills/setup-agent-team/growth-prompt.md— Claude prompt (+ JSON output format).claude/skills/setup-agent-team/growth.sh— service script (+ JSON extraction + POST to SPA).claude/skills/setup-agent-team/reply.sh— new: Reddit comment posting script.claude/skills/setup-agent-team/trigger-server.ts— modified: added POST /reply endpoint.github/workflows/growth.yml— daily trigger (2:37 PM UTC)SPA VM:
.claude/skills/setup-spa/main.ts— modified: HTTP server, button handlers, edit modal.claude/skills/setup-spa/helpers.ts— modified: candidates table + CRUD functions.claude/skills/setup-spa/spa.test.ts— modified: candidate DB testsEnvironment variables
SPA_TRIGGER_URLSPA_TRIGGER_SECRETREDDIT_*(4 vars)TRIGGER_SECRETGROWTH_TRIGGER_URLGROWTH_REPLY_SECRETTest plan
bash -npasses on all shell scripts🤖 Generated with Claude Code