From fb55abc52e65bedecd58d3d118bf4219880ed192 Mon Sep 17 00:00:00 2001 From: Snider Date: Sun, 15 Mar 2026 15:28:59 +0000 Subject: [PATCH 1/5] chore: sync go.mod dependencies Co-Authored-By: Virgil --- go.mod | 34 +++++++++++------------ go.sum | 88 +++++++++++++++++++++++++++++----------------------------- 2 files changed, 61 insertions(+), 61 deletions(-) diff --git a/go.mod b/go.mod index 1d1e1ed..9c6e888 100644 --- a/go.mod +++ b/go.mod @@ -3,23 +3,23 @@ module forge.lthn.ai/core/go-crypt go 1.26.0 require ( - forge.lthn.ai/core/cli v0.3.0 - forge.lthn.ai/core/go v0.3.0 - forge.lthn.ai/core/go-i18n v0.1.0 - forge.lthn.ai/core/go-io v0.1.0 - forge.lthn.ai/core/go-log v0.0.1 - forge.lthn.ai/core/go-store v0.1.3 - github.com/ProtonMail/go-crypto v1.3.0 + forge.lthn.ai/core/cli v0.3.1 + forge.lthn.ai/core/go v0.3.1 + forge.lthn.ai/core/go-i18n v0.1.4 + forge.lthn.ai/core/go-io v0.1.2 + forge.lthn.ai/core/go-log v0.0.4 + forge.lthn.ai/core/go-store v0.1.6 + github.com/ProtonMail/go-crypto v1.4.0 github.com/stretchr/testify v1.11.1 - golang.org/x/crypto v0.48.0 + golang.org/x/crypto v0.49.0 ) require ( - forge.lthn.ai/core/go-inference v0.0.2 // indirect - forge.lthn.ai/core/go-process v0.1.2 // indirect + forge.lthn.ai/core/go-inference v0.1.4 // indirect + forge.lthn.ai/core/go-process v0.2.2 // indirect github.com/aymanbagabas/go-osc52/v2 v2.0.1 // indirect github.com/charmbracelet/bubbletea v1.3.10 // indirect - github.com/charmbracelet/colorprofile v0.4.2 // indirect + github.com/charmbracelet/colorprofile v0.4.3 // indirect github.com/charmbracelet/lipgloss v1.1.1-0.20250404203927-76690c660834 // indirect github.com/charmbracelet/x/ansi v0.11.6 // indirect github.com/charmbracelet/x/cellbuf v0.0.15 // indirect @@ -35,7 +35,7 @@ require ( github.com/lucasb-eyer/go-colorful v1.3.0 // indirect github.com/mattn/go-isatty v0.0.20 // indirect github.com/mattn/go-localereader v0.0.1 // indirect - github.com/mattn/go-runewidth v0.0.20 // indirect + github.com/mattn/go-runewidth v0.0.21 // indirect github.com/muesli/ansi v0.0.0-20230316100256-276c6243b2f6 // indirect github.com/muesli/cancelreader v0.2.2 // indirect github.com/muesli/termenv v0.16.0 // indirect @@ -46,12 +46,12 @@ require ( github.com/spf13/cobra v1.10.2 // indirect github.com/spf13/pflag v1.0.10 // indirect github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e // indirect - golang.org/x/exp v0.0.0-20260218203240-3dfff04db8fa // indirect - golang.org/x/sys v0.41.0 // indirect - golang.org/x/term v0.40.0 // indirect - golang.org/x/text v0.34.0 // indirect + golang.org/x/exp v0.0.0-20260312153236-7ab1446f8b90 // indirect + golang.org/x/sys v0.42.0 // indirect + golang.org/x/term v0.41.0 // indirect + golang.org/x/text v0.35.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect - modernc.org/libc v1.68.0 // indirect + modernc.org/libc v1.70.0 // indirect modernc.org/mathutil v1.7.1 // indirect modernc.org/memory v1.11.0 // indirect modernc.org/sqlite v1.46.1 // indirect diff --git a/go.sum b/go.sum index 11a11e7..f56eeb9 100644 --- a/go.sum +++ b/go.sum @@ -1,27 +1,27 @@ -forge.lthn.ai/core/cli v0.3.0 h1:FpP1Wp4GwhOd+ZHWrjKZUCEnGyWoXOVDTwhytFb6hrA= -forge.lthn.ai/core/cli v0.3.0/go.mod h1:pocya1fKLbIKnNJ9rmfUDqBsH5bg02P426JvDBomcJo= -forge.lthn.ai/core/go v0.3.0 h1:mOG97ApMprwx9Ked62FdWVwXTGSF6JO6m0DrVpoH2Q4= -forge.lthn.ai/core/go v0.3.0/go.mod h1:gE6c8h+PJ2287qNhVUJ5SOe1kopEwHEquvinstpuyJc= -forge.lthn.ai/core/go-i18n v0.1.0 h1:F7JVSoVkZtzx9JfhpntM9z3iQm1vnuMUi/Zklhz8PCI= -forge.lthn.ai/core/go-i18n v0.1.0/go.mod h1:Q4xsrxuNCl/6NfMv1daria7t1RSiyy8ml+6jiPtUcBs= -forge.lthn.ai/core/go-inference v0.0.2 h1:aHjBkYyLKxLr9tbO4AvzzV/lsZueGq/jeo33SLh113k= -forge.lthn.ai/core/go-inference v0.0.2/go.mod h1:jfWz+IJX55wAH98+ic6FEqqGB6/P31CHlg7VY7pxREw= -forge.lthn.ai/core/go-io v0.1.0 h1:aYNvmbU2VVsjXnut0WQ4DfVxcFdheziahJB32mfeJ7g= -forge.lthn.ai/core/go-io v0.1.0/go.mod h1:ZlU9OQpsvNFNmTJoaHbFIkisZyc0eCq0p8znVWQLRf0= -forge.lthn.ai/core/go-log v0.0.1 h1:x/E6EfF9vixzqiLHQOl2KT25HyBcMc9qiBkomqVlpPg= -forge.lthn.ai/core/go-log v0.0.1/go.mod h1:r14MXKOD3LF/sI8XUJQhRk/SZHBE7jAFVuCfgkXoZPw= -forge.lthn.ai/core/go-process v0.1.2 h1:0fdLJq/DPssilN9E5yude/xHNfZRKHghIjo++b5aXgc= -forge.lthn.ai/core/go-process v0.1.2/go.mod h1:9oxVALrZaZCqFe8YDdheIS5bRUV1SBz4tVW/MflAtxM= -forge.lthn.ai/core/go-store v0.1.3 h1:CSVTRdsOXm2pl+FCs12fHOc9eM88DcZRY6HghN98w/I= -forge.lthn.ai/core/go-store v0.1.3/go.mod h1:op+ftjAqYskPv4OGvHZQf7/DLiRnFIdT0XCQTKR/GjE= -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= +forge.lthn.ai/core/cli v0.3.1 h1:ZpHhaDrdbaV98JDxj/f0E5nytYk9tTMRu3qohGyK4M0= +forge.lthn.ai/core/cli v0.3.1/go.mod h1:28cOl9eK0H033Otkjrv9f/QCmtHcJl+IIx4om8JskOg= +forge.lthn.ai/core/go v0.3.1 h1:5FMTsUhLcxSr07F9q3uG0Goy4zq4eLivoqi8shSY4UM= +forge.lthn.ai/core/go v0.3.1/go.mod h1:gE6c8h+PJ2287qNhVUJ5SOe1kopEwHEquvinstpuyJc= +forge.lthn.ai/core/go-i18n v0.1.4 h1:zOHUUJDgRo88/3tj++kN+VELg/buyZ4T2OSdG3HBbLQ= +forge.lthn.ai/core/go-i18n v0.1.4/go.mod h1:aDyAfz7MMgWYgLkZCptfFmZ7jJg3ocwjEJ1WkJSvv4U= +forge.lthn.ai/core/go-inference v0.1.4 h1:fuAgWbqsEDajHniqAKyvHYbRcBrkGEiGSqR2pfTMRY0= +forge.lthn.ai/core/go-inference v0.1.4/go.mod h1:jfWz+IJX55wAH98+ic6FEqqGB6/P31CHlg7VY7pxREw= +forge.lthn.ai/core/go-io v0.1.2 h1:q8hj2jtOFqAgHlBr5wsUAOXtaFkxy9gqGrQT/il0WYA= +forge.lthn.ai/core/go-io v0.1.2/go.mod h1:PbNKW1Q25ywSOoQXeGdQHbV5aiIrTXvHIQ5uhplA//g= +forge.lthn.ai/core/go-log v0.0.4 h1:KTuCEPgFmuM8KJfnyQ8vPOU1Jg654W74h8IJvfQMfv0= +forge.lthn.ai/core/go-log v0.0.4/go.mod h1:r14MXKOD3LF/sI8XUJQhRk/SZHBE7jAFVuCfgkXoZPw= +forge.lthn.ai/core/go-process v0.2.2 h1:bnHFtzg92udochDDB6bD2luzzmr9ETKWmGzSsGjFFYE= +forge.lthn.ai/core/go-process v0.2.2/go.mod h1:gVTbxL16ccUIexlFcyDtCy7LfYvD8Rtyzfo8bnXAXrU= +forge.lthn.ai/core/go-store v0.1.6 h1:7T+K5cciXOaWRxge0WnGkt0PcK3epliWBa1G2FLEuac= +forge.lthn.ai/core/go-store v0.1.6/go.mod h1:/2vqaAn+HgGU14N29B+vIfhjIsBzy7RC+AluI6BIUKI= +github.com/ProtonMail/go-crypto v1.4.0 h1:Zq/pbM3F5DFgJiMouxEdSVY44MVoQNEKp5d5QxIQceQ= +github.com/ProtonMail/go-crypto v1.4.0/go.mod h1:e1OaTyu5SYVrO9gKOEhTc+5UcXtTUa+P3uLudwcgPqo= github.com/aymanbagabas/go-osc52/v2 v2.0.1 h1:HwpRHbFMcZLEVr42D4p7XBqjyuxQH5SMiErDT4WkJ2k= github.com/aymanbagabas/go-osc52/v2 v2.0.1/go.mod h1:uYgXzlJ7ZpABp8OJ+exZzJJhRNQ2ASbcXHWsFqH8hp8= github.com/charmbracelet/bubbletea v1.3.10 h1:otUDHWMMzQSB0Pkc87rm691KZ3SWa4KUlvF9nRvCICw= github.com/charmbracelet/bubbletea v1.3.10/go.mod h1:ORQfo0fk8U+po9VaNvnV95UPWA1BitP1E0N6xJPlHr4= -github.com/charmbracelet/colorprofile v0.4.2 h1:BdSNuMjRbotnxHSfxy+PCSa4xAmz7szw70ktAtWRYrY= -github.com/charmbracelet/colorprofile v0.4.2/go.mod h1:0rTi81QpwDElInthtrQ6Ni7cG0sDtwAd4C4le060fT8= +github.com/charmbracelet/colorprofile v0.4.3 h1:QPa1IWkYI+AOB+fE+mg/5/4HRMZcaXex9t5KX76i20Q= +github.com/charmbracelet/colorprofile v0.4.3/go.mod h1:/zT4BhpD5aGFpqQQqw7a+VtHCzu+zrQtt1zhMt9mR4Q= github.com/charmbracelet/lipgloss v1.1.1-0.20250404203927-76690c660834 h1:ZR7e0ro+SZZiIZD7msJyA+NjkCNNavuiPBLgerbOziE= github.com/charmbracelet/lipgloss v1.1.1-0.20250404203927-76690c660834/go.mod h1:aKC/t2arECF6rNOnaKaVU6y4t4ZeHQzqfxedE/VkVhA= github.com/charmbracelet/x/ansi v0.11.6 h1:GhV21SiDz/45W9AnV2R61xZMRri5NlLnl6CVF7ihZW8= @@ -61,8 +61,8 @@ github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWE github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/mattn/go-localereader v0.0.1 h1:ygSAOl7ZXTx4RdPYinUpg6W99U8jWvWi9Ye2JC/oIi4= github.com/mattn/go-localereader v0.0.1/go.mod h1:8fBrzywKY7BI3czFoHkuzRoWE9C+EiG4R1k4Cjx5p88= -github.com/mattn/go-runewidth v0.0.20 h1:WcT52H91ZUAwy8+HUkdM3THM6gXqXuLJi9O3rjcQQaQ= -github.com/mattn/go-runewidth v0.0.20/go.mod h1:XBkDxAl56ILZc9knddidhrOlY5R/pDhgLpndooCuJAs= +github.com/mattn/go-runewidth v0.0.21 h1:jJKAZiQH+2mIinzCJIaIG9Be1+0NR+5sz/lYEEjdM8w= +github.com/mattn/go-runewidth v0.0.21/go.mod h1:XBkDxAl56ILZc9knddidhrOlY5R/pDhgLpndooCuJAs= github.com/muesli/ansi v0.0.0-20230316100256-276c6243b2f6 h1:ZK8zHtRHOkbHy6Mmr5D264iyp3TiX5OmNcI5cIARiQI= github.com/muesli/ansi v0.0.0-20230316100256-276c6243b2f6/go.mod h1:CJlz5H+gyd6CUWT45Oy4q24RdLyn7Md9Vj2/ldJBSIo= github.com/muesli/cancelreader v0.2.2 h1:3I4Kt4BQjOR54NavqnDogx/MIoWBFa0StPA8ELUXHmA= @@ -90,24 +90,24 @@ github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e h1:JVG44RsyaB9T2KIHavMF/ppJZNG9ZpyihvCd0w101no= github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e/go.mod h1:RbqR21r5mrJuqunuUZ/Dhy/avygyECGrLceyNeo4LiM= go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg= -golang.org/x/crypto v0.48.0 h1:/VRzVqiRSggnhY7gNRxPauEQ5Drw9haKdM0jqfcCFts= -golang.org/x/crypto v0.48.0/go.mod h1:r0kV5h3qnFPlQnBSrULhlsRfryS2pmewsg+XfMgkVos= -golang.org/x/exp v0.0.0-20260218203240-3dfff04db8fa h1:Zt3DZoOFFYkKhDT3v7Lm9FDMEV06GpzjG2jrqW+QTE0= -golang.org/x/exp v0.0.0-20260218203240-3dfff04db8fa/go.mod h1:K79w1Vqn7PoiZn+TkNpx3BUWUQksGO3JcVX6qIjytmA= -golang.org/x/mod v0.33.0 h1:tHFzIWbBifEmbwtGz65eaWyGiGZatSrT9prnU8DbVL8= -golang.org/x/mod v0.33.0/go.mod h1:swjeQEj+6r7fODbD2cqrnje9PnziFuw4bmLbBZFrQ5w= -golang.org/x/sync v0.19.0 h1:vV+1eWNmZ5geRlYjzm2adRgW2/mcpevXNg50YZtPCE4= -golang.org/x/sync v0.19.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI= +golang.org/x/crypto v0.49.0 h1:+Ng2ULVvLHnJ/ZFEq4KdcDd/cfjrrjjNSXNzxg0Y4U4= +golang.org/x/crypto v0.49.0/go.mod h1:ErX4dUh2UM+CFYiXZRTcMpEcN8b/1gxEuv3nODoYtCA= +golang.org/x/exp v0.0.0-20260312153236-7ab1446f8b90 h1:jiDhWWeC7jfWqR9c/uplMOqJ0sbNlNWv0UkzE0vX1MA= +golang.org/x/exp v0.0.0-20260312153236-7ab1446f8b90/go.mod h1:xE1HEv6b+1SCZ5/uscMRjUBKtIxworgEcEi+/n9NQDQ= +golang.org/x/mod v0.34.0 h1:xIHgNUUnW6sYkcM5Jleh05DvLOtwc6RitGHbDk4akRI= +golang.org/x/mod v0.34.0/go.mod h1:ykgH52iCZe79kzLLMhyCUzhMci+nQj+0XkbXpNYtVjY= +golang.org/x/sync v0.20.0 h1:e0PTpb7pjO8GAtTs2dQ6jYa5BWYlMuX047Dco/pItO4= +golang.org/x/sync v0.20.0/go.mod h1:9xrNwdLfx4jkKbNva9FpL6vEN7evnE43NNNJQ2LF3+0= golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.41.0 h1:Ivj+2Cp/ylzLiEU89QhWblYnOE9zerudt9Ftecq2C6k= -golang.org/x/sys v0.41.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= -golang.org/x/term v0.40.0 h1:36e4zGLqU4yhjlmxEaagx2KuYbJq3EwY8K943ZsHcvg= -golang.org/x/term v0.40.0/go.mod h1:w2P8uVp06p2iyKKuvXIm7N/y0UCRt3UfJTfZ7oOpglM= -golang.org/x/text v0.34.0 h1:oL/Qq0Kdaqxa1KbNeMKwQq0reLCCaFtqu2eNuSeNHbk= -golang.org/x/text v0.34.0/go.mod h1:homfLqTYRFyVYemLBFl5GgL/DWEiH5wcsQ5gSh1yziA= -golang.org/x/tools v0.42.0 h1:uNgphsn75Tdz5Ji2q36v/nsFSfR/9BRFvqhGBaJGd5k= -golang.org/x/tools v0.42.0/go.mod h1:Ma6lCIwGZvHK6XtgbswSoWroEkhugApmsXyrUmBhfr0= +golang.org/x/sys v0.42.0 h1:omrd2nAlyT5ESRdCLYdm3+fMfNFE/+Rf4bDIQImRJeo= +golang.org/x/sys v0.42.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw= +golang.org/x/term v0.41.0 h1:QCgPso/Q3RTJx2Th4bDLqML4W6iJiaXFq2/ftQF13YU= +golang.org/x/term v0.41.0/go.mod h1:3pfBgksrReYfZ5lvYM0kSO0LIkAl4Yl2bXOkKP7Ec2A= +golang.org/x/text v0.35.0 h1:JOVx6vVDFokkpaq1AEptVzLTpDe9KGpj5tR4/X+ybL8= +golang.org/x/text v0.35.0/go.mod h1:khi/HExzZJ2pGnjenulevKNX1W67CUy0AsXcNubPGCA= +golang.org/x/tools v0.43.0 h1:12BdW9CeB3Z+J/I/wj34VMl8X+fEXBxVR90JeMX5E7s= +golang.org/x/tools v0.43.0/go.mod h1:uHkMso649BX2cZK6+RpuIPXS3ho2hZo4FVwfoy1vIk0= 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/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= @@ -115,18 +115,18 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= modernc.org/cc/v4 v4.27.1 h1:9W30zRlYrefrDV2JE2O8VDtJ1yPGownxciz5rrbQZis= modernc.org/cc/v4 v4.27.1/go.mod h1:uVtb5OGqUKpoLWhqwNQo/8LwvoiEBLvZXIQ/SmO6mL0= -modernc.org/ccgo/v4 v4.30.2 h1:4yPaaq9dXYXZ2V8s1UgrC3KIj580l2N4ClrLwnbv2so= -modernc.org/ccgo/v4 v4.30.2/go.mod h1:yZMnhWEdW0qw3EtCndG1+ldRrVGS+bIwyWmAWzS0XEw= -modernc.org/fileutil v1.3.40 h1:ZGMswMNc9JOCrcrakF1HrvmergNLAmxOPjizirpfqBA= -modernc.org/fileutil v1.3.40/go.mod h1:HxmghZSZVAz/LXcMNwZPA/DRrQZEVP9VX0V4LQGQFOc= +modernc.org/ccgo/v4 v4.32.0 h1:hjG66bI/kqIPX1b2yT6fr/jt+QedtP2fqojG2VrFuVw= +modernc.org/ccgo/v4 v4.32.0/go.mod h1:6F08EBCx5uQc38kMGl+0Nm0oWczoo1c7cgpzEry7Uc0= +modernc.org/fileutil v1.4.0 h1:j6ZzNTftVS054gi281TyLjHPp6CPHr2KCxEXjEbD6SM= +modernc.org/fileutil v1.4.0/go.mod h1:EqdKFDxiByqxLk8ozOxObDSfcVOv/54xDs/DUHdvCUU= modernc.org/gc/v2 v2.6.5 h1:nyqdV8q46KvTpZlsw66kWqwXRHdjIlJOhG6kxiV/9xI= modernc.org/gc/v2 v2.6.5/go.mod h1:YgIahr1ypgfe7chRuJi2gD7DBQiKSLMPgBQe9oIiito= modernc.org/gc/v3 v3.1.2 h1:ZtDCnhonXSZexk/AYsegNRV1lJGgaNZJuKjJSWKyEqo= modernc.org/gc/v3 v3.1.2/go.mod h1:HFK/6AGESC7Ex+EZJhJ2Gni6cTaYpSMmU/cT9RmlfYY= modernc.org/goabi0 v0.2.0 h1:HvEowk7LxcPd0eq6mVOAEMai46V+i7Jrj13t4AzuNks= modernc.org/goabi0 v0.2.0/go.mod h1:CEFRnnJhKvWT1c1JTI3Avm+tgOWbkOu5oPA8eH8LnMI= -modernc.org/libc v1.68.0 h1:PJ5ikFOV5pwpW+VqCK1hKJuEWsonkIJhhIXyuF/91pQ= -modernc.org/libc v1.68.0/go.mod h1:NnKCYeoYgsEqnY3PgvNgAeaJnso968ygU8Z0DxjoEc0= +modernc.org/libc v1.70.0 h1:U58NawXqXbgpZ/dcdS9kMshu08aiA6b7gusEusqzNkw= +modernc.org/libc v1.70.0/go.mod h1:OVmxFGP1CI/Z4L3E0Q3Mf1PDE0BucwMkcXjjLntvHJo= modernc.org/mathutil v1.7.1 h1:GCZVGXdaN8gTqB1Mf/usp1Y/hSqgI2vAGGP4jZMCxOU= modernc.org/mathutil v1.7.1/go.mod h1:4p5IwJITfppl0G4sUEDtCr4DthTaT47/N3aT6MhfgJg= modernc.org/memory v1.11.0 h1:o4QC8aMQzmcwCK3t3Ux/ZHmwFPzE6hf2Y5LbkRs+hbI= From 39643ddba0f0ca4697f6771244f0d61f03c2bbcd Mon Sep 17 00:00:00 2001 From: Snider Date: Mon, 16 Mar 2026 18:15:55 +0000 Subject: [PATCH 2/5] fix: replace fmt.Errorf and errors.New with coreerr.E() Replace all fmt.Errorf/errors.New calls in auth/auth.go, crypt/pgp/pgp.go, crypt/rsa/rsa.go, crypt/chachapoly/chachapoly.go, and trust/trust.go with coreerr.E(op, msg, err) from go-log. No stale pkg/framework imports found. Co-Authored-By: Virgil --- auth/auth.go | 17 ++++++---- crypt/chachapoly/chachapoly.go | 4 ++- crypt/pgp/pgp.go | 60 ++++++++++++++++++++-------------- crypt/rsa/rsa.go | 29 +++++++++------- trust/trust.go | 7 ++-- 5 files changed, 70 insertions(+), 47 deletions(-) diff --git a/auth/auth.go b/auth/auth.go index 85fd915..6a6faa8 100644 --- a/auth/auth.go +++ b/auth/auth.go @@ -30,7 +30,6 @@ import ( "crypto/rand" "encoding/hex" "encoding/json" - "errors" "fmt" "strings" "sync" @@ -642,16 +641,18 @@ func (a *Authenticator) ReadResponseFile(userID, path string) (*Session, error) // Tries Argon2id (.hash) first, then falls back to legacy LTHN (.lthn). // Returns nil on success, or an error describing the failure. func (a *Authenticator) verifyPassword(userID, password string) error { + const op = "auth.verifyPassword" + // Try Argon2id hash first (.hash file) if a.medium.IsFile(userPath(userID, ".hash")) { storedHash, err := a.medium.Read(userPath(userID, ".hash")) if err == nil && strings.HasPrefix(storedHash, "$argon2id$") { valid, verr := crypt.VerifyPassword(password, storedHash) if verr != nil { - return errors.New("failed to verify password") + return coreerr.E(op, "failed to verify password", nil) } if !valid { - return errors.New("invalid password") + return coreerr.E(op, "invalid password", nil) } return nil } @@ -660,10 +661,10 @@ func (a *Authenticator) verifyPassword(userID, password string) error { // Fall back to legacy LTHN hash (.lthn file) storedHash, err := a.medium.Read(userPath(userID, ".lthn")) if err != nil { - return errors.New("user not found") + return coreerr.E(op, "user not found", nil) } if !lthn.Verify(password, storedHash) { - return errors.New("invalid password") + return coreerr.E(op, "invalid password", nil) } return nil } @@ -671,9 +672,11 @@ func (a *Authenticator) verifyPassword(userID, password string) error { // createSession generates a cryptographically random session token and // stores the session via the SessionStore. func (a *Authenticator) createSession(userID string) (*Session, error) { + const op = "auth.createSession" + tokenBytes := make([]byte, 32) if _, err := rand.Read(tokenBytes); err != nil { - return nil, fmt.Errorf("auth: failed to generate session token: %w", err) + return nil, coreerr.E(op, "failed to generate session token", err) } session := &Session{ @@ -683,7 +686,7 @@ func (a *Authenticator) createSession(userID string) (*Session, error) { } if err := a.store.Set(session); err != nil { - return nil, fmt.Errorf("auth: failed to persist session: %w", err) + return nil, coreerr.E(op, "failed to persist session", err) } return session, nil diff --git a/crypt/chachapoly/chachapoly.go b/crypt/chachapoly/chachapoly.go index 2520c67..7a1f326 100644 --- a/crypt/chachapoly/chachapoly.go +++ b/crypt/chachapoly/chachapoly.go @@ -5,6 +5,8 @@ import ( "fmt" "io" + coreerr "forge.lthn.ai/core/go-log" + "golang.org/x/crypto/chacha20poly1305" ) @@ -32,7 +34,7 @@ func Decrypt(ciphertext []byte, key []byte) ([]byte, error) { minLen := aead.NonceSize() + aead.Overhead() if len(ciphertext) < minLen { - return nil, fmt.Errorf("ciphertext too short: got %d bytes, need at least %d bytes", len(ciphertext), minLen) + return nil, coreerr.E("chachapoly.Decrypt", fmt.Sprintf("ciphertext too short: got %d bytes, need at least %d bytes", len(ciphertext), minLen), nil) } nonce, ciphertext := ciphertext[:aead.NonceSize()], ciphertext[aead.NonceSize():] diff --git a/crypt/pgp/pgp.go b/crypt/pgp/pgp.go index 67170d5..627c43b 100644 --- a/crypt/pgp/pgp.go +++ b/crypt/pgp/pgp.go @@ -6,10 +6,10 @@ package pgp import ( "bytes" - "errors" - "fmt" "io" + coreerr "forge.lthn.ai/core/go-log" + "github.com/ProtonMail/go-crypto/openpgp" "github.com/ProtonMail/go-crypto/openpgp/armor" "github.com/ProtonMail/go-crypto/openpgp/packet" @@ -25,9 +25,11 @@ type KeyPair struct { // If password is non-empty, the private key is encrypted with it. // Returns a KeyPair with armored public and private keys. func CreateKeyPair(name, email, password string) (*KeyPair, error) { + const op = "pgp.CreateKeyPair" + entity, err := openpgp.NewEntity(name, "", email, nil) if err != nil { - return nil, fmt.Errorf("pgp: failed to create entity: %w", err) + return nil, coreerr.E(op, "failed to create entity", err) } // Sign all the identities @@ -39,12 +41,12 @@ func CreateKeyPair(name, email, password string) (*KeyPair, error) { if password != "" { err = entity.PrivateKey.Encrypt([]byte(password)) if err != nil { - return nil, fmt.Errorf("pgp: failed to encrypt private key: %w", err) + return nil, coreerr.E(op, "failed to encrypt private key", err) } for _, subkey := range entity.Subkeys { err = subkey.PrivateKey.Encrypt([]byte(password)) if err != nil { - return nil, fmt.Errorf("pgp: failed to encrypt subkey: %w", err) + return nil, coreerr.E(op, "failed to encrypt subkey", err) } } } @@ -53,11 +55,11 @@ func CreateKeyPair(name, email, password string) (*KeyPair, error) { pubKeyBuf := new(bytes.Buffer) pubKeyWriter, err := armor.Encode(pubKeyBuf, openpgp.PublicKeyType, nil) if err != nil { - return nil, fmt.Errorf("pgp: failed to create armored public key writer: %w", err) + return nil, coreerr.E(op, "failed to create armored public key writer", err) } if err := entity.Serialize(pubKeyWriter); err != nil { pubKeyWriter.Close() - return nil, fmt.Errorf("pgp: failed to serialize public key: %w", err) + return nil, coreerr.E(op, "failed to serialize public key", err) } pubKeyWriter.Close() @@ -65,18 +67,18 @@ func CreateKeyPair(name, email, password string) (*KeyPair, error) { privKeyBuf := new(bytes.Buffer) privKeyWriter, err := armor.Encode(privKeyBuf, openpgp.PrivateKeyType, nil) if err != nil { - return nil, fmt.Errorf("pgp: failed to create armored private key writer: %w", err) + return nil, coreerr.E(op, "failed to create armored private key writer", err) } if password != "" { // Manual serialization to avoid re-signing encrypted keys if err := serializeEncryptedEntity(privKeyWriter, entity); err != nil { privKeyWriter.Close() - return nil, fmt.Errorf("pgp: failed to serialize private key: %w", err) + return nil, coreerr.E(op, "failed to serialize private key", err) } } else { if err := entity.SerializePrivate(privKeyWriter, nil); err != nil { privKeyWriter.Close() - return nil, fmt.Errorf("pgp: failed to serialize private key: %w", err) + return nil, coreerr.E(op, "failed to serialize private key", err) } } privKeyWriter.Close() @@ -115,27 +117,29 @@ func serializeEncryptedEntity(w io.Writer, e *openpgp.Entity) error { // Encrypt encrypts data for the recipient identified by their armored public key. // Returns the encrypted data as armored PGP output. func Encrypt(data []byte, publicKeyArmor string) ([]byte, error) { + const op = "pgp.Encrypt" + keyring, err := openpgp.ReadArmoredKeyRing(bytes.NewReader([]byte(publicKeyArmor))) if err != nil { - return nil, fmt.Errorf("pgp: failed to read public key ring: %w", err) + return nil, coreerr.E(op, "failed to read public key ring", err) } buf := new(bytes.Buffer) armoredWriter, err := armor.Encode(buf, "PGP MESSAGE", nil) if err != nil { - return nil, fmt.Errorf("pgp: failed to create armor encoder: %w", err) + return nil, coreerr.E(op, "failed to create armor encoder", err) } w, err := openpgp.Encrypt(armoredWriter, keyring, nil, nil, nil) if err != nil { armoredWriter.Close() - return nil, fmt.Errorf("pgp: failed to create encryption writer: %w", err) + return nil, coreerr.E(op, "failed to create encryption writer", err) } if _, err := w.Write(data); err != nil { w.Close() armoredWriter.Close() - return nil, fmt.Errorf("pgp: failed to write data: %w", err) + return nil, coreerr.E(op, "failed to write data", err) } w.Close() armoredWriter.Close() @@ -146,16 +150,18 @@ func Encrypt(data []byte, publicKeyArmor string) ([]byte, error) { // Decrypt decrypts armored PGP data using the given armored private key. // If the private key is encrypted, the password is used to decrypt it first. func Decrypt(data []byte, privateKeyArmor, password string) ([]byte, error) { + const op = "pgp.Decrypt" + keyring, err := openpgp.ReadArmoredKeyRing(bytes.NewReader([]byte(privateKeyArmor))) if err != nil { - return nil, fmt.Errorf("pgp: failed to read private key ring: %w", err) + return nil, coreerr.E(op, "failed to read private key ring", err) } // Decrypt the private key if it is encrypted for _, entity := range keyring { if entity.PrivateKey != nil && entity.PrivateKey.Encrypted { if err := entity.PrivateKey.Decrypt([]byte(password)); err != nil { - return nil, fmt.Errorf("pgp: failed to decrypt private key: %w", err) + return nil, coreerr.E(op, "failed to decrypt private key", err) } } for _, subkey := range entity.Subkeys { @@ -168,17 +174,17 @@ func Decrypt(data []byte, privateKeyArmor, password string) ([]byte, error) { // Decode armored message block, err := armor.Decode(bytes.NewReader(data)) if err != nil { - return nil, fmt.Errorf("pgp: failed to decode armored message: %w", err) + return nil, coreerr.E(op, "failed to decode armored message", err) } md, err := openpgp.ReadMessage(block.Body, keyring, nil, nil) if err != nil { - return nil, fmt.Errorf("pgp: failed to read message: %w", err) + return nil, coreerr.E(op, "failed to read message", err) } plaintext, err := io.ReadAll(md.UnverifiedBody) if err != nil { - return nil, fmt.Errorf("pgp: failed to read plaintext: %w", err) + return nil, coreerr.E(op, "failed to read plaintext", err) } return plaintext, nil @@ -188,19 +194,21 @@ func Decrypt(data []byte, privateKeyArmor, password string) ([]byte, error) { // the armored private key. If the key is encrypted, the password is used // to decrypt it first. func Sign(data []byte, privateKeyArmor, password string) ([]byte, error) { + const op = "pgp.Sign" + keyring, err := openpgp.ReadArmoredKeyRing(bytes.NewReader([]byte(privateKeyArmor))) if err != nil { - return nil, fmt.Errorf("pgp: failed to read private key ring: %w", err) + return nil, coreerr.E(op, "failed to read private key ring", err) } signer := keyring[0] if signer.PrivateKey == nil { - return nil, errors.New("pgp: private key not found in keyring") + return nil, coreerr.E(op, "private key not found in keyring", nil) } if signer.PrivateKey.Encrypted { if err := signer.PrivateKey.Decrypt([]byte(password)); err != nil { - return nil, fmt.Errorf("pgp: failed to decrypt private key: %w", err) + return nil, coreerr.E(op, "failed to decrypt private key", err) } } @@ -208,7 +216,7 @@ func Sign(data []byte, privateKeyArmor, password string) ([]byte, error) { config := &packet.Config{} err = openpgp.ArmoredDetachSign(buf, signer, bytes.NewReader(data), config) if err != nil { - return nil, fmt.Errorf("pgp: failed to sign message: %w", err) + return nil, coreerr.E(op, "failed to sign message", err) } return buf.Bytes(), nil @@ -217,14 +225,16 @@ func Sign(data []byte, privateKeyArmor, password string) ([]byte, error) { // Verify verifies an armored detached signature against the given data // and armored public key. Returns nil if the signature is valid. func Verify(data, signature []byte, publicKeyArmor string) error { + const op = "pgp.Verify" + keyring, err := openpgp.ReadArmoredKeyRing(bytes.NewReader([]byte(publicKeyArmor))) if err != nil { - return fmt.Errorf("pgp: failed to read public key ring: %w", err) + return coreerr.E(op, "failed to read public key ring", err) } _, err = openpgp.CheckArmoredDetachedSignature(keyring, bytes.NewReader(data), bytes.NewReader(signature), nil) if err != nil { - return fmt.Errorf("pgp: signature verification failed: %w", err) + return coreerr.E(op, "signature verification failed", err) } return nil diff --git a/crypt/rsa/rsa.go b/crypt/rsa/rsa.go index 9f1cd0c..a20ea0d 100644 --- a/crypt/rsa/rsa.go +++ b/crypt/rsa/rsa.go @@ -6,8 +6,9 @@ import ( "crypto/sha256" "crypto/x509" "encoding/pem" - "errors" "fmt" + + coreerr "forge.lthn.ai/core/go-log" ) // Service provides RSA functionality. @@ -20,12 +21,14 @@ func NewService() *Service { // GenerateKeyPair creates a new RSA key pair. func (s *Service) GenerateKeyPair(bits int) (publicKey, privateKey []byte, err error) { + const op = "rsa.GenerateKeyPair" + if bits < 2048 { - return nil, nil, fmt.Errorf("rsa: key size too small: %d (minimum 2048)", bits) + return nil, nil, coreerr.E(op, fmt.Sprintf("key size too small: %d (minimum 2048)", bits), nil) } privKey, err := rsa.GenerateKey(rand.Reader, bits) if err != nil { - return nil, nil, fmt.Errorf("failed to generate private key: %w", err) + return nil, nil, coreerr.E(op, "failed to generate private key", err) } privKeyBytes := x509.MarshalPKCS1PrivateKey(privKey) @@ -36,7 +39,7 @@ func (s *Service) GenerateKeyPair(bits int) (publicKey, privateKey []byte, err e pubKeyBytes, err := x509.MarshalPKIXPublicKey(&privKey.PublicKey) if err != nil { - return nil, nil, fmt.Errorf("failed to marshal public key: %w", err) + return nil, nil, coreerr.E(op, "failed to marshal public key", err) } pubKeyPEM := pem.EncodeToMemory(&pem.Block{ Type: "PUBLIC KEY", @@ -48,24 +51,26 @@ func (s *Service) GenerateKeyPair(bits int) (publicKey, privateKey []byte, err e // Encrypt encrypts data with a public key. func (s *Service) Encrypt(publicKey, data, label []byte) ([]byte, error) { + const op = "rsa.Encrypt" + block, _ := pem.Decode(publicKey) if block == nil { - return nil, errors.New("failed to decode public key") + return nil, coreerr.E(op, "failed to decode public key", nil) } pub, err := x509.ParsePKIXPublicKey(block.Bytes) if err != nil { - return nil, fmt.Errorf("failed to parse public key: %w", err) + return nil, coreerr.E(op, "failed to parse public key", err) } rsaPub, ok := pub.(*rsa.PublicKey) if !ok { - return nil, errors.New("not an RSA public key") + return nil, coreerr.E(op, "not an RSA public key", nil) } ciphertext, err := rsa.EncryptOAEP(sha256.New(), rand.Reader, rsaPub, data, label) if err != nil { - return nil, fmt.Errorf("failed to encrypt data: %w", err) + return nil, coreerr.E(op, "failed to encrypt data", err) } return ciphertext, nil @@ -73,19 +78,21 @@ func (s *Service) Encrypt(publicKey, data, label []byte) ([]byte, error) { // Decrypt decrypts data with a private key. func (s *Service) Decrypt(privateKey, ciphertext, label []byte) ([]byte, error) { + const op = "rsa.Decrypt" + block, _ := pem.Decode(privateKey) if block == nil { - return nil, errors.New("failed to decode private key") + return nil, coreerr.E(op, "failed to decode private key", nil) } priv, err := x509.ParsePKCS1PrivateKey(block.Bytes) if err != nil { - return nil, fmt.Errorf("failed to parse private key: %w", err) + return nil, coreerr.E(op, "failed to parse private key", err) } plaintext, err := rsa.DecryptOAEP(sha256.New(), rand.Reader, priv, ciphertext, label) if err != nil { - return nil, fmt.Errorf("failed to decrypt data: %w", err) + return nil, coreerr.E(op, "failed to decrypt data", err) } return plaintext, nil diff --git a/trust/trust.go b/trust/trust.go index 69e4a24..9794a6e 100644 --- a/trust/trust.go +++ b/trust/trust.go @@ -11,11 +11,12 @@ package trust import ( - "errors" "fmt" "iter" "sync" "time" + + coreerr "forge.lthn.ai/core/go-log" ) // Tier represents an agent's trust level in the system. @@ -98,10 +99,10 @@ func NewRegistry() *Registry { // Returns an error if the agent name is empty or the tier is invalid. func (r *Registry) Register(agent Agent) error { if agent.Name == "" { - return errors.New("trust.Register: agent name is required") + return coreerr.E("trust.Register", "agent name is required", nil) } if !agent.Tier.Valid() { - return fmt.Errorf("trust.Register: invalid tier %d for agent %q", agent.Tier, agent.Name) + return coreerr.E("trust.Register", fmt.Sprintf("invalid tier %d for agent %q", agent.Tier, agent.Name), nil) } if agent.CreatedAt.IsZero() { agent.CreatedAt = time.Now() From eacbb025b3d4b3cb17f0a3b9fa86dfdf30307fe2 Mon Sep 17 00:00:00 2001 From: Snider Date: Mon, 16 Mar 2026 18:41:47 +0000 Subject: [PATCH 3/5] fix(rsa): update test for Go 1.26 GenerateKey resilience Go 1.26 rsa.GenerateKey recovers from reader errors internally. Test now verifies no panic instead of expecting an error. Co-Authored-By: Virgil --- crypt/rsa/rsa_test.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/crypt/rsa/rsa_test.go b/crypt/rsa/rsa_test.go index c78d91d..7211995 100644 --- a/crypt/rsa/rsa_test.go +++ b/crypt/rsa/rsa_test.go @@ -69,12 +69,12 @@ func TestRSA_Ugly(t *testing.T) { _, err = s.Decrypt([]byte("-----BEGIN RSA PRIVATE KEY-----\nMIIBOQIBAAJBAL/6j/y7/r/9/z/8/f/+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+\nv/7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v4CAwEAAQJB\nAL/6j/y7/r/9/z/8/f/+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+\nv/7+/v7+/v7+/v7+/v7+/v7+/v7+/v4CgYEA/f8/vLv+v/3/P/z9//7+/v7+/v7+\nvv7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v4C\ngYEA/f8/vLv+v/3/P/z9//7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+\nvv7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v4CgYEA/f8/vLv+v/3/P/z9//7+/v7+\nvv7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+\nv/4CgYEA/f8/vLv+v/3/P/z9//7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+\nvv7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v4CgYEA/f8/vLv+v/3/P/z9//7+/v7+\nvv7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+\nv/4=\n-----END RSA PRIVATE KEY-----"), []byte("message"), nil) assert.Error(t, err) - // Key generation failure + // Key generation with broken reader — Go 1.26+ rsa.GenerateKey may + // recover from reader errors internally, so we only verify it doesn't panic. oldReader := rand.Reader rand.Reader = &mockReader{} t.Cleanup(func() { rand.Reader = oldReader }) - _, _, err = s.GenerateKeyPair(2048) - assert.Error(t, err) + _, _, _ = s.GenerateKeyPair(2048) // Encrypt with non-RSA key rand.Reader = oldReader // Restore reader for this test From 60de3e194313c661b00d07cf39d1c44f09cf4b30 Mon Sep 17 00:00:00 2001 From: Snider Date: Mon, 16 Mar 2026 20:50:38 +0000 Subject: [PATCH 4/5] refactor: replace remaining fmt.Errorf/os.* with go-io/go-log conventions Co-Authored-By: Virgil --- auth/session_store.go | 5 +++-- cmd/crypt/cmd_encrypt.go | 12 +++++++----- cmd/testcmd/cmd_runner.go | 8 ++++---- trust/approval.go | 15 ++++++++------- trust/audit.go | 9 +++++---- trust/config.go | 14 ++++++++------ trust/policy.go | 4 +++- 7 files changed, 38 insertions(+), 29 deletions(-) diff --git a/auth/session_store.go b/auth/session_store.go index 12811bb..bf90996 100644 --- a/auth/session_store.go +++ b/auth/session_store.go @@ -1,14 +1,15 @@ package auth import ( - "errors" "maps" "sync" "time" + + coreerr "forge.lthn.ai/core/go-log" ) // ErrSessionNotFound is returned when a session token is not found. -var ErrSessionNotFound = errors.New("auth: session not found") +var ErrSessionNotFound = coreerr.E("auth", "session not found", nil) // SessionStore abstracts session persistence. type SessionStore interface { diff --git a/cmd/crypt/cmd_encrypt.go b/cmd/crypt/cmd_encrypt.go index 95e1dbc..6f3693e 100644 --- a/cmd/crypt/cmd_encrypt.go +++ b/cmd/crypt/cmd_encrypt.go @@ -2,11 +2,11 @@ package crypt import ( "fmt" - "os" "strings" "forge.lthn.ai/core/cli/pkg/cli" "forge.lthn.ai/core/go-crypt/crypt" + coreio "forge.lthn.ai/core/go-io" ) // Encrypt command flags @@ -53,10 +53,11 @@ func runEncrypt(path string) error { return cli.Err("passphrase cannot be empty") } - data, err := os.ReadFile(path) + raw, err := coreio.Local.Read(path) if err != nil { return cli.Wrap(err, "failed to read file") } + data := []byte(raw) var encrypted []byte if encryptAES { @@ -69,7 +70,7 @@ func runEncrypt(path string) error { } outPath := path + ".enc" - if err := os.WriteFile(outPath, encrypted, 0o600); err != nil { + if err := coreio.Local.Write(outPath, string(encrypted)); err != nil { return cli.Wrap(err, "failed to write encrypted file") } @@ -86,10 +87,11 @@ func runDecrypt(path string) error { return cli.Err("passphrase cannot be empty") } - data, err := os.ReadFile(path) + raw, err := coreio.Local.Read(path) if err != nil { return cli.Wrap(err, "failed to read file") } + data := []byte(raw) var decrypted []byte if encryptAES { @@ -106,7 +108,7 @@ func runDecrypt(path string) error { outPath = path + ".dec" } - if err := os.WriteFile(outPath, decrypted, 0o600); err != nil { + if err := coreio.Local.Write(outPath, string(decrypted)); err != nil { return cli.Wrap(err, "failed to write decrypted file") } diff --git a/cmd/testcmd/cmd_runner.go b/cmd/testcmd/cmd_runner.go index 3365491..8224f60 100644 --- a/cmd/testcmd/cmd_runner.go +++ b/cmd/testcmd/cmd_runner.go @@ -2,7 +2,6 @@ package testcmd import ( "bufio" - "errors" "fmt" "io" "os" @@ -11,12 +10,13 @@ import ( "strings" "forge.lthn.ai/core/go-i18n" + coreerr "forge.lthn.ai/core/go-log" ) func runTest(verbose, coverage, short bool, pkg, run string, race, jsonOutput bool) error { // Detect if we're in a Go project if _, err := os.Stat("go.mod"); os.IsNotExist(err) { - return errors.New(i18n.T("cmd.test.error.no_go_mod")) + return coreerr.E("cmd.test", i18n.T("cmd.test.error.no_go_mod"), nil) } // Build command arguments @@ -94,7 +94,7 @@ func runTest(verbose, coverage, short bool, pkg, run string, race, jsonOutput bo // JSON output for CI/agents printJSONResults(results, exitCode) if exitCode != 0 { - return errors.New(i18n.T("i18n.fail.run", "tests")) + return coreerr.E("cmd.test", i18n.T("i18n.fail.run", "tests"), nil) } return nil } @@ -110,7 +110,7 @@ func runTest(verbose, coverage, short bool, pkg, run string, race, jsonOutput bo if exitCode != 0 { fmt.Printf("\n%s %s\n", testFailStyle.Render(i18n.T("cli.fail")), i18n.T("cmd.test.tests_failed")) - return errors.New(i18n.T("i18n.fail.run", "tests")) + return coreerr.E("cmd.test", i18n.T("i18n.fail.run", "tests"), nil) } fmt.Printf("\n%s %s\n", testPassStyle.Render(i18n.T("cli.pass")), i18n.T("common.result.all_passed")) diff --git a/trust/approval.go b/trust/approval.go index a6aafca..8e9a5d1 100644 --- a/trust/approval.go +++ b/trust/approval.go @@ -1,11 +1,12 @@ package trust import ( - "errors" "fmt" "iter" "sync" "time" + + coreerr "forge.lthn.ai/core/go-log" ) // ApprovalStatus represents the state of an approval request. @@ -74,10 +75,10 @@ func NewApprovalQueue() *ApprovalQueue { // Returns an error if the agent name or capability is empty. func (q *ApprovalQueue) Submit(agent string, cap Capability, repo string) (string, error) { if agent == "" { - return "", errors.New("trust.ApprovalQueue.Submit: agent name is required") + return "", coreerr.E("trust.ApprovalQueue.Submit", "agent name is required", nil) } if cap == "" { - return "", errors.New("trust.ApprovalQueue.Submit: capability is required") + return "", coreerr.E("trust.ApprovalQueue.Submit", "capability is required", nil) } q.mu.Lock() @@ -106,10 +107,10 @@ func (q *ApprovalQueue) Approve(id string, reviewedBy string, reason string) err req, ok := q.requests[id] if !ok { - return fmt.Errorf("trust.ApprovalQueue.Approve: request %q not found", id) + return coreerr.E("trust.ApprovalQueue.Approve", fmt.Sprintf("request %q not found", id), nil) } if req.Status != ApprovalPending { - return fmt.Errorf("trust.ApprovalQueue.Approve: request %q is already %s", id, req.Status) + return coreerr.E("trust.ApprovalQueue.Approve", fmt.Sprintf("request %q is already %s", id, req.Status), nil) } req.Status = ApprovalApproved @@ -127,10 +128,10 @@ func (q *ApprovalQueue) Deny(id string, reviewedBy string, reason string) error req, ok := q.requests[id] if !ok { - return fmt.Errorf("trust.ApprovalQueue.Deny: request %q not found", id) + return coreerr.E("trust.ApprovalQueue.Deny", fmt.Sprintf("request %q not found", id), nil) } if req.Status != ApprovalPending { - return fmt.Errorf("trust.ApprovalQueue.Deny: request %q is already %s", id, req.Status) + return coreerr.E("trust.ApprovalQueue.Deny", fmt.Sprintf("request %q is already %s", id, req.Status), nil) } req.Status = ApprovalDenied diff --git a/trust/audit.go b/trust/audit.go index 5b371f4..25ae84a 100644 --- a/trust/audit.go +++ b/trust/audit.go @@ -2,11 +2,12 @@ package trust import ( "encoding/json" - "fmt" "io" "iter" "sync" "time" + + coreerr "forge.lthn.ai/core/go-log" ) // AuditEntry records a single policy evaluation for compliance. @@ -44,7 +45,7 @@ func (d *Decision) UnmarshalJSON(data []byte) error { case "needs_approval": *d = NeedsApproval default: - return fmt.Errorf("trust: unknown decision %q", s) + return coreerr.E("trust.Decision.UnmarshalJSON", "unknown decision: "+s, nil) } return nil } @@ -83,11 +84,11 @@ func (l *AuditLog) Record(result EvalResult, repo string) error { if l.writer != nil { data, err := json.Marshal(entry) if err != nil { - return fmt.Errorf("trust.AuditLog.Record: marshal failed: %w", err) + return coreerr.E("trust.AuditLog.Record", "marshal failed", err) } data = append(data, '\n') if _, err := l.writer.Write(data); err != nil { - return fmt.Errorf("trust.AuditLog.Record: write failed: %w", err) + return coreerr.E("trust.AuditLog.Record", "write failed", err) } } diff --git a/trust/config.go b/trust/config.go index 5b9ad33..fd198dd 100644 --- a/trust/config.go +++ b/trust/config.go @@ -5,6 +5,8 @@ import ( "fmt" "io" "os" + + coreerr "forge.lthn.ai/core/go-log" ) // PolicyConfig is the JSON-serialisable representation of a trust policy. @@ -24,7 +26,7 @@ type PoliciesConfig struct { func LoadPoliciesFromFile(path string) ([]Policy, error) { f, err := os.Open(path) if err != nil { - return nil, fmt.Errorf("trust.LoadPoliciesFromFile: %w", err) + return nil, coreerr.E("trust.LoadPoliciesFromFile", "failed to open file", err) } defer f.Close() return LoadPolicies(f) @@ -36,7 +38,7 @@ func LoadPolicies(r io.Reader) ([]Policy, error) { dec := json.NewDecoder(r) dec.DisallowUnknownFields() if err := dec.Decode(&cfg); err != nil { - return nil, fmt.Errorf("trust.LoadPolicies: %w", err) + return nil, coreerr.E("trust.LoadPolicies", "failed to decode JSON", err) } return convertPolicies(cfg) } @@ -48,7 +50,7 @@ func convertPolicies(cfg PoliciesConfig) ([]Policy, error) { for i, pc := range cfg.Policies { tier := Tier(pc.Tier) if !tier.Valid() { - return nil, fmt.Errorf("trust.LoadPolicies: invalid tier %d at index %d", pc.Tier, i) + return nil, coreerr.E("trust.LoadPolicies", fmt.Sprintf("invalid tier %d at index %d", pc.Tier, i), nil) } p := Policy{ @@ -72,7 +74,7 @@ func (pe *PolicyEngine) ApplyPolicies(r io.Reader) error { } for _, p := range policies { if err := pe.SetPolicy(p); err != nil { - return fmt.Errorf("trust.ApplyPolicies: %w", err) + return coreerr.E("trust.ApplyPolicies", "failed to set policy", err) } } return nil @@ -82,7 +84,7 @@ func (pe *PolicyEngine) ApplyPolicies(r io.Reader) error { func (pe *PolicyEngine) ApplyPoliciesFromFile(path string) error { f, err := os.Open(path) if err != nil { - return fmt.Errorf("trust.ApplyPoliciesFromFile: %w", err) + return coreerr.E("trust.ApplyPoliciesFromFile", "failed to open file", err) } defer f.Close() return pe.ApplyPolicies(f) @@ -107,7 +109,7 @@ func (pe *PolicyEngine) ExportPolicies(w io.Writer) error { enc := json.NewEncoder(w) enc.SetIndent("", " ") if err := enc.Encode(cfg); err != nil { - return fmt.Errorf("trust.ExportPolicies: %w", err) + return coreerr.E("trust.ExportPolicies", "failed to encode JSON", err) } return nil } diff --git a/trust/policy.go b/trust/policy.go index 0b1f1b8..368a1c1 100644 --- a/trust/policy.go +++ b/trust/policy.go @@ -4,6 +4,8 @@ import ( "fmt" "slices" "strings" + + coreerr "forge.lthn.ai/core/go-log" ) // Policy defines the access rules for a given trust tier. @@ -146,7 +148,7 @@ func (pe *PolicyEngine) Evaluate(agentName string, cap Capability, repo string) // SetPolicy replaces the policy for a given tier. func (pe *PolicyEngine) SetPolicy(p Policy) error { if !p.Tier.Valid() { - return fmt.Errorf("trust.SetPolicy: invalid tier %d", p.Tier) + return coreerr.E("trust.SetPolicy", fmt.Sprintf("invalid tier %d", p.Tier), nil) } pe.policies[p.Tier] = &p return nil From f4a219816a44918a233b3f1c5ecfe55b7bacca09 Mon Sep 17 00:00:00 2001 From: Snider Date: Mon, 16 Mar 2026 22:19:33 +0000 Subject: [PATCH 5/5] chore: sync dependencies for v0.1.10 Co-Authored-By: Virgil --- go.mod | 13 ++++++------- go.sum | 22 ++++++++++------------ 2 files changed, 16 insertions(+), 19 deletions(-) diff --git a/go.mod b/go.mod index 9c6e888..fa9be8e 100644 --- a/go.mod +++ b/go.mod @@ -3,12 +3,12 @@ module forge.lthn.ai/core/go-crypt go 1.26.0 require ( - forge.lthn.ai/core/cli v0.3.1 + forge.lthn.ai/core/cli v0.3.5 forge.lthn.ai/core/go v0.3.1 - forge.lthn.ai/core/go-i18n v0.1.4 - forge.lthn.ai/core/go-io v0.1.2 + forge.lthn.ai/core/go-i18n v0.1.6 + forge.lthn.ai/core/go-io v0.1.5 forge.lthn.ai/core/go-log v0.0.4 - forge.lthn.ai/core/go-store v0.1.6 + forge.lthn.ai/core/go-store v0.1.7 github.com/ProtonMail/go-crypto v1.4.0 github.com/stretchr/testify v1.11.1 golang.org/x/crypto v0.49.0 @@ -16,7 +16,6 @@ require ( require ( forge.lthn.ai/core/go-inference v0.1.4 // indirect - forge.lthn.ai/core/go-process v0.2.2 // indirect github.com/aymanbagabas/go-osc52/v2 v2.0.1 // indirect github.com/charmbracelet/bubbletea v1.3.10 // indirect github.com/charmbracelet/colorprofile v0.4.3 // indirect @@ -46,7 +45,7 @@ require ( github.com/spf13/cobra v1.10.2 // indirect github.com/spf13/pflag v1.0.10 // indirect github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e // indirect - golang.org/x/exp v0.0.0-20260312153236-7ab1446f8b90 // indirect + golang.org/x/mod v0.34.0 // indirect golang.org/x/sys v0.42.0 // indirect golang.org/x/term v0.41.0 // indirect golang.org/x/text v0.35.0 // indirect @@ -54,5 +53,5 @@ require ( modernc.org/libc v1.70.0 // indirect modernc.org/mathutil v1.7.1 // indirect modernc.org/memory v1.11.0 // indirect - modernc.org/sqlite v1.46.1 // indirect + modernc.org/sqlite v1.46.2 // indirect ) diff --git a/go.sum b/go.sum index f56eeb9..6df95e4 100644 --- a/go.sum +++ b/go.sum @@ -1,19 +1,17 @@ -forge.lthn.ai/core/cli v0.3.1 h1:ZpHhaDrdbaV98JDxj/f0E5nytYk9tTMRu3qohGyK4M0= -forge.lthn.ai/core/cli v0.3.1/go.mod h1:28cOl9eK0H033Otkjrv9f/QCmtHcJl+IIx4om8JskOg= +forge.lthn.ai/core/cli v0.3.5 h1:P7yK0DmSA1QnUMFuCjJZf/fk/akKPIxopQ6OwD8Sar8= +forge.lthn.ai/core/cli v0.3.5/go.mod h1:SeArHx+hbpX5iZqgASCD7Q1EDoc6uaaGiGBotmNzIx4= forge.lthn.ai/core/go v0.3.1 h1:5FMTsUhLcxSr07F9q3uG0Goy4zq4eLivoqi8shSY4UM= forge.lthn.ai/core/go v0.3.1/go.mod h1:gE6c8h+PJ2287qNhVUJ5SOe1kopEwHEquvinstpuyJc= -forge.lthn.ai/core/go-i18n v0.1.4 h1:zOHUUJDgRo88/3tj++kN+VELg/buyZ4T2OSdG3HBbLQ= -forge.lthn.ai/core/go-i18n v0.1.4/go.mod h1:aDyAfz7MMgWYgLkZCptfFmZ7jJg3ocwjEJ1WkJSvv4U= +forge.lthn.ai/core/go-i18n v0.1.6 h1:Z9h6sEZsgJmWlkkq3ZPZyfgWipeeqN5lDCpzltpamHU= +forge.lthn.ai/core/go-i18n v0.1.6/go.mod h1:C6CbwdN7sejTx/lbutBPrxm77b8paMHBO6uHVLHOdqQ= forge.lthn.ai/core/go-inference v0.1.4 h1:fuAgWbqsEDajHniqAKyvHYbRcBrkGEiGSqR2pfTMRY0= forge.lthn.ai/core/go-inference v0.1.4/go.mod h1:jfWz+IJX55wAH98+ic6FEqqGB6/P31CHlg7VY7pxREw= -forge.lthn.ai/core/go-io v0.1.2 h1:q8hj2jtOFqAgHlBr5wsUAOXtaFkxy9gqGrQT/il0WYA= -forge.lthn.ai/core/go-io v0.1.2/go.mod h1:PbNKW1Q25ywSOoQXeGdQHbV5aiIrTXvHIQ5uhplA//g= +forge.lthn.ai/core/go-io v0.1.5 h1:+XJ1YhaGGFLGtcNbPtVlndTjk+pO0Ydi2hRDj5/cHOM= +forge.lthn.ai/core/go-io v0.1.5/go.mod h1:FRtXSsi8W+U9vewCU+LBAqqbIj3wjXA4dBdSv3SAtWI= forge.lthn.ai/core/go-log v0.0.4 h1:KTuCEPgFmuM8KJfnyQ8vPOU1Jg654W74h8IJvfQMfv0= forge.lthn.ai/core/go-log v0.0.4/go.mod h1:r14MXKOD3LF/sI8XUJQhRk/SZHBE7jAFVuCfgkXoZPw= -forge.lthn.ai/core/go-process v0.2.2 h1:bnHFtzg92udochDDB6bD2luzzmr9ETKWmGzSsGjFFYE= -forge.lthn.ai/core/go-process v0.2.2/go.mod h1:gVTbxL16ccUIexlFcyDtCy7LfYvD8Rtyzfo8bnXAXrU= -forge.lthn.ai/core/go-store v0.1.6 h1:7T+K5cciXOaWRxge0WnGkt0PcK3epliWBa1G2FLEuac= -forge.lthn.ai/core/go-store v0.1.6/go.mod h1:/2vqaAn+HgGU14N29B+vIfhjIsBzy7RC+AluI6BIUKI= +forge.lthn.ai/core/go-store v0.1.7 h1:M1lA+YKX6NR+g5EzXkKjrTNRznGz5nypYahvPlbYVdQ= +forge.lthn.ai/core/go-store v0.1.7/go.mod h1:8HSEYfcU9tuivAzBz3i0FLBV0ls44QzXnlcd7cqL6PA= github.com/ProtonMail/go-crypto v1.4.0 h1:Zq/pbM3F5DFgJiMouxEdSVY44MVoQNEKp5d5QxIQceQ= github.com/ProtonMail/go-crypto v1.4.0/go.mod h1:e1OaTyu5SYVrO9gKOEhTc+5UcXtTUa+P3uLudwcgPqo= github.com/aymanbagabas/go-osc52/v2 v2.0.1 h1:HwpRHbFMcZLEVr42D4p7XBqjyuxQH5SMiErDT4WkJ2k= @@ -135,8 +133,8 @@ modernc.org/opt v0.1.4 h1:2kNGMRiUjrp4LcaPuLY2PzUfqM/w9N23quVwhKt5Qm8= modernc.org/opt v0.1.4/go.mod h1:03fq9lsNfvkYSfxrfUhZCWPk1lm4cq4N+Bh//bEtgns= modernc.org/sortutil v1.2.1 h1:+xyoGf15mM3NMlPDnFqrteY07klSFxLElE2PVuWIJ7w= modernc.org/sortutil v1.2.1/go.mod h1:7ZI3a3REbai7gzCLcotuw9AC4VZVpYMjDzETGsSMqJE= -modernc.org/sqlite v1.46.1 h1:eFJ2ShBLIEnUWlLy12raN0Z1plqmFX9Qe3rjQTKt6sU= -modernc.org/sqlite v1.46.1/go.mod h1:CzbrU2lSB1DKUusvwGz7rqEKIq+NUd8GWuBBZDs9/nA= +modernc.org/sqlite v1.46.2 h1:gkXQ6R0+AjxFC/fTDaeIVLbNLNrRoOK7YYVz5BKhTcE= +modernc.org/sqlite v1.46.2/go.mod h1:hWjRO6Tj/5Ik8ieqxQybiEOUXy0NJFNp2tpvVpKlvig= modernc.org/strutil v1.2.1 h1:UneZBkQA+DX2Rp35KcM69cSsNES9ly8mQWD71HKlOA0= modernc.org/strutil v1.2.1/go.mod h1:EHkiggD70koQxjVdSBM3JKM7k6L0FbGE5eymy9i3B9A= modernc.org/token v1.1.0 h1:Xl7Ap9dKaEs5kLoOQeQmPWevfnk/DM5qcLcYlA8ys6Y=