From dbe5086a0aee87741f2f58c82269fa3650edb247 Mon Sep 17 00:00:00 2001 From: Snider Date: Tue, 17 Mar 2026 07:19:20 +0000 Subject: [PATCH] fix(dx): audit errors, update CLAUDE.md, clean up node import guard - Replace errors.New() with coreerr.E() in sigil/sigils.go (HashSigil.In, NewSigil) - Update CLAUDE.md: add missing deps (go-crypt, x/crypto, testify), fix go/pkg/core path, add GOWORK=off note, document sentinel error convention, add qa command - Remove redundant unused import guard in node/node.go Co-Authored-By: Virgil --- CLAUDE.md | 17 +++++++++++++++-- node/node.go | 3 --- sigil/sigils.go | 6 +++--- 3 files changed, 18 insertions(+), 8 deletions(-) diff --git a/CLAUDE.md b/CLAUDE.md index 607841e..9a27f7a 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -22,6 +22,12 @@ core go test --run Name # Single test core go fmt # Format core go lint # Lint core go vet # Vet +core go qa # fmt + vet + lint + test +``` + +If running `go` directly (outside `core`), set `GOWORK=off` to avoid workspace resolution errors: +```bash +GOWORK=off go test -cover ./... ``` ## Architecture @@ -113,10 +119,17 @@ Backend packages use `var _ io.Medium = (*Medium)(nil)` to verify interface comp - `forge.lthn.ai/Snider/Borg` — DataNode container - `forge.lthn.ai/core/go-log` — error handling (`coreerr.E()`) -- `forge.lthn.ai/core/go/pkg/core` — Core DI (workspace service only) +- `forge.lthn.ai/core/go` — Core DI (workspace service only) +- `forge.lthn.ai/core/go-crypt` — PGP key generation (workspace service only) - `aws-sdk-go-v2` — S3 backend +- `golang.org/x/crypto` — XChaCha20-Poly1305, BLAKE2, SHA-3 (sigil package) - `modernc.org/sqlite` — SQLite backends (pure Go, no CGO) +- `github.com/stretchr/testify` — test assertions + +### Sentinel Errors + +Sentinel errors (`var ErrNotFound`, `var ErrInvalidKey`, etc.) use standard `errors.New()` — this is correct Go convention. Only inline error returns in functions should use `coreerr.E()`. ## Testing -All backends have full test coverage. Use `io.MockMedium` or `io.NewSandboxed(t.TempDir())` in tests — never hit real S3/SQLite unless integration testing. +Use `io.MockMedium` or `io.NewSandboxed(t.TempDir())` in tests — never hit real S3/SQLite unless integration testing. S3 tests use an interface-based mock (`s3API`). diff --git a/node/node.go b/node/node.go index 45d29c1..2c93c45 100644 --- a/node/node.go +++ b/node/node.go @@ -607,6 +607,3 @@ var _ fs.File = (*dataFileReader)(nil) // ensure all internal compile-time checks are grouped above // no further type assertions needed - -// unused import guard -var _ = os.ErrNotExist diff --git a/sigil/sigils.go b/sigil/sigils.go index 4ef0762..2baffff 100644 --- a/sigil/sigils.go +++ b/sigil/sigils.go @@ -11,9 +11,9 @@ import ( "encoding/base64" "encoding/hex" "encoding/json" - "errors" "io" + coreerr "forge.lthn.ai/core/go-log" "golang.org/x/crypto/blake2b" "golang.org/x/crypto/blake2s" "golang.org/x/crypto/md4" @@ -204,7 +204,7 @@ func (s *HashSigil) In(data []byte) ([]byte, error) { h, _ = blake2b.New512(nil) default: // MD5SHA1 is not supported as a direct hash - return nil, errors.New("sigil: hash algorithm not available") + return nil, coreerr.E("sigil.HashSigil.In", "hash algorithm not available", nil) } h.Write(data) @@ -269,6 +269,6 @@ func NewSigil(name string) (Sigil, error) { case "blake2b-512": return NewHashSigil(crypto.BLAKE2b_512), nil default: - return nil, errors.New("sigil: unknown sigil name") + return nil, coreerr.E("sigil.NewSigil", "unknown sigil name: "+name, nil) } }