AX Principle 2: comments show HOW with real values, not WHAT the type
signature already says. "Send sends an encrypted message over the
connection." adds zero information.
Co-Authored-By: Charon <charon@lethean.io>
All private handler function comments restated what the function name
already said (AX Principle 2 violation). Replaced with concrete call
examples showing how each handler is invoked.
Co-Authored-By: Charon <charon@lethean.io>
AX Principle 2: comments show HOW with real values, not WHAT the
signature already says. "processes incoming messages and returns a
response" restates the signature; the usage example shows how
HandleMessage is wired up via RegisterWithTransport.
Co-Authored-By: Charon <charon@lethean.io>
Replace fmt.Errorf with a local testErr type to eliminate the banned
fmt import. The type carries its own usage example comment per AX
Principle 2.
Co-Authored-By: Charon <charon@lethean.io>
ProtocolError and ResponseHandler had prose descriptions restating
their names — AX Principle 2 violation. Replaced with concrete call
examples showing how callers use each type.
Co-Authored-By: Charon <charon@lethean.io>
ConnectedPeers() had a comment that restated the function name ("returns
the number of connected peers"), violating AX Principle 2. Replaced with
a concrete usage example showing the guard pattern.
Co-Authored-By: Charon <charon@lethean.io>
Dimension weights are never reassigned — declaring them as mutable vars
implies changeability that does not exist. Const declares what IS (AX §5).
Co-Authored-By: Charon <charon@lethean.io>
AX Principle 2 — comments show HOW with real values, not WHAT the
signature already says. The old comment restated the method name;
the new comment shows the exact call pattern used in transport.go.
Co-Authored-By: Charon <charon@lethean.io>
AX principle 10 requires all three categories (Good, Bad, Ugly) per
function. lethean_test.go had only Good for parseComment; Bad (invalid
input, missing keys, empty values) and Ugly (empty string, semicolons
only, duplicate keys, value-with-equals) are now present.
Co-Authored-By: Charon <charon@lethean.io>
Renamed `allowedPublicKeyMu` to `allowedPublicKeyMutex` in PeerRegistry.
`Mu` is an abbreviation that violates AX Principle 1 (predictable names
over short names) — the full word `Mutex` removes any ambiguity about
what the field represents.
Co-Authored-By: Charon <charon@lethean.io>
AX Principle 1: predictable names over short names. `resp` and `raw`
require mental mapping; `response` and `responseBody` are self-describing.
Co-Authored-By: Charon <charon@lethean.io>
'wg' is an abbreviation requiring mental mapping; 'waitGroup' names what
it IS — an explicit sync.WaitGroup, predictable across all call sites.
Co-Authored-By: Charon <charon@lethean.io>
AX Principle 2 — comments must show HOW with real values, not describe
WHAT the signature already says. Replaced three prose descriptions on
getBuffer, putBuffer, and MarshalJSON with concrete call-site examples.
Co-Authored-By: Charon <charon@lethean.io>
AX Principle 2: comments that restate the type signature add zero
information. Replaced "Send sends a message to a specific peer." with a
concrete call-site example showing error handling.
Co-Authored-By: Charon <charon@lethean.io>
PingPeer, ConnectToPeer, and DisconnectFromPeer had comments that
restated the signature in prose. AX-2 requires concrete call examples,
not descriptions. Replaced all three with usage-example comments.
Co-Authored-By: Charon <charon@lethean.io>
AX Principle 2: comments as usage examples, not restatements of the
signature. "Count returns the number of registered peers." says nothing
the signature does not already say. Replaced with a concrete call site.
Co-Authored-By: Charon <charon@lethean.io>
AX Principle 2: comments that restate the function name add zero
information. Replace with a concrete call pattern showing iteration
over the returned map.
Co-Authored-By: Charon <charon@lethean.io>
AX Principle 1 — predictable names over short names. `mu` and `wg` require
mental mapping; `resultsMutex` and `waitGroup` state their purpose directly.
Co-Authored-By: Charon <charon@lethean.io>
AX Principle 1 — predictable names over short names.
`respCh` is an abbreviated compound; `responseChannel` is
unambiguous without context.
Co-Authored-By: Charon <charon@lethean.io>
AX Principle #1: names must not require a comment to explain.
The comment "Calculate round-trip time" existed solely to decode
the abbreviation rtt — proof the name was too short.
Co-Authored-By: Charon <charon@lethean.io>
geo is an abbreviation that requires domain knowledge to parse;
geographicWeight makes the dimension self-describing.
Co-Authored-By: Charon <charon@lethean.io>
AX Principle 1 — predictable names over short names. idx is an
abbreviation requiring a mental mapping; separatorIndex names the
variable by its role (the index of the = separator character).
Co-Authored-By: Charon <charon@lethean.io>
Single-letter v is not AX-exempt — only i (index) is allowed in range loops.
The element variable names the thing being iterated, so: supported.
Co-Authored-By: Charon <charon@lethean.io>
AX Principle 1 — predictable names over short names. The single-letter `a`
requires context to understand; `alias` is self-describing at every read site.
Co-Authored-By: Charon <charon@lethean.io>
Move module declaration and all internal imports from
github.com/Snider/Mining to forge.lthn.ai/Snider/Mining. Also updates
Borg, Enchantrix, and Poindexter dependency paths to forge.lthn.ai.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Updated `Worker.handleDeploy` to handle STIM bundles using `ExtractProfileBundle` and `ExtractMinerBundle`.
- Used `PeerConnection.SharedSecret` as the password for decryption.
- Implemented logic for `BundleProfile`, `BundleMiner`, and `BundleFull`.
- Fixed broken files `pkg/node/dispatcher.go` and `pkg/node/peer.go` to ensure compilation and testing.
- Updated tests in `pkg/node/worker_test.go` and added coverage for deployment logic.
This commit introduces a new audit document, `AUDIT-ERROR-HANDLING.md`, which provides a comprehensive review of the project's error handling and logging practices.
The audit covers:
- **Error Handling:** Analyzes the inconsistency between the well-structured API error responses and the simpler, unstructured error handling at the application's entry points.
- **Logging:** Details the existing custom logger, its lack of JSON output, and its inconsistent use across the codebase.
- **Recommendations:** Provides actionable steps for improvement, including adopting structured JSON logging, centralizing logger configuration, and standardizing on the global logger.
This commit also includes fixes for pre-existing build errors to allow the CI to pass:
- Adds a missing package declaration and imports in `pkg/node/dispatcher.go` and comments out calls to undefined methods.
- Adds a missing import in `pkg/node/peer.go` and resolves an unused variable error.
- Removes an unused import in `pkg/ueps/packet.go`.
Co-authored-by: Snider <631881+Snider@users.noreply.github.com>
This commit introduces a new audit document, `AUDIT-ERROR-HANDLING.md`, which provides a comprehensive review of the project's error handling and logging practices.
The audit covers:
- **Error Handling:** Analyzes the inconsistency between the well-structured API error responses and the simpler, unstructured error handling at the application's entry points.
- **Logging:** Details the existing custom logger, its lack of JSON output, and its inconsistent use across the codebase.
- **Recommendations:** Provides actionable steps for improvement, including adopting structured JSON logging, centralizing logger configuration, and standardizing on the global logger.
Co-authored-by: Snider <631881+Snider@users.noreply.github.com>
This commit introduces a new audit document, `AUDIT-ERROR-HANDLING.md`, which provides a comprehensive review of the project's error handling and logging practices.
The audit covers:
- **Error Handling:** Analyzes the inconsistency between the well-structured API error responses and the simpler, unstructured error handling at the application's entry points.
- **Logging:** Details the existing custom logger, its lack of JSON output, and its inconsistent use across the codebase.
- **Recommendations:** Provides actionable steps for improvement, including adopting structured JSON logging, centralizing logger configuration, and standardizing on the global logger.
Additionally, this commit includes minor, unrelated fixes to address pre-existing build failures:
- Adds a missing package declaration and imports in `pkg/node/dispatcher.go`.
- Removes an unused import in `pkg/ueps/packet.go`.
Co-authored-by: Snider <631881+Snider@users.noreply.github.com>
- P2P-HIGH-1: Add peer scoring system with success/failure/timeout tracking
- PERF-HIGH-2: Add JSON encoding buffer pool for hot paths
- API-HIGH-1: Standardize error responses using APIError struct
- RESIL-MED-5: Add graceful disconnect with reason/code messages
All verified items (SQL indexes, keepalive) were already implemented.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add GenerateChallenge() for random 32-byte challenge generation
- Add SignChallenge() using HMAC-SHA256 with shared secret
- Add VerifyChallenge() with constant-time comparison
- Update performHandshake() to send challenge and verify response
- Update handleWSUpgrade() to sign incoming challenges
- Add comprehensive tests for challenge-response flow
The challenge-response authentication proves the peer has the matching
private key for their public key by signing a random challenge with
the ECDH-derived shared secret. This prevents impersonation attacks.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add PeerAuthMode to control peer registration:
- PeerAuthOpen: Allow all peers (backward compatible default)
- PeerAuthAllowlist: Only allow pre-registered peers or allowlisted public keys
New features:
- PeerRegistry.SetAuthMode/GetAuthMode for mode control
- PeerRegistry.AllowPublicKey/RevokePublicKey for key management
- PeerRegistry.IsPeerAllowed check before connection acceptance
- Transport rejects unauthorized peers with proper handshake rejection
New API endpoints:
- GET/PUT /peers/auth/mode - Get/set authentication mode
- GET/POST/DELETE /peers/auth/allowlist - Manage allowlisted keys
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
CONC-HIGH-1: Add mutex to wsClient.miners map to prevent race condition
P2P-CRIT-2: Add MaxMessageSize config (1MB default) to prevent memory exhaustion
P2P-CRIT-3: Track pending connections during handshake to enforce connection limits
RESIL-HIGH-1: Add recover() to 4 background goroutines to prevent service crashes
TEST-CRIT-1: Create auth_test.go with 16 tests covering Basic/Digest auth
RESIL-HIGH-3: Implement circuit breaker for GitHub API with caching fallback
Also fixed: NonceExpiry validation in auth.go to prevent panic on zero interval
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Error Handling:
- Fix silent Write() error in WebSocket (events.go)
- Add error context to transport handshake messages
- Check os.MkdirAll error in zip extraction (miner.go)
- Explicitly ignore io.Copy errors on drain with comments
- Add retry logic (2 attempts) for transient stats collection failures
Resource Lifecycle:
- Add shutdown mechanism to DigestAuth goroutine
- Call Service.Stop() on context cancellation
- Add NodeService transport cleanup to Service.Stop()
- Fix WriteStdin goroutine leak on timeout with non-blocking send
API Design:
- Add profile validation (name, miner type required)
- Return 404 instead of 500 for missing profile PUT
- Make DELETE profile idempotent (return success if not found)
- Standardize error responses in node_service.go handlers
Observability:
- Add logging for P2P GetAllStats failures
- Add request ID correlation helper for handler logs
- Add logging for miner process exits (xmrig_start.go)
- Rate limit debug logs in transport hot path (1 in 100)
- Add metrics infrastructure with /metrics endpoint
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>