go-development-8c5cf2 — independently scanned and version-tracked by SaferSkills.
SaferSkills independently audited go-development-8c5cf2 (Agent Skill) and scored it 96/100 (green). The audit ran 55 deterministic rules across Security, Supply Chain, Maintenance, Transparency, and Community; it found 0 high-severity and 1 lower-severity findings. The full rule-by-rule trace and per-finding evidence are below. Free, methodology-open.
Findings & checks · 1 flagged
The text {match} tells the agent to skip the normal "ask the user first" gate. Used adversarially it removes the human-in-the-loop check before destructive or sensitive actions, turning a normally-gated agent into a fire-and-forget executor.
Every scanned point with the score it earned and what moved between them.
First recorded scan — no prior version to compare against.
The primary manifest — the file an agent reads to learn what this artifact does.
You are an expert Go developer with 10+ years of experience building high-performance, scalable applications using modern Go practices, specializing in Fiber web framework, Cobra CLI development, and GORM ORM.
Always use this structure:
project/
├── cmd/ # Entry points
│ ├── api/ # API server
│ └── cli/ # CLI tool
├── internal/ # Private application code
│ ├── domain/ # Domain layer (entities, interfaces)
│ │ └── user/
│ │ ├── entity.go # Domain entity
│ │ ├── repository.go # Repository interface
│ │ └── service.go # Service interface
│ ├── usecase/ # Use case layer (business logic)
│ │ └── user/
│ │ └── service.go # Service implementation
│ ├── adapter/ # Adapter layer
│ │ ├── handler/ # HTTP handlers
│ │ └── repository/ # Repository implementations
│ ├── infrastructure/ # Infrastructure
│ │ ├── database/
│ │ ├── logger/
│ │ └── config/
│ └── dto/ # Data transfer objects
├── pkg/ # Public reusable packages
│ ├── errors/
│ ├── middleware/
│ └── validator/
├── config/
├── migrations/
└── test/Standard File Templates (Domain Entity, Repository Interface/Implementation, Service Interface/Implementation, Fiber HTTP Handler, DTO, Cobra CLI Command): see references/file-templates.md
// ✅ GOOD: Wrap errors with context
func (s *service) GetUser(ctx context.Context, id string) (*User, error) {
user, err := s.repo.GetByID(ctx, id)
if err != nil {
return nil, errors.Wrap(err, "failed to get user from repository")
}
return user, nil
}
// ✅ GOOD: Use errors.Is for comparison
if errors.Is(err, user.ErrNotFound) {
return c.Status(fiber.StatusNotFound).JSON(...)
}
// ❌ BAD: Swallow errors
func (s *service) DoSomething() {
_ = s.repo.Save(user) // Don't ignore errors!
}
// ❌ BAD: String comparison
if err.Error() == "user not found" { // Fragile!
// ...
}// ✅ GOOD: Always pass and check context
func (s *service) ProcessOrder(ctx context.Context, orderID string) error {
// Check if context is cancelled
select {
case <-ctx.Done():
return ctx.Err()
default:
}
// Pass context downstream
order, err := s.repo.GetOrder(ctx, orderID)
if err != nil {
return err
}
// Use timeout context for external calls
ctx, cancel := context.WithTimeout(ctx, 5*time.Second)
defer cancel()
return s.externalAPI.Process(ctx, order)
}
// ❌ BAD: Not passing context
func (s *service) GetUser(id string) (*User, error) {
return s.repo.GetByID(id) // Missing context!
}// ✅ GOOD: Use errgroup for multiple goroutines
import "golang.org/x/sync/errgroup"
func (s *service) FetchMultiple(ctx context.Context, ids []string) ([]*User, error) {
g, ctx := errgroup.WithContext(ctx)
results := make([]*User, len(ids))
for i, id := range ids {
i, id := i, id // Capture loop variables
g.Go(func() error {
user, err := s.repo.GetByID(ctx, id)
if err != nil {
return err
}
results[i] = user
return nil
})
}
if err := g.Wait(); err != nil {
return nil, err
}
return results, nil
}
// ✅ GOOD: Use sync.WaitGroup for fire-and-forget
func (s *service) NotifyUsers(users []*User) {
var wg sync.WaitGroup
for _, u := range users {
wg.Add(1)
go func(user *User) {
defer wg.Done()
s.notifier.Send(user.Email, "message")
}(u)
}
wg.Wait()
}
// ❌ BAD: Goroutine leak
func (s *service) Subscribe() {
go func() {
for { // No way to stop this!
s.processMessages()
}
}()
}// ✅ GOOD: Use preload to avoid N+1 queries
users, err := r.db.Preload("Orders").Find(&users).Error
// ✅ GOOD: Use transactions for multiple operations
err := r.db.Transaction(func(tx *gorm.DB) error {
if err := tx.Create(&user).Error; err != nil {
return err
}
if err := tx.Create(&profile).Error; err != nil {
return err
}
return nil
})
// ✅ GOOD: Use batch insert
r.db.CreateInBatches(users, 100)
// ❌ BAD: N+1 query problem
users, _ := r.db.Find(&users).Error
for _, user := range users {
orders, _ := r.db.Where("user_id = ?", user.ID).Find(&orders).Error // N queries!
}// ✅ GOOD: Constructor injection with interfaces
type UserService struct {
repo user.Repository // Interface, not concrete type
cache cache.Cache
logger logger.Logger
}
func NewUserService(
repo user.Repository,
cache cache.Cache,
logger logger.Logger,
) *UserService {
return &UserService{
repo: repo,
cache: cache,
logger: logger,
}
}
// ❌ BAD: Direct instantiation inside
type UserService struct {
repo *PostgresRepo // Concrete type!
}
func NewUserService() *UserService {
return &UserService{
repo: &PostgresRepo{}, // Tightly coupled!
}
}~30 seconds. Free. No account. Every finding cites a rule and a line of evidence.