Skip to content

feat(foreman): provider-neutral CodeHost/WorkItems/ChangePolicy seams (#1158)#1161

Merged
Defilan merged 1 commit into
defilantech:mainfrom
Defilan:feat/1158-decouple-github-phase1
Jul 19, 2026
Merged

feat(foreman): provider-neutral CodeHost/WorkItems/ChangePolicy seams (#1158)#1161
Defilan merged 1 commit into
defilantech:mainfrom
Defilan:feat/1158-decouple-github-phase1

Conversation

@Defilan

@Defilan Defilan commented Jul 19, 2026

Copy link
Copy Markdown
Member

What

Introduce three provider-neutral interfaces in pkg/foreman/agentcodehost.CodeHost, worktracker.WorkItems, and changepolicy.ChangePolicy — and route the agent executor through them instead of calling the GitHub packages directly. GitHub remains the only implementation; no behavior change.

Why

Foreman's node-side agent is hard-wired to GitHub across three concerns: code hosting (repo/PR), work tracking (issues), and change policy (path classification for human review). Decoupling these behind interfaces is the enabling refactor for non-GitHub setups (e.g. Forgejo + Linear + Woodpecker). Part of #1158.

How

  • codehost.CodeHost — clone-URL resolution, change-request (PR) creation, and head-commit subject. GitHubCodeHost wraps githubpr.Ensurer and the github.com clone-URL template.
  • worktracker.WorkItems — fetch a work item by string ID. GitHubWorkItems wraps githubissue.Fetcher, mapping the issue number to/from a string ID at the adapter boundary.
  • changepolicy.ChangePolicy — classify changed paths into work classes and gate human review; mirrors workclass.go / verdict_policy.go.
  • The executor reaches each seam via accessor methods that prefer the injected interface and otherwise wrap the legacy IssueFetcher / PREnsurer fields (threading the run's git-auth token), so existing callers and tests keep working. upstreamURLForRepo now delegates to codehost.ResolveCloneURL and applyVerdictPolicy classifies via changepolicy, so all three packages are live. cmd/foreman-agent wires the GitHub-backed implementations.

Scope: Phase 1 = interface extraction only. The CRD work-item ID intstring migration and the Forgejo/Linear implementations are separate follow-ups; that migration ripples across the controller, CLI, audit, and generated CRDs, so it is kept out here to bound the blast radius. The AgenticTaskPayload.Issue field stays int32 (converted to a string at the worktracker boundary).

Testing

  • go build ./... — clean on GOOS=darwin and GOOS=linux.
  • golangci-lint run (repo-pinned v2.12.2) on the touched packages — 0 issues, darwin and linux.
  • go test ./pkg/foreman/agent/... including the three new packages — passing. Behavior is preserved: the existing executor PR, issue-fetch, and verdict-policy tests pass with only the mechanical signature updates.

Checklist

  • Behavior preserved (GitHub-only; no functional change)
  • Build + lint clean on darwin and linux
  • Tests pass
  • No CRD change in this phase

AI-assisted (Claude Code) under the project's AI contribution policy; authored and reviewed by @Defilan.

…defilantech#1158)

Introduce three provider-neutral interfaces in pkg/foreman/agent so the
agent executor no longer calls the GitHub packages directly. This is the
enabling refactor for supporting non-GitHub integrations (Forgejo, Linear,
Woodpecker); GitHub remains the only implementation and behavior is
unchanged.

- codehost.CodeHost: clone-URL resolution, change-request (PR) creation,
  and head-commit subject. GitHubCodeHost wraps githubpr.Ensurer and the
  github.com clone-URL template.
- worktracker.WorkItems: fetch a work item by string ID. GitHubWorkItems
  wraps githubissue.Fetcher, mapping the issue number to/from a string ID
  at the adapter boundary.
- changepolicy.ChangePolicy: classify changed paths into work classes and
  gate human review. Mirrors the logic in workclass.go / verdict_policy.go.

The executor reaches all three through accessor methods that prefer the
injected seam and otherwise wrap the legacy IssueFetcher / PREnsurer fields
(threading the run's git-auth token), so existing callers and tests keep
working. upstreamURLForRepo now delegates to codehost.ResolveCloneURL and
applyVerdictPolicy classifies through changepolicy, so all three packages
are live. cmd/foreman-agent wires the GitHub-backed implementations.

Phase 1 of defilantech#1158 is the interface extraction only. The CRD work-item ID
int->string migration and the Forgejo/Linear implementations are separate
follow-ups.

Part of defilantech#1158

Signed-off-by: Christopher Maher <chris@mahercode.io>
@codecov

codecov Bot commented Jul 19, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 84.05797% with 22 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
cmd/foreman-agent/main.go 0.00% 12 Missing ⚠️
pkg/foreman/agent/executor_native.go 85.00% 3 Missing and 3 partials ⚠️
pkg/foreman/agent/changepolicy/changepolicy.go 95.34% 2 Missing ⚠️
pkg/foreman/agent/codehost/codehost.go 90.00% 1 Missing and 1 partial ⚠️

📢 Thoughts on this report? Let us know!

@Defilan
Defilan merged commit d3a8ad6 into defilantech:main Jul 19, 2026
24 checks passed
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.

1 participant