Uh oh!
There was an error while loading. Please reload this page.
feat(automation): tracked-repo management via UI/API + seed marker - #46
Conversation
… marker Closes#36. AutomationRepo is the canonical tracked-repos table. Adds a `source` column ("env" | "user", default "env"; backfilled to "env" via migration) so the UI can distinguish seeded entries from user-added ones, and makes the management surface actually work end-to-end. Behavior: - `getTrackedRepos` env-seed path tags new rows with `source: "env"`. - `POST /api/automation/repos` creates an AutomationRepo with `source: "user"`, returns 409 on duplicate, writes `add_tracked_repo` AuditLog rows for both success and failure. - `DELETE /api/automation/repos/[repo]` hard-deletes the AutomationRepo (cascading workflow/run/release history), soft-disables the matching Repository row (`enabled=false`) so cached issues remain visible for historical board context, and writes a `remove_tracked_repo` AuditLog row. - `POST /api/repos` now writes both AutomationRepo (source=user) and the mirror Repository row in a transaction, with audit, so the board sees the new repo without waiting for the next /api/sync. Bug fixes spotted on the way: - /automation Add/Remove buttons were calling `/api/automation/repositories` (which doesn't exist) and 404'ing silently. Repointed at `/api/automation/repos`. - The `[repo]` path param on /api/automation/repos was unused; GET now reads the path-encoded fullName as a fallback to the `?repo=` query param it was previously hard-coded against. UI: - New `seed` badge on /automation cards when `source === "env"`. - Delete now passes through a confirm() and uses the URL-encoded fullName. Tests: 62 passing (was 53). New coverage: - POST /api/automation/repos — validation, success-with-audit, duplicate-409, failure-with-audit - DELETE /api/automation/repos/[repo] — 404, success-with-audit, failure-with-audit Docs: - README clarifies that GITHUB_REPOSITORIES is a *one-time* bootstrap seed (read only when the tracked-repos table is empty), documents the new endpoints, and the seed/user-added distinction. - AGENTS.md env-var table updated accordingly. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
✅ Automated recommendation: APPROVE Analysis engine: anthropic/MiniMax-M2.7@https://litellm.jory.dev/v1 (anthropic) PR Review: feat(automation): tracked-repo management via UI/API + seed markerRecommendation: ApproveThis PR comprehensively addresses issue #36, implementing full tracked-repo management through the UI and API while correctly distinguishing env-seeded repos from user-added ones. The implementation is well-tested, well-documented, and follows repository conventions. Change-by-Change FindingsSchema & Migration (prisma/)
API Routes (src/app/api/)
|
| Acceptance Criteria | Status |
|---|---|
| Existing tracked repo UI supports add/remove/disable | ✅ Fixed 404 bug + implemented add/remove |
| Env-seeded repos marked in UI vs user-added | ✅ seed badge with tooltip |
| Repos can be added via UI without editing Kubernetes env | ✅ POST /api/automation/repos |
| Adding/removing audited in AuditLog | ✅ Both endpoints write audit rows |
| GET /api/repos and POST /api/repos work end-to-end | ✅ Rewired to create both rows atomically |
| Docs explain GITHUB_REPOSITORIES is bootstrap seed only | ✅ README.md and AGENTS.md updated |
| POST /api/repos handles seed-vs-added distinction | ✅ Creates source: "user" row |
Evidence Provider Findings
No evidence providers configured. No external verification needed.
Tool Harness Findings
No tool requests executed. The diff is self-contained and reviewable without external API calls.
Unknowns / Needs Verification
Minor observation (non-blocking): The source field is typed as String in Prisma but the TypeScript interface uses literal union "env" | "user". This is functionally harmless (TS allows any string for a String field), but for stricter typing, the interface could use string instead. This does not affect runtime behavior.
Cascade verification: The DELETE handler assumes Prisma cascade delete is configured for AutomationRepo → workflows/runs/releases. The diff does not show the full schema, but this is consistent with the PR description. Recommend verifying cascade relations in schema before deploy.
Summary
This PR is well-structured, thoroughly tested (62 tests passing, up from 53), and correctly implements all acceptance criteria from issue #36. The bug fixes (wrong API path, unused path segment) are a bonus. Documentation is accurate and reflects the new one-time seed semantics. No blockers identified.
Verdict: Approve
Uh oh!
There was an error while loading. Please reload this page.
… on them (#709) * fix(pr-followup): skip informational bot comments instead of blocking on them The comment path ingested every non-author comment on a bot PR as REVIEW_FEEDBACK, so a CI bot posting a size-diff table became a work item: classifyFeedback finds no actionable pattern in markdown, defaults to needs_human, and the PR sits BLOCKED on a human forever. Observed on misospace/llmkube-images#114 — a MERGEABLE, unreviewed PR blocked since 2026-08-04 by an app-size-diff comment reporting +0 B (+0%). Same cause on #46 and #99. The queue read 9 NEEDS_HUMAN items when only informational noise and already-merged PRs were behind them. Gate the comment descriptor on a new isInformationalComment(): sticky comment markers (the sticky-pull-request-comment convention embeds one so the action can update in place, which makes it a structural signal rather than a prose guess) plus dispatch's own pr-fix-blocked notice. An ai-pr-reviewer comment stays ingestible even when it carries a marker — it ships structured findings and is genuine review feedback. Does not address the stale-item half of the same symptom (#692): items already queued when their PR merges are still never reaped. Signed-off-by: Jory Irving <jory.irving@users.noreply.github.com> * fix(test): import vi in pr-followup-ingestion tests The informational-comment tests use vi.restoreAllMocks(); vitest globals make that work at runtime, so the suite passed while tsc and next build failed on TS2304. Signed-off-by: Jory Irving <jory.irving@users.noreply.github.com> --------- Signed-off-by: Jory Irving <jory.irving@users.noreply.github.com> Co-authored-by: Jory Irving <jory.irving@users.noreply.github.com>
Summary
Closes#36. Makes the tracked-repo management surface (the
/automationAdd/Remove buttons +POST /api/repos) actually work end-to-end, and adds asourcemarker so the UI can distinguish env-seeded repos from user-added ones.Canonical model:
AutomationRepois the source of truth for "what to track" (this is whatgetTrackedReposalready reads).Repositoryis a derived/cached view used by board issue sync.Schema
source: String @default("env")toAutomationRepo.20260514000000_automation_repo_source— simpleALTER TABLE ... ADD COLUMN ... DEFAULT 'env'(backfills existing rows correctly since they were all env-seeded under the old code).Behavior changes
getTrackedReposenv-seed path: tags newly-seeded rows withsource: "env".POST /api/automation/repos— creates anAutomationRepowithsource: "user". Returns 409 on duplicate. Writesadd_tracked_repoAuditLog (success + failure paths).DELETE /api/automation/repos/[repo]— hard-deletes theAutomationReporow (cascading workflow/run/release history), soft-disables the matchingRepositoryrow (enabled = false) so cached issues remain visible historically but disappear from active board filters. Writesremove_tracked_repoAuditLog (success + failure paths).[repo]is the URL-encodedowner/repofullName.POST /api/repos(existing): rewired to create bothAutomationRepo(source=user) and the mirrorRepositoryrow in a Prisma transaction, with audit. Means newly-added repos surface on the board without waiting for the next/api/sync.Bug fixes uncovered in scope
/automationAdd/Remove buttons were POST/DELETEing to/api/automation/repositories— a path that doesn't exist. Both were silently 404'ing. Repointed at/api/automation/repos.[repo]dynamic segment on/api/automation/repos/[repo]was previously unused — the GET handler read?repo=from the query string instead. GET now uses the path param as a fallback (still accepts the query param for backwards compat).UI
seedbadge on/automationrepo cards whensource === "env", with a tooltip explaining it was bootstrapped fromGITHUB_REPOSITORIES.confirm()and uses the URL-encoded fullName.Tests (62 passing, was 53)
POST /api/automation/repos— malformed JSON, missing fullName, bad format, success+audit, duplicate-409 (no audit row written for the constraint hit), failure+auditDELETE /api/automation/repos/[repo]— 404 when not tracked, success path (cascade delete + Repository soft-disable + audit), failure-with-auditDocs
README.md— flagsGITHUB_REPOSITORIESas a one-time bootstrap seed (only consulted when the tracked-repos table is empty), documents the new endpoints, explains the seed/user-added distinction.AGENTS.md— env-var table updated accordingly.Test plan
npm run lint— cleannpm run typecheck— clean (afternpx prisma generate)npm test— 62/62 passing across 11 files/automation, confirm the existing repos show aseedbadgeowner/name, confirm a card appears without aseedbadge and an audit row is visible atGET /api/auditremove_tracked_repoaudit row appears/boardafter a remove; cached issues for the removed repo should be hidden from default filters but available inGET /api/audithistory🤖 Generated with Claude Code