Skip to content

feat(gateway): confirmed problem → GitHub issue (🎫 reaction opens a structured issue)#61

Open
hanfour wants to merge 22 commits into
mainfrom
feat/confirmed-problem-to-github-issue
Open

feat(gateway): confirmed problem → GitHub issue (🎫 reaction opens a structured issue)#61
hanfour wants to merge 22 commits into
mainfrom
feat/confirmed-problem-to-github-issue

Conversation

@hanfour

@hanfour hanfour commented Jun 12, 2026

Copy link
Copy Markdown
Owner

Summary

A tech, after the bot escalates a diagnosed problem in a Slack thread, confirms it with a 🎫 reaction → the gateway opens a structured GitHub issue in the problem's repo. Uses a work GitHub token passed per-command as GH_TOKEN (never the host's personal gh login). Sub-project 1 of the larger "clarify → diagnose → notify tech → confirm → issue → (later) draft PR" pipeline. End state is a well-formed issue; a human (or a future sub-project 2) picks up development.

Spec: docs/superpowers/specs/2026-06-12-confirmed-problem-to-github-issue-design.md (converged over 6 grounded review rounds). Plan: docs/superpowers/plans/2026-06-12-confirmed-problem-to-github-issue.md (9 tasks, TDD, subagent-driven with per-task spec + quality review + an opus whole-feature final review).

What's included

  • adapters/github.ts — gh-CLI wrapper (findGhBinary, resolveRepoSlug, repoVisibility, createIssue, githubDoctor) behind an injectable exec seam; no-leak error sanitisation.
  • gateway/issue-candidate.ts — durable snapshot record (independent of the consumable escalation marker, so the 🎫 path survives "reply first, react later"), lock-then-finalize lifecycle, mode 0600, doctor self-heal sweep.
  • gateway/slack/issue.tsIssueCoordinator: load → authorize → atomic claim → gh-check → slug → token → public-repo guard → createIssue → finalize → audit → reply.
  • gateway/slack/escalation.ts + free-chat-turn.ts — writes the candidate at escalate time (gated on request.repo), plumbs the diagnosis snapshot, best-effort permalink, appends the 🎫 affordance via chat.update only after the record is saved.
  • gateway/slack/index.ts — widened reaction_added gate + 🎫 dispatch.
  • config.ts / events.ts / escalate.ts / doctor-checks/github-token.tsgithub.token (SecretSource {cmd}/{env}) + allowPublicRepos; two token-free audit events; nested-repo parser support; doctor check + stale-claim recovery.

Security properties (verified in review)

  • No-leak: the work token never reaches a Slack reply, an audit event, a host log line, a thrown error, or process argv (GH_TOKEN via env, errors sanitised to exit-code only).
  • No duplicate issues: once createIssue is invoked, no failure path releases the .claiming lock; every pre-create early-return does release. Crash-consistent finalize (write url → atomic rename); doctor finalizes url-present locks, never re-creates.
  • Injection/traversal: all gh/git calls use execFile arg-arrays (no shell); three independent path guards (safeRepoHint parser boundary, isSafeRepoPath, assertSafeSegment).
  • Authorization: only a tech in the snapshot mentionedUserIds (not the live pool) and not blocklisted can trigger; public-repo guard is default-deny (incl. "unknown" visibility) so internal diagnosis content can't reach a public repo.

Test plan

  • Unit + integration suite: 691 tests pass, 0 fail; npm run cli:build clean.
  • Live Slack verification (BEFORE merge/tag): configure github.token (work account {cmd} reference) + a private target repo in a real ~/.pmk/gateway.json; drive a real escalation, react 🎫 as a tagged tech, confirm a real issue is opened in the correct repo and the URL is posted back to the thread.
  • Verify pmk gateway doctor reports the github-token check correctly (configured vs unconfigured).
  • Verify the public-repo guard blocks a public target repo with a friendly stop reply.
  • Confirm gh is on the host PATH and the work token has repo scope.

🤖 Generated with Claude Code

…claim lifecycle, public-repo guard, exec/path hardening, fail-soft, naming/gate accuracy)
… on post-createIssue fail), diagnosis plumbing, snapshot-only consistency, permalink source, affordance ordering
… split created/failed event payloads, audit precedes best-effort Slack reply
…safeRepoHint parser for nested repos, pre-create gh check releases claim
…re repoVisibility (no-gh no longer misclassified as public-repo block)
…permalink), gated on repo, 🎫 via chat.update
…ce slug-fail, title fallback, recover rename guard
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.

2 participants