Compare commits

..

3 commits

Author SHA1 Message Date
Claude
5874fd3e77
ci: add Forgejo Actions test and security scan workflows
Some checks failed
Security Scan / security (push) Failing after 14s
Test / test (push) Successful in 4m51s
Uses reusable workflows from core/go-devops for Go testing
(with race detector and coverage) and security scanning
(govulncheck, gitleaks, trivy).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-23 03:28:30 +00:00
Claude
1a0db9bb2a
chore: sync workspace dependency versions
Some checks failed
Go / build (push) Failing after 2s
Publish Docs / build (push) Failing after 6s
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-22 22:04:45 +00:00
Claude
c8531fa66b
chore: migrate module path from github.com to forge.lthn.ai
Some checks failed
Go / build (push) Failing after 27s
Publish Docs / build (push) Failing after 1m0s
Move module declaration and all internal imports from
github.com/Snider/Enchantrix to forge.lthn.ai/Snider/Enchantrix.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-22 21:34:26 +00:00
25 changed files with 76 additions and 126 deletions

View file

@ -0,0 +1,12 @@
name: Security Scan
on:
push:
branches: [main, dev, 'feat/*']
pull_request:
branches: [main]
jobs:
security:
uses: core/go-devops/.forgejo/workflows/security-scan.yml@main
secrets: inherit

View file

@ -0,0 +1,14 @@
name: Test
on:
push:
branches: [main, dev]
pull_request:
branches: [main]
jobs:
test:
uses: core/go-devops/.forgejo/workflows/go-test.yml@main
with:
race: true
coverage: true

View file

@ -1,76 +0,0 @@
# API Audit: Enchantrix Library and CLI
## 1. Go Library API Audit (`pkg/`)
### 1.1. Overall Design & Consistency
The public Go API across the `crypt`, `enchantrix`, and `trix` packages is well-designed, consistent, and adheres to Go best practices. The separation of concerns is clear, with each package serving a distinct purpose.
- **Naming Conventions**: Public functions and types consistently use `PascalCase` as is idiomatic in Go.
- **Error Handling**: Errors are returned as the last value from functions and are descriptive (e.g., `ErrInvalidMagicNumber`, `ErrChecksumMismatch`).
- **Structs vs. Functions**: The API strikes a good balance between service-based structs (`crypt.Service`) and data-centric structs with methods (`trix.Trix`), alongside package-level functions where appropriate (`trix.Encode`, `trix.Decode`).
### 1.2. Package-Specific Audit
#### `pkg/crypt`
- **Strengths**:
- The `crypt.Service` acts as a clean facade for all cryptographic operations.
- Lazy initialization of internal services (`ensureRSA`, `ensurePGP`) is efficient.
- The API is grouped logically: Hashing, Checksums, RSA, and PGP.
- Method names are clear and predictable (e.g., `GenerateRSAKeyPair`, `EncryptRSA`).
- **Recommendations**:
- **Minor**: The `Hash` function accepts a `crypt.HashType`, while `IsHashAlgo` accepts a `string`. While functional, aligning `IsHashAlgo` to also accept a `crypt.HashType` would improve type safety and consistency.
#### `pkg/enchantrix`
- **Strengths**:
- The `Sigil` interface is a powerful and elegant abstraction for data transformation.
- The `NewSigil` factory provides a centralized and user-friendly way to create sigil instances.
- The separation of standard sigils (`sigils.go`) from cryptographic sigils (`crypto_sigil.go`) is logical and improves organization.
- The pre-obfuscation layer is a thoughtful security feature that is well-documented and implemented.
- **Recommendations**:
- **Feature**: The package does not provide a public function to list all available sigil names. The CLI currently uses a hardcoded list, which could lead to inconsistencies. Exposing a `ListSigils() []string` function from this package would be beneficial.
#### `pkg/trix`
- **Strengths**:
- The `.trix` format is clearly defined and implemented. The `Trix` struct serves as a good in-memory representation.
- The `Encode` and `Decode` functions provide a simple, high-level API for serialization.
- Integration with the `enchantrix` package via `Pack` and `Unpack` methods is seamless.
- Constants are used effectively for header keys (e.g., `HeaderKeyEncrypted`), preventing magic strings.
- **Recommendations**:
- None. The API is robust and well-designed.
## 2. CLI API Audit (`cmd/trix/`)
### 2.1. Overall Design & Consistency
The `trix` CLI is built on `spf13/cobra`, a standard for modern Go CLIs. It follows common Unix conventions, including the use of `stdin`/`stdout` and file-based I/O.
- **Command Structure**: The command hierarchy is logical and easy to navigate (`trix encode`, `trix decode`, `trix hash`).
- **Flags**: Flags are consistent across commands (`--input`, `--output`, `--magic`) and include convenient short aliases (`-i`, `-o`, `-m`).
- **User Interaction**: The tool provides clear error messages and behaves predictably.
### 2.2. Specific Commands Audit
- **`trix encode`/`decode`**:
- These commands are the core of the tool and function as expected.
- **Minor Recommendation**: Sigils are passed as positional arguments (e.g., `trix encode base64 gzip`). While this works, a dedicated flag like `--sigils "base64,gzip"` or repeated flags (`--sigil base64 --sigil gzip`) would be more self-documenting and in line with typical `cobra` application design.
- **`trix hash`**:
- The command is straightforward and works as expected.
- **Direct Sigil Commands** (`trix hex`, `trix base64`, etc.):
- This is a clever and useful feature that exposes the power of the `enchantrix` library directly from the command line for quick, one-off transformations.
### 2.3. Maintainability
- **Recommendation**: As noted in the `enchantrix` section, the `availableSigils` slice in `cmd/trix/main.go` is hardcoded. This creates a maintenance burden, as any new sigil added to the `enchantrix` package must also be manually added to this list. This could be resolved by having the `enchantrix` package expose a function to list available sigils.
## 3. Conclusion
The Enchantrix project exhibits a high degree of API quality and consistency in both its Go library and its command-line interface. The design is thoughtful, robust, and adheres to idiomatic Go practices. The few recommendations provided are minor and aimed at further improving maintainability and user experience rather than fixing significant flaws.

View file

@ -5,9 +5,9 @@ import (
"io/ioutil"
"os"
"github.com/Snider/Enchantrix/pkg/crypt"
"github.com/Snider/Enchantrix/pkg/enchantrix"
"github.com/Snider/Enchantrix/pkg/trix"
"forge.lthn.ai/Snider/Enchantrix/pkg/crypt"
"forge.lthn.ai/Snider/Enchantrix/pkg/enchantrix"
"forge.lthn.ai/Snider/Enchantrix/pkg/trix"
"github.com/spf13/cobra"
)

View file

@ -9,7 +9,7 @@ package main
import (
"fmt"
"github.com/Snider/Enchantrix/pkg/crypt"
"forge.lthn.ai/Snider/Enchantrix/pkg/crypt"
)
func main() {

View file

@ -9,7 +9,7 @@ package main
import (
"fmt"
"github.com/Snider/Enchantrix/pkg/crypt"
"forge.lthn.ai/Snider/Enchantrix/pkg/crypt"
)
func main() {

View file

@ -11,7 +11,7 @@ import (
"fmt"
"log"
"github.com/Snider/Enchantrix/pkg/crypt"
"forge.lthn.ai/Snider/Enchantrix/pkg/crypt"
)
func main() {

View file

@ -11,7 +11,7 @@ import (
"fmt"
"log"
"github.com/Snider/Enchantrix/pkg/crypt"
"forge.lthn.ai/Snider/Enchantrix/pkg/crypt"
)
func main() {

View file

@ -11,7 +11,7 @@ import (
"fmt"
"log"
"github.com/Snider/Enchantrix/pkg/crypt"
"forge.lthn.ai/Snider/Enchantrix/pkg/crypt"
)
func main() {

View file

@ -11,7 +11,7 @@ import (
"fmt"
"log"
"github.com/Snider/Enchantrix/pkg/crypt"
"forge.lthn.ai/Snider/Enchantrix/pkg/crypt"
)
func main() {

View file

@ -12,7 +12,7 @@ import (
"fmt"
"log"
"github.com/Snider/Enchantrix/pkg/crypt"
"forge.lthn.ai/Snider/Enchantrix/pkg/crypt"
)
func main() {

View file

@ -11,7 +11,7 @@ import (
"fmt"
"log"
"github.com/Snider/Enchantrix/pkg/enchantrix"
"forge.lthn.ai/Snider/Enchantrix/pkg/enchantrix"
)
func main() {

View file

@ -12,8 +12,8 @@ import (
"log"
"time"
"github.com/Snider/Enchantrix/pkg/crypt"
"github.com/Snider/Enchantrix/pkg/trix"
"forge.lthn.ai/Snider/Enchantrix/pkg/crypt"
"forge.lthn.ai/Snider/Enchantrix/pkg/trix"
)
func main() {

19
go.mod
View file

@ -1,20 +1,23 @@
module github.com/Snider/Enchantrix
module forge.lthn.ai/Snider/Enchantrix
go 1.25
require (
github.com/ProtonMail/go-crypto v1.3.0
github.com/spf13/cobra v1.10.1
github.com/spf13/cobra v1.10.2
github.com/stretchr/testify v1.11.1
golang.org/x/crypto v0.43.0
golang.org/x/crypto v0.48.0
)
require (
github.com/cloudflare/circl v1.6.0 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/cloudflare/circl v1.6.3 // indirect
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
github.com/inconshreveable/mousetrap v1.1.0 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/spf13/pflag v1.0.9 // indirect
golang.org/x/sys v0.37.0 // indirect
github.com/kr/pretty v0.3.1 // indirect
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
github.com/rogpeppe/go-internal v1.14.1 // indirect
github.com/spf13/pflag v1.0.10 // indirect
golang.org/x/sys v0.41.0 // indirect
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)

25
go.sum
View file

@ -1,26 +1,23 @@
github.com/ProtonMail/go-crypto v1.3.0 h1:ILq8+Sf5If5DCpHQp4PbZdS1J7HDFRXz/+xKBiRGFrw=
github.com/ProtonMail/go-crypto v1.3.0/go.mod h1:9whxjD8Rbs29b4XWbB8irEcE8KHMqaR2e7GWU1R+/PE=
github.com/cloudflare/circl v1.6.0 h1:cr5JKic4HI+LkINy2lg3W2jF8sHCVTBncJr5gIIq7qk=
github.com/cloudflare/circl v1.6.0/go.mod h1:uddAzsPgqdMAYatqJ0lsjX1oECcQLIlRpzZh3pJrofs=
github.com/cloudflare/circl v1.6.3 h1:9GPOhQGF9MCYUeXyMYlqTR6a5gTrgR/fBLXvUgtVcg8=
github.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM=
github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U=
github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ=
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
github.com/spf13/cobra v1.10.1 h1:lJeBwCfmrnXthfAupyUTzJ/J4Nc1RsHC/mSRU2dll/s=
github.com/spf13/cobra v1.10.1/go.mod h1:7SmJGaTHFVBY0jW4NXGluQoLvhqFQM+6XSKD+P4XaB0=
github.com/spf13/pflag v1.0.9 h1:9exaQaMOCwffKiiiYk6/BndUBv+iRViNW+4lEMi0PvY=
github.com/spf13/cobra v1.10.2 h1:DMTTonx5m65Ic0GOoRY2c16WCbHxOOw6xxezuLaBpcU=
github.com/spf13/pflag v1.0.9/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
github.com/spf13/pflag v1.0.10 h1:4EBh2KAYBwaONj6b2Ye1GiHfwjqyROoF4RwYO+vPwFk=
github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U=
github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U=
golang.org/x/crypto v0.43.0 h1:dduJYIi3A3KOfdGOHX8AVZ/jGiyPa3IbBozJ5kNuE04=
golang.org/x/crypto v0.43.0/go.mod h1:BFbav4mRNlXJL4wNeejLpWxB7wMbc79PdRGhWKncxR0=
golang.org/x/sys v0.37.0 h1:fdNQudmxPjkdUTPnLn5mdQv7Zwvbvpaxqs831goi9kQ=
golang.org/x/sys v0.37.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
golang.org/x/crypto v0.48.0 h1:/VRzVqiRSggnhY7gNRxPauEQ5Drw9haKdM0jqfcCFts=
golang.org/x/sys v0.41.0 h1:Ivj+2Cp/ylzLiEU89QhWblYnOE9zerudt9Ftecq2C6k=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=

View file

@ -11,9 +11,9 @@ import (
"strconv"
"strings"
"github.com/Snider/Enchantrix/pkg/crypt/std/lthn"
"github.com/Snider/Enchantrix/pkg/crypt/std/pgp"
"github.com/Snider/Enchantrix/pkg/crypt/std/rsa"
"forge.lthn.ai/Snider/Enchantrix/pkg/crypt/std/lthn"
"forge.lthn.ai/Snider/Enchantrix/pkg/crypt/std/pgp"
"forge.lthn.ai/Snider/Enchantrix/pkg/crypt/std/rsa"
)
// Service is the main struct for the crypt service.

View file

@ -4,7 +4,7 @@ import (
"strings"
"testing"
"github.com/Snider/Enchantrix/pkg/crypt"
"forge.lthn.ai/Snider/Enchantrix/pkg/crypt"
"github.com/stretchr/testify/assert"
)

View file

@ -4,7 +4,7 @@ import (
"fmt"
"log"
"github.com/Snider/Enchantrix/pkg/crypt"
"forge.lthn.ai/Snider/Enchantrix/pkg/crypt"
)
func ExampleService_Hash() {

View file

@ -4,7 +4,7 @@ import (
"errors"
"testing"
"github.com/Snider/Enchantrix/pkg/enchantrix"
"forge.lthn.ai/Snider/Enchantrix/pkg/enchantrix"
"github.com/stretchr/testify/assert"
)

View file

@ -4,7 +4,7 @@ import (
"fmt"
"log"
"github.com/Snider/Enchantrix/pkg/enchantrix"
"forge.lthn.ai/Snider/Enchantrix/pkg/enchantrix"
)
func ExampleTransmute() {

View file

@ -4,7 +4,7 @@ import (
"errors"
"time"
"github.com/Snider/Enchantrix/pkg/enchantrix"
"forge.lthn.ai/Snider/Enchantrix/pkg/enchantrix"
)
var (

View file

@ -4,7 +4,7 @@ import (
"bytes"
"testing"
"github.com/Snider/Enchantrix/pkg/trix"
"forge.lthn.ai/Snider/Enchantrix/pkg/trix"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)

View file

@ -4,8 +4,8 @@ import (
"fmt"
"log"
"github.com/Snider/Enchantrix/pkg/crypt"
"github.com/Snider/Enchantrix/pkg/trix"
"forge.lthn.ai/Snider/Enchantrix/pkg/crypt"
"forge.lthn.ai/Snider/Enchantrix/pkg/trix"
)
func ExampleEncode() {

View file

@ -28,8 +28,8 @@ import (
"fmt"
"io"
"github.com/Snider/Enchantrix/pkg/crypt"
"github.com/Snider/Enchantrix/pkg/enchantrix"
"forge.lthn.ai/Snider/Enchantrix/pkg/crypt"
"forge.lthn.ai/Snider/Enchantrix/pkg/enchantrix"
)
const (

View file

@ -8,8 +8,8 @@ import (
"reflect"
"testing"
"github.com/Snider/Enchantrix/pkg/crypt"
"github.com/Snider/Enchantrix/pkg/trix"
"forge.lthn.ai/Snider/Enchantrix/pkg/crypt"
"forge.lthn.ai/Snider/Enchantrix/pkg/trix"
"github.com/stretchr/testify/assert"
)