refactor(server): migrate janitor to ForgePort — impl seam wraps adapter #279
No reviewers
Labels
No labels
area:agents
area:dashboard
area:database
area:design
area:design-review
area:flows
area:infra
area:meta
area:security
area:sessions
area:webhook
area:workdir
security
type:bug
type:chore
type:meta
type:user-story
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
charles/claude-hooks!279
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "refactor/janitor-forge-port"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Fifth per-consumer Forgejo migration. Janitor uses an
implseam pattern for test isolation (notmock.module, which is process-global and leaks across suites); this PR rewrites the seam entries to wrapForgejoAdaptercalls while preserving the seam's swap-for-tests contract.Scope
background/janitor.ts+background/janitor.test.ts. One additional port extension surfaced by three rules.Port extension
ForgeIssueRef({number, state}) — added. Three janitor rules (closes_keyword_drift,dependent_unblocked,stale_idle_assigned) need blocker state to decide whether to act. The port'sgetBlockers/getBlockedpreviously returnednumber[]and dropped thestatefield from the dependency payload.getBlockers(repo, number): Promise<ForgeIssueRef[]>getBlocked(repo, number): Promise<ForgeIssueRef[]>Adapter projects
api.IssueDependencyEntry.state(default"open"when absent on older Forgejo builds) into the new ref shape.Downstream consumer impact: only
domain/workflow/deps.tsuses these methods via the port, and per #277's report it kept a rawforgejo-api.getIssueBlocksimport for its cross-repo filter — so the port change doesn't affect the deps PR.implseam rewriteEach entry now wraps the adapter, e.g.:
Rule bodies read domain fields (
issue.labels.includes("area:design")instead ofissue.labels.some(l => l.name === "area:design"),r.reviewerinstead ofr.user.login, etc.).Label-mutation simplification
label_dispatch_misspreviously pre-loadedlistRepoLabelsto resolvename → id. The port'saddLabels/removeLabeltake names; the adapter resolves IDs internally. Rule dropped thelistRepoLabelsstep; test asserts now compare against the name string.Tests
janitor.test.ts— new fixture buildersissue(),pr(),review(),comment(),blocker()mirror the pipeline/board patternOverlap with sibling PRs
Opened alongside #277 (deps) and earlier webhook-ci PR. If deps merges first this one auto-rebases cleanly; if this merges first, deps needs a trivial
.numberextraction fixup.