<< All versions

Skill v1.0.1

currentAutomated scan100/100
reliant-labs/forge/role-interface

+1 new

──Details
PublishedNovember 4, 2026 at 08:42 PM
Content Hashsha256:ffb37e9e77979999...
Git SHA6f0052403007
Bump Typepatch
Compare with v1.0.0
──Files
Files (1 file, 1.8 KB)
SKILL.md1.8 KBactive
SKILL.md · 31 lines · 1.8 KB

name: role-interface description: Extend a service's Repository without breaking sibling fakes — the opt-in role-interface pattern for parallel-migration rounds, and when to promote it back onto Repository. metadata: version: "1.0.1"


Extending Repository without breaking fakes (role-interface pattern)

Repository is the canonical name for a service's storage interface — one per service, extended as needed. But in a parallel-migration round, adding a single method to Repository atomically breaks every fake Repository in sibling files (test fakes, in-memory e2e/ fakes, the generated mocks/<svc>_mock_gen.go). The fix is the opt-in role interface: declare a narrow interface in the consuming file and type-assert s.deps.Repo to it at call time:

go
type ModelPerformanceLister interface {
GetModelPerformance(ctx context.Context, opts ModelPerformanceOpts) ([]*db.ModelPerformance, error)
}
func (s *Service) GetModelPerformance(ctx context.Context, req ...) (..., error) {
lister, ok := s.deps.Repo.(ModelPerformanceLister)
if !ok {
return nil, connect.NewError(connect.CodeUnimplemented, fmt.Errorf("Repo lacks ModelPerformanceLister"))
}
// ... use lister ...
}

Production *ormRepo implements both, so the assertion is a runtime no-op; sibling fakes that haven't grown the method still satisfy Repository and return CodeUnimplemented — same outcome as a CRUD shape-mismatch stub.

Use it when adding a method to a Repository with 2+ fakes in sibling lanes, or whose impl is in-flight in a parallel agent's package; don't in greenfield work where you own the Repository and every fake.

Once every consumer implements it (or the round ends), promote it back onto Repository — consuming code unchanged, assertion becomes always-true; forge lint --conventions flags one ready to consolidate.

← v1.0.0All versions