Merge pull request '[agent/claude:opus] DX audit and fix. 1) Review CLAUDE.md — update any outdate...' (#1) from agent/dx-audit-and-fix--1--review-claude-md into main

This commit is contained in:
Virgil 2026-03-17 08:03:32 +00:00
commit 9c7a447214
3 changed files with 18 additions and 8 deletions

View file

@ -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`).

View file

@ -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

View file

@ -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)
}
}