Every captured commit receives deterministic security triage and a separate communication-quality score. Security candidates and broader second-pass signals receive full-patch Ollama analysis.
Message quality measures whether a commit identifies its scope, purpose, rationale, testing, and supporting references. It does not change the security-severity score.
This commit adds validation checks for BOLT 12 invoices in the LND Lightning node software. It ensures invoices contain required fields (creation time, amount, payment hash, node ID, payment paths), match their originating invoice requests…
New validation gate added to Invoice.Encode() to reject malformed invoices before serializationReader rejects unknown even invoice TLV types and unknown even feature bitsReader enforces chain compatibility against activeChain
This commit is a hardening and cleanup of a GitHub Actions workflow that automatically labels pull requests by severity. It does not change any LND node code, wallet logic, or network protocol. Instead, it splits the workflow into two jobs…
Principle of least privilege: write token moved out of the model-bearing jobUntrusted input (model-generated comment) sanitized before privileged API useExternal action pinned to immutable commit SHA instead of mutable tag
This commit adds a new RPC called SubmitPackage to LND's WalletKit. It lets users submit a group of related Bitcoin transactions together so a zero-fee parent can be accepted because a later child transaction pays its fee. This is a featur…
New RPC endpoint gated by onchain:write macaroon permissionPackage size bounded to 25 transactions to limit deserialization workFee-rate ceiling passed through to backend; explicit 0 disables limit
This commit adds validation checks for BOLT 12 invoice requests in the LND Lightning node. It ensures that invoice requests follow protocol rules when being created (written) and received (read), rejecting malformed or non-compliant reques…
New input validation functions added for protocol messagesValidation now runs before encoding, preventing malformed outbound messagesOverflow guard added for amount*quantity calculation
This is a large dependency upgrade for the LND Lightning node software. It moves LND from older btcd Bitcoin library packages to new 'v2' packages and updates related wallet and network libraries. The commit is almost entirely mechanical i…
Large dependency upgrade touching core Bitcoin primitives (wire, txscript, chainhash, btcutil, psbt, address)Migration to new v2 module layout with API changes in address handlingPins new upstream releases (btcd 0.26.0, btcwallet 0.17.0, neutrino 0.18.0, lightning-onion 1.4.0) that may include undisclosed fixes
This commit fixes a bug in LND's DNS seed bootstrap code that could crash the node. The code assumed every record in a DNS response was an SRV record, so a non-SRV record (like a normal A or CNAME record) would cause a panic. The fix safel…
Unconditional type assertion panic in DNS fallback pathMissing bounds check on LookupHost result before array indexingMissing network deadline on manually dialed DNS TCP connection
This commit removes a temporary security workaround in a Go module file. The workaround forced the use of a newer, fixed version of a compression library (xz) to avoid a known historical vulnerability. The commit message says the library i…
Removal of a dependency-level vulnerability workaroundReference to historical advisory GHSA-25xm-hr59-7c27 in deleted commentNo code changes; only go.mod cleanup
This commit removes an old workaround in LND's dependency file (go.mod) that pinned a safe version of the 'xz' compression library. The workaround was originally added because another dependency once pulled in a vulnerable version of xz. T…
Removal of a dependency override that was a security mitigation for CVE-2021-29482Commit explicitly references the original GHSA advisory (GHSA-25xm-hr59-7c27)No actual downgrade or re-introduction of the vulnerable module is visible in the diff
This commit is a cleanup-only change that removes unnecessary loop-variable copies in Go test files. Since Go 1.22, loop variables are already scoped per-iteration, so the old `x := x` workarounds are redundant. The change affects only tes…
This commit updates a dependency version in LND's build files. It bumps the internal 'kvdb' submodule from version 1.5.0 to 1.5.1 so that downstream projects importing kvdb directly do not pull in an older, vulnerable telemetry library (Op…
Dependency bump explicitly motivated by a known vulnerability identifier (GO-2026-4394)No source code changes in LND itself; only module metadata updatedVendor describes the root build as already unaffected, limiting direct security impact on LND
This commit removes support for obsolete Tor v2 onion addresses from the Lightning Network Daemon (lnd). Tor v2 services were shut down by the Tor network in October 2021, so lnd will no longer create, accept, or dial v2 onion addresses. H…
Removal of deprecated network protocol (Tor v2) reduces attack surface and prevents futile/unsafe dials to unreachable services.Input validation added at operator boundaries (ParseAddressString, parseAddr) to reject v2 .onion addresses with a clear error.On-disk legacy key fallback now validates decrypted key type and rejects non-v3 (RSA1024) keys before passing them to Tor.
This commit fixes a bug in LND's remote-signing setup where zero-value previous transaction outputs were wrongly ignored when preparing a PSBT for a remote signer. The most concrete affected use case is BIP-322 message attestation, where t…
Functional denial-of-service in remote-signer BIP-322 workflows due to PSBT rejectionIncorrect zero-value UTXO validation caused legitimate outputs to be droppedFix removes Value check while preserving non-empty PkScript sanity check
This commit only adds new unit tests for an existing helper function in LND's RPC wallet code. It does not change any production logic, so it cannot introduce a security vulnerability or directly fix one in the code being committed. The te…
This commit removes old, unused code paths for sending Lightning payments through the main RPC server. These RPCs (SendPayment, SendPaymentSync, SendToRoute, SendToRouteSync) were already deleted from the service definition in a prior chan…
Removal of deprecated RPC handlers and macaroon permissionsDeletion of dead payment-dispatch helper codeNo new input parsing, network exposure, or privilege changes introduced
This commit removes three old, deprecated payment RPC methods (SendPayment, SendToRoute, and TrackPayment) from the LND Lightning node's router service. These methods were already replaced by newer V2 versions and were only thin wrappers a…
Removal of deprecated RPC surface reduces attack surfaceMacaroon permission entries for removed methods are deletedNo new code paths or logic added
This change closes a denial-of-service weakness in LND's onion-message forwarding. Previously, an attacker could create unlimited free peer identities and burn through the global byte-budget reserved for onion messages, starving real peers…
Adds a Sybil-resistance gate requiring funded, non-pending channels for onion message ingressChannel gate runs before per-peer and global rate limiters, preventing no-channel peers from consuming any token budgetIntroduces atomic shadow counter for O(1) hot-path checks on every incoming onion packet
This commit only updates test data in a JSON file used for automated tests of Lightning's new taproot channel features. It adds secret nonce values and corrects public nonce values so the test vectors match the expected commitment transact…
No production code modifiedTest-only JSON fixture updateNonce values are part of test vectors, not live secrets
This change adds a hidden switch that lets developers plug in a custom random source when creating MuSig2 signing nonces, mainly so tests can produce exactly the same signatures every time. In normal operation the switch is left empty, so …
New optional custom random source for MuSig2 nonce generationDefault call sites explicitly pass empty option, preserving CSPRNG behaviorCode comments state the option is intended only for reproducible test vectors
This commit only adds new test code and a JSON file of expected test outputs for Taproot Lightning channels. It does not change any production logic, network behavior, or wallet handling. There is no security issue in the commit itself.
This commit only adds a new test to the project's test suite. It does not change any production code, user-facing behavior, or network protocol. The new test cryptographically checks that example transactions in the project's test data car…
Adds independent cryptographic signature verification for test vectorsUses txscript.NewEngine with StandardVerifyFlags to mirror on-chain validationVerifies both the commitment transaction and each HTLC resolution transaction
This commit implements MigrationBulkKVStore for Postgres/pgx. The Postgres wrapper is available through an explicit constructor, so regular Postgres and shared SQLite backends do not expose the migration capability accidentally.
The bulk load transaction pins a dedicated *sql.Conn. InsertLeaves streams rows through pgx COPY inside that transaction. The copied row count is checked against the input to catch partial loads. Bucket rows are inserted individually with RETURNING id so nested buckets can reference their parent.
Verification uses a read-only repeatable-read transaction. It fetches children of a parent-id batch with a native pgx bigint-array and a single ANY($1) query.
Migration transactions honor the WithTxLevelLock used by regular transactions. Loads take the write lock and verification takes the read lock. Commit and Rollback release both the lock and the dedicated connection. Rollback is idempotent and tolerates an already-closed transaction.
78/100 · AdequateMessage clarity
✓ Descriptive subject✓ Names a concrete action or component✓ Provides detailed explanatory context✓ Mentions testing or verification
This commit introduces a migration-only interface set that lets the KV-to-SQL migration load and verify the raw SQL KV schema directly, bypassing the walletdb/kvdb bucket abstraction. Normal application code continues to use the bucket APIs; these helpers exist solely to make the one-time bulk migration fast and verifiable.
MigrationBulkKVStore is the entry point. It exposes CheckEmpty to guard against migrating into a populated table, TruncateTargetTable to recover from an interrupted fresh-only attempt, and two transaction openers: BeginBulk for loading and BeginBulkVerify for batched verification.
The write path inserts buckets one at a time to obtain generated ids. It inserts leaves in batches, leaving the concrete bulk strategy to the backend. The read path walks the tree level with FetchTopLevel and FetchChildren.
MigrationBulkChild uses an explicit IsBucket flag rather than inspecting the value column. This prevents an empty leaf value from being confused with the SQL NULL marker used for buckets.
The interfaces use the same build constraints as the SQL kvdb backends. Backends expose the migration capability explicitly; the first concrete implementation is Postgres-only.
78/100 · AdequateMessage clarity
✓ Descriptive subject✓ Names a concrete action or component✓ Provides detailed explanatory context✓ Mentions testing or verification
✓ Descriptive subject✓ Names a concrete action or component✓ Uses a recognizable type or scope! No meaningful explanatory body
Why it was queued
documentation-only discount
Lower-prioritypeer: never use RBF coop close for aux channelsby Jared Tobin · ceff3ceb · Jul 14, 2026 · 3 filesMessage 76 · AdequateTriage 0Details
Commit message · Jared Tobin
peer: never use RBF coop close for aux channels
The RBF coop close flow was selected purely from the peer-level feature bits (rbfCoopCloseAllowed), with no per-channel exclusion. The RBF close state machine does not invoke any of the aux closer hooks: the Shutdown message it sends carries no aux custom records, and the close transaction it negotiates contains no aux outputs. For a taproot asset (overlay) channel this means the funding output -- which anchors the asset commitment -- is spent by a transaction that does not re-commit the assets, irrevocably destroying them on-chain. The aux closer then fails to finalize the confirmed close (it was never asked to produce vPackets), which blocks the chain watcher's coop close handler and leaves the channel stuck in waiting-close.
See lightninglabs/taproot-assets#2196 for an instance of this happening in the wild.
Extend rbfCoopCloseAllowed to take the channel type: it now requires the RBF feature bits AND that the channel type carries no tapscript root, and is used at every site that chooses between the RBF closer and the legacy negotiate closer. The RBF close actor's own eligibility check is dropped entirely: an actor is only ever registered after initRbfChanCloser has vetted the channel, so the check was redundant. Aux channels now always fall back to the legacy closer, which is aux-aware, regardless of the negotiated feature bits. Since no RBF msg-router endpoint is registered for aux channels, an incoming Shutdown from the peer likewise falls through to the legacy close handling. As a backstop, initRbfChanCloser now refuses to construct an RBF closer for aux channels outright.
76/100 · AdequateMessage clarity
✓ Descriptive subject✓ Names a concrete action or component✓ Provides detailed explanatory context✓ Links an issue, advisory, or supporting reference
On an already-seen channel, the loop returned from the whole node callback instead of continuing, skipping the node's remaining channels, this undercounted the stats.
68/100 · AdequateMessage clarity
✓ Descriptive subject✓ Names a concrete action or component✓ Provides detailed explanatory context
✓ Subject identifies a change✓ Uses a recognizable type or scope! No meaningful explanatory body
Why it was queued
documentation-only discount
Lower-prioritysweep: account for aux extra budget when filtering inputsby Jared Tobin · a9e3e9ae · Jul 9, 2026 · 3 filesMessage 73 · AdequateTriage 0Details
Commit message · Jared Tobin
sweep: account for aux extra budget when filtering inputs
The BudgetAggregator filters out inputs whose budget cannot cover the min relay fee or their requested starting fee rate. For inputs that carry a resolution blob (custom channel outputs), the aux sweeper contributes a sizable extra budget to any input set they join, but the filter only considered the input's own budget, which for asset outputs is tiny (their value is carried off-chain).
The filter is mostly harmless with default parameters, but the starting fee rate of an input is ratcheted whenever a sweep attempt fails, including failures that have nothing to do with fees: e.g. when a concurrent sweep transaction spends the wallet UTXO that was backing this input's set (the sweeper currently doesn't lease selected wallet UTXOs, so concurrent input sets can pick the same one). One such collision is enough to push the required starting fee above a small asset input's own budget, after which the input is filtered out of every future input set and the sweep is silently stranded forever.
Account for the aux extra budget in the filter, mirroring how the budget input set itself accounts for it when deciding whether wallet inputs are needed. Inputs without a resolution blob (the only kind that exists without an aux sweeper) are unaffected.
73/100 · AdequateMessage clarity
✓ Specific, descriptive subject✓ Names a concrete action or component✓ Provides detailed explanatory context
Implement the structural validators for the BOLT 12 invoice, adding ValidateInvoiceWrite, ValidateInvoiceRead, ValidateInvoiceExpiry, and ValidateInvoiceAgainstRequest.
The validators implement the spec writer and reader requirements in the order the spec lists them. The reader confirms the signature TLV is present but defers actual Schnorr verification until the merkle and signing primitives land, mirroring the ValidateInvoiceRequestRead precedent.
This commit adds validation checks for BOLT 12 invoices in the LND Lightning node software. It ensures invoices contain required fields (creation time, amount, payment hash, node ID, payment paths), match their originating invoice requests, and aren't expired or malformed before being encoded or accepted. The change is defensive: it rejects invalid invoices rather than letting them propagate, which helps prevent payment failures, confusion, or minor abuse. Signature verification is explicitly left for a future patch, so this is not a complete security fix on its own.
lnwire: reject onion message payloads with unknown even types
BOLT 4 requires the final node to ignore an onion message whose onionmsg_tlv contains an unknown even type, since even types are "must understand". The TLV stream decoder does not enforce this on its own: its parsed-type map collects unknown types of either parity, so an even type such as 70 would otherwise be accepted as a final hop payload.
Reject any unknown even type during decode, regardless of its range. The check runs before the final hop range skip so unknown even types below type 64 are rejected as well.
85/100 · StrongMessage clarity
✓ Specific, descriptive subject✓ Names a concrete action or component✓ Provides detailed explanatory context✓ Explains rationale or failure mode
Lower-prioritylnwire: reject onion message payloads with multiple final hop fieldsby bitromortac · 233e3777 · Jul 9, 2026 · 2 filesMessage 83 · StrongTriage 0Details
Commit message · bitromortac
lnwire: reject onion message payloads with multiple final hop fields
BOLT 4 requires the final node to ignore an onion message whose onionmsg_tlv contains more than one payload field, where payload fields are the tlv types reserved for the final hop (type 64 and above). Decode previously accumulated every such field it found, so a payload bundling invoice_request, invoice, and invoice_error together was accepted.
Reject the payload when more than one final hop field is present. Every entry collected in FinalHopTLVs is in the final hop range, so its count is the number of payload fields. The round-trip test for multiple fields becomes a rejection test, and the property test now draws at most one payload field.
83/100 · StrongMessage clarity
✓ Specific, descriptive subject✓ Names a concrete action or component✓ Provides detailed explanatory context✓ Mentions testing or verification
lnwire: preserve unknown odd zero-length final hop TLVs
When decoding an onion message payload, the loop that forwards unrecognized final hop TLVs to higher layers skipped any entry with a zero-length value. DecodeWithParsedTypesP2P marks a recognized type with a nil map entry but records the raw bytes for an unknown type, and an unknown odd TLV with an empty value is valid. Keying the skip off a length check therefore dropped such a TLV instead of passing it through.
Test the recognized-type skip against a nil entry so a valid unknown odd zero-length TLV is preserved.
83/100 · StrongMessage clarity
✓ Specific, descriptive subject✓ Names a concrete action or component✓ Provides detailed explanatory context✓ Mentions testing or verification
Add the truncated uint32 (tu32) TLV type used by invoice_relative_expiry and the dynamic invoice subtypes BlindedPayInfo and FallbackAddress, along with their encode/decode helpers and round-trip tests.
These primitives are the building blocks for the BOLT 12 Invoice message struct that follows. Isolating them keeps that codec commit focused on the message shape rather than its component records.
78/100 · AdequateMessage clarity
✓ Descriptive subject✓ Names a concrete action or component✓ Provides detailed explanatory context✓ Mentions testing or verification
bolt12: inject feature-bit catalogues into Offer and InvoiceRequest validators
Inject known feature-bit catalogues into the read-side validators to enable correct must-understand capability checks, and remove write-side feature enforcement entirely.
Whether a feature bit is "unknown" is a runtime property of the reading node, not of the wire format or pure codec.
73/100 · AdequateMessage clarity
✓ Specific, descriptive subject✓ Names a concrete action or component✓ Provides detailed explanatory context
Add the BOLT 12 Invoice message: a struct mirroring the invoice_request fields (types 0-91) plus the invoice-specific fields (types 160-176) and the signature (type 240), together with its pure-TLV Encode/DecodeInvoice codec and the UsableFallbackAddresses accessor that applies the spec's MUST-ignore filter.
Additionally, add the NewInvoiceFromRequest constructor to build an Invoice from a corresponding request. This copies all non-signature fields from the request (including unknown signed-range TLVs via the decodedTLVs sidecar) and mirrors invreq_amount into invoice_amount.
73/100 · AdequateMessage clarity
✓ Descriptive subject✓ Names a concrete action or component✓ Provides detailed explanatory context✓ Names security-relevant behavior explicitly
ci: split PR severity workflow into classify and apply jobs
In this commit, we separate the two concerns in the PR severity workflow: working out the severity, and applying it. The classify job inspects the PR and records its verdict (the severity level, whether to comment, and the comment body) to a few files. A second apply job reads those files and does the mechanical work of setting the label and posting the comment.
Pulling the classification apart from the application keeps each job doing one thing and makes the flow easier to follow. The apply job takes the severity the classifier picked and checks it against the known set before touching a label, and posts the comment from a file via --body-file so the body is handled as plain data. We also turn off checkout credential persistence, since neither job needs a git credential on disk.
85/100 · StrongMessage clarity
✓ Specific, descriptive subject✓ Names a concrete action or component✓ Uses a recognizable type or scope✓ Provides detailed explanatory context
Why it was queued
credential or privilege state
AI analysis · Informational 15/100
This commit is a hardening and cleanup of a GitHub Actions workflow that automatically labels pull requests by severity. It does not change any LND node code, wallet logic, or network protocol. Instead, it splits the workflow into two jobs: a read-only 'classify' job that runs an AI model to decide the severity, and a separate 'apply' job that actually sets the label and posts the comment. The change reduces security risk by keeping write permissions out of the job that processes untrusted pull-request text, pins the external AI action to a fixed commit hash, disables unnecessary git credentials, and adds input sanitization for the model-generated comment. It is a defensive improvement, not a vulnerability fix.
Security candidateci: split issue dedupe into find and post jobsby Olaoluwa Osuntokun · d1ea8687 · Jul 8, 2026 · 1 fileMessage 80 · StrongTriage 8Details
Commit message · Olaoluwa Osuntokun
ci: split issue dedupe into find and post jobs
In this commit, we give the issue dedupe workflow the same shape: one job finds the duplicate candidates, another posts the comment. The find job records the candidate issue numbers to a file, and the post job hands those numbers to comment-on-duplicates.sh, which already validates each number and renders the comment from a fixed template.
Keeping detection and posting apart mirrors how the script is already factored, so the post job ends up a thin wrapper over it. We also drop the unused id-token permission and turn off checkout credential persistence while we're in here.
80/100 · StrongMessage clarity
✓ Descriptive subject✓ Names a concrete action or component✓ Uses a recognizable type or scope✓ Provides detailed explanatory context
Why it was queued
defensive validationcredential or privilege statedocumentation-only discount
Update the gateway-action pin and runtime_ref to the v0.5.0 release commits, and extend the shim for the new inline-command support: a pull_request_review_comment trigger plus comment_in_reply_to input so /gateway dismiss, promote, and explain work as replies on a finding's inline thread. Same fork-PR safety profile as issue_comment — comment events receive no secrets on fork PRs.
Runtime highlights in v0.5.0: /gateway promote (file a finding as an issue and dismiss it), batch dismiss, gateway-approved label with stale-approval retraction, and one review comment per run with a verdict-first body.
68/100 · AdequateMessage clarity
✓ Descriptive subject✓ Names a concrete action or component✓ Provides detailed explanatory context
Why it was queued
access controldocumentation-only discount
Lower-prioritychanstate: match active htlcs by identityby ziggie · 489a6dab · Jul 7, 2026 · 2 filesMessage 78 · AdequateTriage 0Details
Commit message · ziggie
chanstate: match active htlcs by identity
ActiveHtlcs previously matched HTLCs across the local and remote commitment snapshots by hashing the onion blob. The onion blob is routing payload data and can be duplicated by buggy or malicious senders, so it is not a reliable key for identifying the same HTLC on both commitments.
Match on the HTLC's channel identity instead: the channel-level HTLC index combined with the direction of the offer uniquely identifies an offered HTLC within the channel state. A test is added to lock in the new matching behavior.
78/100 · AdequateMessage clarity
✓ Descriptive subject✓ Names a concrete action or component✓ Provides detailed explanatory context✓ Mentions testing or verification
The Copy method omitted the CloseConfirmationHeight and Db fields when cloning an OpenChannel, so the returned copy silently diverged from the original. Copy both fields over so the clone is a faithful copy, which consumers that operate on channel copies rely on.
68/100 · AdequateMessage clarity
✓ Descriptive subject✓ Names a concrete action or component✓ Provides detailed explanatory context
Lower-prioritychanrestore: use channel state open channelby ziggie · 05bea1dd · Jul 7, 2026 · 1 fileMessage 68 · AdequateTriage 0Details
Commit message · ziggie
chanrestore: use channel state open channel
Build restored channel shells with chanstate.OpenChannel instead of the channeldb alias.
The restored shell is channel state data, so this keeps the constructor aligned with the package that now owns the type.
68/100 · AdequateMessage clarity
✓ Descriptive subject✓ Names a concrete action or component✓ Provides detailed explanatory context
Lower-prioritycontractcourt: use channel state open channelby ziggie · e0b86913 · Jul 7, 2026 · 15 filesMessage 68 · AdequateTriage 0Details
Commit message · ziggie
contractcourt: use channel state open channel
Update contractcourt channel and resolver state boundaries to use chanstate.OpenChannel instead of the channeldb alias.
This keeps the contract resolution package depending on channel state data through the package that now owns the type, while leaving channeldb references for store and error types that still belong there.
68/100 · AdequateMessage clarity
✓ Descriptive subject✓ Names a concrete action or component✓ Provides detailed explanatory context