feat(api): split api/ into a Go submodule for cross-repo typed import
Nobody has claimed this yet.
Assessment
- Difficulty
- 5/5
- Estimated time
- Over a week
- Newbie friendliness
- 38/100
- Issue type
- Feature
- Clarity
- Clearly specified
- Activity status
- Quiet
- Tech stack
- go, kubernetes
- Domain
- api, backend, build-system, devops
Research direction
Start by inspecting api/v1alpha1/ for imports from internal/ or cmd/, then compare api/go.mod and the main go.mod requirements. Run cd api && go build ./..., go list -m -json for the api module, and the existing controller test suites. Done means both modules build, consumers can import the typed package without a cycle, and the documented acceptance criteria are met.
Written by the indexing model from the issue text.
Description
Problem
The typed CRD surface at api/v1alpha1/ (SeiNode, SeiNodeDeployment, etc.) lives inside the main github.com/sei-protocol/sei-k8s-controller module. Downstream consumers that want typed access (seictl's new nodedeployment CLI per sei-protocol/seictl/docs/design/nodedeployment-cli.md, future controllers, the seiload harness) cannot import these types directly: sei-k8s-controller/internal/... imports github.com/sei-protocol/seictl/sidecar/client from 17+ sites, so a typed import in the reverse direction creates a Go module-level cycle.
The seictl nodedeployment CLI implementation hits this immediately. The architectural fallback is unstructured.Unstructured everywhere — verbose accessors, no compile-time type safety, ongoing drift risk against schema changes — paid by every consumer that wants typed CRD access.
Impact
- seictl's PR-1 for the new CLI needs to choose: either ship with
unstructuredand refactor later, or block on the split landing here. - Future consumers (additional controllers, fuzzers, upcoming harnesses) each pay the same
unstructuredtax until the split lands. - "Single source of truth for CRD types" is the standard K8s ecosystem pattern. Cluster-API, Argo CD, Longhorn, Karpenter, and Crossplane all split
api/into a leaf module for exactly this reason.
Relevant experts
kubernetes-specialist— kubebuilder/controller-runtime conventions, module structure.
Proposed approach
Extract api/ into a Go submodule (github.com/sei-protocol/sei-k8s-controller/api):
- Add
api/go.moddeclaring the new module path. Direct dependencies should be limited tok8s.io/apimachinery,k8s.io/api, andsigs.k8s.io/controller-runtime/pkg/scheme— no project-internal imports. - Verify
api/v1alpha1/is leaf-clean (no imports fromsei-k8s-controller/internal/...orcmd/...). If not, lift the offending shared code intoapi/or push it down intointernal/. - Update the main module's
go.modto require the api submodule. Use areplacedirective pointing at./apifor local development;go worksyncs across both. - Update all
sei-k8s-controller/internal/...andcmd/...imports ofapi/v1alpha1to reference the new module path. The package import path stays the same (github.com/sei-protocol/sei-k8s-controller/api/v1alpha1); only the module boundary changes. - CI: build both modules; run controller tests against the submodule.
- Release: tag
api/v0.1.0independently from main module tags. Subsequent CRD changes bump api/ minor; controller-only changes don't touch it.
Standard pattern. References:
kubernetes-sigs/cluster-api/api— separatego.modunderapi/.argoproj/argo-cd/pkg/apis— separate module for typed CRDs.longhorn/longhorn-manager/k8s/pkg/apis— same pattern.- Kubebuilder docs: Using Multiple Groups → Multiple Module Repository.
Architectural constraints
- Leaf-clean. The api submodule must not import anything from
sei-k8s-controller/internal/,cmd/, or any project-specific package. Any shared utility (e.g., validation helpers) either moves intoapi/or stays controller-side. - Same import path. Consumers should continue to write
import "github.com/sei-protocol/sei-k8s-controller/api/v1alpha1". Only the module boundary changes. This avoids breaking any existing internal consumer of the same package. - Independent versioning.
api/vX.Y.Ztags are independent from main module tags. Schema changes bump api; controller-only changes don't.
Acceptance criteria
-
api/go.modexists declaringgithub.com/sei-protocol/sei-k8s-controller/api. -
go list -m -json github.com/sei-protocol/sei-k8s-controller/apifrom the main module resolves cleanly. -
cd api && go build ./...succeeds with no project-internal imports. - Main module imports api via
require+replace(local dev) and a tagged version (CI). - All controller unit / integration / envtest suites pass against the submodule.
-
api/v0.1.0(or first cut) tagged and pushed. - A consumer outside this repo (initially:
sei-protocol/seictl) canimport "github.com/sei-protocol/sei-k8s-controller/api/v1alpha1"and successfully construct a typed client without cycle.
Out of scope
- Moving controller reconcile logic, planner, or task code. This issue is structural-only.
- Renaming the CRD or any of its fields. Additive schema changes only.
- Splitting the controller itself into a separate repo. Submodule, not subrepo.
References
sei-protocol/seictl#135— design doc that hit this constraint and worked around it with unstructured.sei-protocol/seictl/docs/design/nodedeployment-cli.md— consumer side; the "Implementation: build on existing libraries" section currently assumes unstructured pending this split.- Brandon's directive 2026-05-05: "break the CRD spec model from the sei-k8s-controller and import in both places."
- Dominant language
- Go
- Stars
- 1
- Forks
- 2
- Avg merge
- 2h 29m
- Merged PRs (30d)
- 56
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from sei-protocol/sei-k8s-controller
-
Difficulty 5/5 Over a week Newbie friendliness 32/100
-
Difficulty 5/5 Over a week Newbie friendliness 32/100
sei-protocol/sei-k8s-controller#457 · 2 comments ·
-
Difficulty 3/5 1-2 days Newbie friendliness 68/100
-
Difficulty 4/5 3-5 days Newbie friendliness 45/100
-
Difficulty 3/5 1-2 days Newbie friendliness 65/100
All issues in sei-protocol/sei-k8s-controller
Similar issues
-
optimization optimization:agents-md-curator
Difficulty 2/5 1-3 hours Newbie friendliness 86/100
githubnext/gh-aw-cao#13143 ·
-
Difficulty 2/5 1-3 hours Newbie friendliness 84/100
blinklabs-io/bursa#904 ·
-
Difficulty 2/5 1-3 hours Newbie friendliness 84/100
yanet-platform/ipfw-go#129 ·
-
bug confmap/provider/googlesecretmanagerprovider needs triage
Difficulty 2/5 1-3 hours Newbie friendliness 72/100
open-telemetry/opentelemetry-collector-contrib#51273 · 2 comments ·
-
bug: AI Gateway client filter lists "Unknown" twice when NULL and literal Unknown clients coexist Openbug
Difficulty 2/5 1-3 hours Newbie friendliness 90/100