Command Start/Stop: Assignee manager for issues
Ubiquity OS · 2024 · Start and stop work from issue comments with wallet and limits enforcement; workerized, tested, and CI-ready.
So what?
<1d turnaround delivery
<1d turnaround delivery
Problem
Hunters needed a simple way to start/stop work from issue comments without risking unintended XP penalties. The system also had to enforce prerequisites (e.g., registered wallet) and limits.
Approach
- Parse
/start
and/stop
fromissue_comment.created
- Validate: wallet present, max concurrent tasks, issue constraints
- Assign/unassign via GitHub API; close linked PRs on stop
- Persist events and wallet lookups via Supabase helpers
- Workerize for responsiveness; align CI with yarn/corepack
System diagram
flowchart LR Client[Client Comment] --> Webhook[GitHub Webhook] Webhook --> Kernel[UbiquityOS Kernel] Kernel --> Parser[Command Parser] Parser --> Validation[Validation Layer] Validation --> DB[Supabase Database] DB --> Assignment[Assignment Logic] Assignment --> Response[GitHub API Response]
Outcome
- Comment-driven assignment flows with predictable rules
- Reduced maintainer overhead for routine assignment changes
- CI stabilized; coverage reported and checks enforced
Constraints
- Urgent delivery (<1 day) and iterative review cadence
- Yarn 4/corepack alignment required in CI
- XP policy distinction between voluntary stop and admin removal
Design choices
- Wallet-gated
/start
to ensure payout readiness - Explicit limit checks; fail fast with actionable messages
- Separate adapters for GitHub and Supabase; testable boundaries
- Backgroundable/workerized handlers to keep responses snappy
Proof
Code excerpt — core start/stop branching with wallet guard
// handlers (trimmed)
if (command === "start") {
if (!userWallet && config.startRequiresWallet) {
throw new Error("Wallet required to start tasks");
}
await assignUserToIssue(context, issue, user);
} else if (command === "stop") {
await unassignUserFromIssue(context, issue, user);
await closeLinkedPullRequests(context, issue, user);
}
Code excerpt — Supabase helper for wallet lookup
export async function getUserWallet(userId: number): Promise<string | null> {
const { data, error } = await supabase
.from("wallets")
.select("address")
.eq("user_id", userId)
.single();
if (error || !data) return null;
return data.address;
}
CI and review evidence — workflow and coverage (trimmed)
All checks passed. Corepack/yarn version aligned; coverage reported.
Merged with multi-review iteration.
References
- Issue — #9 - command/[start | stop]
- PR — #1 - command-start-stop init
- Files — handlers, adapters, workflow (see PR diff)