Compare commits

...
Author SHA1 Message Date
zeekay bb9bb5e6fc deps: update to latest real-semver, drop local replaces, fix breaks 2026-06-11 09:28:29 -07:00
zeekay d3f261e98f deps: update to latest real-semver, drop local replaces, fix breaks 2026-06-11 09:07:45 -07:00
hanzo-dev b8a2ad507b deps: bump Go to 1.26.4 across go.mod, Dockerfiles, GH Actions
Workspace-wide sync. luxfi/node already shipped on 1.26.4 in v1.30.6
(commit 121aca1fa9); this is the cross-repo catch-up.
2026-06-07 12:10:18 -07:00
hanzo-dev 33f276fac9 cloud: Postgres lockdown — env-var guard at orchestrator boot
The Go cloud orchestrator (HIP-0106) has no PG of its own and
delegates all storage to subsystems via hanzoai/base (HIP-0302).
Adds internal/storagelock that refuses to boot when DATABASE_URL,
DATABASE_HOST, POSTGRES_URL/DSN/HOST, CLOUD_DATABASE_URL,
CLOUD_POSTGRES_URL, or HANZO_CLOUD_DB are set.

Also rejects the two legacy cloud-api Python knobs:
  driverName=postgres / driverName=postgresql
  dbName=hanzo_cloud
Other values (driverName=sqlite, dbName=anything_else) pass through
as intentional transition signals.

12 tests cover Postgres DSN rejection, legacy Python driver/db
classification, multi-violation reporting, password redaction, and
whitespace handling.

Wired in cmd/cloud/main.go before cloud.LoadConfig(). Adds LLM.md
documenting the storage policy + migration CLI.

Per ~/work/hanzo/CLAUDE_PG_TO_SQLITE_MIGRATION.md (#4 — cloud).
2026-06-05 09:44:51 -07:00
hanzo-dev aef1d4a5b8 cloud: migrate-pg-to-sqlite — legacy hanzo_cloud PG → per-(org,user) SQLite
Adds migration/ + cmd/migrate-pg-to-sqlite for the Hanzo PG → SQLite
plan (~/work/hanzo/CLAUDE_PG_TO_SQLITE_MIGRATION.md, service #4).

The Go cloud orchestrator (HIP-0106) has no PG of its own — every
subsystem owns its per-(org, user) SQLite via hanzoai/base (HIP-0302).
The legacy deployed cloud-api Python image used a shared hanzo_cloud
PG on postgres.hanzo.svc; this CLI drains it into the canonical
/data/<org>/<user>/cloud.sqlite layout.

Introspective copy via information_schema (we don't own the legacy
Python schema). Routing:

  has user_id  → /data/<org>/<user>/cloud.sqlite
  has org_id   → /data/<org>/_org/cloud.sqlite
  has neither  → /data/_global/_org/cloud.sqlite (fail-loud sentinel)

Canonical routing columns (org_id, user_id) with documented fallbacks
(owner, user_email, owner_user_id). PG types mapped conservatively to
SQLite affinities. Path-traversal tokens validated against a
~/.claude-style grammar before any filesystem touch.

8 tests cover three-way routing, canonical-fallback column picking,
path-traversal rejection, PG type mapping, and Options validation.
Promotes lib/pq + modernc.org/sqlite from indirect to direct require.
2026-06-05 09:44:42 -07:00
hanzo-dev 9b7a4ccc67 feat: bind ZAP listener for cloud binary (gateway plugin unblock)
Before this commit the cfg.ZAPListenAddr was logged at startup but
never actually bound — api.hanzo.ai gateway plugin pointing at
cloud-api:9999 returned "no available server" (memory:gateway_zap_cloud_api).
The cluster Deployment exposed containerPort 9999 → cloud-api → nowhere.

server.go wires up luxfi/zap.Node on cfg.ZAPListenAddr with:

  - Built-in MsgTypeControl (10) handshake — gateway health probes hit
    this to confirm the listener is up before routing real traffic.
  - Per-subsystem msgType registry (200-209 for iam/kms/base/commerce/
    ai/o11y/vfs/mq/payments/vault; 302 reserved for datastore which is
    already in use by hanzoai/datastore zap-bridge). 8-bit wire-key
    projection handled centrally so callers think in 16-bit source IDs.
  - Inflight tracking + recover wrapper around every registered
    handler. A panic in a subsystem handler becomes a 500-equivalent
    ZAP response, never crashes the cloud process.
  - 5s graceful drain on Shutdown.

deps.go gets a Deps.ZAP field (ZAPServer interface) so subsystems can
deps.ZAP.RegisterHandler(MsgTypeIAM, fn) from their Mount(). Interface
lives in server.go so luxfi/zap import stays scoped to one file. Nil-
guarded for embedded use in tests where there's no listener.

main.go brings up the server BEFORE MountAll so subsystems can register
in their Mount closures. The server lifecycle bookends app.Listen via
defer Shutdown.

luxfi/zap promoted from // indirect to direct require — minimal go.mod
delta (single line move, no version bump, no go.sum changes).

Verification: go vet . clean; go build . clean. The cmd/cloud build
hits ambient sibling-rebrand churn (authz/base/o11y packaging in flux
across the monorepo) that's not introduced here.
2026-06-03 11:36:24 -07:00
13 changed files with 2115 additions and 284 deletions
+1 -1
View File
@@ -1,4 +1,4 @@
FROM golang:1.26-alpine AS build
FROM golang:1.26.4-alpine AS build
RUN apk add --no-cache ca-certificates tzdata
RUN addgroup -g 65532 -S nonroot && adduser -u 65532 -S nonroot -G nonroot
WORKDIR /src
+118
View File
@@ -0,0 +1,118 @@
# LLM.md — hanzoai/cloud
## What this is
`hanzoai/cloud` is the unified Go binary per HIP-0106. One process,
many subsystems (iam, base, kms, commerce, ai, gateway, o11y, vfs, mq,
authz, mcp, amqp, ingress) — each registered via `init()` and
mounted at startup based on `--enable=...`. Same artifact serves
`api.hanzo.ai`, `api.osage.cloud`, `api.lux.cloud`, `api.zoo.cloud`,
and every white-label resold cloud surface.
## Storage — SQLite-only via subsystems
The orchestrator has NO storage of its own. Every subsystem owns its
per-(org, user) SQLite via `hanzoai/base` (HIP-0302). The orchestrator
is purely a fan-out: HTTP → router → subsystem.Mount() handlers.
Per the Hanzo PG → SQLite migration plan
(`~/work/hanzo/CLAUDE_PG_TO_SQLITE_MIGRATION.md`, service #4 — cloud):
### Postgres lockdown
`internal/storagelock` refuses to boot when any of these are set:
```
DATABASE_URL, DATABASE_HOST, POSTGRES_URL, POSTGRES_DSN, POSTGRES_HOST,
CLOUD_DATABASE_URL, CLOUD_POSTGRES_URL, HANZO_CLOUD_DB,
driverName (when "postgres" / "postgresql"),
dbName (when "hanzo_cloud" exactly)
```
The `driverName` / `dbName` envs are the legacy Python `cloud-api`
deployment's knobs (see
`~/work/hanzo/universe/infra/k8s/cloud/deployment.yaml`). When that
manifest gets reused with the new Go binary by accident, this
lockdown crashes the pod loudly. The Go binary never reads these
envs; the lockdown is purely a regression guard.
`driverName=sqlite` is intentionally allowed (a transition signal an
operator might set). `dbName=anything_else` is also allowed — only the
legacy `hanzo_cloud` literal value is rejected.
Wired in `cmd/cloud/main.go` before `cloud.LoadConfig()`; 12 tests in
`internal/storagelock/storagelock_test.go`.
### Migration CLI
`cmd/migrate-pg-to-sqlite` copies a legacy `hanzo_cloud` PG database
into per-(org, user) SQLite files at `/data/<org>/<user>/cloud.sqlite`
(user-scoped) or `/data/<org>/_org/cloud.sqlite` (org-scoped).
Introspective (not schema-aware) because we don't own the legacy
`cloud-api` Python schema and it has drifted across Python/TS
versions. The migrator:
1. Reads `information_schema.tables` for the table set.
2. For each table, reads `information_schema.columns` to synthesize
conservative SQLite DDL (`mapPGType`: int/bool → INTEGER, real/numeric
→ REAL, bytea → BLOB, everything else → TEXT).
3. Resolves routing columns: `org_id` (canonical) or `owner` (fallback),
plus `user_id` (canonical), `user_email` or `owner_user_id` (fallbacks).
4. For each row, computes the destination file from the routing
columns. Tokens are validated against `^[A-Za-z0-9._@+-]+$`
anything failing falls to the `_global` / `_org` sentinel.
5. Batched commit every 500 rows per destination handle.
Usage:
```
migrate-pg-to-sqlite \
--src 'postgres://cloud:pass@postgres.hanzo.svc:5432/hanzo_cloud?sslmode=disable' \
--dst /data
```
Tests in `migration/pg_to_sqlite_test.go` cover three-way routing
(user-scoped, org-scoped, no-routing), column-fallback picking,
path-traversal rejection, PG type mapping, and Options validation.
## ZAP listener
Two listeners per cloud process:
```
HTTP (cfg.ListenAddr, default :8080) — external client surface
ZAP (cfg.ZAPListenAddr, default :9999) — intra-Hanzo subsystem RPC
```
ZAP message-type registry (append-only):
```
10 = control — handshake, heartbeat (built-in)
200 = iam — VerifyJWT, GetUser, GetOrg
201 = kms — GetSecret, PutSecret, Sign
202 = base — Open (per-tenant SQLite handle)
203 = commerce — GetTenantConfig
204 = ai — ChatCompletion
205 = o11y — Counter, Timing, Span
206 = vfs — Put, Get
207 = mq — Publish, Subscribe
208 = payments — CreateIntent, ConfirmIntent, GetIntentStatus
209 = vault — Charge
302 = datastore — already in use by hanzoai/datastore zap-bridge
```
Wire dispatch quirk: luxfi/zap routes on `msg.Flags() >> 8` which
truncates 16-bit msgType to its low byte. Senders write
`FinishWithFlags(msgType << 8)`.
## Build
```
GOWORK=off go build ./internal/... ./migration/... ./cmd/migrate-pg-to-sqlite/
GOWORK=off go test ./internal/... ./migration/...
```
`cmd/cloud` itself currently has a pre-existing build break against a
stale o11y module path (`pkg/query-service/utils/times`) — unrelated
to this migration work.
+30
View File
@@ -9,8 +9,10 @@ package main
import (
"fmt"
"os"
"time"
"github.com/hanzoai/cloud"
"github.com/hanzoai/cloud/internal/storagelock"
"github.com/hanzoai/zip"
"github.com/hanzoai/zip/middleware"
@@ -32,6 +34,16 @@ import (
)
func main() {
// Storage lockdown: cloud is an HIP-0106 orchestrator with no PG
// of its own — every subsystem owns its per-(org, user) SQLite via
// hanzoai/base. Reject env-var overrides leaking from the legacy
// cloud-api Python manifest. See
// ~/work/hanzo/CLAUDE_PG_TO_SQLITE_MIGRATION.md (#4 — cloud).
if err := storagelock.CheckEnv(os.Getenv); err != nil {
fmt.Fprintf(os.Stderr, "%v\n", err)
os.Exit(1)
}
cfg := cloud.LoadConfig()
if err := cfg.Validate(); err != nil {
fmt.Fprintf(os.Stderr, "config: %v\n", err)
@@ -40,6 +52,24 @@ func main() {
deps := cloud.BuildDeps(cfg)
// Bring up the ZAP listener first — subsystems' Mount(...) call
// deps.ZAP.RegisterHandler(...) to expose their per-msgType
// surface, so the server must exist before MountAll runs.
// Without this the cfg.ZAPListenAddr was just logged, never bound;
// gateway plugins targeting cloud-api got "no available server"
// (see memory:gateway_zap_cloud_api).
zapsrv, err := cloud.NewServer(cfg, deps.Logger)
if err != nil {
fmt.Fprintf(os.Stderr, "zap server: %v\n", err)
os.Exit(1)
}
if err := zapsrv.Start(); err != nil {
fmt.Fprintf(os.Stderr, "zap start: %v\n", err)
os.Exit(1)
}
defer zapsrv.Shutdown(5 * time.Second)
deps.ZAP = zapsrv
app := zip.New(zip.Config{Logger: deps.Logger})
// Canonical middleware pipeline. Order matters:
+67
View File
@@ -0,0 +1,67 @@
// Command migrate-pg-to-sqlite copies a legacy `hanzo_cloud`
// PostgreSQL database into per-(org, user) SQLite files served by the
// Hanzo cloud orchestrator (HIP-0106).
//
// The migrator is introspective: it reads information_schema for the
// table set and columns, then routes each row to its destination file
// based on org_id / user_id columns (or canonical fallbacks). Rows
// with neither column land under /<root>/_global/_org/cloud.sqlite so
// the operator can triage rather than silently dropping them.
//
// Usage:
//
// migrate-pg-to-sqlite \
// --src 'postgres://cloud:pass@postgres.hanzo.svc:5432/hanzo_cloud?sslmode=disable' \
// --dst /data
//
// Per ~/work/hanzo/CLAUDE_PG_TO_SQLITE_MIGRATION.md (service #4 — cloud).
package main
import (
"context"
"flag"
"fmt"
"os"
"strings"
"github.com/hanzoai/cloud/migration"
)
func main() {
src := flag.String("src", "", "PostgreSQL DSN (postgres://user:pass@host:5432/dbname)")
dst := flag.String("dst", "", "Destination data root (default /data)")
schemas := flag.String("schemas", "public", "Comma-separated PG schemas to include")
excludes := flag.String("exclude", "schema_migrations,knex_migrations", "Comma-separated table basenames to skip")
batch := flag.Int("batch", 500, "Insert batch size")
flag.Parse()
if *src == "" || *dst == "" {
fmt.Fprintln(os.Stderr, "usage: migrate-pg-to-sqlite --src <pg-dsn> --dst <data-root>")
os.Exit(2)
}
reports, err := migration.Run(context.Background(), migration.Options{
SrcDSN: *src,
DstRoot: *dst,
IncludeSchemas: split(*schemas),
ExcludeTables: split(*excludes),
BatchSize: *batch,
})
if err != nil {
fmt.Fprintln(os.Stderr, "migrate-pg-to-sqlite:", err)
os.Exit(1)
}
fmt.Println("table\tsource\twritten\ttargets")
for _, r := range reports {
fmt.Printf("%s\t%d\t%d\t%d\n", r.Table, r.SourceRows, r.WrittenRows, len(r.Targets))
}
}
func split(s string) []string {
var out []string
for _, p := range strings.Split(s, ",") {
p = strings.TrimSpace(p)
if p != "" {
out = append(out, p)
}
}
return out
}
+10
View File
@@ -55,6 +55,16 @@ type Deps struct {
// never in-process.
Payments PaymentsClient
Vault VaultClient
// ZAP is the ZAP server this process is bound to. Subsystems that
// want to expose themselves over the wire (so out-of-process peers
// can call them) register a handler in their Mount(...) via
// deps.ZAP.RegisterHandler(MsgTypeXxx, fn). Nil during BuildDeps;
// set by main() between server-up and MountAll(). Subsystems must
// guard with `if deps.ZAP != nil` to allow embedded use without a
// listener (e.g. inside tests). The interface lives in server.go to
// keep the luxfi/zap import scoped to one place.
ZAP ZAPServer
}
// Per-subsystem client interfaces live in cloud/types so the
+100 -102
View File
@@ -1,29 +1,30 @@
module github.com/hanzoai/cloud
go 1.26.3
go 1.26.4
// Dependencies will be added as subsystems are mounted per HIP-0106.
require (
github.com/hanzoai/zip v0.1.0
github.com/hanzoai/zip v0.2.0
github.com/lib/pq v1.12.1
github.com/luxfi/log v1.4.3
modernc.org/sqlite v1.51.0
)
require (
capnproto.org/go/capnp/v3 v3.0.1-alpha.2 // indirect
cel.dev/expr v0.25.1 // indirect
cloud.google.com/go v0.123.0 // indirect
cloud.google.com/go/auth v0.18.1 // indirect
cloud.google.com/go/auth v0.20.0 // indirect
cloud.google.com/go/auth/oauth2adapt v0.2.8 // indirect
cloud.google.com/go/compute/metadata v0.9.0 // indirect
cloud.google.com/go/iam v1.5.3 // indirect
cloud.google.com/go/kms v1.25.0 // indirect
cloud.google.com/go/longrunning v0.8.0 // indirect
cloud.google.com/go/monitoring v1.24.3 // indirect
cloud.google.com/go/pubsub v1.50.1 // indirect
cloud.google.com/go/pubsub/v2 v2.3.0 // indirect
cloud.google.com/go/storage v1.59.2 // indirect
cloud.google.com/go/trace v1.11.7 // indirect
cloud.google.com/go/iam v1.7.0 // indirect
cloud.google.com/go/kms v1.27.0 // indirect
cloud.google.com/go/longrunning v0.9.0 // indirect
cloud.google.com/go/monitoring v1.25.0 // indirect
cloud.google.com/go/pubsub v1.50.2 // indirect
cloud.google.com/go/pubsub/v2 v2.5.1 // indirect
cloud.google.com/go/storage v1.61.3 // indirect
cloud.google.com/go/trace v1.12.0 // indirect
contrib.go.opencensus.io/exporter/aws v0.0.0-20230502192102-15967c811cec // indirect
contrib.go.opencensus.io/exporter/jaeger v0.2.1 // indirect
contrib.go.opencensus.io/exporter/ocagent v0.7.0 // indirect
@@ -31,7 +32,7 @@ require (
contrib.go.opencensus.io/exporter/stackdriver v0.13.14 // indirect
contrib.go.opencensus.io/exporter/zipkin v0.1.2 // indirect
dario.cat/mergo v1.0.2 // indirect
filippo.io/edwards25519 v1.1.1 // indirect
filippo.io/edwards25519 v1.2.0 // indirect
filippo.io/hpke v0.4.0 // indirect
github.com/ALTree/bigfloat v0.2.0 // indirect
github.com/AfterShip/clickhouse-sql-parser v0.4.16 // indirect
@@ -39,7 +40,7 @@ require (
github.com/Azure/azure-pipeline-go v0.2.3 // indirect
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.21.0 // indirect
github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.13.1 // indirect
github.com/Azure/azure-sdk-for-go/sdk/internal v1.11.2 // indirect
github.com/Azure/azure-sdk-for-go/sdk/internal v1.12.0 // indirect
github.com/Azure/azure-sdk-for-go/sdk/keyvault/azkeys v0.10.0 // indirect
github.com/Azure/azure-sdk-for-go/sdk/keyvault/internal v0.7.1 // indirect
github.com/Azure/azure-sdk-for-go/sdk/messaging/azservicebus v1.7.1 // indirect
@@ -52,13 +53,12 @@ require (
github.com/DataDog/datadog-go v4.8.3+incompatible // indirect
github.com/DataDog/opencensus-go-exporter-datadog v0.0.0-20220622145613-731d59e8b567 // indirect
github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp v1.31.0 // indirect
github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/metric v0.54.0 // indirect
github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/resourcemapping v0.54.0 // indirect
github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/metric v0.55.0 // indirect
github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/resourcemapping v0.55.0 // indirect
github.com/IBM/sarama v1.46.3 // indirect
github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible // indirect
github.com/Machiel/slugify v1.0.1 // indirect
github.com/Microsoft/go-winio v0.6.2 // indirect
github.com/ProjectZKM/Ziren/crates/go-runtime/zkvm_runtime v0.0.0-20260311194731-d5b7577c683d // indirect
github.com/ProtonMail/go-crypto v1.1.6 // indirect
github.com/PuerkitoBio/goquery v1.8.1 // indirect
github.com/RocketChat/Rocket.Chat.Go.SDK v0.0.0-20240116134246-a8cbe886bab0 // indirect
@@ -94,24 +94,24 @@ require (
github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 // indirect
github.com/atc0005/go-teams-notify/v2 v2.13.0 // indirect
github.com/aws/aws-sdk-go v1.55.8 // indirect
github.com/aws/aws-sdk-go-v2 v1.41.2 // indirect
github.com/aws/aws-sdk-go-v2/config v1.32.8 // indirect
github.com/aws/aws-sdk-go-v2/credentials v1.19.8 // indirect
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.17 // indirect
github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.18 // indirect
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.18 // indirect
github.com/aws/aws-sdk-go-v2/internal/ini v1.8.4 // indirect
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.5 // indirect
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.18 // indirect
github.com/aws/aws-sdk-go-v2/service/kms v1.35.3 // indirect
github.com/aws/aws-sdk-go-v2 v1.41.5 // indirect
github.com/aws/aws-sdk-go-v2/config v1.32.13 // indirect
github.com/aws/aws-sdk-go-v2/credentials v1.19.13 // indirect
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.21 // indirect
github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.21 // indirect
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.21 // indirect
github.com/aws/aws-sdk-go-v2/internal/ini v1.8.6 // indirect
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.7 // indirect
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.21 // indirect
github.com/aws/aws-sdk-go-v2/service/kms v1.50.4 // indirect
github.com/aws/aws-sdk-go-v2/service/s3 v1.96.2 // indirect
github.com/aws/aws-sdk-go-v2/service/signin v1.0.5 // indirect
github.com/aws/aws-sdk-go-v2/service/signin v1.0.9 // indirect
github.com/aws/aws-sdk-go-v2/service/sns v1.39.11 // indirect
github.com/aws/aws-sdk-go-v2/service/sqs v1.42.21 // indirect
github.com/aws/aws-sdk-go-v2/service/sso v1.30.9 // indirect
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.35.14 // indirect
github.com/aws/aws-sdk-go-v2/service/sts v1.41.6 // indirect
github.com/aws/smithy-go v1.24.1 // indirect
github.com/aws/aws-sdk-go-v2/service/sso v1.30.14 // indirect
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.35.18 // indirect
github.com/aws/aws-sdk-go-v2/service/sts v1.41.10 // indirect
github.com/aws/smithy-go v1.24.2 // indirect
github.com/aymerick/raymond v2.0.2+incompatible // indirect
github.com/baidubce/bce-sdk-go v0.9.260 // indirect
github.com/beego/beego/v2 v2.3.8 // indirect
@@ -142,13 +142,13 @@ require (
github.com/cloudwego/base64x v0.1.6 // indirect
github.com/cncf/xds/go v0.0.0-20251210132809-ee656c7534f5 // indirect
github.com/coder/quartz v0.3.0 // indirect
github.com/colega/zeropool v0.0.0-20230505084239-6fb4a4f75381 // indirect
github.com/consensys/gnark-crypto v0.20.1 // indirect
github.com/corazawaf/coraza/v3 v3.3.3 // indirect
github.com/corazawaf/libinjection-go v0.2.2 // indirect
github.com/coreos/go-oidc/v3 v3.17.0 // indirect
github.com/coreos/go-systemd/v22 v22.6.0 // indirect
github.com/coreos/go-systemd/v22 v22.7.0 // indirect
github.com/corpix/uarand v0.2.0 // indirect
github.com/cronokirby/saferith v0.33.0 // indirect
github.com/cschomburg/go-pushbullet v0.0.0-20171206132031-67759df45fbb // indirect
github.com/cyphar/filepath-securejoin v0.5.1 // indirect
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
@@ -198,7 +198,7 @@ require (
github.com/go-git/go-git/v5 v5.16.4 // indirect
github.com/go-ini/ini v1.67.0 // indirect
github.com/go-jose/go-jose/v3 v3.0.4 // indirect
github.com/go-jose/go-jose/v4 v4.1.3 // indirect
github.com/go-jose/go-jose/v4 v4.1.4 // indirect
github.com/go-kit/log v0.2.1 // indirect
github.com/go-lark/lark v1.15.1 // indirect
github.com/go-ldap/ldap/v3 v3.4.6 // indirect
@@ -262,8 +262,8 @@ require (
github.com/google/martian v2.1.1-0.20190517191504-25dcb96d9e51+incompatible // indirect
github.com/google/s2a-go v0.1.9 // indirect
github.com/google/wire v0.6.0 // indirect
github.com/googleapis/enterprise-certificate-proxy v0.3.11 // indirect
github.com/googleapis/gax-go/v2 v2.17.0 // indirect
github.com/googleapis/enterprise-certificate-proxy v0.3.14 // indirect
github.com/googleapis/gax-go/v2 v2.21.0 // indirect
github.com/gorilla/mux v1.8.1 // indirect
github.com/gorilla/rpc v1.2.1 // indirect
github.com/gorilla/schema v1.4.1 // indirect
@@ -274,11 +274,15 @@ require (
github.com/grandcat/zeroconf v1.0.0 // indirect
github.com/gregdel/pushover v1.3.1 // indirect
github.com/grpc-ecosystem/grpc-gateway/v2 v2.28.0 // indirect
github.com/gtank/merlin v0.1.1 // indirect
github.com/gtank/ristretto255 v0.2.0 // indirect
github.com/hanzoai/authzstore v0.1.1 // indirect
github.com/hanzoai/builder v0.3.13 // indirect
github.com/hanzoai/datastore-go/v2 v2.45.0 // indirect
github.com/hanzoai/dbx v1.16.0 // indirect
github.com/hanzoai/go-sms-sender v0.25.2 // indirect
github.com/hanzoai/goauthorizenet v0.0.0-20180920213706-626992b83568 // indirect
github.com/hanzoai/gochimp3 v0.0.0-20241127054040-6051f77e24f1 // indirect
github.com/hanzoai/gomail/v2 v2.3.2 // indirect
github.com/hanzoai/iam v1.18.0 // indirect
github.com/hanzoai/iamsdk/v2 v2.1.0 // indirect
@@ -291,6 +295,7 @@ require (
github.com/hanzoai/oss v1.8.5 // indirect
github.com/hanzoai/pubsub-go v1.0.0 // indirect
github.com/hanzoai/search-go v0.36.0 // indirect
github.com/hanzoai/sendgrid-go v3.4.2-0.20180724185151-733a05184a8d+incompatible // indirect
github.com/hanzoai/storage-go v1.0.0 // indirect
github.com/hanzoai/tasks v1.40.0 // indirect
github.com/hanzoai/xorm v1.1.6 // indirect
@@ -312,6 +317,7 @@ require (
github.com/hashicorp/hcl v1.0.1-vault-5 // indirect
github.com/hashicorp/memberlist v0.5.4 // indirect
github.com/hashicorp/vault/api v1.14.0 // indirect
github.com/holiman/uint256 v1.3.2 // indirect
github.com/hsluoyz/modsecurity-go v0.0.7 // indirect
github.com/huandu/go-sqlbuilder v1.35.0 // indirect
github.com/huandu/xstrings v1.5.0 // indirect
@@ -336,6 +342,7 @@ require (
github.com/josharian/intern v1.0.0 // indirect
github.com/jpillora/backoff v1.0.0 // indirect
github.com/json-iterator/go v1.1.13-0.20220915233716-71ac16282d12 // indirect
github.com/keighl/mandrill v0.0.0-20170605120353-1775dd4b3b41 // indirect
github.com/kevinburke/ssh_config v1.2.0 // indirect
github.com/klauspost/cpuid/v2 v2.3.0 // indirect
github.com/klauspost/crc32 v1.3.0 // indirect
@@ -382,7 +389,6 @@ require (
github.com/lestrrat-go/iter v1.0.2 // indirect
github.com/lestrrat-go/jwx v1.2.29 // indirect
github.com/lestrrat-go/option v1.0.1 // indirect
github.com/lib/pq v1.12.1 // indirect
github.com/likexian/gokit v0.25.13 // indirect
github.com/likexian/whois v1.15.1 // indirect
github.com/likexian/whois-parser v1.24.9 // indirect
@@ -390,28 +396,42 @@ require (
github.com/lor00x/goldap v0.0.0-20180618054307-a546dffdd1a3 // indirect
github.com/lufia/plan9stats v0.0.0-20251013123823-9fd1530e3ec3 // indirect
github.com/luraproject/lura/v2 v2.12.1 // indirect
github.com/luxfi/accel v1.0.7 // indirect
github.com/luxfi/accel v1.1.9 // indirect
github.com/luxfi/address v1.0.1 // indirect
github.com/luxfi/age v1.5.0 // indirect
github.com/luxfi/cache v1.2.1 // indirect
github.com/luxfi/compress v0.0.5 // indirect
github.com/luxfi/concurrent v0.0.3 // indirect
github.com/luxfi/consensus v1.22.85 // indirect
github.com/luxfi/consensus v1.25.0 // indirect
github.com/luxfi/constants v1.5.8 // indirect
github.com/luxfi/container v0.0.4 // indirect
github.com/luxfi/crypto v1.19.0 // indirect
github.com/luxfi/corona v0.7.6 // indirect
github.com/luxfi/crypto v1.19.17 // indirect
github.com/luxfi/crypto/ipa v1.2.4 // indirect
github.com/luxfi/database v1.18.1 // indirect
github.com/luxfi/fhe v1.7.9 // indirect
github.com/luxfi/ids v1.2.9 // indirect
github.com/luxfi/kms v1.5.2 // indirect
github.com/luxfi/lattice/v7 v7.0.0 // indirect
github.com/luxfi/math v1.2.4 // indirect
github.com/luxfi/database v1.18.3 // indirect
github.com/luxfi/fhe v1.8.2 // indirect
github.com/luxfi/formatting v1.0.1 // indirect
github.com/luxfi/geth v1.16.100 // indirect
github.com/luxfi/go-bip32 v1.0.2 // indirect
github.com/luxfi/go-bip39 v1.1.2 // indirect
github.com/luxfi/ids v1.2.15 // indirect
github.com/luxfi/keys v1.1.0 // indirect
github.com/luxfi/kms v1.11.0 // indirect
github.com/luxfi/lattice/v7 v7.1.4 // indirect
github.com/luxfi/lens v0.1.4 // indirect
github.com/luxfi/math v1.4.1 // indirect
github.com/luxfi/math/big v0.1.0 // indirect
github.com/luxfi/mdns v0.1.0 // indirect
github.com/luxfi/metric v1.5.1 // indirect
github.com/luxfi/mdns v0.1.1 // indirect
github.com/luxfi/metric v1.5.7 // indirect
github.com/luxfi/mock v0.1.1 // indirect
github.com/luxfi/ringtail v0.2.0 // indirect
github.com/luxfi/zap v0.3.1 // indirect
github.com/luxfi/zapdb v1.9.0 // indirect
github.com/luxfi/pq v1.0.3 // indirect
github.com/luxfi/proto v1.0.0 // indirect
github.com/luxfi/pulsar v1.1.1 // indirect
github.com/luxfi/sampler v1.1.0 // indirect
github.com/luxfi/threshold v1.9.4 // indirect
github.com/luxfi/tls v1.0.3 // indirect
github.com/luxfi/vm v1.2.0 // indirect
github.com/luxfi/zapdb v1.10.0 // indirect
github.com/magefile/mage v1.15.1-0.20241126214340-bdc92f694516 // indirect
github.com/mailru/easyjson v0.9.0 // indirect
github.com/markbates/going v1.0.0 // indirect
@@ -426,6 +446,7 @@ require (
github.com/microsoft/go-mssqldb v1.9.5 // indirect
github.com/miekg/dns v1.1.72 // indirect
github.com/mileusna/viber v1.0.1 // indirect
github.com/mimoo/StrobeGo v0.0.0-20220103164710-9a04d6ca976b // indirect
github.com/minio/crc64nvme v1.1.1 // indirect
github.com/minio/md5-simd v1.1.2 // indirect
github.com/minio/minio-go/v7 v7.0.100 // indirect
@@ -438,7 +459,7 @@ require (
github.com/modelcontextprotocol/go-sdk v1.4.0 // indirect
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee // indirect
github.com/montanaflynn/stats v0.8.2 // indirect
github.com/montanaflynn/stats v0.9.0 // indirect
github.com/mr-tron/base58 v1.2.0 // indirect
github.com/mrjones/oauth v0.0.0-20180629183705-f4e24b6d100c // indirect
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
@@ -447,6 +468,7 @@ require (
github.com/nats-io/nkeys v0.4.15 // indirect
github.com/nats-io/nuid v1.0.1 // indirect
github.com/ncruces/go-strftime v1.0.0 // indirect
github.com/netlify/netlify-go v0.1.11 // indirect
github.com/nyaruka/phonenumbers v1.2.2 // indirect
github.com/oklog/run v1.2.0 // indirect
github.com/oklog/ulid v1.3.1 // indirect
@@ -468,6 +490,7 @@ require (
github.com/pjbgf/sha1cd v0.3.2 // indirect
github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c // indirect
github.com/pkg/errors v0.9.1 // indirect
github.com/plaid/plaid-go/v15 v15.3.0 // indirect
github.com/planetscale/vtprotobuf v0.6.1-0.20240319094008-0393e58bdf10 // indirect
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
github.com/power-devops/perfstat v0.0.0-20240221224432-82ca36839d55 // indirect
@@ -498,7 +521,7 @@ require (
github.com/rs/cors v1.11.1 // indirect
github.com/rs/cors/wrapper/gin v0.0.0-20240830163046-1084d89a1692 // indirect
github.com/rs/xid v1.6.0 // indirect
github.com/rs/zerolog v1.34.0 // indirect
github.com/rs/zerolog v1.35.0 // indirect
github.com/russellhaering/gosaml2 v0.11.0 // indirect
github.com/russellhaering/goxmldsig v1.6.0 // indirect
github.com/ryanuber/go-glob v1.0.0 // indirect
@@ -528,6 +551,7 @@ require (
github.com/spf13/cobra v1.10.2 // indirect
github.com/spf13/pflag v1.0.10 // indirect
github.com/spiffe/go-spiffe/v2 v2.6.0 // indirect
github.com/square/square-go-sdk/v3 v3.0.1 // indirect
github.com/stoewer/go-strcase v1.3.0 // indirect
github.com/stretchr/objx v0.5.3 // indirect
github.com/stretchr/testify v1.11.1 // indirect
@@ -581,10 +605,9 @@ require (
github.com/yosida95/uritemplate/v3 v3.0.2 // indirect
github.com/yuin/gopher-lua v1.1.1 // indirect
github.com/yusufpapurcu/wmi v1.2.4 // indirect
github.com/zap-proto/http v0.0.0-20260506200741-fd6047874433 // indirect
github.com/zeebo/blake3 v0.2.4 // indirect
go.mau.fi/util v0.8.3 // indirect
go.mongodb.org/mongo-driver v1.17.6 // indirect
go.mongodb.org/mongo-driver v1.17.9 // indirect
go.mongodb.org/mongo-driver/v2 v2.5.0 // indirect
go.opencensus.io v0.24.0 // indirect
go.opentelemetry.io/auto/sdk v1.2.1 // indirect
@@ -611,9 +634,9 @@ require (
go.opentelemetry.io/collector/semconv v0.128.1-0.20250610090210-188191247685 // indirect
go.opentelemetry.io/contrib/config v0.10.0 // indirect
go.opentelemetry.io/contrib/detectors/gcp v1.39.0 // indirect
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.63.0 // indirect
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.67.0 // indirect
go.opentelemetry.io/contrib/instrumentation/net/http/httptrace/otelhttptrace v0.65.0 // indirect
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.65.0 // indirect
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.67.0 // indirect
go.opentelemetry.io/contrib/propagators/autoprop v0.63.0 // indirect
go.opentelemetry.io/contrib/propagators/aws v1.38.0 // indirect
go.opentelemetry.io/contrib/propagators/b3 v1.39.0 // indirect
@@ -624,11 +647,11 @@ require (
go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.39.0 // indirect
go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.39.0 // indirect
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.43.0 // indirect
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.40.0 // indirect
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.42.0 // indirect
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.43.0 // indirect
go.opentelemetry.io/otel/exporters/prometheus v0.60.0 // indirect
go.opentelemetry.io/otel/exporters/stdout/stdoutlog v0.14.0 // indirect
go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.39.0 // indirect
go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.40.0 // indirect
go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.39.0 // indirect
go.opentelemetry.io/otel/log v0.15.0 // indirect
go.opentelemetry.io/otel/metric v1.43.0 // indirect
@@ -650,17 +673,18 @@ require (
gocloud.dev/secrets/hashivault v0.39.0 // indirect
golang.org/x/arch v0.25.0 // indirect
golang.org/x/exp v0.0.0-20260312153236-7ab1446f8b90 // indirect
golang.org/x/image v0.38.0 // indirect
golang.org/x/mod v0.34.0 // indirect
golang.org/x/image v0.41.0 // indirect
golang.org/x/mod v0.36.0 // indirect
golang.org/x/oauth2 v0.36.0 // indirect
golang.org/x/sync v0.20.0 // indirect
golang.org/x/time v0.15.0 // indirect
golang.org/x/tools v0.43.0 // indirect
golang.org/x/tools v0.45.0 // indirect
golang.org/x/xerrors v0.0.0-20240903120638-7835f813f4da // indirect
google.golang.org/api v0.267.0 // indirect
google.golang.org/genproto v0.0.0-20260128011058-8636f8732409 // indirect
google.golang.org/genproto/googleapis/api v0.0.0-20260401024825-9d38bb4040a9 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20260401024825-9d38bb4040a9 // indirect
gonum.org/v1/gonum v0.17.0 // indirect
google.golang.org/api v0.275.0 // indirect
google.golang.org/genproto v0.0.0-20260406210006-6f92a3bedf2d // indirect
google.golang.org/genproto/googleapis/api v0.0.0-20260511170946-3700d4141b60 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20260511170946-3700d4141b60 // indirect
google.golang.org/grpc v1.80.0 // indirect
google.golang.org/protobuf v1.36.11 // indirect
gopkg.in/DataDog/dd-trace-go.v1 v1.62.0 // indirect
@@ -677,10 +701,9 @@ require (
k8s.io/utils v0.0.0-20251002143259-bc988d571ff4 // indirect
layeh.com/radius v0.0.0-20231213012653-1006025d24f8 // indirect
maunium.net/go/mautrix v0.22.1 // indirect
modernc.org/libc v1.72.0 // indirect
modernc.org/libc v1.72.3 // indirect
modernc.org/mathutil v1.7.1 // indirect
modernc.org/memory v1.11.0 // indirect
modernc.org/sqlite v1.50.0 // indirect
rsc.io/binaryregexp v0.2.0 // indirect
)
@@ -694,25 +717,26 @@ require (
github.com/hanzoai/amqp v0.2.0
github.com/hanzoai/authz v1.10.0
github.com/hanzoai/base v1.3.1
github.com/hanzoai/commerce v1.37.0
github.com/hanzoai/commerce v1.42.21
github.com/hanzoai/gateway v0.2.0
github.com/hanzoai/iam/pkg/iam v1.18.0
github.com/hanzoai/ingress v1.8.0
github.com/hanzoai/kms v0.159.0
github.com/hanzoai/mcp/go v0.1.0
github.com/hanzoai/o11y v0.1.0
github.com/hanzoai/vfs v0.1.0
github.com/hanzoai/vfs v0.4.0
github.com/klauspost/compress v1.18.5 // indirect
github.com/luxfi/zap v0.7.2
github.com/mattn/go-colorable v0.1.14 // indirect
github.com/mattn/go-isatty v0.0.21 // indirect
github.com/mattn/go-isatty v0.0.22 // indirect
github.com/philhofer/fwd v1.2.0 // indirect
github.com/tinylib/msgp v1.6.4 // indirect
github.com/valyala/bytebufferpool v1.0.0 // indirect
github.com/valyala/fasthttp v1.70.0 // indirect
golang.org/x/crypto v0.50.0 // indirect
golang.org/x/net v0.53.0 // indirect
golang.org/x/sys v0.43.0 // indirect
golang.org/x/text v0.36.0 // indirect
golang.org/x/crypto v0.52.0 // indirect
golang.org/x/net v0.55.0 // indirect
golang.org/x/sys v0.45.0 // indirect
golang.org/x/text v0.37.0 // indirect
gopkg.in/natefinch/lumberjack.v2 v2.2.1 // indirect
)
@@ -727,29 +751,3 @@ replace github.com/gorilla/mux => github.com/containous/mux v0.0.0-2025052312054
replace github.com/mailgun/minheap => github.com/containous/minheap v0.0.0-20190809180810-6e71eb837595
replace github.com/vulcand/oxy/v2 => github.com/traefik/oxy/v2 v2.0.0-20260126093803-fb11d60e0fdf
replace github.com/hanzoai/ai => ../ai
replace github.com/hanzoai/amqp => ../amqp
replace github.com/hanzoai/authz => ../authz
replace github.com/hanzoai/base => ../base
replace github.com/hanzoai/commerce => ../commerce
replace github.com/hanzoai/gateway => ../gateway
replace github.com/hanzoai/iam => ../iam
replace github.com/hanzoai/ingress => ../ingress
replace github.com/hanzoai/kms => ../kms
replace github.com/hanzoai/o11y => ../o11y
replace github.com/hanzoai/vfs => ../vfs
replace github.com/hanzoai/iam/pkg/iam => ../iam/pkg/iam
replace github.com/hanzoai/mcp/go => ../mcp/go
+260 -181
View File
@@ -1,7 +1,5 @@
c2sp.org/CCTV/age v0.0.0-20251208015420-e9274a7bdbfd h1:ZLsPO6WdZ5zatV4UfVpr7oAwLGRZ+sebTUruuM4Ra3M=
c2sp.org/CCTV/age v0.0.0-20251208015420-e9274a7bdbfd/go.mod h1:SrHC2C7r5GkDk8R+NFVzYy/sdj0Ypg9htaPXQq5Cqeo=
capnproto.org/go/capnp/v3 v3.0.1-alpha.2 h1:W/cf+XEArUSwcBBE/9wS2NpWDkM5NLQOjmzEiHZpYi0=
capnproto.org/go/capnp/v3 v3.0.1-alpha.2/go.mod h1:2vT5D2dtG8sJGEoEKU17e+j7shdaYp1Myl8X03B3hmc=
cel.dev/expr v0.25.1 h1:1KrZg61W6TWSxuNZ37Xy49ps13NUovb66QLprthtwi4=
cel.dev/expr v0.25.1/go.mod h1:hrXvqGP6G6gyx8UAHSHJ5RGk//1Oj5nXQ2NI02Nrsg4=
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
@@ -35,10 +33,11 @@ cloud.google.com/go v0.94.1/go.mod h1:qAlAugsXlC+JWO+Bke5vCtc9ONxjQT3drlTTnAplMW
cloud.google.com/go v0.97.0/go.mod h1:GF7l59pYBVlXQIBLx3a761cZ41F9bBH3JUlihCt2Udc=
cloud.google.com/go v0.99.0/go.mod h1:w0Xx2nLzqWJPuozYQX+hFfCSI8WioryfRDzkoI/Y2ZA=
cloud.google.com/go v0.100.2/go.mod h1:4Xra9TjzAeYHrl5+oeLlzbM2k3mjVhZh4UqTZ//w99A=
cloud.google.com/go v0.102.0/go.mod h1:oWcCzKlqJ5zgHQt9YsaeTY9KzIvjyy0ArmiBUgpQ+nc=
cloud.google.com/go v0.123.0 h1:2NAUJwPR47q+E35uaJeYoNhuNEM9kM8SjgRgdeOJUSE=
cloud.google.com/go v0.123.0/go.mod h1:xBoMV08QcqUGuPW65Qfm1o9Y4zKZBpGS+7bImXLTAZU=
cloud.google.com/go/auth v0.18.1 h1:IwTEx92GFUo2pJ6Qea0EU3zYvKnTAeRCODxfA/G5UWs=
cloud.google.com/go/auth v0.18.1/go.mod h1:GfTYoS9G3CWpRA3Va9doKN9mjPGRS+v41jmZAhBzbrA=
cloud.google.com/go/auth v0.20.0 h1:kXTssoVb4azsVDoUiF8KvxAqrsQcQtB53DcSgta74CA=
cloud.google.com/go/auth v0.20.0/go.mod h1:942/yi/itH1SsmpyrbnTMDgGfdy2BUqIKyd0cyYLc5Q=
cloud.google.com/go/auth/oauth2adapt v0.2.8 h1:keo8NaayQZ6wimpNSmW5OPc283g65QNIiLpZnkHRbnc=
cloud.google.com/go/auth/oauth2adapt v0.2.8/go.mod h1:XQ9y31RkqZCcwJWNSx2Xvric3RrU88hAYYbjDWYDL+c=
cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o=
@@ -52,39 +51,42 @@ cloud.google.com/go/compute v1.3.0/go.mod h1:cCZiE1NHEtai4wiufUhW8I8S1JKkAnhnQJW
cloud.google.com/go/compute v1.5.0/go.mod h1:9SMHyhJlzhlkJqrPAc839t2BZFTSk6Jdj6mkzQJeu0M=
cloud.google.com/go/compute v1.6.0/go.mod h1:T29tfhtVbq1wvAPo0E3+7vhgmkOYeXjhFvz/FMzPu0s=
cloud.google.com/go/compute v1.6.1/go.mod h1:g85FgpzFvNULZ+S8AYq87axRKuf2Kh7deLqV/jJ3thU=
cloud.google.com/go/compute v1.7.0/go.mod h1:435lt8av5oL9P3fv1OEzSbSUe+ybHXGMPQHHZWZxy9U=
cloud.google.com/go/compute/metadata v0.9.0 h1:pDUj4QMoPejqq20dK0Pg2N4yG9zIkYGdBtwLoEkH9Zs=
cloud.google.com/go/compute/metadata v0.9.0/go.mod h1:E0bWwX5wTnLPedCKqk3pJmVgCBSM6qQI1yTBdEb3C10=
cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE=
cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk=
cloud.google.com/go/firestore v1.6.1/go.mod h1:asNXNOzBdyVQmEU+ggO8UPodTkEVFW5Qx+rwHnAz+EY=
cloud.google.com/go/iam v1.5.3 h1:+vMINPiDF2ognBJ97ABAYYwRgsaqxPbQDlMnbHMjolc=
cloud.google.com/go/iam v1.5.3/go.mod h1:MR3v9oLkZCTlaqljW6Eb2d3HGDGK5/bDv93jhfISFvU=
cloud.google.com/go/kms v1.25.0 h1:gVqvGGUmz0nYCmtoxWmdc1wli2L1apgP8U4fghPGSbQ=
cloud.google.com/go/kms v1.25.0/go.mod h1:XIdHkzfj0bUO3E+LvwPg+oc7s58/Ns8Nd8Sdtljihbk=
cloud.google.com/go/logging v1.13.1 h1:O7LvmO0kGLaHY/gq8cV7T0dyp6zJhYAOtZPX4TF3QtY=
cloud.google.com/go/logging v1.13.1/go.mod h1:XAQkfkMBxQRjQek96WLPNze7vsOmay9H5PqfsNYDqvw=
cloud.google.com/go/longrunning v0.8.0 h1:LiKK77J3bx5gDLi4SMViHixjD2ohlkwBi+mKA7EhfW8=
cloud.google.com/go/longrunning v0.8.0/go.mod h1:UmErU2Onzi+fKDg2gR7dusz11Pe26aknR4kHmJJqIfk=
cloud.google.com/go/monitoring v1.24.3 h1:dde+gMNc0UhPZD1Azu6at2e79bfdztVDS5lvhOdsgaE=
cloud.google.com/go/monitoring v1.24.3/go.mod h1:nYP6W0tm3N9H/bOw8am7t62YTzZY+zUeQ+Bi6+2eonI=
cloud.google.com/go/iam v0.3.0/go.mod h1:XzJPvDayI+9zsASAFO68Hk07u3z+f+JrT2xXNdp4bnY=
cloud.google.com/go/iam v1.7.0 h1:JD3zh0C6LHl16aCn5Akff0+GELdp1+4hmh6ndoFLl8U=
cloud.google.com/go/iam v1.7.0/go.mod h1:tetWZW1PD/m6vcuY2Zj/aU0eCHNPuxedbnbRTyKXvdY=
cloud.google.com/go/kms v1.27.0 h1:iYYgoD0HJIqz35A+He1G0dS5qTQzQsDXFsyXwzkUCXM=
cloud.google.com/go/kms v1.27.0/go.mod h1:KPxrdf61iYEOZ86uPwR86muBpSik2y4Ion6e83fVl1Q=
cloud.google.com/go/logging v1.14.0 h1:xpPpY8cVT6n9DgIRgrWyE+YEsGlO/994pWnbc7o5Eh4=
cloud.google.com/go/logging v1.14.0/go.mod h1:jmI+Try/fZeOTOAer3wVYOuPf9WX9PyzhlSDoBAi4HM=
cloud.google.com/go/longrunning v0.9.0 h1:0EzbDEGsAvOZNbqXopgniY0w0a1phvu5IdUFq8grmqY=
cloud.google.com/go/longrunning v0.9.0/go.mod h1:pkTz846W7bF4o2SzdWJ40Hu0Re+UoNT6Q5t+igIcb8E=
cloud.google.com/go/monitoring v1.25.0 h1:HnsTIOxTN6BCSkt1P/Im23r1m7MHTTpmSYCzPkW7NK4=
cloud.google.com/go/monitoring v1.25.0/go.mod h1:wlj6rX+JGyusw/8+2duW4cJ6kmDHGmde3zMTJuG3Jpc=
cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I=
cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw=
cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA=
cloud.google.com/go/pubsub v1.3.1/go.mod h1:i+ucay31+CNRpDW4Lu78I4xXG+O1r/MAHgjpRVR+TSU=
cloud.google.com/go/pubsub v1.50.1 h1:fzbXpPyJnSGvWXF1jabhQeXyxdbCIkXTpjXHy7xviBM=
cloud.google.com/go/pubsub v1.50.1/go.mod h1:6YVJv3MzWJUVdvQXG081sFvS0dWQOdnV+oTo++q/xFk=
cloud.google.com/go/pubsub/v2 v2.3.0 h1:DgAN907x+sP0nScYfBzneRiIhWoXcpCD8ZAut8WX9vs=
cloud.google.com/go/pubsub/v2 v2.3.0/go.mod h1:O5f0KHG9zDheZAd3z5rlCRhxt2JQtB+t/IYLKK3Bpvw=
cloud.google.com/go/pubsub v1.50.2 h1:54Up97HnThdP4H8jjWJSSQ/mnYG2EKon7ZSNETRq0tM=
cloud.google.com/go/pubsub v1.50.2/go.mod h1:jyCWeZdGFqd4mitSsBERnJcpqaHBsxQoPkNvjj4sp0w=
cloud.google.com/go/pubsub/v2 v2.5.1 h1:+TwXJr78P9RrMV3S8lKHIhJo2E99jI7ta65e+ujJjts=
cloud.google.com/go/pubsub/v2 v2.5.1/go.mod h1:Pd+qeabMX+576vQJhTN7TelE4k6kJh15dLU/ptOQ/UA=
cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw=
cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos=
cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk=
cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs=
cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0=
cloud.google.com/go/storage v1.14.0/go.mod h1:GrKmX003DSIwi9o29oFT7YDnHYwZoctc3fOKtUw0Xmo=
cloud.google.com/go/storage v1.59.2 h1:gmOAuG1opU8YvycMNpP+DvHfT9BfzzK5Cy+arP+Nocw=
cloud.google.com/go/storage v1.59.2/go.mod h1:cMWbtM+anpC74gn6qjLh+exqYcfmB9Hqe5z6adx+CLI=
cloud.google.com/go/trace v1.11.7 h1:kDNDX8JkaAG3R2nq1lIdkb7FCSi1rCmsEtKVsty7p+U=
cloud.google.com/go/trace v1.11.7/go.mod h1:TNn9d5V3fQVf6s4SCveVMIBS2LJUqo73GACmq/Tky0s=
cloud.google.com/go/storage v1.22.1/go.mod h1:S8N1cAStu7BOeFfE8KAQzmyyLkK8p/vmRq6kuBTW58Y=
cloud.google.com/go/storage v1.61.3 h1:VS//ZfBuPGDvakfD9xyPW1RGF1Vy3BWUoVZXgW1KMOg=
cloud.google.com/go/storage v1.61.3/go.mod h1:JtqK8BBB7TWv0HVGHubtUdzYYrakOQIsMLffZ2Z/HWk=
cloud.google.com/go/trace v1.12.0 h1:XvWHYfr9q88cX4pZyou6qCcSagnuASyUq2ej1dB6NzQ=
cloud.google.com/go/trace v1.12.0/go.mod h1:TOYfyeoyCGsSH0ifXD6Aius24uQI9xV3RyvOdljFIyg=
contrib.go.opencensus.io/exporter/aws v0.0.0-20230502192102-15967c811cec h1:CSNP8nIEQt4sZEo2sGUiWSmVJ9c5QdyIQvwzZAsn+8Y=
contrib.go.opencensus.io/exporter/aws v0.0.0-20230502192102-15967c811cec/go.mod h1:uu1P0UCM/6RbsMrgPa98ll8ZcHM858i/AD06a9aLRCA=
contrib.go.opencensus.io/exporter/jaeger v0.2.1 h1:yGBYzYMewVL0yO9qqJv3Z5+IRhPdU7e9o/2oKpX4YvI=
@@ -100,8 +102,8 @@ contrib.go.opencensus.io/exporter/zipkin v0.1.2/go.mod h1:mP5xM3rrgOjpn79MM8fZbj
dario.cat/mergo v1.0.2 h1:85+piFYR1tMbRrLcDwR18y4UKJ3aH1Tbzi24VRW1TK8=
dario.cat/mergo v1.0.2/go.mod h1:E/hbnu0NxMFBjpMIE34DRGLWqDy0g5FuKDhCb31ngxA=
dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
filippo.io/edwards25519 v1.1.1 h1:YpjwWWlNmGIDyXOn8zLzqiD+9TyIlPhGFG96P39uBpw=
filippo.io/edwards25519 v1.1.1/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4=
filippo.io/edwards25519 v1.2.0 h1:crnVqOiS4jqYleHd9vaKZ+HKtHfllngJIiOpNpoJsjo=
filippo.io/edwards25519 v1.2.0/go.mod h1:xzAOLCNug/yB62zG1bQ8uziwrIqIuxhctzJT18Q77mc=
filippo.io/hpke v0.4.0 h1:p575VVQ6ted4pL+it6M00V/f2qTZITO0zgmdKCkd5+A=
filippo.io/hpke v0.4.0/go.mod h1:EmAN849/P3qdeK+PCMkDpDm83vRHM5cDipBJ8xbQLVY=
gitea.com/xorm/sqlfiddle v0.0.0-20180821085327-62ce714f951a h1:lSA0F4e9A2NcQSqGqTOXqu2aRi/XEQxDCBwM8yJtE6s=
@@ -121,8 +123,8 @@ github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.13.1 h1:Hk5QBxZQC1jb2Fwj6mpz
github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.13.1/go.mod h1:IYus9qsFobWIc2YVwe/WPjcnyCkPKtnHAqUYeebc8z0=
github.com/Azure/azure-sdk-for-go/sdk/azidentity/cache v0.3.2 h1:yz1bePFlP5Vws5+8ez6T3HWXPmwOK7Yvq8QxDBD3SKY=
github.com/Azure/azure-sdk-for-go/sdk/azidentity/cache v0.3.2/go.mod h1:Pa9ZNPuoNu/GztvBSKk9J1cDJW6vk/n0zLtV4mgd8N8=
github.com/Azure/azure-sdk-for-go/sdk/internal v1.11.2 h1:9iefClla7iYpfYWdzPCRDozdmndjTm8DXdpCzPajMgA=
github.com/Azure/azure-sdk-for-go/sdk/internal v1.11.2/go.mod h1:XtLgD3ZD34DAaVIIAyG3objl5DynM3CQ/vMcbBNJZGI=
github.com/Azure/azure-sdk-for-go/sdk/internal v1.12.0 h1:fhqpLE3UEXi9lPaBRpQ6XuRW0nU7hgg4zlmZZa+a9q4=
github.com/Azure/azure-sdk-for-go/sdk/internal v1.12.0/go.mod h1:7dCRMLwisfRH3dBupKeNCioWYUZ4SS09Z14H+7i8ZoY=
github.com/Azure/azure-sdk-for-go/sdk/keyvault/azkeys v0.10.0 h1:m/sWOGCREuSBqg2htVQTBY8nOZpyajYztF0vUvSZTuM=
github.com/Azure/azure-sdk-for-go/sdk/keyvault/azkeys v0.10.0/go.mod h1:Pu5Zksi2KrU7LPbZbNINx6fuVrUp/ffvpxdDj+i8LeE=
github.com/Azure/azure-sdk-for-go/sdk/keyvault/internal v0.7.1 h1:FbH3BbSb4bvGluTesZZ+ttN/MDsnMmQP36OSnDuSXqw=
@@ -134,10 +136,10 @@ github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/compute/armcompute/v5 v5.7
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/compute/armcompute/v5 v5.7.0/go.mod h1:QyiQdW4f4/BIfB8ZutZ2s+28RAgfa/pT+zS++ZHyM1I=
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/network/armnetwork/v4 v4.3.0 h1:bXwSugBiSbgtz7rOtbfGf+woewp4f06orW9OP5BjHLA=
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/network/armnetwork/v4 v4.3.0/go.mod h1:Y/HgrePTmGy9HjdSGTqZNa+apUpTVIEVKXJyARP2lrk=
github.com/Azure/azure-sdk-for-go/sdk/security/keyvault/azkeys v1.3.1 h1:Wgf5rZba3YZqeTNJPtvqZoBu1sBN/L4sry+u2U3Y75w=
github.com/Azure/azure-sdk-for-go/sdk/security/keyvault/azkeys v1.3.1/go.mod h1:xxCBG/f/4Vbmh2XQJBsOmNdxWUY5j/s27jujKPbQf14=
github.com/Azure/azure-sdk-for-go/sdk/security/keyvault/internal v1.1.1 h1:bFWuoEKg+gImo7pvkiQEFAc8ocibADgXeiLAxWhWmkI=
github.com/Azure/azure-sdk-for-go/sdk/security/keyvault/internal v1.1.1/go.mod h1:Vih/3yc6yac2JzU4hzpaDupBJP0Flaia9rXXrU8xyww=
github.com/Azure/azure-sdk-for-go/sdk/security/keyvault/azkeys v1.4.0 h1:E4MgwLBGeVB5f2MdcIVD3ELVAWpr+WD6MUe1i+tM/PA=
github.com/Azure/azure-sdk-for-go/sdk/security/keyvault/azkeys v1.4.0/go.mod h1:Y2b/1clN4zsAoUd/pgNAQHjLDnTis/6ROkUfyob6psM=
github.com/Azure/azure-sdk-for-go/sdk/security/keyvault/internal v1.2.0 h1:nCYfgcSyHZXJI8J0IWE5MsCGlb2xp9fJiXyxWgmOFg4=
github.com/Azure/azure-sdk-for-go/sdk/security/keyvault/internal v1.2.0/go.mod h1:ucUjca2JtSZboY8IoUqyQyuuXvwbMBVwFOm0vdQPNhA=
github.com/Azure/azure-storage-blob-go v0.15.0 h1:rXtgp8tN1p29GvpGgfJetavIG0V7OgcSXPpwp3tx6qk=
github.com/Azure/azure-storage-blob-go v0.15.0/go.mod h1:vbjsVbX0dlxnRc4FFMPsS9BsJWPcne7GB7onqlPvz58=
github.com/Azure/go-amqp v0.17.0/go.mod h1:9YJ3RhxRT1gquYnzpZO1vcYMMpAdJT+QEg6fwmw9Zlg=
@@ -167,6 +169,8 @@ github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03
github.com/BurntSushi/toml v1.6.0 h1:dRaEfpa2VI55EwlIW72hMRHdWouJeRF7TPYhI+AUQjk=
github.com/BurntSushi/toml v1.6.0/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2lLoLwho=
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
github.com/ChainSafe/go-schnorrkel v1.1.0 h1:rZ6EU+CZFCjB4sHUE1jIu8VDoB/wRKZxoe1tkcO71Wk=
github.com/ChainSafe/go-schnorrkel v1.1.0/go.mod h1:ABkENxiP+cvjFiByMIZ9LYbRoNNLeBLiakC1XeTFxfE=
github.com/ClickHouse/ch-go v0.71.0 h1:bUdZ/EZj/LcVHsMqaRUP2holqygrPWQKeMjc6nZoyRM=
github.com/ClickHouse/ch-go v0.71.0/go.mod h1:NwbNc+7jaqfY58dmdDUbG4Jl22vThgx1cYjBw0vtgXw=
github.com/ClickHouse/clickhouse-go/v2 v2.40.1 h1:PbwsHBgqXRydU7jKULD1C8CHmifczffvQqmFvltM2W4=
@@ -184,12 +188,12 @@ github.com/DataDog/opencensus-go-exporter-datadog v0.0.0-20220622145613-731d59e8
github.com/DataDog/opencensus-go-exporter-datadog v0.0.0-20220622145613-731d59e8b567/go.mod h1:/VV3EFO/hTNQZHAqaj+CPGy2+ioFrP4EX3iRwozubhQ=
github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp v1.31.0 h1:DHa2U07rk8syqvCge0QIGMCE1WxGj9njT44GH7zNJLQ=
github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp v1.31.0/go.mod h1:P4WPRUkOhJC13W//jWpyfJNDAIpvRbAUIYLX/4jtlE0=
github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/metric v0.54.0 h1:lhhYARPUu3LmHysQ/igznQphfzynnqI3D75oUyw1HXk=
github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/metric v0.54.0/go.mod h1:l9rva3ApbBpEJxSNYnwT9N4CDLrWgtq3u8736C5hyJw=
github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/cloudmock v0.54.0 h1:xfK3bbi6F2RDtaZFtUdKO3osOBIhNb+xTs8lFW6yx9o=
github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/cloudmock v0.54.0/go.mod h1:vB2GH9GAYYJTO3mEn8oYwzEdhlayZIdQz6zdzgUIRvA=
github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/resourcemapping v0.54.0 h1:s0WlVbf9qpvkh1c/uDAPElam0WrL7fHRIidgZJ7UqZI=
github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/resourcemapping v0.54.0/go.mod h1:Mf6O40IAyB9zR/1J8nGDDPirZQQPbYJni8Yisy7NTMc=
github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/metric v0.55.0 h1:UnDZ/zFfG1JhH/DqxIZYU/1CUAlTUScoXD/LcM2Ykk8=
github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/metric v0.55.0/go.mod h1:IA1C1U7jO/ENqm/vhi7V9YYpBsp+IMyqNrEN94N7tVc=
github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/cloudmock v0.55.0 h1:7t/qx5Ost0s0wbA/VDrByOooURhp+ikYwv20i9Y07TQ=
github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/cloudmock v0.55.0/go.mod h1:vB2GH9GAYYJTO3mEn8oYwzEdhlayZIdQz6zdzgUIRvA=
github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/resourcemapping v0.55.0 h1:0s6TxfCu2KHkkZPnBfsQ2y5qia0jl3MMrmBhu3nCOYk=
github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/resourcemapping v0.55.0/go.mod h1:Mf6O40IAyB9zR/1J8nGDDPirZQQPbYJni8Yisy7NTMc=
github.com/HdrHistogram/hdrhistogram-go v1.1.0/go.mod h1:yDgFjdqOqDEKOvasDdhWNXYg9BVp4O+o5f6V/ehm6Oo=
github.com/HdrHistogram/hdrhistogram-go v1.1.2/go.mod h1:yDgFjdqOqDEKOvasDdhWNXYg9BVp4O+o5f6V/ehm6Oo=
github.com/IBM/sarama v1.46.3 h1:njRsX6jNlnR+ClJ8XmkO+CM4unbrNr/2vB5KK6UA+IE=
@@ -207,8 +211,6 @@ github.com/Microsoft/go-winio v0.5.2/go.mod h1:WpS1mjBmmwHBEWmogvA2mj8546UReBk4v
github.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERoyfY=
github.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU=
github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
github.com/ProjectZKM/Ziren/crates/go-runtime/zkvm_runtime v0.0.0-20260311194731-d5b7577c683d h1:EA+kZ8mxGb1W/ewiIBMzb/1gg5BiW1Fvr3r4qCUBJEg=
github.com/ProjectZKM/Ziren/crates/go-runtime/zkvm_runtime v0.0.0-20260311194731-d5b7577c683d/go.mod h1:ioLG6R+5bUSO1oeGSDxOV3FADARuMoytZCSX6MEMQkI=
github.com/ProtonMail/go-crypto v1.1.6 h1:ZcV+Ropw6Qn0AX9brlQLAUXfqLBc7Bl+f/DmNxpLfdw=
github.com/ProtonMail/go-crypto v1.1.6/go.mod h1:rA3QumHc/FZ8pAHreoekgiAbzpNsfQAosU5td4SnOrE=
github.com/PuerkitoBio/goquery v1.8.1 h1:uQxhNlArOIdbrH1tr0UXwdVFgDcZDrZVdcpygAcwmWM=
@@ -362,60 +364,60 @@ github.com/aws/aws-sdk-go v1.55.8 h1:JRmEUbU52aJQZ2AjX4q4Wu7t4uZjOu71uyNmaWlUkJQ
github.com/aws/aws-sdk-go v1.55.8/go.mod h1:ZkViS9AqA6otK+JBBNH2++sx1sgxrPKcSzPPvQkUtXk=
github.com/aws/aws-sdk-go-v2 v1.9.1/go.mod h1:cK/D0BBs0b/oWPIcX/Z/obahJK1TT7IPVjy53i/mX/4=
github.com/aws/aws-sdk-go-v2 v1.9.2/go.mod h1:cK/D0BBs0b/oWPIcX/Z/obahJK1TT7IPVjy53i/mX/4=
github.com/aws/aws-sdk-go-v2 v1.41.2 h1:LuT2rzqNQsauaGkPK/7813XxcZ3o3yePY0Iy891T2ls=
github.com/aws/aws-sdk-go-v2 v1.41.2/go.mod h1:IvvlAZQXvTXznUPfRVfryiG1fbzE2NGK6m9u39YQ+S4=
github.com/aws/aws-sdk-go-v2 v1.41.5 h1:dj5kopbwUsVUVFgO4Fi5BIT3t4WyqIDjGKCangnV/yY=
github.com/aws/aws-sdk-go-v2 v1.41.5/go.mod h1:mwsPRE8ceUUpiTgF7QmQIJ7lgsKUPQOUl3o72QBrE1o=
github.com/aws/aws-sdk-go-v2/config v1.8.3/go.mod h1:4AEiLtAb8kLs7vgw2ZV3p2VZ1+hBavOc84hqxVNpCyw=
github.com/aws/aws-sdk-go-v2/config v1.32.8 h1:iu+64gwDKEoKnyTQskSku72dAwggKI5sV6rNvgSMpMs=
github.com/aws/aws-sdk-go-v2/config v1.32.8/go.mod h1:MI2XvA+qDi3i9AJxX1E2fu730syEBzp/jnXrjxuHwgI=
github.com/aws/aws-sdk-go-v2/config v1.32.13 h1:5KgbxMaS2coSWRrx9TX/QtWbqzgQkOdEa3sZPhBhCSg=
github.com/aws/aws-sdk-go-v2/config v1.32.13/go.mod h1:8zz7wedqtCbw5e9Mi2doEwDyEgHcEE9YOJp6a8jdSMY=
github.com/aws/aws-sdk-go-v2/credentials v1.4.3/go.mod h1:FNNC6nQZQUuyhq5aE5c7ata8o9e4ECGmS4lAXC7o1mQ=
github.com/aws/aws-sdk-go-v2/credentials v1.19.8 h1:Jp2JYH1lRT3KhX4mshHPvVYsR5qqRec3hGvEarNYoR0=
github.com/aws/aws-sdk-go-v2/credentials v1.19.8/go.mod h1:fZG9tuvyVfxknv1rKibIz3DobRaFw1Poe8IKtXB3XYY=
github.com/aws/aws-sdk-go-v2/credentials v1.19.13 h1:mA59E3fokBvyEGHKFdnpNNrvaR351cqiHgRg+JzOSRI=
github.com/aws/aws-sdk-go-v2/credentials v1.19.13/go.mod h1:yoTXOQKea18nrM69wGF9jBdG4WocSZA1h38A+t/MAsk=
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.6.0/go.mod h1:gqlclDEZp4aqJOancXK6TN24aKhT0W0Ae9MHk3wzTMM=
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.17 h1:I0GyV8wiYrP8XpA70g1HBcQO1JlQxCMTW9npl5UbDHY=
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.17/go.mod h1:tyw7BOl5bBe/oqvoIeECFJjMdzXoa/dfVz3QQ5lgHGA=
github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.18 h1:F43zk1vemYIqPAwhjTjYIz0irU2EY7sOb/F5eJ3HuyM=
github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.18/go.mod h1:w1jdlZXrGKaJcNoL+Nnrj+k5wlpGXqnNrKoP22HvAug=
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.18 h1:xCeWVjj0ki0l3nruoyP2slHsGArMxeiiaoPN5QZH6YQ=
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.18/go.mod h1:r/eLGuGCBw6l36ZRWiw6PaZwPXb6YOj+i/7MizNl5/k=
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.21 h1:NUS3K4BTDArQqNu2ih7yeDLaS3bmHD0YndtA6UP884g=
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.21/go.mod h1:YWNWJQNjKigKY1RHVJCuupeWDrrHjRqHm0N9rdrWzYI=
github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.21 h1:Rgg6wvjjtX8bNHcvi9OnXWwcE0a2vGpbwmtICOsvcf4=
github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.21/go.mod h1:A/kJFst/nm//cyqonihbdpQZwiUhhzpqTsdbhDdRF9c=
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.21 h1:PEgGVtPoB6NTpPrBgqSE5hE/o47Ij9qk/SEZFbUOe9A=
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.21/go.mod h1:p+hz+PRAYlY3zcpJhPwXlLC4C+kqn70WIHwnzAfs6ps=
github.com/aws/aws-sdk-go-v2/internal/ini v1.2.4/go.mod h1:ZcBrrI3zBKlhGFNYWvju0I3TR93I7YIgAfy82Fh4lcQ=
github.com/aws/aws-sdk-go-v2/internal/ini v1.8.4 h1:WKuaxf++XKWlHWu9ECbMlha8WOEGm0OUEZqm4K/Gcfk=
github.com/aws/aws-sdk-go-v2/internal/ini v1.8.4/go.mod h1:ZWy7j6v1vWGmPReu0iSGvRiise4YI5SkR3OHKTZ6Wuc=
github.com/aws/aws-sdk-go-v2/internal/ini v1.8.6 h1:qYQ4pzQ2Oz6WpQ8T3HvGHnZydA72MnLuFK9tJwmrbHw=
github.com/aws/aws-sdk-go-v2/internal/ini v1.8.6/go.mod h1:O3h0IK87yXci+kg6flUKzJnWeziQUKciKrLjcatSNcY=
github.com/aws/aws-sdk-go-v2/service/appconfig v1.4.2/go.mod h1:FZ3HkCe+b10uFZZkFdvf98LHW21k49W8o8J366lqVKY=
github.com/aws/aws-sdk-go-v2/service/cloudwatch v1.8.1/go.mod h1:CM+19rL1+4dFWnOQKwDc7H1KwXTz+h61oUSHyhV0b3o=
github.com/aws/aws-sdk-go-v2/service/ec2 v1.285.0 h1:cRZQsqCy59DSJmvmUYzi9K+dutysXzfx6F+fkcIHtOk=
github.com/aws/aws-sdk-go-v2/service/ec2 v1.285.0/go.mod h1:Uy+C+Sc58jozdoL1McQr8bDsEvNFx+/nBY+vpO1HVUY=
github.com/aws/aws-sdk-go-v2/service/ecs v1.71.0 h1:MzP/ElwTpINq+hS80ZQz4epKVnUTlz8Sz+P/AFORCKM=
github.com/aws/aws-sdk-go-v2/service/ecs v1.71.0/go.mod h1:pMlGFDpHoLTJOIZHGdJOAWmi+xeIlQXuFTuQxs1epYE=
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.5 h1:CeY9LUdur+Dxoeldqoun6y4WtJ3RQtzk0JMP2gfUay0=
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.5/go.mod h1:AZLZf2fMaahW5s/wMRciu1sYbdsikT/UHwbUjOdEVTc=
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.7 h1:5EniKhLZe4xzL7a+fU3C2tfUN4nWIqlLesfrjkuPFTY=
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.7/go.mod h1:x0nZssQ3qZSnIcePWLvcoFisRXJzcTVvYpAAdYX8+GI=
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.3.2/go.mod h1:72HRZDLMtmVQiLG2tLfQcaWLCssELvGl+Zf2WVxMmR8=
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.18 h1:LTRCYFlnnKFlKsyIQxKhJuDuA3ZkrDQMRYm6rXiHlLY=
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.18/go.mod h1:XhwkgGG6bHSd00nO/mexWTcTjgd6PjuvWQMqSn2UaEk=
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.21 h1:c31//R3xgIJMSC8S6hEVq+38DcvUlgFY0FM6mSI5oto=
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.21/go.mod h1:r6+pf23ouCB718FUxaqzZdbpYFyDtehyZcmP5KL9FkA=
github.com/aws/aws-sdk-go-v2/service/kafka v1.46.7 h1:0jDb9b505gbCmtjH1RT7kx8hDbVDzOhnTeZm7dzskpQ=
github.com/aws/aws-sdk-go-v2/service/kafka v1.46.7/go.mod h1:tWnHS64fg5ydLHivFlCAtEh/1iMNzr56QsH3F+UTwD4=
github.com/aws/aws-sdk-go-v2/service/kms v1.35.3 h1:UPTdlTOwWUX49fVi7cymEN6hDqCwe3LNv1vi7TXUutk=
github.com/aws/aws-sdk-go-v2/service/kms v1.35.3/go.mod h1:gjDP16zn+WWalyaUqwCCioQ8gU8lzttCCc9jYsiQI/8=
github.com/aws/aws-sdk-go-v2/service/kms v1.50.4 h1:PgD1y0ZagPokGIZPmejCBUySBzOFDN+leZxCOfb1OEQ=
github.com/aws/aws-sdk-go-v2/service/kms v1.50.4/go.mod h1:FfXDb5nXrsoGgxsBFxwxr3vdHXheC2tV+6lmuLghhjQ=
github.com/aws/aws-sdk-go-v2/service/lightsail v1.50.11 h1:VM5e5M39zRSs+aT0O9SoxHjUXqXxhbw3Yi0FdMQWPIc=
github.com/aws/aws-sdk-go-v2/service/lightsail v1.50.11/go.mod h1:0jvzYPIQGCpnY/dmdaotTk2JH4QuBlnW0oeyrcGLWJ4=
github.com/aws/aws-sdk-go-v2/service/s3 v1.96.2 h1:M1A9AjcFwlxTLuf0Faj88L8Iqw0n/AJHjpZTQzMMsSc=
github.com/aws/aws-sdk-go-v2/service/s3 v1.96.2/go.mod h1:KsdTV6Q9WKUZm2mNJnUFmIoXfZux91M3sr/a4REX8e0=
github.com/aws/aws-sdk-go-v2/service/signin v1.0.5 h1:VrhDvQib/i0lxvr3zqlUwLwJP4fpmpyD9wYG1vfSu+Y=
github.com/aws/aws-sdk-go-v2/service/signin v1.0.5/go.mod h1:k029+U8SY30/3/ras4G/Fnv/b88N4mAfliNn08Dem4M=
github.com/aws/aws-sdk-go-v2/service/signin v1.0.9 h1:QKZH0S178gCmFEgst8hN0mCX1KxLgHBKKY/CLqwP8lg=
github.com/aws/aws-sdk-go-v2/service/signin v1.0.9/go.mod h1:7yuQJoT+OoH8aqIxw9vwF+8KpvLZ8AWmvmUWHsGQZvI=
github.com/aws/aws-sdk-go-v2/service/sns v1.39.11 h1:Ke7RS0NuP9Xwk31prXYcFGA1Qfn8QmNWcxyjKPcXZdc=
github.com/aws/aws-sdk-go-v2/service/sns v1.39.11/go.mod h1:hdZDKzao0PBfJJygT7T92x2uVcWc/htqlhrjFIjnHDM=
github.com/aws/aws-sdk-go-v2/service/sqs v1.42.21 h1:Oa0IhwDLVrcBHDlNo1aosG4CxO4HyvzDV5xUWqWcBc0=
github.com/aws/aws-sdk-go-v2/service/sqs v1.42.21/go.mod h1:t98Ssq+qtXKXl2SFtaSkuT6X42FSM//fnO6sfq5RqGM=
github.com/aws/aws-sdk-go-v2/service/sso v1.4.2/go.mod h1:NBvT9R1MEF+Ud6ApJKM0G+IkPchKS7p7c2YPKwHmBOk=
github.com/aws/aws-sdk-go-v2/service/sso v1.30.9 h1:v6EiMvhEYBoHABfbGB4alOYmCIrcgyPPiBE1wZAEbqk=
github.com/aws/aws-sdk-go-v2/service/sso v1.30.9/go.mod h1:yifAsgBxgJWn3ggx70A3urX2AN49Y5sJTD1UQFlfqBw=
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.35.14 h1:0jbJeuEHlwKJ9PfXtpSFc4MF+WIWORdhN1n30ITZGFM=
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.35.14/go.mod h1:sTGThjphYE4Ohw8vJiRStAcu3rbjtXRsdNB0TvZ5wwo=
github.com/aws/aws-sdk-go-v2/service/sso v1.30.14 h1:GcLE9ba5ehAQma6wlopUesYg/hbcOhFNWTjELkiWkh4=
github.com/aws/aws-sdk-go-v2/service/sso v1.30.14/go.mod h1:WSvS1NLr7JaPunCXqpJnWk1Bjo7IxzZXrZi1QQCkuqM=
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.35.18 h1:mP49nTpfKtpXLt5SLn8Uv8z6W+03jYVoOSAl/c02nog=
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.35.18/go.mod h1:YO8TrYtFdl5w/4vmjL8zaBSsiNp3w0L1FfKVKenZT7w=
github.com/aws/aws-sdk-go-v2/service/sts v1.7.2/go.mod h1:8EzeIqfWt2wWT4rJVu3f21TfrhJ8AEMzVybRNSb/b4g=
github.com/aws/aws-sdk-go-v2/service/sts v1.41.6 h1:5fFjR/ToSOzB2OQ/XqWpZBmNvmP/pJ1jOWYlFDJTjRQ=
github.com/aws/aws-sdk-go-v2/service/sts v1.41.6/go.mod h1:qgFDZQSD/Kys7nJnVqYlWKnh0SSdMjAi0uSwON4wgYQ=
github.com/aws/aws-sdk-go-v2/service/sts v1.41.10 h1:p8ogvvLugcR/zLBXTXrTkj0RYBUdErbMnAFFp12Lm/U=
github.com/aws/aws-sdk-go-v2/service/sts v1.41.10/go.mod h1:60dv0eZJfeVXfbT1tFJinbHrDfSJ2GZl4Q//OSSNAVw=
github.com/aws/smithy-go v1.8.0/go.mod h1:SObp3lf9smib00L/v3U2eAKG8FyQ7iLrJnQiAmR5n+E=
github.com/aws/smithy-go v1.24.1 h1:VbyeNfmYkWoxMVpGUAbQumkODcYmfMRfZ8yQiH30SK0=
github.com/aws/smithy-go v1.24.1/go.mod h1:LEj2LM3rBRQJxPZTB4KuzZkaZYnZPnvgIhb4pu07mx0=
github.com/aws/smithy-go v1.24.2 h1:FzA3bu/nt/vDvmnkg+R8Xl46gmzEDam6mZ1hzmwXFng=
github.com/aws/smithy-go v1.24.2/go.mod h1:YE2RhdIuDbA5E5bTdciG9KrW3+TiEONeUWCqxX9i1Fc=
github.com/aymerick/raymond v2.0.2+incompatible h1:VEp3GpgdAnv9B2GFyTvqgcKvY+mfKMjPOA3SbKLtnU0=
github.com/aymerick/raymond v2.0.2+incompatible/go.mod h1:osfaiScAUVup+UC9Nfq76eWqDhXlp+4UYaA8uhTBO6g=
github.com/baidubce/bce-sdk-go v0.9.260 h1:1v1+2GTP+NGK3L24rJ+bnoiTaDaIy2YoaUM+ot2GTcw=
@@ -540,8 +542,6 @@ github.com/cncf/xds/go v0.0.0-20251210132809-ee656c7534f5 h1:6xNmx7iTtyBRev0+D/T
github.com/cncf/xds/go v0.0.0-20251210132809-ee656c7534f5/go.mod h1:KdCmV+x/BuvyMxRnYBlmVaq4OLiKW6iRQfvC62cvdkI=
github.com/coder/quartz v0.3.0 h1:bUoSEJ77NBfKtUqv6CPSC0AS8dsjqAqqAv7bN02m1mg=
github.com/coder/quartz v0.3.0/go.mod h1:BgE7DOj/8NfvRgvKw0jPLDQH/2Lya2kxcTaNJ8X0rZk=
github.com/colega/zeropool v0.0.0-20230505084239-6fb4a4f75381 h1:d5EKgQfRQvO97jnISfR89AiCCCJMwMFoSxUiU0OGCRU=
github.com/colega/zeropool v0.0.0-20230505084239-6fb4a4f75381/go.mod h1:OU76gHeRo8xrzGJU3F3I1CqX1ekM8dfJw0+wPeMwnp0=
github.com/consensys/gnark-crypto v0.20.1 h1:PXDUBvk8AzhvWowHLWBEAfUQcV1/aZgWIqD6eMpXmDg=
github.com/consensys/gnark-crypto v0.20.1/go.mod h1:RBWrSgy+IDbGR69RRV313th3M/aZU1ubk2om+qHuTSc=
github.com/containerd/errdefs v1.0.0 h1:tg5yIfIlQIrxYtu9ajqY42W3lpS19XqdxRQeEwYG8PI=
@@ -560,14 +560,17 @@ github.com/coreos/go-oidc/v3 v3.17.0 h1:hWBGaQfbi0iVviX4ibC7bk8OKT5qNr4klBaCHVNv
github.com/coreos/go-oidc/v3 v3.17.0/go.mod h1:wqPbKFrVnE90vty060SB40FCJ8fTHTxSwyXJqZH+sI8=
github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
github.com/coreos/go-systemd/v22 v22.3.2/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc=
github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc=
github.com/coreos/go-systemd/v22 v22.6.0 h1:aGVa/v8B7hpb0TKl0MWoAavPDmHvobFe5R5zn0bCJWo=
github.com/coreos/go-systemd/v22 v22.6.0/go.mod h1:iG+pp635Fo7ZmV/j14KUcmEyWF+0X7Lua8rrTWzYgWU=
github.com/coreos/go-systemd/v22 v22.7.0 h1:LAEzFkke61DFROc7zNLX/WA2i5J8gYqe0rSj9KI28KA=
github.com/coreos/go-systemd/v22 v22.7.0/go.mod h1:xNUYtjHu2EDXbsxz1i41wouACIwT7Ybq9o0BQhMwD0w=
github.com/corpix/uarand v0.2.0 h1:U98xXwud/AVuCpkpgfPF7J5TQgr7R5tqT8VZP5KWbzE=
github.com/corpix/uarand v0.2.0/go.mod h1:/3Z1QIqWkDIhf6XWn/08/uMHoQ8JUoTIKc2iPchBOmM=
github.com/cosmos/go-bip39 v0.0.0-20180819234021-555e2067c45d h1:49RLWk1j44Xu4fjHb6JFYmeUnDORVwHNkDxaQ0ctCVU=
github.com/cosmos/go-bip39 v0.0.0-20180819234021-555e2067c45d/go.mod h1:tSxLoYXyBmiFeKpvmq4dzayMdCjCnu8uqmCysIGBT2Y=
github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
github.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g=
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
github.com/cronokirby/saferith v0.33.0 h1:TgoQlfsD4LIwx71+ChfRcIpjkw+RPOapDEVxa+LhwLo=
github.com/cronokirby/saferith v0.33.0/go.mod h1:QKJhjoqUtBsXCAVEjw38mFqoi7DebT7kthcD7UzbnoA=
github.com/cschomburg/go-pushbullet v0.0.0-20171206132031-67759df45fbb h1:7X9nrm+LNWdxzQOiCjy0G51rNUxbH35IDHCjAMvogyM=
github.com/cschomburg/go-pushbullet v0.0.0-20171206132031-67759df45fbb/go.mod h1:RfQ9wji3fjcSEsQ+uFCtIh3+BXgcZum8Kt3JxvzYzlk=
github.com/cyphar/filepath-securejoin v0.5.1 h1:eYgfMq5yryL4fbWfkLpFFy2ukSELzaJOTaUTuh+oF48=
@@ -750,8 +753,8 @@ github.com/go-ini/ini v1.67.0 h1:z6ZrTEZqSWOTyH2FlglNbNgARyHG8oLW9gMELqKr06A=
github.com/go-ini/ini v1.67.0/go.mod h1:ByCAeIL28uOIIG0E3PJtZPDL8WnHpFKFOtgjp+3Ies8=
github.com/go-jose/go-jose/v3 v3.0.4 h1:Wp5HA7bLQcKnf6YYao/4kpRpVMp/yf6+pJKV8WFSaNY=
github.com/go-jose/go-jose/v3 v3.0.4/go.mod h1:5b+7YgP7ZICgJDBdfjZaIt+H/9L9T/YQrVfLAMboGkQ=
github.com/go-jose/go-jose/v4 v4.1.3 h1:CVLmWDhDVRa6Mi/IgCgaopNosCaHz7zrMeF9MlZRkrs=
github.com/go-jose/go-jose/v4 v4.1.3/go.mod h1:x4oUasVrzR7071A4TnHLGSPpNOm2a21K9Kf04k1rs08=
github.com/go-jose/go-jose/v4 v4.1.4 h1:moDMcTHmvE6Groj34emNPLs/qtYXRVcd6S7NHbHz3kA=
github.com/go-jose/go-jose/v4 v4.1.4/go.mod h1:x4oUasVrzR7071A4TnHLGSPpNOm2a21K9Kf04k1rs08=
github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
github.com/go-kit/kit v0.12.0/go.mod h1:lHd+EkCZPIwYItmGDDRdhinkzX2A1sj+M9biaEaizzs=
@@ -1017,8 +1020,8 @@ github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLe
github.com/google/pprof v0.0.0-20210601050228-01bbb1931b22/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
github.com/google/pprof v0.0.0-20210609004039-a478d1d731e9/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
github.com/google/pprof v0.0.0-20260302011040-a15ffb7f9dcc h1:VBbFa1lDYWEeV5FZKUiYKYT0VxCp9twUmmaq9eb8sXw=
github.com/google/pprof v0.0.0-20260302011040-a15ffb7f9dcc/go.mod h1:MxpfABSjhmINe3F1It9d+8exIHFvUqtLIRCdOGNXqiI=
github.com/google/pprof v0.0.0-20260402051712-545e8a4df936 h1:EwtI+Al+DeppwYX2oXJCETMO23COyaKGP6fHVpkpWpg=
github.com/google/pprof v0.0.0-20260402051712-545e8a4df936/go.mod h1:MxpfABSjhmINe3F1It9d+8exIHFvUqtLIRCdOGNXqiI=
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
github.com/google/s2a-go v0.1.9 h1:LGD7gtMgezd8a/Xak7mEWL0PjoTQFvpRudN895yqKW0=
github.com/google/s2a-go v0.1.9/go.mod h1:YA0Ei2ZQL3acow2O62kdp9UlnvMmU7kA6Eutn0dXayM=
@@ -1032,8 +1035,9 @@ github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/google/wire v0.6.0 h1:HBkoIh4BdSxoyo9PveV8giw7ZsaBOvzWKfcg/6MrVwI=
github.com/google/wire v0.6.0/go.mod h1:F4QhpQ9EDIdJ1Mbop/NZBRB+5yrR6qg3BnctaoUk6NA=
github.com/googleapis/enterprise-certificate-proxy v0.3.11 h1:vAe81Msw+8tKUxi2Dqh/NZMz7475yUvmRIkXr4oN2ao=
github.com/googleapis/enterprise-certificate-proxy v0.3.11/go.mod h1:RFV7MUdlb7AgEq2v7FmMCfeSMCllAzWxFgRdusoGks8=
github.com/googleapis/enterprise-certificate-proxy v0.0.0-20220520183353-fd19c99a87aa/go.mod h1:17drOmN3MwGY7t0e+Ei9b45FFGA3fBs3x36SsCg1hq8=
github.com/googleapis/enterprise-certificate-proxy v0.3.14 h1:yh8ncqsbUY4shRD5dA6RlzjJaT4hi3kII+zYw8wmLb8=
github.com/googleapis/enterprise-certificate-proxy v0.3.14/go.mod h1:vqVt9yG9480NtzREnTlmGSBmFrA+bzb0yl0TxoBQXOg=
github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=
github.com/googleapis/gax-go/v2 v2.1.0/go.mod h1:Q3nei7sK6ybPYH7twZdmQpAd1MKb7pfu6SK+H1/DsU0=
@@ -1041,8 +1045,9 @@ github.com/googleapis/gax-go/v2 v2.1.1/go.mod h1:hddJymUZASv3XPyGkUpKj8pPO47Rmb0
github.com/googleapis/gax-go/v2 v2.2.0/go.mod h1:as02EH8zWkzwUoLbBaFeQ+arQaj/OthfcblKl4IGNaM=
github.com/googleapis/gax-go/v2 v2.3.0/go.mod h1:b8LNqSzNabLiUpXKkY7HAR5jr6bIT99EXz9pXxye9YM=
github.com/googleapis/gax-go/v2 v2.4.0/go.mod h1:XOTVJ59hdnfJLIP/dh8n5CGryZR2LxK9wbMD5+iXC6c=
github.com/googleapis/gax-go/v2 v2.17.0 h1:RksgfBpxqff0EZkDWYuz9q/uWsTVz+kf43LsZ1J6SMc=
github.com/googleapis/gax-go/v2 v2.17.0/go.mod h1:mzaqghpQp4JDh3HvADwrat+6M3MOIDp5YKHhb9PAgDY=
github.com/googleapis/gax-go/v2 v2.21.0 h1:h45NjjzEO3faG9Lg/cFrBh2PgegVVgzqKzuZl/wMbiI=
github.com/googleapis/gax-go/v2 v2.21.0/go.mod h1:But/NJU6TnZsrLai/xBAQLLz+Hc7fHZJt/hsCz3Fih4=
github.com/googleapis/go-type-adapters v1.0.0/go.mod h1:zHW75FOG2aur7gAO2B+MLby+cLsWGBF62rFAi7WjWO4=
github.com/googleapis/google-cloud-go-testing v0.0.0-20200911160855-bcd43fbb19e8/go.mod h1:dvDLG8qkwmyD9a/MJJN3XJcT3xFxOKAvTZGvuZmac9g=
github.com/gopackage/ddp v0.0.0-20170117053602-652027933df4 h1:4EZlYQIiyecYJlUbVkFXCXHz1QPhVXcHnQKAzBTPfQo=
github.com/gopackage/ddp v0.0.0-20170117053602-652027933df4/go.mod h1:lEO7XoHJ/xNRBCxrn4h/CEB67h0kW1B0t4ooP2yrjUA=
@@ -1082,30 +1087,62 @@ github.com/grpc-ecosystem/grpc-gateway v1.14.6/go.mod h1:zdiPV4Yse/1gnckTHtghG4G
github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw=
github.com/grpc-ecosystem/grpc-gateway/v2 v2.28.0 h1:HWRh5R2+9EifMyIHV7ZV+MIZqgz+PMpZ14Jynv3O2Zs=
github.com/grpc-ecosystem/grpc-gateway/v2 v2.28.0/go.mod h1:JfhWUomR1baixubs02l85lZYYOm7LV6om4ceouMv45c=
github.com/gtank/merlin v0.1.1 h1:eQ90iG7K9pOhtereWsmyRJ6RAwcP4tHTDBHXNg+u5is=
github.com/gtank/merlin v0.1.1/go.mod h1:T86dnYJhcGOh5BjZFCJWTDeTK7XW8uE+E21Cy/bIQ+s=
github.com/gtank/ristretto255 v0.2.0 h1:LeOuWr6giplWkkMizx2emfG03SRPJqKt1nfIHLVHQ/0=
github.com/gtank/ristretto255 v0.2.0/go.mod h1:OJ1ox/dWcp7sJ5grYDcZ+kkHYuj5nelW5aaL7ESVXBw=
github.com/hanzoai/ai v1.785.0 h1:Hi5j1TbnPBIyNEIEAQHbACFMGaQNJBp/jCUhV24+dO8=
github.com/hanzoai/ai v1.785.0/go.mod h1:5bGB4eYd4Ynb5bcCmqGJRK4fGy58ch6m+9dZzK+aM94=
github.com/hanzoai/amqp v0.2.0 h1:zv8/QQoV0QIqsTDAboBPOyaFPEULncIw4Byvx261IN8=
github.com/hanzoai/amqp v0.2.0/go.mod h1:eauLzYCcXeccALrznAoVNrtIVs8AECo942Ov+58C+Rk=
github.com/hanzoai/authz v1.10.0 h1:aTDQWL7+Ek/8I+NLqETk2fyeMPFhKRVfMd+ERj3aXnY=
github.com/hanzoai/authz v1.10.0/go.mod h1:jFfnuJG6Sg2YwDnShCcYNr2yn/SJ0XBmcPWnrgKii3E=
github.com/hanzoai/authzstore v0.1.1 h1:4GsvB+bKs+gFtfKDMoYq/C7KxJAHrXLwtwdSutTakbo=
github.com/hanzoai/authzstore v0.1.1/go.mod h1:ZpiA4r7yoCC/4WO9CcsDezcYVVv40AmH8qoQSrBNtLo=
github.com/hanzoai/base v1.3.1 h1:fdURtJG7qwZxDv5Iw6oca5nXrVQdfuwZ3buqErp4EhU=
github.com/hanzoai/base v1.3.1/go.mod h1:u4FWazPAkwLb3DPe9fvMWeqdBMY85eZv++iGI9GvKaQ=
github.com/hanzoai/builder v0.3.13 h1:tAOJ+0Q0xrrovk7lkvaZxuKZ4lqENIB6tE0Rr9+6Bo8=
github.com/hanzoai/builder v0.3.13/go.mod h1:TWZaiP0Y9tCMwtLH2EvQqBAeT1f3aJI5Y0XPM8S0wcE=
github.com/hanzoai/commerce v1.42.21 h1:g3TNqQTK5OvdxMLUmaRKeMbdiTaDXBcFdxoIY2aFhvA=
github.com/hanzoai/commerce v1.42.21/go.mod h1:MygklZy7eNZdwHQzc55YD3awzhxPC5YtzsEBEhpBd6E=
github.com/hanzoai/datastore-go/v2 v2.45.0 h1:73RSPKFV/Bm75VUlwFwx1namCS2bnEYEVH+FMMTf50o=
github.com/hanzoai/datastore-go/v2 v2.45.0/go.mod h1:6mGC9Y5mMVVwZ8HB/peBpfVI87dDqdkCQYhtGI57wyA=
github.com/hanzoai/dbx v1.16.0 h1:C8wsb9BIiit4nYnXizpcB4SyzVaepPkQFwq5i9fxAV0=
github.com/hanzoai/dbx v1.16.0/go.mod h1:ynP6HSiDDoFZ8M3DC+XvSglBPFRygfTd/gjTWabh4yA=
github.com/hanzoai/gateway v0.2.0 h1:ZL+15SuzfJ15Lfe2d68Pq56J0I845DWgxFjSQhVjpbg=
github.com/hanzoai/gateway v0.2.0/go.mod h1:v8a2KlxYdxLkH2itactiHukg20G7FgYPYcCVKpQLDFg=
github.com/hanzoai/go-sms-sender v0.25.2 h1:6LfBdHInC+Wj2poXi3nZZnxtCGmiKPVy3XRiWZw3CIA=
github.com/hanzoai/go-sms-sender v0.25.2/go.mod h1:uudrECC0t9Qnx7odPTO602eE+xTiwBm3eF/ueJzeau0=
github.com/hanzoai/goauthorizenet v0.0.0-20180920213706-626992b83568 h1:b9VAc4r4DtL8KmwnNS22o80ZP+YDuRkP//CtqeDX2OM=
github.com/hanzoai/goauthorizenet v0.0.0-20180920213706-626992b83568/go.mod h1:og+Sdlmdd7/78F6twMd6wIofJkIREs6x1EbiEBBrlE0=
github.com/hanzoai/gochimp3 v0.0.0-20241127054040-6051f77e24f1 h1:uQGUlQsmBvZmfUeRgZS8BkUdlPbF2VA0GqKMnUop+Fc=
github.com/hanzoai/gochimp3 v0.0.0-20241127054040-6051f77e24f1/go.mod h1:zJr4NZygb2gyqkQpZ2Yf/UzbOhIhVfLCj8ST925KPrI=
github.com/hanzoai/gomail/v2 v2.3.2 h1:qQY5O5d9OJKf137OpDPJWNebqcSZhixK0jg3iEMKkxE=
github.com/hanzoai/gomail/v2 v2.3.2/go.mod h1:5iSiOcaBeJW0m4mp8j8jzby6zeVq31+ogMewkn4xxMw=
github.com/hanzoai/iam v1.18.0 h1:jxDKSmchNxJNyFeEcx7m/EeVgE5W+7KMsg2M68CZsu4=
github.com/hanzoai/iam v1.18.0/go.mod h1:IP9KCffnb30D5ulFgUdHMKPNZVJ1SXfU0nOoWkg4iD0=
github.com/hanzoai/iam/pkg/iam v1.18.0 h1:DjnoOdJtYXHKpCBklIzB6VOjmqgNzLqCPttMvjganMU=
github.com/hanzoai/iam/pkg/iam v1.18.0/go.mod h1:t3POxo8z2MZ6lHrZIwFq+/QZyecUnTQLIiGxpbOIzAA=
github.com/hanzoai/iamsdk/v2 v2.1.0 h1:BuU3323zi6Jx7mgNo/wao4iuYoQsfviVgzRUNjmFduk=
github.com/hanzoai/iamsdk/v2 v2.1.0/go.mod h1:oBI91+bAbrIt2MEPYuXUM6NinpjwcREz85sccdDkUY4=
github.com/hanzoai/idv v1.0.0 h1:z+z5KS3cZnM7ndtlLB2mmuh7hc+p78hJNa+zVSD8pIE=
github.com/hanzoai/idv v1.0.0/go.mod h1:vujJF4DQmwRrdh2UxnpCjWLkYKJ1bbgp10thlo4xZYQ=
github.com/hanzoai/ingress v1.8.0 h1:6kgc5u9KxcDYmHvAYREybh+L05kSXBYtp5hxkFQhwDw=
github.com/hanzoai/ingress v1.8.0/go.mod h1:LqCPdwxhDUhHBZGUKtnJ3ghvIqVgXUtGcN/J78uNCjQ=
github.com/hanzoai/kms v0.159.0 h1:BFbLDhUpvyZsMVDbkuUo3NSgtXCeYu/0zosO5qBGq9Q=
github.com/hanzoai/kms v0.159.0/go.mod h1:W6RBS/k2eRqcYcnvZGe3aziGZfdNJv/IWYqnHlHSYw8=
github.com/hanzoai/kms/sdk/go v1.0.0 h1:rY7LDkRvjPotwJ4ydqDfRkQ+2Ob4QW3ptRydAa52x9g=
github.com/hanzoai/kms/sdk/go v1.0.0/go.mod h1:kPPvEuE3K+fcOY+S6hiNO8nffxDNChvC1Uc4fR5Y+xk=
github.com/hanzoai/kv-go/v9 v9.18.0 h1:vO2SD8dV0+H9WWCVKV9KHaWZq4yeMsZruohrsZN9448=
github.com/hanzoai/kv-go/v9 v9.18.0/go.mod h1:S+Li20E6Bskpw6r+c8WWhfi4hCr8SVV32qPXO0wdl+E=
github.com/hanzoai/ldapserver v1.2.1 h1:H+AFuntREWo1n96cCUBnrzNeb07npTEUyvqXZRH4x20=
github.com/hanzoai/ldapserver v1.2.1/go.mod h1:mPwAbPBw9YeXfC2hfg1QSAw6CiGt6o2oF2pi9VR+j3U=
github.com/hanzoai/mcp/go v0.1.0 h1:JMKcksR48LxLCm6NLJBaKPKZctzbgrJ8CnPvSxYiMVY=
github.com/hanzoai/mcp/go v0.1.0/go.mod h1:qfoEdhu/QtJr6e2l9gBAZwVa4vMmPcFF6HqKWQPSkkc=
github.com/hanzoai/notify2 v1.6.3 h1:E0yE3mhwpCPLYAY7AAKJIzf+XL2yXcyxXD7/tK9giLs=
github.com/hanzoai/notify2 v1.6.3/go.mod h1:tF4lEPIr2J42/gpHjyWnpJey5545bLfRei6pxbVuFzc=
github.com/hanzoai/o11y v0.1.0 h1:FmSthTMgbWRffbAMuIevss/fPHr4lrrcsOBnxKNqiqA=
github.com/hanzoai/o11y v0.1.0/go.mod h1:o/hauE+uQMjj66dPOv3rIRp7eH7Z6+Qac9QYxeO3xD0=
github.com/hanzoai/orm v0.5.1 h1:jBery6NrhShoYwiRlPo8DRdASsKTJljnQAV2/8kY0hw=
github.com/hanzoai/orm v0.5.1/go.mod h1:ks/a76Vuf6E4CLmFToiPPnafYjdxfMuFrOunnrIyBhQ=
github.com/hanzoai/oss v1.8.5 h1:ukFSUKDuZV9bxorOeT3kliJ2EXi/4nHLEV//ZinqDxI=
@@ -1114,14 +1151,18 @@ github.com/hanzoai/pubsub-go v1.0.0 h1:nUZ4jK+MFlFQ5qTMri/Yffnqs/R5avI99SfZ9e3t6
github.com/hanzoai/pubsub-go v1.0.0/go.mod h1:ZHWDgSLsYHK4TiitzNwGc7Cn+oApKyMp0uK8cU7jwpg=
github.com/hanzoai/search-go v0.36.0 h1:bQfbAs/bc/s3qZDCtSqEAxp48koHkb0Z4ezUknt2AQc=
github.com/hanzoai/search-go v0.36.0/go.mod h1:jdcYUdG6exMfRfJvilWhaNdAR8XWQRPvZtuRxQBzn34=
github.com/hanzoai/sendgrid-go v3.4.2-0.20180724185151-733a05184a8d+incompatible h1:xmFYu3gTLpu78mIx6z0bgpYy3MVdMAEFFeKs2YPybVo=
github.com/hanzoai/sendgrid-go v3.4.2-0.20180724185151-733a05184a8d+incompatible/go.mod h1:HTKx0R5LWWt7H1eG4pCpNS4PVO6tZIUVVZN/80sHz9o=
github.com/hanzoai/storage-go v1.0.0 h1:c5EO04oGQY67VzZYaiA2Dtc/swTc5k5x8Ts/fpw5VDk=
github.com/hanzoai/storage-go v1.0.0/go.mod h1:IPXouQWTki5LKa9Y3qfOr6o8Qwlmc4sGObJnGMNKCOM=
github.com/hanzoai/tasks v1.40.0 h1:1Y0uXHmdGsU3QSv5So7NH55DhWqw/UPV3kgFeBaaWls=
github.com/hanzoai/tasks v1.40.0/go.mod h1:VwQ9ljfO0zYW694NPr4eIdc7WBPpPIs4zC8dbrNALZ0=
github.com/hanzoai/vfs v0.4.0 h1:4BmTTAvuiyuOxl3Yh06B01ze25N6iIhfZcKC7hYUrYo=
github.com/hanzoai/vfs v0.4.0/go.mod h1:8AzyntfZgjK6iiB4A+xPestHgSAGUEHMthTkhACRIjM=
github.com/hanzoai/xorm v1.1.6 h1:z8B3alP39taTGLA4BonBa+7RHIOMmjYjxF3N9gpzh84=
github.com/hanzoai/xorm v1.1.6/go.mod h1:wso0cQDDuzgjJwNOj3AXCftkKF3uOoUowKp5A7ol0zc=
github.com/hanzoai/zip v0.1.0 h1:rsGLHl0cr7EBvp2EQk6KoEizBpOvgU7Uv0JP9GJ7cnw=
github.com/hanzoai/zip v0.1.0/go.mod h1:3G+k2wy5bQ1wld66m0OPH8/LJ0kgIeNi1KPymMmlbf4=
github.com/hanzoai/zip v0.2.0 h1:2GI1OoUv4QdCxmfiwoiyYsSHpiPAxrp0v+Gu4BLtTVI=
github.com/hanzoai/zip v0.2.0/go.mod h1:3G+k2wy5bQ1wld66m0OPH8/LJ0kgIeNi1KPymMmlbf4=
github.com/hashicorp/consul/api v1.10.1/go.mod h1:XjsvQN+RJGWI2TWy1/kqaE16HrR2J/FWgkYjdZQsX9M=
github.com/hashicorp/consul/api v1.12.0/go.mod h1:6pVBMo0ebnYdt2S3H87XhekM/HHrUoTD2XXb/VrZVy0=
github.com/hashicorp/consul/api v1.13.0/go.mod h1:ZlVrynguJKcYr54zGaDbaL3fOvKC9m72FhPvA8T35KQ=
@@ -1307,6 +1348,8 @@ github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfV
github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM=
github.com/jung-kurt/gofpdf v1.0.3-0.20190309125859-24315acbbda5/go.mod h1:7Id9E/uU8ce6rXgefFLlgrJj/GYY22cpxn+r32jIOes=
github.com/keighl/mandrill v0.0.0-20170605120353-1775dd4b3b41 h1:UKfGHZTAF2kEH9TkM4aw+IxpjiNXzB/c8+/N2yUQf+c=
github.com/keighl/mandrill v0.0.0-20170605120353-1775dd4b3b41/go.mod h1:+mEDstlvUwlcUrduEzwxRm8q3GnjOa7GlNVJdgvWpiU=
github.com/kevinburke/ssh_config v1.2.0 h1:x584FjTGwHzMwvHx18PXxbBVzfnxogHaAReU4gf13a4=
github.com/kevinburke/ssh_config v1.2.0/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM=
github.com/keybase/go-keychain v0.0.1 h1:way+bWYa6lDppZoZcgMbYsvC7GxljxrskdNInRtuthU=
@@ -1383,8 +1426,6 @@ github.com/krakend/krakend-jose/v2 v2.10.0 h1:zISCdMGd4qvJntqG32cIc37RpbLkkGV0yb
github.com/krakend/krakend-jose/v2 v2.10.0/go.mod h1:PJvsljCeamhxQnIe6sNj8S/rdVSOIqvrWXcIv2BCj6E=
github.com/krakend/krakend-jsonschema/v2 v2.1.0 h1:jiWnJmA7QwiRMasZFujnbE3Fipzpqg8Fdet8dww9aCM=
github.com/krakend/krakend-jsonschema/v2 v2.1.0/go.mod h1:z+lZEhZUtPsp0BnKEY7Ln/KcP2tJOvRQ1l3LMe4u1f8=
github.com/krakend/krakend-koanf v0.0.0-20251111142508-ab36eebbcf9b h1:D94Zyeg26yRQc98/eDDJy2GGpgHh1TK72SjJgc8wwIM=
github.com/krakend/krakend-koanf v0.0.0-20251111142508-ab36eebbcf9b/go.mod h1:x02jzsb521azFk5+pmvF2GMwleU/5QXPgl+YZu407DE=
github.com/krakend/krakend-lambda/v2 v2.1.0 h1:I76j4cp/I8Cd7vQMyIq08aJSr42SDFZWAE48/absu2k=
github.com/krakend/krakend-lambda/v2 v2.1.0/go.mod h1:a1j6PHQtSwp3gdvpgHNJDSeIzHbHbIjcmVvDw4HU9qg=
github.com/krakend/krakend-logstash/v2 v2.1.0 h1:z7PSWGk/1y6K8eE+wE/iwF1YBpC1qh2Rm5vZOpVZSNc=
@@ -1453,8 +1494,10 @@ github.com/lufia/plan9stats v0.0.0-20251013123823-9fd1530e3ec3 h1:PwQumkgq4/acIi
github.com/lufia/plan9stats v0.0.0-20251013123823-9fd1530e3ec3/go.mod h1:autxFIvghDt3jPTLoqZ9OZ7s9qTGNAWmYCjVFWPX/zg=
github.com/luraproject/lura/v2 v2.12.1 h1:+0itsccgsguOeGRjkgtdgE3RGdiMac4VC3/qE7eZKqE=
github.com/luraproject/lura/v2 v2.12.1/go.mod h1:ZUBYMsjVwPAZWVEoBtJ6keodn13tgw/5QQyY3nDkk2I=
github.com/luxfi/accel v1.0.7 h1:ksHieAp50umwqxqgyHk9WiOmXM54kia3IEDb5H7FsM8=
github.com/luxfi/accel v1.0.7/go.mod h1:iZD3oxffiMEIT/KvzD8bgwC/cBn4AYlMW3QJpbRa4RE=
github.com/luxfi/accel v1.1.9 h1:Tsk6gXj2uKE19501bD0ajRYdeCHIlTGb6jYyLc+F8hc=
github.com/luxfi/accel v1.1.9/go.mod h1:K00BcnLzEYMPHwCFq8Tf/450ApmTs9xBVvYOnofJCkc=
github.com/luxfi/address v1.0.1 h1:Sc4keyuVzBIvHr7uVeYZf2/WY9YDGUgDi/iiWenj49g=
github.com/luxfi/address v1.0.1/go.mod h1:5j3Eh66v9zvv1GbNdZwt+23krV8JlSDaRzmWZU8ZRM0=
github.com/luxfi/age v1.5.0 h1:G69HbSV4R3vKEH9B0CulnRaMdSdf4RalMgP8xKmxHeI=
github.com/luxfi/age v1.5.0/go.mod h1:iAYAxgvrXxcy746+Ovh/eWWDuF9teJLNcCSSOX9RYW0=
github.com/luxfi/atomic v1.0.0 h1:xUV60MuzRvXngaQ1sM0yVC2v4TRoLlUGkkH7M9PS4yw=
@@ -1465,52 +1508,72 @@ github.com/luxfi/compress v0.0.5 h1:4tEUHw5MK1bu5UOjfYCt4OKMiH7yykIgmGPRA/BfJTM=
github.com/luxfi/compress v0.0.5/go.mod h1:Cc1yxD2pfzrvpO32W2GDwLKff+CylHEvzZh2Ko8RSIU=
github.com/luxfi/concurrent v0.0.3 h1:eJyv1fhaC0jMLMw6+QS774cUmp7GK+ouMgvLCqnC7cc=
github.com/luxfi/concurrent v0.0.3/go.mod h1:Aj/FR5NpM0cB2P4Nt3+tz9+dV6V+LUW4HuMgSjwq5hw=
github.com/luxfi/consensus v1.22.85 h1:S/XpPF+eDapbZb4AIu0Vr1GXzg/sAxjrAff2M2mkOx0=
github.com/luxfi/consensus v1.22.85/go.mod h1:y6y+bVjvpDLkkTBCCKLcch6R4PRW8EA+lTfr+6sB6F8=
github.com/luxfi/constants v1.5.0 h1:hVOn2fa1+VoZqYCldFfZM8sX+Qk4UbU4ca6mbyGyTbA=
github.com/luxfi/constants v1.5.0/go.mod h1:hOszZ2NDQ8gMZKncfcZ67PXkb5OIbnwAzXC3oFbQwW0=
github.com/luxfi/consensus v1.25.0 h1:ak82ufqeklLJGQMCizxx5agiwLkjbrnrk7kFezvEtZo=
github.com/luxfi/consensus v1.25.0/go.mod h1:jkKzKyIgg/JqaEumxZOJd9ofWM3pXnVVLlQp+3qo9SM=
github.com/luxfi/constants v1.5.8 h1:iNP9AWNUcM4Tps7jYnx49CwtCWAC9mYRxJfGou2za0g=
github.com/luxfi/constants v1.5.8/go.mod h1:Pu5jWHdnUtQRbWC43yTUjU/pbIIKMDOd2a2yroSfo48=
github.com/luxfi/container v0.0.4 h1:BXhF82WyfqVP5mjlNcr7tP0Fcnvl0Ap1rkiu+rq5XuM=
github.com/luxfi/container v0.0.4/go.mod h1:Z3SpmMF5d4t77MM0nHYXURpn+EMVaeu1fhbd/3BGaek=
github.com/luxfi/crypto v1.19.0 h1:VtH6kvZrCEjCnkHPkhExDU+GJ0ZulYX4rnA+lXJdJHw=
github.com/luxfi/crypto v1.19.0/go.mod h1:ee525i8Recbpb0jVTDZYZBr1MmvJ27OITJHZ/nlNMBw=
github.com/luxfi/corona v0.7.6 h1:CJP6smygD55dL0HHkKkWryL9H24a+wXvs+L+WchK7Nc=
github.com/luxfi/corona v0.7.6/go.mod h1:4aD7+ZqnlZ2aVuU/DBQ5aspIagv5ux45LW2sJ4+siY8=
github.com/luxfi/crypto v1.19.17 h1:l2LLu7UFyICtJVfraLDLRi+lFGiDXKHSL18M9/m1gsQ=
github.com/luxfi/crypto v1.19.17/go.mod h1:INjdZtke85k8hX/QAmTMAY8bbZ4gzGZQLqURg3xf6Gk=
github.com/luxfi/crypto/ipa v1.2.4 h1:6xfwhI9/HrcDkF3Ti5/NxsNQIWbwYDJmRSNIHRQ/xfU=
github.com/luxfi/crypto/ipa v1.2.4/go.mod h1:43J6f6rcfUMrZt4cQectMOZb6Ps+fAEj8ZTPC3Kk+gE=
github.com/luxfi/database v1.18.1 h1:Bvovo6MW3XSdUd1DkGNluB2tyvyiT/+N5d3QVwtoNo8=
github.com/luxfi/database v1.18.1/go.mod h1:PW0oGujt165mYg7j/lctVbnfsUW6QLfIAgjyQdS66SM=
github.com/luxfi/fhe v1.7.9 h1://6Od/hbYef+sOfg0B364u4nJYv6SB01cZn4PdgXQwQ=
github.com/luxfi/fhe v1.7.9/go.mod h1:Pmt8Wy1zPTYbtOuOCUdXa0lw4vDMuSKBV/pgGRlLWF4=
github.com/luxfi/geth v1.16.79 h1:MtP8ZUuSVZDjmZDa1kTJCl0PpG8+wGbQft652GO6a3A=
github.com/luxfi/geth v1.16.79/go.mod h1:6xNi4sHoh0v1kBf0TOjmFhBg5+4umbSqrwiFZsDanZ0=
github.com/luxfi/ids v1.2.9 h1:+yjdhXW99drnd2Zlp1u/p8k3G23W3/1btJQ4ogHawUI=
github.com/luxfi/ids v1.2.9/go.mod h1:khJOEdOPxd22yn0jcVrnbX1ADa0GHn5Y74gvCzN5BYc=
github.com/luxfi/kms v1.5.2 h1:TSe4W+pHj9qCyiVxnwVddS2e+uEzZSFnePrOFHU7Du0=
github.com/luxfi/kms v1.5.2/go.mod h1:dqYV18HmDgc3jwDD+q+iLI+M9cySiyyxcphnWwvrVPQ=
github.com/luxfi/lattice/v7 v7.0.0 h1:d1vgan6mlb2KtwYfPc1g69uxVYaoVYZmlrIm4aCO88w=
github.com/luxfi/lattice/v7 v7.0.0/go.mod h1:PFDdOkuGTQ0cbJMbKojzEJMGWUQmZW+wK9/wJ9F9fOs=
github.com/luxfi/database v1.18.3 h1:gg+xwhKUxXa7fDoOD8IS91E71QqoEtcDCl2nfS61Jgg=
github.com/luxfi/database v1.18.3/go.mod h1:sv0pYCGKlK1aNJTICxFUDpVWCJTigoLlshHmV/1pg7c=
github.com/luxfi/fhe v1.8.2 h1:QllnObNFbi6D4mvFI6uQkepW8HgLtdy4RMR1TKYAInA=
github.com/luxfi/fhe v1.8.2/go.mod h1:16yxwhcnCez/rNcd/C9JjH9IjbEz73X+0tvlsONyLeA=
github.com/luxfi/formatting v1.0.1 h1:ZnE1rAdEUds9yAegdVdGDOBGN6hLMPOv6E03Fp8IEYo=
github.com/luxfi/formatting v1.0.1/go.mod h1:mYzNf5DJOiqSSKUPzNj5dKy4tstFbN3pZlkI5716eKc=
github.com/luxfi/geth v1.16.100 h1:Oz37d3nfZgFBIyk5Rj2kKl5t/AL7aU1RsfFVL0brSJY=
github.com/luxfi/geth v1.16.100/go.mod h1:TeW6ptPzi5J52Ljg8EuyBQMWlwWr/PIUWYi8Er2eclA=
github.com/luxfi/go-bip32 v1.0.2 h1:7vFbb+Wr4Z499q2tuCLdd7wWjtn8sH+HWBlx76mhH9Y=
github.com/luxfi/go-bip32 v1.0.2/go.mod h1:bc7/LXDKAJQZ/F0Xjf5yXaTZxY9/ssLb4FC+Hxn/cDk=
github.com/luxfi/go-bip39 v1.1.2 h1:p+wLMPGs6MLQh7q0YIsmy2EhHL7LHiELEGTJko6t/Jg=
github.com/luxfi/go-bip39 v1.1.2/go.mod h1:96de9VkR2kY/ASAnhMtvt3TSh+PZkAFAngNj0GjRGDo=
github.com/luxfi/ids v1.2.15 h1:omE+E4+0Poj9DzM11ejSFgteaSQ3KDHi5g54iH6jcxI=
github.com/luxfi/ids v1.2.15/go.mod h1:Fj73K5xcblvdE0SxU/ip+jE8VqNdu+80548su5KJ7xI=
github.com/luxfi/keys v1.1.0 h1:a4UkVVg6G09XC7vPtXKxEGwVt50GNPjEvq2pkjYZW2k=
github.com/luxfi/keys v1.1.0/go.mod h1:U3tZNDmv3nXkPoZwLtq9RNjwyN0XyoN29worigfT+c0=
github.com/luxfi/kms v1.11.0 h1:YNoBUkMmLhrdcUuAir0a7GEyDm4QKHWpZhJz9gBKEiM=
github.com/luxfi/kms v1.11.0/go.mod h1:RfKmev2qiP4ZxcrPYW5FRpMbovivMaOlZ6a4wfNt028=
github.com/luxfi/lattice/v7 v7.1.4 h1:hQR02M6cHTAV5+joOPi9gb9Gm+z/hKJnhJF4IlciIJs=
github.com/luxfi/lattice/v7 v7.1.4/go.mod h1:DmIQFi3mJiehVsR235l1NKYEU0JhU649OX5p7gMEW2c=
github.com/luxfi/lens v0.1.4 h1:goGjGDXx2BNdjzXDunL5QT8elK2ZyCcc0z8TAbtWYrg=
github.com/luxfi/lens v0.1.4/go.mod h1:mL+G8IK+9L41d78/2FYRgfhEzAjcr5+VEXB8SGuHbus=
github.com/luxfi/log v1.4.3 h1:xkUKRWvQ4ZwvlUC2e0/RTtHYZOYSMvSQ9W9lbjwBmiI=
github.com/luxfi/log v1.4.3/go.mod h1:myIkufyiQomSQH34K981kbz6cG4WUoerRUh7F4XhlQI=
github.com/luxfi/math v1.2.4 h1:iVz7s0gToCNUU/2cLT8gUa8MLzc0YRp4jBmeXBeKdXk=
github.com/luxfi/math v1.2.4/go.mod h1:i+Am9YvFsqDE75ZW8MPE62XCXGukXNiN/7mD9SKxxZY=
github.com/luxfi/math v1.4.1 h1:1t9bCCsEqnl9yIKrShlbs80DBKyYTWdnzkVfBqEeO7Q=
github.com/luxfi/math v1.4.1/go.mod h1:QvbRxauQyE1w4lvbcLSe6c8yeJz2Zj1Bq1rayGgs2tA=
github.com/luxfi/math/big v0.1.0 h1:Vz4c0RsZVPdIKPsHPgAJChH/R3p15WHRUz7LkLf+NIQ=
github.com/luxfi/math/big v0.1.0/go.mod h1:BuxSu22RbO93xBLk5Eam5nldFponoJ73xDFz4uJ3Huk=
github.com/luxfi/mdns v0.1.0 h1:VB3mQcETc9j5SY1S6lAgFtuGr/rjWuDgPYnxS+OKWMQ=
github.com/luxfi/mdns v0.1.0/go.mod h1:/3dheKVjUk2yiS/ocH1IDzeLXOIe+kpVsErIGDOZdiQ=
github.com/luxfi/metric v1.5.1 h1:6tVarXMnNR3Xzud8FYUHjtXabTll3HI/OEqG0tgLAcI=
github.com/luxfi/metric v1.5.1/go.mod h1:PkD4D4JoGuyKtfUkqPNYkrg9xKrJeNVZFdW/5XvAe/A=
github.com/luxfi/mdns v0.1.1 h1:g2eRr9AXcziPkkcd24M+Qu9ApEpoKKjfI79QSNqv0rQ=
github.com/luxfi/mdns v0.1.1/go.mod h1:dbp5f3h3aE7CGzwbaWzBM9cwdcekhmSrWhQevgYhhNA=
github.com/luxfi/metric v1.5.7 h1:LoSPEUpak2SLcynF+LT2cXjl9ECp4nY+Lia9zudmDv4=
github.com/luxfi/metric v1.5.7/go.mod h1:CMguEhyuLi4YUWyXimJ+UHply99BDFrL0pxedB7rBqM=
github.com/luxfi/mock v0.1.1 h1:0HEtIjg1J6CWz+IUyP6rsGqNWTcmxjFnSQIhaDuARwY=
github.com/luxfi/mock v0.1.1/go.mod h1:jo35akl3Vtd8LbzDts8VJ0jmSVycrd1/eBi6g6t5hKU=
github.com/luxfi/pq v1.0.3 h1:pFlQm1+5FuKTDUh2y/23bXWkN4I2Rc5iuxJypwDFFMs=
github.com/luxfi/pq v1.0.3/go.mod h1:8bppZcRElfrVt0n3nYCZW3iX1TvhvzNbdjNdK1irgIE=
github.com/luxfi/ringtail v0.2.0 h1:DbLMZmE//2T2wXXS/gEkKZrTbre9LD+7EE/tz5SQszU=
github.com/luxfi/ringtail v0.2.0/go.mod h1:SZ+aDLUdfSAtaTRaaYzeDZ5DNQiLaOCelSaIGjL21R0=
github.com/luxfi/sampler v1.0.0 h1:k8Sf6otW83w4pQp0jXLA+g3J/joB7w7SqXQsWmNTOV0=
github.com/luxfi/sampler v1.0.0/go.mod h1:f96/ozlj9vFfZj+akLtrHn4VpulQahwB+MQQhpeIekk=
github.com/luxfi/utils v1.1.4 h1:8OY0jXCkpp6OotN1Y++6DATJkvtEwzq2k0p56imJlAk=
github.com/luxfi/utils v1.1.4/go.mod h1:c3yz1RjzrB+cs5GZm+q1T3/2cCKElO9vxm9yRRtgSEM=
github.com/luxfi/zap v0.3.1 h1:RlOHthFTw3cikft3JmrdT/R8BFId2Ej7xeNiHDoTNs4=
github.com/luxfi/zap v0.3.1/go.mod h1:+RVBXJPxTqY5RU148058qew9/3fyRWTg/eBIwOIMlCY=
github.com/luxfi/zapdb v1.9.0 h1:Z6UxdWLSSqfCDOYY+4isSLhud3mm30eE1j+H6+scH5w=
github.com/luxfi/zapdb v1.9.0/go.mod h1:Qukh3hDRD0MnxA6z+a28JTnXhN85AiLLgp6TYr4QAMc=
github.com/luxfi/proto v1.0.0 h1:nlxv4lt/i75XDB2Q3nTqC1o0RDPmJ9K9CJ8UyYvceak=
github.com/luxfi/proto v1.0.0/go.mod h1:pZLKsCmhiPtmm3z7ezBbnsYT2m79q+cFSmzxvuBeANE=
github.com/luxfi/pulsar v1.1.1 h1:jo1jEgUsGiVxpT17Eg7Gw4Ax+07pbKFzq4NhHMLmDpI=
github.com/luxfi/pulsar v1.1.1/go.mod h1:U7tPleeAHJ9dZ61ymtstzLKKoZjxM2zFeGZ+RSjHyRw=
github.com/luxfi/sampler v1.1.0 h1:u3iRDl7V06ARh0e85h3HT+aZ1saCFo2yMMsh+dCJbqk=
github.com/luxfi/sampler v1.1.0/go.mod h1:kJa53S3tC9+VSbuV3RFu68MmbCCBlr2UM39LOClQ/Hs=
github.com/luxfi/threshold v1.9.4 h1:H69e9QkvygDtWkni1FkD5ztLdiTasmpJXcuVzgebdxo=
github.com/luxfi/threshold v1.9.4/go.mod h1:o50rsc4H9fIXHuZXSf93qDFfRTXncXaXf1Q+6JAD1vU=
github.com/luxfi/tls v1.0.3 h1:rK3nxSAxrUOOSHOZnKChwV4f6UJ+cfOl8KWJXAQx/SI=
github.com/luxfi/tls v1.0.3/go.mod h1:dQqSiGE7YxXUxOwICoReUuIitBms9DYOaCeteBwmIWw=
github.com/luxfi/utils v1.1.5 h1:6q85557b7djbZ/OF6S1k5wyGddozWnsoUuhokPHQRvo=
github.com/luxfi/utils v1.1.5/go.mod h1:T2OCKT1xG9jtKR/gyJQoSkticzrE9WFQ8eohJHGu9Fg=
github.com/luxfi/vm v1.2.0 h1:jTwQRHdC9VmyRZTPSn+IqjMju7f6xlxLc6P9CEg+Y2M=
github.com/luxfi/vm v1.2.0/go.mod h1:qasVIBRerVQuvy9vFGrX3H8X8pPMPG5un/KbZSyq5YY=
github.com/luxfi/zap v0.7.2 h1:YecWTWNE5PPJXL56sLIkzS8b23bprUwZ5lPAQuLUtTE=
github.com/luxfi/zap v0.7.2/go.mod h1:1k+nwT+JW802YzuPAuf7CxMSGr/qxvbGgGwi5k6X9Ok=
github.com/luxfi/zapdb v1.10.0 h1:1lLHEmkyC0BucnA/zjQYsMkUVxuEo2vQkEaQGjYfuuc=
github.com/luxfi/zapdb v1.10.0/go.mod h1:Qukh3hDRD0MnxA6z+a28JTnXhN85AiLLgp6TYr4QAMc=
github.com/lyft/protoc-gen-validate v0.0.13/go.mod h1:XbGvPuh87YZc5TdIa2/I4pLk0QoUACkjt2znoq26NVQ=
github.com/magefile/mage v1.15.1-0.20241126214340-bdc92f694516 h1:aAO0L0ulox6m/CLRYvJff+jWXYYCKGpEm3os7dM/Z+M=
github.com/magefile/mage v1.15.1-0.20241126214340-bdc92f694516/go.mod h1:z5UZb/iS3GoOSn0JgWuiw7dxlurVYTu+/jHXqQg881A=
@@ -1529,7 +1592,6 @@ github.com/mattn/go-colorable v0.1.6/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope
github.com/mattn/go-colorable v0.1.8/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
github.com/mattn/go-colorable v0.1.9/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4=
github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
github.com/mattn/go-colorable v0.1.14 h1:9A9LHSqF/7dyVVX6g0U9cwm9pG3kP9gSzcuIPHPsaIE=
github.com/mattn/go-colorable v0.1.14/go.mod h1:6LmQG8QLFO4G5z1gPvYEzlUgJ2wF+stgPZH1UqBm1s8=
github.com/mattn/go-ieproxy v0.0.1 h1:qiyop7gCflfhwCzGyeT0gro3sF9AIg9HU98JORTkqfI=
@@ -1540,10 +1602,8 @@ github.com/mattn/go-isatty v0.0.10/go.mod h1:qgIWMr58cqv1PHHyhnkY9lrL7etaEgOFcME
github.com/mattn/go-isatty v0.0.11/go.mod h1:PhnuNfih5lzO57/f3n+odYbM4JtupLOxQOAqxQCu2WE=
github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94=
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
github.com/mattn/go-isatty v0.0.21 h1:xYae+lCNBP7QuW4PUnNG61ffM4hVIfm+zUzDuSzYLGs=
github.com/mattn/go-isatty v0.0.21/go.mod h1:ZXfXG4SQHsB/w3ZeOYbR0PrPwLy+n6xiMrJlRFqopa4=
github.com/mattn/go-isatty v0.0.22 h1:j8l17JJ9i6VGPUFUYoTUKPSgKe/83EYU2zBC7YNKMw4=
github.com/mattn/go-isatty v0.0.22/go.mod h1:ZXfXG4SQHsB/w3ZeOYbR0PrPwLy+n6xiMrJlRFqopa4=
github.com/mattn/go-sqlite3 v2.0.3+incompatible h1:gXHsfypPkaMZrKbD5209QV9jbUTJKjyR5WD3HYQSd+U=
github.com/mattn/go-sqlite3 v2.0.3+incompatible/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
@@ -1566,6 +1626,9 @@ github.com/miekg/dns v1.1.72 h1:vhmr+TF2A3tuoGNkLDFK9zi36F2LS+hKTRW0Uf8kbzI=
github.com/miekg/dns v1.1.72/go.mod h1:+EuEPhdHOsfk6Wk5TT2CzssZdqkmFhf8r+aVyDEToIs=
github.com/mileusna/viber v1.0.1 h1:gWB6/lKoWYVxkH0Jb8jRnGIRZ/9DEM7RBZRJHRfdYWs=
github.com/mileusna/viber v1.0.1/go.mod h1:Pxu/iPMnYjnHgu+bEp3SiKWHWmlf/kDp/yOX8XUdYrQ=
github.com/mimoo/StrobeGo v0.0.0-20181016162300-f8f6d4d2b643/go.mod h1:43+3pMjjKimDBf5Kr4ZFNGbLql1zKkbImw+fZbw3geM=
github.com/mimoo/StrobeGo v0.0.0-20220103164710-9a04d6ca976b h1:QrHweqAtyJ9EwCaGHBu1fghwxIPiopAHV06JlXrMHjk=
github.com/mimoo/StrobeGo v0.0.0-20220103164710-9a04d6ca976b/go.mod h1:xxLb2ip6sSUts3g1irPVHyk/DGslwQsNOo9I7smJfNU=
github.com/minio/crc64nvme v1.1.1 h1:8dwx/Pz49suywbO+auHCBpCtlW1OfpcLN7wYgVR6wAI=
github.com/minio/crc64nvme v1.1.1/go.mod h1:eVfm2fAzLlxMdUGc0EEBGSMmPwmXD5XiNRpnu9J3bvg=
github.com/minio/highwayhash v1.0.1/go.mod h1:BQskDq+xkJ12lmlUUi7U0M5Swg3EWR+dLTk+kldvVxY=
@@ -1612,8 +1675,8 @@ github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3Rllmb
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee h1:W5t00kpgFdJifH4BDsTlE89Zl93FEloxaWZfGcifgq8=
github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
github.com/montanaflynn/stats v0.8.2 h1:52wnefTJnPI5FoHif1DQh2soKRw0yYs+4AVyvtcZCH0=
github.com/montanaflynn/stats v0.8.2/go.mod h1:etXPPgVO6n31NxCd9KQUMvCM+ve0ruNzt6R8Bnaayow=
github.com/montanaflynn/stats v0.9.0 h1:tsBJ0RXwph9BmAuFoCmqGv6e8xa0MENQ8m0ptKq29mQ=
github.com/montanaflynn/stats v0.9.0/go.mod h1:etXPPgVO6n31NxCd9KQUMvCM+ve0ruNzt6R8Bnaayow=
github.com/mr-tron/base58 v1.2.0 h1:T/HDJBh4ZCPbU39/+c3rRvE0uKBQlU27+QI8LJ4t64o=
github.com/mr-tron/base58 v1.2.0/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjWI2mNwc=
github.com/mrjones/oauth v0.0.0-20180629183705-f4e24b6d100c h1:3wkDRdxK92dF+c1ke2dtj7ZzemFWBHB9plnJOtlwdFA=
@@ -1642,6 +1705,8 @@ github.com/nats-io/nuid v1.0.1 h1:5iA8DT8V7q8WK2EScv2padNa/rTESc1KdnPw4TC2paw=
github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OSON2c=
github.com/ncruces/go-strftime v1.0.0 h1:HMFp8mLCTPp341M/ZnA4qaf7ZlsbTc+miZjCLOFAw7w=
github.com/ncruces/go-strftime v1.0.0/go.mod h1:Fwc5htZGVVkseilnfgOVb9mKy6w1naJmn9CehxcKcls=
github.com/netlify/netlify-go v0.1.11 h1:kfl9s526nEBsNV6rVpd+XT/eqHPUNPG1Hb68iWNfTOs=
github.com/netlify/netlify-go v0.1.11/go.mod h1:dsok3DAnu34A4p2B4oNVetyuc/8c7P2UmpXhDlX2mk8=
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
github.com/npillmayer/nestext v0.1.3/go.mod h1:h2lrijH8jpicr25dFY+oAJLyzlya6jhnuG+zWp9L0Uk=
github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A=
@@ -1714,7 +1779,6 @@ github.com/paulmach/orb v0.13.0 h1:r7n7mQGGF+cj/CbcivEj9J3HGK+XR+yXnvzRdq9saIw=
github.com/paulmach/orb v0.13.0/go.mod h1:6scRWINywA2Jf05dcjOfLfxrUIMECvTSG2MVbRLxu/k=
github.com/pborman/getopt v0.0.0-20170112200414-7148bc3a4c30/go.mod h1:85jBQOZwpVEaDAr341tbn15RS4fCAsIst0qp7i8ex1o=
github.com/pelletier/go-toml v1.7.0/go.mod h1:vwGMzjaWMwyfHwgIBhI2YUM4fB6nL6lVAvS1LBMMhTE=
github.com/pelletier/go-toml v1.9.5 h1:4yBQzkHv+7BHq2PQUZF3Mx0IYxG7LsP222s7Agd3ve8=
github.com/pelletier/go-toml v1.9.5/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c=
github.com/pelletier/go-toml/v2 v2.0.5/go.mod h1:OMHamSCAODeSsVrwwvcJOaoN0LIUIaFVNZzmWyNfXas=
github.com/pelletier/go-toml/v2 v2.3.0 h1:k59bC/lIZREW0/iVaQR8nDHxVq8OVlIzYCOJf421CaM=
@@ -1742,6 +1806,8 @@ github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/profile v1.2.1/go.mod h1:hJw3o1OdXxsrSjjVksARp5W95eeEaEfptyVZyv6JUPA=
github.com/pkg/sftp v1.13.1/go.mod h1:3HaPG6Dq1ILlpPZRO0HVMrsydcdLt6HRDccSgb87qRg=
github.com/plaid/plaid-go/v15 v15.3.0 h1:Q/eJ/nAK0KimNjsqRGVZ2jZronYDOwd3D2RPCCQBvJ0=
github.com/plaid/plaid-go/v15 v15.3.0/go.mod h1:Hwx1C2tMzJh8w6bAhKyL/RUSlaSxiMI2FdBXrY85mEM=
github.com/planetscale/vtprotobuf v0.6.1-0.20240319094008-0393e58bdf10 h1:GFCKgmp0tecUJ0sJuv4pzYCqS9+RGSn52M3FUwPs+uo=
github.com/planetscale/vtprotobuf v0.6.1-0.20240319094008-0393e58bdf10/go.mod h1:t/avpk3KcrXxUnYOhZhMXJlSEyie6gQbtLq5NM3loB8=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
@@ -1845,8 +1911,8 @@ github.com/rs/cors/wrapper/gin v0.0.0-20240830163046-1084d89a1692 h1:lwzJgPw5Y6p
github.com/rs/cors/wrapper/gin v0.0.0-20240830163046-1084d89a1692/go.mod h1:742Ialb8SOs5yB2PqRDzFcyND3280PoaS5/wcKQUQKE=
github.com/rs/xid v1.6.0 h1:fV591PaemRlL6JfRxGDEPl69wICngIQ3shQtzfy2gxU=
github.com/rs/xid v1.6.0/go.mod h1:7XoLgs4eV+QndskICGsho+ADou8ySMSjJKDIan90Nz0=
github.com/rs/zerolog v1.34.0 h1:k43nTLIwcTVQAncfCw4KZ2VY6ukYoZaBPNOE8txlOeY=
github.com/rs/zerolog v1.34.0/go.mod h1:bJsvje4Z08ROH4Nhs5iH600c3IkWhwp44iRc54W6wYQ=
github.com/rs/zerolog v1.35.0 h1:VD0ykx7HMiMJytqINBsKcbLS+BJ4WYjz+05us+LRTdI=
github.com/rs/zerolog v1.35.0/go.mod h1:EjML9kdfa/RMA7h/6z6pYmq1ykOuA8/mjWaEvGI+jcw=
github.com/russellhaering/gosaml2 v0.11.0 h1:wlWm7dWMrpJBzh0xEOZof70nVen4f/2BEF8ZXaidJ9o=
github.com/russellhaering/gosaml2 v0.11.0/go.mod h1:GmL5LeCP7PBYzSkkFxtmHuRzC2eUZ/6JSLYQd5fzKK4=
github.com/russellhaering/goxmldsig v1.6.0 h1:8fdWXEPh2k/NZNQBPFNoVfS3JmzS4ZprY/sAOpKQLks=
@@ -1944,6 +2010,8 @@ github.com/spf13/pflag v1.0.10/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3A
github.com/spf13/viper v1.13.0/go.mod h1:Icm2xNL3/8uyh/wFuB1jI7TiTNKp8632Nwegu+zgdYw=
github.com/spiffe/go-spiffe/v2 v2.6.0 h1:l+DolpxNWYgruGQVV0xsfeya3CsC7m8iBzDnMpsbLuo=
github.com/spiffe/go-spiffe/v2 v2.6.0/go.mod h1:gm2SeUoMZEtpnzPNs2Csc0D/gX33k1xIx7lEzqblHEs=
github.com/square/square-go-sdk/v3 v3.0.1 h1:nI8SHaFsTsEjbIDPOGZAVQNnnnZ0JSJx/yYWVCMv9CY=
github.com/square/square-go-sdk/v3 v3.0.1/go.mod h1:DFNgamK1woSVMdgsNSw3ibODixOO3iFSJ9924CHTnxY=
github.com/srikanthccv/ClickHouse-go-mock v0.13.0 h1:/b7DQphGkh29ocNtLh4DGmQxQYA0CfHz65Wy2zAH2GM=
github.com/srikanthccv/ClickHouse-go-mock v0.13.0/go.mod h1:LiiyBUdXNwB/1DE9rgK/8q9qjVYsTzg6WXQ/3mU3TeY=
github.com/stackitcloud/stackit-sdk-go/core v0.21.1 h1:Y/PcAgM7DPYMNqum0MLv4n1mF9ieuevzcCIZYQfm3Ts=
@@ -2009,6 +2077,7 @@ github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/sms v1.0.744/go.mod h1:
github.com/thanhpk/randstr v1.0.4 h1:IN78qu/bR+My+gHCvMEXhR/i5oriVHcTB/BJJIRTsNo=
github.com/thanhpk/randstr v1.0.4/go.mod h1:M/H2P1eNLZzlDwAzpkkkUvoyNNMbzRGhESZuEQk3r0U=
github.com/tidwall/gjson v1.14.2/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk=
github.com/tidwall/gjson v1.14.4/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk=
github.com/tidwall/gjson v1.18.0 h1:FIDeeyB800efLX89e5a8Y0BNH+LOngJyGrIWxG2FKQY=
github.com/tidwall/gjson v1.18.0/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk=
github.com/tidwall/match v1.1.1 h1:+Ho715JplO36QYgwN9PGYNhgZvoUSc9X2c80KVTi+GA=
@@ -2023,8 +2092,6 @@ github.com/timtadh/lexmachine v0.2.2/go.mod h1:GBJvD5OAfRn/gnp92zb9KTgHLB7akKyxm
github.com/tinylib/msgp v1.1.2/go.mod h1:+d+yLhGm8mzTaHzB+wgMYrodPfmZrzkirds8fDWklFE=
github.com/tinylib/msgp v1.6.4 h1:mOwYbyYDLPj35mkA2BjjYejgJk9BuHxDdvRnb6v2ZcQ=
github.com/tinylib/msgp v1.6.4/go.mod h1:RSp0LW9oSxFut3KzESt5Voq4GVWyS+PSulT77roAqEA=
github.com/tj/assert v0.0.3 h1:Df/BlaZ20mq6kuai7f5z2TvPFiwC3xaWJSDQNiIS3Rk=
github.com/tj/assert v0.0.3/go.mod h1:Ne6X72Q+TB1AteidzQncjw9PabbMp4PBMZ1k+vd1Pvk=
github.com/tjfoc/gmsm v1.3.2/go.mod h1:HaUcFuY0auTiaHB9MHFGCPx5IaLhTUd2atbCFBQXn9w=
github.com/tjfoc/gmsm v1.4.1 h1:aMe1GlZb+0bLjn+cKTPEvvn9oUEBlJitaZiiBwsbgho=
github.com/tjfoc/gmsm v1.4.1/go.mod h1:j4INPkHWMrhJb38G+J6W4Tw0AbuN8Thu3PbdVYhVcTE=
@@ -2123,8 +2190,6 @@ github.com/yuin/gopher-lua v1.1.1 h1:kYKnWBjvbNP4XLT3+bPEwAXJx262OhaHDWDVOPjL46M
github.com/yuin/gopher-lua v1.1.1/go.mod h1:GBR0iDaNXjAgGg9zfCvksxSRnQx76gclCIb7kdAd1Pw=
github.com/yusufpapurcu/wmi v1.2.4 h1:zFUKzehAFReQwLys1b/iSMl+JQGSCSjtVqQn9bBrPo0=
github.com/yusufpapurcu/wmi v1.2.4/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0=
github.com/zap-proto/http v0.0.0-20260506200741-fd6047874433 h1:7WsCr/pZvWozimdYNffL3B9K6gLr8w0Z7WAi1+eZWtc=
github.com/zap-proto/http v0.0.0-20260506200741-fd6047874433/go.mod h1:xySyVTIwjknmVE+p+6rukkX86rFZtXeAu/QY7KXMYqw=
github.com/zeebo/assert v1.3.1 h1:vukIABvugfNMZMQO1ABsyQDJDTVQbn+LWSMy1ol1h6A=
github.com/zeebo/assert v1.3.1/go.mod h1:Pq9JiuJQpG8JLJdtkwrJESF0Foym2/D9XMU5ciN/wJ0=
github.com/zeebo/blake3 v0.2.4 h1:KYQPkhpRtcqh0ssGYcKLG1JYvddkEA8QwCM/yBqhaZI=
@@ -2143,8 +2208,8 @@ go.etcd.io/etcd/client/v3 v3.5.0/go.mod h1:AIKXXVX/DQXtfTEqBryiLTUXwON+GuvO6Z7lL
go.etcd.io/etcd/client/v3 v3.5.4/go.mod h1:ZaRkVgBZC+L+dLCjTcF1hRXpgZXQPOvnA/Ak/gq3kiY=
go.mau.fi/util v0.8.3 h1:sulhXtfquMrQjsOP67x9CzWVBYUwhYeoo8hNQIpCWZ4=
go.mau.fi/util v0.8.3/go.mod h1:c00Db8xog70JeIsEvhdHooylTkTkakgnAOsZ04hplQY=
go.mongodb.org/mongo-driver v1.17.6 h1:87JUG1wZfWsr6rIz3ZmpH90rL5tea7O3IHuSwHUpsss=
go.mongodb.org/mongo-driver v1.17.6/go.mod h1:Hy04i7O2kC4RS06ZrhPRqj/u4DTYkFDAAccj+rVKqgQ=
go.mongodb.org/mongo-driver v1.17.9 h1:IexDdCuuNJ3BHrELgBlyaH9p60JXAvdzWR128q+U5tU=
go.mongodb.org/mongo-driver v1.17.9/go.mod h1:LlOhpH5NUEfhxcAwG0UEkMqwYcc4JU18gtCdGudk/tQ=
go.mongodb.org/mongo-driver/v2 v2.5.0 h1:yXUhImUjjAInNcpTcAlPHiT7bIXhshCTL3jVBkF3xaE=
go.mongodb.org/mongo-driver/v2 v2.5.0/go.mod h1:yOI9kBsufol30iFsl1slpdq1I0eHPzybRWdyYUs8K/0=
go.opencensus.io v0.15.0/go.mod h1:UffZAU+4sDEINUGP/B7UfBBkq4fqLu9zXAX7ke6CHW0=
@@ -2234,12 +2299,12 @@ go.opentelemetry.io/contrib/config v0.10.0 h1:2JknAzMaYjxrHkTnZh3eOme/Y2P5eHE2SW
go.opentelemetry.io/contrib/config v0.10.0/go.mod h1:aND2M6/KfNkntI5cyvHriR/zvZgPf8j9yETdSmvpfmc=
go.opentelemetry.io/contrib/detectors/gcp v1.39.0 h1:kWRNZMsfBHZ+uHjiH4y7Etn2FK26LAGkNFw7RHv1DhE=
go.opentelemetry.io/contrib/detectors/gcp v1.39.0/go.mod h1:t/OGqzHBa5v6RHZwrDBJ2OirWc+4q/w2fTbLZwAKjTk=
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.63.0 h1:YH4g8lQroajqUwWbq/tr2QX1JFmEXaDLgG+ew9bLMWo=
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.63.0/go.mod h1:fvPi2qXDqFs8M4B4fmJhE92TyQs9Ydjlg3RvfUp+NbQ=
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.67.0 h1:yI1/OhfEPy7J9eoa6Sj051C7n5dvpj0QX8g4sRchg04=
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.67.0/go.mod h1:NoUCKYWK+3ecatC4HjkRktREheMeEtrXoQxrqYFeHSc=
go.opentelemetry.io/contrib/instrumentation/net/http/httptrace/otelhttptrace v0.65.0 h1:ab5U7DpTjjN8pNgwqlA/s0Csb+N2Raqo9eTSDhfg4Z8=
go.opentelemetry.io/contrib/instrumentation/net/http/httptrace/otelhttptrace v0.65.0/go.mod h1:nwFJC46Dxhqz5R9k7IV8To/Z46JPvW+GNKhTxQQlUzg=
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.65.0 h1:7iP2uCb7sGddAr30RRS6xjKy7AZ2JtTOPA3oolgVSw8=
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.65.0/go.mod h1:c7hN3ddxs/z6q9xwvfLPk+UHlWRQyaeR1LdgfL/66l0=
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.67.0 h1:OyrsyzuttWTSur2qN/Lm0m2a8yqyIjUVBZcxFPuXq2o=
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.67.0/go.mod h1:C2NGBr+kAB4bk3xtMXfZ94gqFDtg/GkI7e9zqGh5Beg=
go.opentelemetry.io/contrib/propagators/autoprop v0.63.0 h1:S3+4UwR3Y1tUKklruMwOacAFInNvtuOexz4ZTmJNAyw=
go.opentelemetry.io/contrib/propagators/autoprop v0.63.0/go.mod h1:qpIuOggbbw2T9nKRaO1je/oTRKd4zslAcJonN8LYbTg=
go.opentelemetry.io/contrib/propagators/aws v1.38.0 h1:eRZ7asSbLc5dH7+TBzL6hFKb1dabz0IV51uUUwYRZts=
@@ -2260,16 +2325,16 @@ go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.39.0 h1:nKP
go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.39.0/go.mod h1:NwjeBbNigsO4Aj9WgM0C+cKIrxsZUaRmZUO7A8I7u8o=
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.43.0 h1:88Y4s2C8oTui1LGM6bTWkw0ICGcOLCAI5l6zsD1j20k=
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.43.0/go.mod h1:Vl1/iaggsuRlrHf/hfPJPvVag77kKyvrLeD10kpMl+A=
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.40.0 h1:DvJDOPmSWQHWywQS6lKL+pb8s3gBLOZUtw4N+mavW1I=
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.40.0/go.mod h1:EtekO9DEJb4/jRyN4v4Qjc2yA7AtfCBuz2FynRUWTXs=
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.42.0 h1:zWWrB1U6nqhS/k6zYB74CjRpuiitRtLLi68VcgmOEto=
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.42.0/go.mod h1:2qXPNBX1OVRC0IwOnfo1ljoid+RD0QK3443EaqVlsOU=
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.43.0 h1:3iZJKlCZufyRzPzlQhUIWVmfltrXuGyfjREgGP3UUjc=
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.43.0/go.mod h1:/G+nUPfhq2e+qiXMGxMwumDrP5jtzU+mWN7/sjT2rak=
go.opentelemetry.io/otel/exporters/prometheus v0.60.0 h1:cGtQxGvZbnrWdC2GyjZi0PDKVSLWP/Jocix3QWfXtbo=
go.opentelemetry.io/otel/exporters/prometheus v0.60.0/go.mod h1:hkd1EekxNo69PTV4OWFGZcKQiIqg0RfuWExcPKFvepk=
go.opentelemetry.io/otel/exporters/stdout/stdoutlog v0.14.0 h1:B/g+qde6Mkzxbry5ZZag0l7QrQBCtVm7lVjaLgmpje8=
go.opentelemetry.io/otel/exporters/stdout/stdoutlog v0.14.0/go.mod h1:mOJK8eMmgW6ocDJn6Bn11CcZ05gi3P8GylBXEkZtbgA=
go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.39.0 h1:5gn2urDL/FBnK8OkCfD1j3/ER79rUuTYmCvlXBKeYL8=
go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.39.0/go.mod h1:0fBG6ZJxhqByfFZDwSwpZGzJU671HkwpWaNe2t4VUPI=
go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.40.0 h1:ZrPRak/kS4xI3AVXy8F7pipuDXmDsrO8Lg+yQjBLjw0=
go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.40.0/go.mod h1:3y6kQCWztq6hyW8Z9YxQDDm0Je9AJoFar2G0yDcmhRk=
go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.39.0 h1:8UPA4IbVZxpsD76ihGOQiFml99GPAEZLohDXvqHdi6U=
go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.39.0/go.mod h1:MZ1T/+51uIVKlRzGw1Fo46KEWThjlCBZKl2LzY5nv4g=
go.opentelemetry.io/otel/log v0.15.0 h1:0VqVnc3MgyYd7QqNVIldC3dsLFKgazR6P3P3+ypkyDY=
@@ -2367,8 +2432,8 @@ golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v
golang.org/x/crypto v0.24.0/go.mod h1:Z1PMYSOR5nyMcyAVAIQSKCDwalqy85Aqn1x3Ws4L5DM=
golang.org/x/crypto v0.31.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk=
golang.org/x/crypto v0.32.0/go.mod h1:ZnnJkOaASj8g0AjIduWNlq2NRxL0PlBrbKVyZ6V/Ugc=
golang.org/x/crypto v0.50.0 h1:zO47/JPrL6vsNkINmLoo/PH1gcxpls50DNogFvB5ZGI=
golang.org/x/crypto v0.50.0/go.mod h1:3muZ7vA7PBCE6xgPX7nkzzjiUq87kRItoJQM1Yo8S+Q=
golang.org/x/crypto v0.52.0 h1:RMs7fP2rXdep0CftQlK8Uf+kibLm7qkCcradZWYz988=
golang.org/x/crypto v0.52.0/go.mod h1:1QgfPxDqh0T2M/elOJtp9RvuR95kVjir0e6/BvEmGbc=
golang.org/x/exp v0.0.0-20180321215751-8460e604b9de/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20180807140117-3d87b88a115f/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
@@ -2388,8 +2453,8 @@ golang.org/x/image v0.0.0-20180708004352-c73c2afc3b81/go.mod h1:ux5Hcp/YLpHSI86h
golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
golang.org/x/image v0.0.0-20191009234506-e7c1f5e7dbb8/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
golang.org/x/image v0.38.0 h1:5l+q+Y9JDC7mBOMjo4/aPhMDcxEptsX+Tt3GgRQRPuE=
golang.org/x/image v0.38.0/go.mod h1:/3f6vaXC+6CEanU4KJxbcUZyEePbyKbaLoDOe4ehFYY=
golang.org/x/image v0.41.0 h1:8wS72eGJMJaBxK6okTzd4WaXumUlTVlb753MlsSvTCo=
golang.org/x/image v0.41.0/go.mod h1:uIc348UZMSvS5Z65CVZ7iDPaNobNFEPeJ4kbqTOszmA=
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
@@ -2420,8 +2485,8 @@ golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
golang.org/x/mod v0.14.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
golang.org/x/mod v0.15.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
golang.org/x/mod v0.17.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
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/mod v0.36.0 h1:JJjpVx6myfUsUdAzZuOSTTmRE0PfZeNWzzvKrP7amb4=
golang.org/x/mod v0.36.0/go.mod h1:moc6ELqsWcOw5Ef3xVprK5ul/MvtVvkIXLziUOICjUQ=
golang.org/x/net v0.0.0-20171115151908-9dfe39835686/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180719180050-a680a1efc54d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
@@ -2487,7 +2552,9 @@ golang.org/x/net v0.0.0-20220412020605-290c469a71a5/go.mod h1:CfG3xpIq0wQ8r1q4Su
golang.org/x/net v0.0.0-20220425223048-2871e0cb64e4/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
golang.org/x/net v0.0.0-20220520000938-2e3eb7b945c2/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
golang.org/x/net v0.0.0-20220607020251-c690dde0001d/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
golang.org/x/net v0.0.0-20220624214902-1bab6f366d9e/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
golang.org/x/net v0.0.0-20220826154423-83b083e8dc8b/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk=
golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
golang.org/x/net v0.9.0/go.mod h1:d48xBJpPfHeWQsugry2m+kC02ZBRGRgulfHnEXEuWns=
@@ -2502,8 +2569,8 @@ golang.org/x/net v0.23.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg=
golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM=
golang.org/x/net v0.26.0/go.mod h1:5YKkiSynbBIh3p6iOc/vibscux0x38BZDkn8sCUPxHE=
golang.org/x/net v0.34.0/go.mod h1:di0qlW3YNM5oh6GqDGQr92MyTozJPmybPK4Ev/Gm31k=
golang.org/x/net v0.53.0 h1:d+qAbo5L0orcWAr0a9JweQpjXF19LMXJE8Ey7hwOdUA=
golang.org/x/net v0.53.0/go.mod h1:JvMuJH7rrdiCfbeHoo3fCQU24Lf5JJwT9W3sJFulfgs=
golang.org/x/net v0.55.0 h1:bcvxaJn3e1U6InsFWt1JUq1aSjnRxLzT2rtD2KfkDF8=
golang.org/x/net v0.55.0/go.mod h1:L5U2KuzuOe1lY7Z+aWVIKK6qEeJXnXV9yzGA+WCHJww=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
@@ -2524,6 +2591,8 @@ golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8/go.mod h1:KelEdhl1UZF7XfJ
golang.org/x/oauth2 v0.0.0-20220223155221-ee480838109b/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc=
golang.org/x/oauth2 v0.0.0-20220309155454-6242fa91716a/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc=
golang.org/x/oauth2 v0.0.0-20220411215720-9780585627b5/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc=
golang.org/x/oauth2 v0.0.0-20220608161450-d0670ef3b1eb/go.mod h1:jaDAt6Dkxork7LmZnYtzbRWj0W47D86a3TGe0YHBvmE=
golang.org/x/oauth2 v0.0.0-20220822191816-0ebed06d0094/go.mod h1:h4gKUeWbJ4rQPri7E0u6Gs4e9Ri2zaLxzw5DI5XGrYg=
golang.org/x/oauth2 v0.36.0 h1:peZ/1z27fi9hUOFCAZaHyrpWG5lwe0RJEEEeH0ThlIs=
golang.org/x/oauth2 v0.36.0/go.mod h1:YDBUJMTkDnJS+A4BP4eZBjCqtokkg1hODuPjwiGPO7Q=
golang.org/x/sync v0.0.0-20171101214715-fd80eb99c8f6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
@@ -2644,14 +2713,15 @@ golang.org/x/sys v0.0.0-20220227234510-4e6760a101f9/go.mod h1:oPkhp1MJrh7nUepCBc
golang.org/x/sys v0.0.0-20220328115105-d36c6a25d886/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220412211240-33da011f77ad/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220502124256-b6088ccd6cba/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220503163025-988cb79eb6c6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220610221304-9f5ed59c137d/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220708085239-5a0f0661e09d/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.9.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
@@ -2665,8 +2735,8 @@ golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.21.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.29.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.43.0 h1:Rlag2XtaFTxp19wS8MXlJwTvoh8ArU6ezoyFsMyCTNI=
golang.org/x/sys v0.43.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw=
golang.org/x/sys v0.45.0 h1:dO4czNzziLiiXplLQgBCEpCvXQ3dnkn0SdaZSYdQ+FY=
golang.org/x/sys v0.45.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw=
golang.org/x/telemetry v0.0.0-20240228155512-f48c80bd79b2/go.mod h1:TeRTkGYfJXctD9OcfyVLyj2J3IxLnKwHJR8f4D8a3YE=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
@@ -2684,8 +2754,8 @@ golang.org/x/term v0.20.0/go.mod h1:8UkIAJTvZgivsXaD6/pH6U9ecQzZ45awqEOzuCvwpFY=
golang.org/x/term v0.21.0/go.mod h1:ooXLefLobQVslOqselCNF4SxFAaoS6KujMbsGzSDmX0=
golang.org/x/term v0.27.0/go.mod h1:iMsnZpn0cago0GOrHO2+Y7u7JPn5AylBrcoWkElMTSM=
golang.org/x/term v0.28.0/go.mod h1:Sw/lC2IAUZ92udQNf3WodGtn4k/XoLyZoh8v/8uiwek=
golang.org/x/term v0.42.0 h1:UiKe+zDFmJobeJ5ggPwOshJIVt6/Ft0rcfrXZDLWAWY=
golang.org/x/term v0.42.0/go.mod h1:Dq/D+snpsbazcBG5+F9Q1n2rXV8Ma+71xEjTRufARgY=
golang.org/x/term v0.43.0 h1:S4RLU2sB31O/NCl+zFN9Aru9A/Cq2aqKpTZJ6B+DwT4=
golang.org/x/term v0.43.0/go.mod h1:lrhlHNdQJHO+1qVYiHfFKVuVioJIheAc3fBSMFYEIsk=
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
@@ -2705,8 +2775,8 @@ golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI=
golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ=
golang.org/x/text v0.36.0 h1:JfKh3XmcRPqZPKevfXVpI1wXPTqbkE5f7JA92a55Yxg=
golang.org/x/text v0.36.0/go.mod h1:NIdBknypM8iqVmPiuco0Dh6P5Jcdk8lJL0CUebqK164=
golang.org/x/text v0.37.0 h1:Cqjiwd9eSg8e0QAkyCaQTNHFIIzWtidPahFWR83rTrc=
golang.org/x/text v0.37.0/go.mod h1:a5sjxXGs9hsn/AJVwuElvCAo9v8QYLzvavO5z2PiM38=
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
@@ -2781,8 +2851,8 @@ golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
golang.org/x/tools v0.13.0/go.mod h1:HvlwmtVNQAhOuCjW7xxvovg8wbNq7LwfXh/k7wXUl58=
golang.org/x/tools v0.17.0/go.mod h1:xsh6VxdV005rRVaS6SSAf9oiAqljS7UZUacMZ8Bnsps=
golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk=
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=
golang.org/x/tools v0.45.0 h1:18qN3FAooORvApf5XjCXgsuayZOEtXf6JK18I3+ONa8=
golang.org/x/tools v0.45.0/go.mod h1:LuUGqqaXcXMEFEruIVJVm5mgDD8vww/z/SR1gQ4uE/0=
golang.org/x/tools/godoc v0.1.0-deprecated h1:o+aZ1BOj6Hsx/GBdJO/s815sqftjSnrZZwyYTHODvtk=
golang.org/x/tools/godoc v0.1.0-deprecated/go.mod h1:qM63CriJ961IHWmnWa9CjZnBndniPt4a3CK0PVB9bIg=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
@@ -2791,6 +2861,7 @@ golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8T
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20220411194840-2f41105eb62f/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20220517211312-f3a8303e98df/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8=
golang.org/x/xerrors v0.0.0-20220609144429-65e65417b02f/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8=
golang.org/x/xerrors v0.0.0-20240903120638-7835f813f4da h1:noIWHXmPHxILtqtCOPIhSt0ABwskkZKjD3bXGnZGpNY=
golang.org/x/xerrors v0.0.0-20240903120638-7835f813f4da/go.mod h1:NDW/Ps6MPRej6fsCIbMTohpP40sJ/P/vI1MoTEGwX90=
gonum.org/v1/gonum v0.0.0-20180816165407-929014505bf4/go.mod h1:Y+Yx5eoAFn32cQvJDxZx5Dpnq+c3wtXuadVZAcxbbBo=
@@ -2838,9 +2909,11 @@ google.golang.org/api v0.71.0/go.mod h1:4PyU6e6JogV1f9eA4voyrTY2batOLdgZ5qZ5HOCc
google.golang.org/api v0.74.0/go.mod h1:ZpfMZOVRMywNyvJFeqL9HRWBgAuRfSjJFpe9QtRRyDs=
google.golang.org/api v0.75.0/go.mod h1:pU9QmyHLnzlpar1Mjt4IbapUCy8J+6HD6GeELN69ljA=
google.golang.org/api v0.78.0/go.mod h1:1Sg78yoMLOhlQTeF+ARBoytAcH1NNyyl390YMy6rKmw=
google.golang.org/api v0.80.0/go.mod h1:xY3nI94gbvBrE0J6NHXhxOmW97HG7Khjkku6AFB3Hyg=
google.golang.org/api v0.81.0/go.mod h1:FA6Mb/bZxj706H2j+j2d6mHEEaHBmbbWnkfvmorOCko=
google.golang.org/api v0.267.0 h1:w+vfWPMPYeRs8qH1aYYsFX68jMls5acWl/jocfLomwE=
google.golang.org/api v0.267.0/go.mod h1:Jzc0+ZfLnyvXma3UtaTl023TdhZu6OMBP9tJ+0EmFD0=
google.golang.org/api v0.84.0/go.mod h1:NTsGnUFJMYROtiquksZHBWtHfeMC7iYthki7Eq3pa8o=
google.golang.org/api v0.275.0 h1:vfY5d9vFVJeWEZT65QDd9hbndr7FyZ2+6mIzGAh71NI=
google.golang.org/api v0.275.0/go.mod h1:Fnag/EWUPIcJXuIkP1pjoTgS5vdxlk3eeemL7Do6bvw=
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
@@ -2891,6 +2964,7 @@ google.golang.org/genproto v0.0.0-20210226172003-ab064af71705/go.mod h1:FWY/as6D
google.golang.org/genproto v0.0.0-20210303154014-9728d6b83eeb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20210310155132-4ce2db91004e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20210319143718-93e7006c17a6/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20210329143202-679c6ae281ee/go.mod h1:9lPAdzaEmUacj36I+k7YKbEc5CXzPIeORRgDAUOu28A=
google.golang.org/genproto v0.0.0-20210402141018-6c239bbf2bb1/go.mod h1:9lPAdzaEmUacj36I+k7YKbEc5CXzPIeORRgDAUOu28A=
google.golang.org/genproto v0.0.0-20210513213006-bf773b8c8384/go.mod h1:P3QM42oQyzQSnHPnZ/vqoCdDmzH28fzWByN9asMeM8A=
google.golang.org/genproto v0.0.0-20210602131652-f16073e35f0c/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0=
@@ -2928,13 +3002,17 @@ google.golang.org/genproto v0.0.0-20220414192740-2d67ff6cf2b4/go.mod h1:8w6bsBMX
google.golang.org/genproto v0.0.0-20220421151946-72621c1f0bd3/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo=
google.golang.org/genproto v0.0.0-20220429170224-98d788798c3e/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo=
google.golang.org/genproto v0.0.0-20220505152158-f39f71e6c8f3/go.mod h1:RAyBrSAP7Fh3Nc84ghnVLDPuV51xc9agzmm4Ph6i0Q4=
google.golang.org/genproto v0.0.0-20220518221133-4f43b3371335/go.mod h1:RAyBrSAP7Fh3Nc84ghnVLDPuV51xc9agzmm4Ph6i0Q4=
google.golang.org/genproto v0.0.0-20220519153652-3a47de7e79bd/go.mod h1:RAyBrSAP7Fh3Nc84ghnVLDPuV51xc9agzmm4Ph6i0Q4=
google.golang.org/genproto v0.0.0-20260128011058-8636f8732409 h1:VQZ/yAbAtjkHgH80teYd2em3xtIkkHd7ZhqfH2N9CsM=
google.golang.org/genproto v0.0.0-20260128011058-8636f8732409/go.mod h1:rxKD3IEILWEu3P44seeNOAwZN4SaoKaQ/2eTg4mM6EM=
google.golang.org/genproto/googleapis/api v0.0.0-20260401024825-9d38bb4040a9 h1:VPWxll4HlMw1Vs/qXtN7BvhZqsS9cdAittCNvVENElA=
google.golang.org/genproto/googleapis/api v0.0.0-20260401024825-9d38bb4040a9/go.mod h1:7QBABkRtR8z+TEnmXTqIqwJLlzrZKVfAUm7tY3yGv0M=
google.golang.org/genproto/googleapis/rpc v0.0.0-20260401024825-9d38bb4040a9 h1:m8qni9SQFH0tJc1X0vmnpw/0t+AImlSvp30sEupozUg=
google.golang.org/genproto/googleapis/rpc v0.0.0-20260401024825-9d38bb4040a9/go.mod h1:4Hqkh8ycfw05ld/3BWL7rJOSfebL2Q+DVDeRgYgxUU8=
google.golang.org/genproto v0.0.0-20220523171625-347a074981d8/go.mod h1:RAyBrSAP7Fh3Nc84ghnVLDPuV51xc9agzmm4Ph6i0Q4=
google.golang.org/genproto v0.0.0-20220608133413-ed9918b62aac/go.mod h1:KEWEmljWE5zPzLBa/oHl6DaEt9LmfH6WtH1OHIvleBA=
google.golang.org/genproto v0.0.0-20220616135557-88e70c0c3a90/go.mod h1:KEWEmljWE5zPzLBa/oHl6DaEt9LmfH6WtH1OHIvleBA=
google.golang.org/genproto v0.0.0-20260406210006-6f92a3bedf2d h1:N1Ec54vZnIPd7MnxRiYLW+oY4fDR4BOS/LrssdD9+ek=
google.golang.org/genproto v0.0.0-20260406210006-6f92a3bedf2d/go.mod h1:c2hJ1grtnH0xUiEKGDGkjGNTJ1Hy2LrblyKOHF0sqRM=
google.golang.org/genproto/googleapis/api v0.0.0-20260511170946-3700d4141b60 h1:3WsB1FAbiRIf2tOxscWKs3pQBD9he1NsrnbhMuWfekc=
google.golang.org/genproto/googleapis/api v0.0.0-20260511170946-3700d4141b60/go.mod h1:7yoXV7RIh5gblj/xVYoogxAWvA9wUeVbpsK/M694l00=
google.golang.org/genproto/googleapis/rpc v0.0.0-20260511170946-3700d4141b60 h1:seT2EwLWM78plQ7wcDfuWBc/4FAEAXDDiaSol4ku4qo=
google.golang.org/genproto/googleapis/rpc v0.0.0-20260511170946-3700d4141b60/go.mod h1:4Hqkh8ycfw05ld/3BWL7rJOSfebL2Q+DVDeRgYgxUU8=
google.golang.org/grpc v1.14.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw=
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
google.golang.org/grpc v1.20.0/go.mod h1:chYK+tFQF0nDUGJgXMSgLCQk3phJEuONr2DCgLDdAQM=
@@ -2968,6 +3046,7 @@ google.golang.org/grpc v1.44.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ5
google.golang.org/grpc v1.45.0/go.mod h1:lN7owxKUQEqMfSyQikvvk5tf/6zMPsrK+ONuO11+0rQ=
google.golang.org/grpc v1.46.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk=
google.golang.org/grpc v1.46.2/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk=
google.golang.org/grpc v1.47.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk=
google.golang.org/grpc v1.80.0 h1:Xr6m2WmWZLETvUNvIUmeD5OAagMw3FiKmMlTdViWsHM=
google.golang.org/grpc v1.80.0/go.mod h1:ho/dLnxwi3EDJA4Zghp7k2Ec1+c2jqup0bFkw07bwF4=
google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0/go.mod h1:6Kw0yEErY5E/yWrBtf03jp27GLLJujG4z/JK95pnjjw=
@@ -3062,10 +3141,10 @@ layeh.com/radius v0.0.0-20231213012653-1006025d24f8 h1:orYXpi6BJZdvgytfHH4ybOe4w
layeh.com/radius v0.0.0-20231213012653-1006025d24f8/go.mod h1:QRf+8aRqXc019kHkpcs/CTgyWXFzf+bxlsyuo2nAl1o=
maunium.net/go/mautrix v0.22.1 h1:2lCM37vmVzZGE0tWD7UOySMtAuC5hq6Pw33KlY2VU/c=
maunium.net/go/mautrix v0.22.1/go.mod h1:1rhqwH34Rz54ZqzdQYkmNW6rQUymNeTdaLA4l9LK6AI=
modernc.org/cc/v4 v4.27.3 h1:uNCgn37E5U09mTv1XgskEVUJ8ADKpmFMPxzGJ0TSo+U=
modernc.org/cc/v4 v4.27.3/go.mod h1:3YjcbCqhoTTHPycJDRl2WZKKFj0nwcOIPBfEZK0Hdk8=
modernc.org/ccgo/v4 v4.32.4 h1:L5OB8rpEX4ZsXEQwGozRfJyJSFHbbNVOoQ59DU9/KuU=
modernc.org/ccgo/v4 v4.32.4/go.mod h1:lY7f+fiTDHfcv6YlRgSkxYfhs+UvOEEzj49jAn2TOx0=
modernc.org/cc/v4 v4.28.2 h1:3tQ0lf2ADtoby2EtSP+J7IE2SHwEJdP8ioR59wx7XpY=
modernc.org/cc/v4 v4.28.2/go.mod h1:OnovgIhbbMXMu1aISnJ0wvVD1KnW+cAUJkIrAWh+kVI=
modernc.org/ccgo/v4 v4.34.0 h1:yRLPFZieg532OT4rp4JFNIVcquwalMX26G95WQDqwCQ=
modernc.org/ccgo/v4 v4.34.0/go.mod h1:AS5WYMyBakQ+fhsHhtP8mWB82KTGPkNNJDGfGQCe0/A=
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=
@@ -3074,18 +3153,18 @@ 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.72.0 h1:IEu559v9a0XWjw0DPoVKtXpO2qt5NVLAnFaBbjq+n8c=
modernc.org/libc v1.72.0/go.mod h1:tTU8DL8A+XLVkEY3x5E/tO7s2Q/q42EtnNWda/L5QhQ=
modernc.org/libc v1.72.3 h1:ZnDF4tXn4NBXFutMMQC4vtbTFSXhhKzR73fv0beZEAU=
modernc.org/libc v1.72.3/go.mod h1:dn0dZNnnn1clLyvRxLxYExxiKRZIRENOfqQ8XEeg4Qs=
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=
modernc.org/memory v1.11.0/go.mod h1:/JP4VbVC+K5sU2wZi9bHoq2MAkCnrt2r98UGeSK7Mjw=
modernc.org/opt v0.1.4 h1:2kNGMRiUjrp4LcaPuLY2PzUfqM/w9N23quVwhKt5Qm8=
modernc.org/opt v0.1.4/go.mod h1:03fq9lsNfvkYSfxrfUhZCWPk1lm4cq4N+Bh//bEtgns=
modernc.org/opt v0.2.0 h1:tGyef5ApycA7FSEOMraay9SaTk5zmbx7Tu+cJs4QKZg=
modernc.org/opt v0.2.0/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.50.0 h1:eMowQSWLK0MeiQTdmz3lqoF5dqclujdlIKeJA11+7oM=
modernc.org/sqlite v1.50.0/go.mod h1:m0w8xhwYUVY3H6pSDwc3gkJ/irZT/0YEXwBlhaxQEew=
modernc.org/sqlite v1.51.0 h1:aH/MMSoayAIhozZ7uJbVTT9QO/VhzBf0J9tymmmuC/U=
modernc.org/sqlite v1.51.0/go.mod h1:tcNzv5p84E0skkmJn038y+hWJbLQXQqEnQfeh5r2JLM=
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=
+159
View File
@@ -0,0 +1,159 @@
// Package storagelock refuses to boot the canonical Hanzo cloud
// orchestrator against Postgres.
//
// The Go cloud binary (HIP-0106) is an orchestrator that mounts every
// Hanzo subsystem (iam, base, kms, commerce, ai, ...) into one process.
// It has no storage of its own — every subsystem owns its own
// per-(org, user) SQLite via hanzoai/base (HIP-0302).
//
// The legacy deployed image (cloud-api Python/TS) used a shared
// PostgreSQL database `hanzo_cloud` on `postgres.hanzo.svc`. That
// service is being retired in favour of the Go orchestrator. The
// lockdown ensures the new binary never picks up a leaked
// `DATABASE_URL` env from a manifest that still carries the legacy
// driverName=postgres / dbName=hanzo_cloud knobs.
//
// Per the Hanzo PG → SQLite migration plan
// (~/work/hanzo/CLAUDE_PG_TO_SQLITE_MIGRATION.md, service #4 — cloud).
package storagelock
import (
"errors"
"fmt"
"strings"
)
// forbiddenEnvs is the closed set of env vars that the legacy cloud-api
// Python deployment used to pin its Postgres backend. They are
// dispositive — non-empty at boot for the Go orchestrator means a
// regression copying from the legacy manifest.
var forbiddenEnvs = []string{
"DATABASE_URL",
"DATABASE_HOST",
"POSTGRES_URL",
"POSTGRES_DSN",
"POSTGRES_HOST",
"CLOUD_DATABASE_URL",
"CLOUD_POSTGRES_URL",
"HANZO_CLOUD_DB",
// Legacy cloud-api Python/TS driverName/dbName pair. driverName ==
// "postgres" is the smoking-gun configuration.
"driverName",
"dbName",
}
// pgSchemes is the prefix set that marks a DSN as a Postgres URL.
var pgSchemes = []string{
"postgres://",
"postgresql://",
"postgres+",
}
// ErrPostgresForbidden is returned when an env var pins cloud at PG.
var ErrPostgresForbidden = errors.New("cloud: Postgres is not a supported storage backend (use per-tenant SQLite via hanzoai/base)")
// Violation captures one offending (var, value) pair.
type Violation struct {
Var string
Value string
}
// Violations enumerates every offending env var found in the supplied
// lookup function. The lookup is parameterised so tests can drive it
// without mutating os.Environ.
//
// For driverName specifically, only "postgres" / "postgresql" values
// are violations; any other value (e.g. "sqlite") is benign and would
// be intentionally set by an operator running a transitional config.
func Violations(lookup func(string) string) []Violation {
if lookup == nil {
return nil
}
var out []Violation
for _, k := range forbiddenEnvs {
v := strings.TrimSpace(lookup(k))
if v == "" {
continue
}
// driverName is the legacy cloud-api Python knob; we only
// reject "postgres" / "postgresql". Other values (e.g.
// "sqlite") are intentional transition signals from the
// operator and must not crash the pod.
if k == "driverName" {
low := strings.ToLower(v)
if low != "postgres" && low != "postgresql" {
continue
}
}
// dbName by itself is not a violation unless paired with a
// postgres driver; but since "hanzo_cloud" is the exact legacy
// name and the Go binary never reads dbName, we report it as
// an informational violation only when it has the legacy
// value. Other values pass through.
if k == "dbName" {
if v != "hanzo_cloud" {
continue
}
}
out = append(out, Violation{Var: k, Value: v})
}
return out
}
// IsPostgres reports whether the value parses as a Postgres DSN.
func IsPostgres(v string) bool {
v = strings.ToLower(strings.TrimSpace(v))
for _, s := range pgSchemes {
if strings.HasPrefix(v, s) {
return true
}
}
return false
}
// CheckEnv returns nil when the environment is clean, or a wrapped
// ErrPostgresForbidden enumerating every violation. cloud's main wires
// this and fails fast on any non-nil return.
func CheckEnv(lookup func(string) string) error {
vs := Violations(lookup)
if len(vs) == 0 {
return nil
}
var b strings.Builder
fmt.Fprintf(&b, "%v:", ErrPostgresForbidden)
for _, v := range vs {
kind := classify(v.Var, v.Value)
fmt.Fprintf(&b, " %s=%s (%s)", v.Var, redact(v.Value), kind)
}
return errors.New(b.String())
}
func classify(k, v string) string {
switch {
case IsPostgres(v):
return "Postgres DSN"
case k == "driverName":
return "legacy Python driver pin"
case k == "dbName":
return "legacy Python db pin"
default:
return "set"
}
}
// redact masks credentials in a DSN so the lockdown log does not leak
// passwords. Non-DSN values pass through.
func redact(v string) string {
if !IsPostgres(v) {
return v
}
atIdx := strings.LastIndex(v, "@")
if atIdx < 0 {
return v
}
schemeEnd := strings.Index(v, "://")
if schemeEnd < 0 || schemeEnd+3 >= atIdx {
return v
}
return v[:schemeEnd+3] + "***" + v[atIdx:]
}
+153
View File
@@ -0,0 +1,153 @@
package storagelock
import (
"errors"
"strings"
"testing"
)
func TestCheckEnvCleanReturnsNil(t *testing.T) {
if err := CheckEnv(func(string) string { return "" }); err != nil {
t.Fatalf("expected nil for empty env, got %v", err)
}
}
func TestCheckEnvNilLookup(t *testing.T) {
if err := CheckEnv(nil); err != nil {
t.Fatalf("expected nil for nil lookup, got %v", err)
}
}
func TestCheckEnvDatabaseURLRejected(t *testing.T) {
env := map[string]string{
"DATABASE_URL": "postgres://cloud:secret@postgres.hanzo.svc:5432/hanzo_cloud?sslmode=disable",
}
err := CheckEnv(mapLookup(env))
if err == nil {
t.Fatal("expected error, got nil")
}
if !errors.Is(err, ErrPostgresForbidden) {
if !strings.Contains(err.Error(), ErrPostgresForbidden.Error()) {
t.Fatalf("expected wrapped ErrPostgresForbidden, got %v", err)
}
}
if !strings.Contains(err.Error(), "DATABASE_URL") {
t.Errorf("expected error to mention DATABASE_URL, got %v", err)
}
if !strings.Contains(err.Error(), "Postgres DSN") {
t.Errorf("expected error to classify as Postgres DSN, got %v", err)
}
if strings.Contains(err.Error(), "secret") {
t.Errorf("expected password to be redacted, got %v", err)
}
}
func TestCheckEnvLegacyDriverNamePostgresRejected(t *testing.T) {
env := map[string]string{
"driverName": "postgres",
}
err := CheckEnv(mapLookup(env))
if err == nil {
t.Fatal("expected error for driverName=postgres")
}
if !strings.Contains(err.Error(), "driverName") {
t.Errorf("expected driverName in error, got %v", err)
}
if !strings.Contains(err.Error(), "legacy Python driver pin") {
t.Errorf("expected legacy Python driver classification, got %v", err)
}
}
func TestCheckEnvDriverNameSqliteIgnored(t *testing.T) {
// driverName=sqlite is an intentional transition signal — must not
// crash the pod.
env := map[string]string{"driverName": "sqlite"}
if err := CheckEnv(mapLookup(env)); err != nil {
t.Errorf("expected nil for driverName=sqlite, got %v", err)
}
}
func TestCheckEnvLegacyDBNameHanzoCloudRejected(t *testing.T) {
env := map[string]string{"dbName": "hanzo_cloud"}
err := CheckEnv(mapLookup(env))
if err == nil {
t.Fatal("expected error for dbName=hanzo_cloud")
}
if !strings.Contains(err.Error(), "legacy Python db pin") {
t.Errorf("expected legacy Python db pin classification, got %v", err)
}
}
func TestCheckEnvDBNameOtherIgnored(t *testing.T) {
env := map[string]string{"dbName": "something_else"}
if err := CheckEnv(mapLookup(env)); err != nil {
t.Errorf("expected nil for dbName=something_else, got %v", err)
}
}
func TestCheckEnvCloudDatabaseURLRejected(t *testing.T) {
env := map[string]string{
"CLOUD_DATABASE_URL": "postgresql://u:p@h:5432/d",
}
err := CheckEnv(mapLookup(env))
if err == nil {
t.Fatal("expected error for CLOUD_DATABASE_URL")
}
}
func TestCheckEnvMultipleViolationsAllReported(t *testing.T) {
env := map[string]string{
"DATABASE_URL": "postgresql://u:p@h:5432/d",
"driverName": "postgres",
"dbName": "hanzo_cloud",
}
err := CheckEnv(mapLookup(env))
if err == nil {
t.Fatal("expected error")
}
for _, k := range []string{"DATABASE_URL", "driverName", "dbName"} {
if !strings.Contains(err.Error(), k) {
t.Errorf("expected %s in error, got %v", k, err)
}
}
}
func TestCheckEnvWhitespaceTrimmed(t *testing.T) {
env := map[string]string{"DATABASE_URL": " "}
if err := CheckEnv(mapLookup(env)); err != nil {
t.Fatalf("expected nil for whitespace-only value, got %v", err)
}
}
func TestIsPostgres(t *testing.T) {
cases := map[string]bool{
"postgres://u@h/d": true,
"postgresql://u@h/d": true,
" POSTGRES://U@H/D ": true,
"sqlite:///data/x.db": false,
"file:///data/x.db": false,
"": false,
}
for v, want := range cases {
if got := IsPostgres(v); got != want {
t.Errorf("IsPostgres(%q) = %v, want %v", v, got, want)
}
}
}
func TestRedactStripsCredentials(t *testing.T) {
in := "postgres://cloud:supersecret@host:5432/db?sslmode=disable"
out := redact(in)
if strings.Contains(out, "supersecret") {
t.Errorf("redact did not strip password: %s", out)
}
if !strings.HasPrefix(out, "postgres://***@") {
t.Errorf("expected postgres://***@ prefix, got %s", out)
}
}
// mapLookup builds a lookup function from a map literal so tests don't
// have to mutate os.Environ.
func mapLookup(env map[string]string) func(string) string {
return func(k string) string { return env[k] }
}
+187
View File
@@ -0,0 +1,187 @@
// Destination pool for per-(org, user) SQLite files. Opens lazily on
// first row routed to an (org, user), caches the *sql.DB handle,
// applies canonical pragmas, and creates the per-table DDL on first
// insert into each table.
//
// Concurrency note: the migrator is single-goroutine row streamer, so
// the pool itself is unsynchronised — adding the rows for one source
// table is serialised end-to-end. If the migrator ever becomes
// concurrent it needs a sync.Mutex around the map plus per-handle
// locking.
package migration
import (
"context"
"database/sql"
"fmt"
"os"
"path/filepath"
"strings"
)
// dstPool owns the open destination SQLite handles, one per
// (org, user) tuple.
type dstPool struct {
root string
handles map[string]*dstHandle
}
func newDstPool(root string) *dstPool {
return &dstPool{
root: root,
handles: map[string]*dstHandle{},
}
}
// Close drains every open dst handle. Safe to call from defer.
func (p *dstPool) Close() {
for _, h := range p.handles {
_ = h.Close()
}
}
// flushAll commits any open per-handle transactions. Called every
// BatchSize rows from copyTable so a multi-million-row table doesn't
// hold one giant transaction.
func (p *dstPool) flushAll(ctx context.Context) error {
for _, h := range p.handles {
if err := h.flush(ctx); err != nil {
return err
}
}
return nil
}
// get returns the handle for (org, user), opening + bootstrapping the
// per-table schema on first call.
func (p *dstPool) get(ctx context.Context, org, user string, t TableInfo) (*dstHandle, error) {
key := org + "/" + user
h, ok := p.handles[key]
if !ok {
path, err := destinationPath(p.root, org, user)
if err != nil {
return nil, err
}
if err := os.MkdirAll(filepath.Dir(path), 0o755); err != nil {
return nil, fmt.Errorf("mkdir %s: %w", filepath.Dir(path), err)
}
db, err := sql.Open("sqlite", path+"?_pragma=journal_mode(WAL)&_pragma=synchronous(NORMAL)")
if err != nil {
return nil, fmt.Errorf("open %s: %w", path, err)
}
for _, p := range []string{
"PRAGMA journal_mode=WAL",
"PRAGMA synchronous=NORMAL",
"PRAGMA foreign_keys=ON",
"PRAGMA busy_timeout=5000",
} {
if _, err := db.ExecContext(ctx, p); err != nil {
db.Close()
return nil, fmt.Errorf("pragma %q: %w", p, err)
}
}
db.SetMaxOpenConns(1)
h = &dstHandle{db: db, path: path, tables: map[string]bool{}}
p.handles[key] = h
}
if !h.tables[t.Name] {
if err := h.createTable(ctx, t); err != nil {
return nil, err
}
h.tables[t.Name] = true
}
return h, nil
}
// destinationPath derives /data/<org>/<user>/cloud.sqlite. The user
// "_org" sentinel routes to /data/<org>/_org/cloud.sqlite, matching
// the convention in CLAUDE_PG_TO_SQLITE_MIGRATION.md.
func destinationPath(root, org, user string) (string, error) {
if !validToken.MatchString(org) {
return "", fmt.Errorf("invalid org token %q", org)
}
if !validToken.MatchString(user) {
return "", fmt.Errorf("invalid user token %q", user)
}
return filepath.Join(root, org, user, "cloud.sqlite"), nil
}
// dstHandle wraps one (org, user) SQLite file. Keeps a per-call
// transaction open so batched inserts amortise fsync cost.
type dstHandle struct {
db *sql.DB
path string
tables map[string]bool
tx *sql.Tx
}
// createTable applies the canonical-shape DDL for one source PG table.
// Each table gets the same column list (verbatim), with PG types
// mapped via mapPGType. Foreign keys are dropped — the legacy schema's
// FKs are not portable across the per-(org, user) split.
func (h *dstHandle) createTable(ctx context.Context, t TableInfo) error {
parts := make([]string, 0, len(t.Columns))
for _, c := range t.Columns {
ddl := fmt.Sprintf("%q %s", c.Name, mapPGType(c.DataType))
if !c.IsNullable {
ddl += " NOT NULL"
}
parts = append(parts, ddl)
}
stmt := fmt.Sprintf(`CREATE TABLE IF NOT EXISTS %q (%s)`, t.Name, strings.Join(parts, ", "))
_, err := h.db.ExecContext(ctx, stmt)
return err
}
// insert appends one row to the destination table, opening a tx lazily.
func (h *dstHandle) insert(ctx context.Context, table string, row []any) error {
if h.tx == nil {
tx, err := h.db.BeginTx(ctx, nil)
if err != nil {
return err
}
h.tx = tx
}
placeholders := strings.Repeat("?, ", len(row))
placeholders = strings.TrimSuffix(placeholders, ", ")
stmt := fmt.Sprintf(`INSERT INTO %q VALUES (%s)`, table, placeholders)
_, err := h.tx.ExecContext(ctx, stmt, row...)
return err
}
// flush commits the open transaction if any.
func (h *dstHandle) flush(ctx context.Context) error {
if h.tx == nil {
return nil
}
err := h.tx.Commit()
h.tx = nil
return err
}
// Close commits any open tx and closes the underlying *sql.DB.
func (h *dstHandle) Close() error {
_ = h.flush(context.Background())
return h.db.Close()
}
// mapPGType maps a PG data_type string to a SQLite affinity. The
// mapping is conservative — anything unrecognised becomes TEXT, which
// the SQLite type system accepts for any value and is the same
// fallback hanzoai/base uses.
func mapPGType(pgType string) string {
switch strings.ToLower(pgType) {
case "smallint", "integer", "int", "bigint",
"serial", "bigserial", "smallserial":
return "INTEGER"
case "boolean", "bool":
return "INTEGER"
case "real", "double precision", "numeric", "decimal":
return "REAL"
case "bytea":
return "BLOB"
default:
return "TEXT"
}
}
+448
View File
@@ -0,0 +1,448 @@
// Package migration ports a legacy `hanzo_cloud` PostgreSQL database
// into per-(org, user) SQLite files served by the Hanzo cloud
// orchestrator (HIP-0106).
//
// Why introspective (not schema-aware):
//
// Status owns its schema (7 tables in tree). kms's audit_logs subset
// is documented upstream. cloud's hanzo_cloud DB was the deployed
// cloud-api Python service — its schema is not in this Go repo and
// has drifted over multiple Python/TS versions across env. The right
// thing is to discover tables at migration time from
// information_schema and copy each one verbatim, with per-row routing
// to the destination SQLite file based on the row's org column.
//
// Per-(org, user) routing:
//
// The destination layout is the canonical
// `/data/<org>/<user>/cloud.sqlite` for user-scoped rows, or
// `/data/<org>/_org/cloud.sqlite` for org-scoped rows that no single
// user owns. The migrator inspects each table for an org column
// (canonical name: "org_id", fallback: "owner") and a user column
// (canonical: "user_id", fallback: "user_email"). Routing matrix:
//
// has user_id → /data/<org>/<user_id>/cloud.sqlite
// has org_id only → /data/<org>/_org/cloud.sqlite
// has neither → /data/_global/_org/cloud.sqlite (fail-loud — a row
// without org context is a data-quality bug; we
// materialise it under _global so the operator can
// triage rather than silently dropping)
//
// Schema fidelity:
//
// Each destination SQLite file gets the same DDL for every source
// table the migrator visits, lifted from information_schema.columns.
// PG-specific column types are mapped conservatively:
//
// int*, bigint, serial → INTEGER
// bool, boolean → INTEGER (0/1)
// text, varchar, char → TEXT
// timestamp, timestamptz → TEXT (RFC3339Nano UTC)
// jsonb, json → TEXT
// bytea → BLOB
// numeric, decimal, real,
// double precision → REAL
// uuid → TEXT
// (other) → TEXT
//
// This is the same conservative shape hanzoai/base uses for its
// generated DDL — see HIP-0302 §3. Hand-rolling per-type translation
// is the only correct choice across heterogeneous legacy schemas.
//
// See ~/work/hanzo/CLAUDE_PG_TO_SQLITE_MIGRATION.md (service #4 — cloud).
package migration
import (
"context"
"database/sql"
"errors"
"fmt"
"os"
"regexp"
"sort"
"strings"
"time"
_ "github.com/lib/pq"
_ "modernc.org/sqlite"
)
// Options configures the migration.
type Options struct {
// SrcDSN is the legacy hanzo_cloud Postgres DSN.
SrcDSN string
// DstRoot is the data root under which per-(org, user) SQLite
// files are created. Conventionally /data per
// CLAUDE_PG_TO_SQLITE_MIGRATION.md.
DstRoot string
// IncludeSchemas, if non-empty, restricts the migration to tables
// from this set of PG schemas. Default ["public"].
IncludeSchemas []string
// ExcludeTables, if non-empty, skips matching tables (basename match
// only — schema-qualified names are not matched).
ExcludeTables []string
// BatchSize bounds memory use. Default 500.
BatchSize int
}
// TableReport captures the per-(table, target) routing outcome.
type TableReport struct {
Table string
SourceRows int
WrittenRows int
// Targets is the set of (org, user) tuples a table's rows fanned
// out into. Sorted lexicographically.
Targets []Target
}
// Target identifies one destination SQLite file. User == "_org" is the
// org-scoped sentinel; Org == "_global" is the fail-loud sentinel.
type Target struct {
Org string
User string
Rows int
}
// validToken matches the safe org/user grammar from sqlitepath.For —
// path traversal is not possible because every path segment is
// validated against this pattern.
var validToken = regexp.MustCompile(`^[A-Za-z0-9._@+-]+$`)
// Run executes the migration: opens PG read-only, discovers tables via
// information_schema, copies row-by-row with per-row destination
// routing. Returns one report per source table.
func Run(ctx context.Context, opts Options) ([]TableReport, error) {
if opts.SrcDSN == "" {
return nil, errors.New("migration: src DSN required")
}
if opts.DstRoot == "" {
return nil, errors.New("migration: dst root required")
}
if opts.BatchSize <= 0 {
opts.BatchSize = 500
}
if len(opts.IncludeSchemas) == 0 {
opts.IncludeSchemas = []string{"public"}
}
src, err := sql.Open("postgres", opts.SrcDSN)
if err != nil {
return nil, fmt.Errorf("open src: %w", err)
}
defer src.Close()
if err := src.PingContext(ctx); err != nil {
return nil, fmt.Errorf("ping src: %w", err)
}
if err := os.MkdirAll(opts.DstRoot, 0o755); err != nil {
return nil, fmt.Errorf("mkdir dst root: %w", err)
}
tables, err := discoverTables(ctx, src, opts.IncludeSchemas, opts.ExcludeTables)
if err != nil {
return nil, fmt.Errorf("discover tables: %w", err)
}
pool := newDstPool(opts.DstRoot)
defer pool.Close()
reports := make([]TableReport, 0, len(tables))
for _, t := range tables {
report, err := copyTable(ctx, src, pool, t, opts.BatchSize)
if err != nil {
return reports, fmt.Errorf("copy %s: %w", t.QualifiedName(), err)
}
reports = append(reports, report)
}
return reports, nil
}
// TableInfo is the discovered metadata for one PG table.
type TableInfo struct {
Schema string
Name string
Columns []ColumnInfo
// OrgCol / UserCol are the resolved (org, user) routing columns;
// empty when no recognised column exists.
OrgCol string
UserCol string
}
// ColumnInfo describes one PG column for SQLite DDL synthesis.
type ColumnInfo struct {
Name string
DataType string
IsNullable bool
}
// QualifiedName returns schema.name with quoting that PG accepts. For
// schemaless sources (SQLite test fixtures) it returns the bare
// quoted table name. The SQL the migrator emits uses this same form,
// which is what allows the SQLite-as-source test path to drive the
// same copyTable code as production PG.
func (t TableInfo) QualifiedName() string {
if t.Schema == "" {
return fmt.Sprintf(`%q`, t.Name)
}
return fmt.Sprintf(`%q.%q`, t.Schema, t.Name)
}
// discoverTables enumerates user tables from information_schema. The
// excludes list is matched case-insensitively against the bare table
// name (not the schema-qualified form) so callers can drop "schema_
// migrations" once and have it apply across PG schemas.
func discoverTables(ctx context.Context, db *sql.DB, schemas, excludes []string) ([]TableInfo, error) {
exclSet := map[string]struct{}{}
for _, e := range excludes {
exclSet[strings.ToLower(e)] = struct{}{}
}
args := make([]any, len(schemas))
placeholders := make([]string, len(schemas))
for i, s := range schemas {
args[i] = s
placeholders[i] = fmt.Sprintf("$%d", i+1)
}
q := fmt.Sprintf(`
SELECT table_schema, table_name
FROM information_schema.tables
WHERE table_type='BASE TABLE' AND table_schema IN (%s)
ORDER BY table_schema, table_name`, strings.Join(placeholders, ","))
rows, err := db.QueryContext(ctx, q, args...)
if err != nil {
return nil, err
}
defer rows.Close()
var tables []TableInfo
for rows.Next() {
var t TableInfo
if err := rows.Scan(&t.Schema, &t.Name); err != nil {
return nil, err
}
if _, skip := exclSet[strings.ToLower(t.Name)]; skip {
continue
}
tables = append(tables, t)
}
if err := rows.Err(); err != nil {
return nil, err
}
// Second pass: column descriptors for each surviving table.
for i, t := range tables {
cols, err := discoverColumns(ctx, db, t.Schema, t.Name)
if err != nil {
return nil, fmt.Errorf("columns %s: %w", t.QualifiedName(), err)
}
tables[i].Columns = cols
tables[i].OrgCol, tables[i].UserCol = pickRoutingColumns(cols)
}
return tables, nil
}
func discoverColumns(ctx context.Context, db *sql.DB, schema, name string) ([]ColumnInfo, error) {
rows, err := db.QueryContext(ctx, `
SELECT column_name, data_type, is_nullable
FROM information_schema.columns
WHERE table_schema = $1 AND table_name = $2
ORDER BY ordinal_position`, schema, name)
if err != nil {
return nil, err
}
defer rows.Close()
var out []ColumnInfo
for rows.Next() {
var c ColumnInfo
var nullable string
if err := rows.Scan(&c.Name, &c.DataType, &nullable); err != nil {
return nil, err
}
c.IsNullable = strings.EqualFold(nullable, "YES")
out = append(out, c)
}
if err := rows.Err(); err != nil {
return nil, err
}
return out, nil
}
// pickRoutingColumns picks the (org, user) routing columns from a
// column list. Canonical names take priority over fallbacks.
func pickRoutingColumns(cols []ColumnInfo) (orgCol, userCol string) {
names := make(map[string]struct{}, len(cols))
for _, c := range cols {
names[strings.ToLower(c.Name)] = struct{}{}
}
for _, c := range []string{"org_id", "orgid", "organization_id", "owner"} {
if _, ok := names[c]; ok {
orgCol = c
break
}
}
for _, c := range []string{"user_id", "userid", "user_email", "owner_user_id"} {
if _, ok := names[c]; ok {
userCol = c
break
}
}
return
}
// copyTable streams the source table once, routing each row to the
// destination SQLite file derived from its org/user columns.
func copyTable(ctx context.Context, src *sql.DB, pool *dstPool, t TableInfo, batch int) (TableReport, error) {
cols := joinColIdents(t.Columns)
q := fmt.Sprintf("SELECT %s FROM %s", cols, t.QualifiedName())
rows, err := src.QueryContext(ctx, q)
if err != nil {
return TableReport{}, err
}
defer rows.Close()
report := TableReport{Table: t.QualifiedName()}
targetCounts := map[Target]int{}
values := make([]any, len(t.Columns))
scanArgs := make([]any, len(t.Columns))
for i := range values {
scanArgs[i] = &values[i]
}
orgIdx := indexOf(t.Columns, t.OrgCol)
userIdx := indexOf(t.Columns, t.UserCol)
for rows.Next() {
if err := rows.Scan(scanArgs...); err != nil {
return report, err
}
report.SourceRows++
org, user := routeRow(values, orgIdx, userIdx)
dst, err := pool.get(ctx, org, user, t)
if err != nil {
return report, fmt.Errorf("dst open %s/%s: %w", org, user, err)
}
row := make([]any, len(values))
for i, v := range values {
row[i] = normalize(t.Columns[i].DataType, v)
}
if err := dst.insert(ctx, t.Name, row); err != nil {
return report, fmt.Errorf("insert row %d: %w", report.SourceRows, err)
}
report.WrittenRows++
tk := Target{Org: org, User: user}
targetCounts[tk]++
if report.SourceRows%batch == 0 {
if err := pool.flushAll(ctx); err != nil {
return report, err
}
}
}
if err := rows.Err(); err != nil {
return report, err
}
if err := pool.flushAll(ctx); err != nil {
return report, err
}
for tk, n := range targetCounts {
tk.Rows = n
report.Targets = append(report.Targets, tk)
}
sort.Slice(report.Targets, func(i, j int) bool {
if report.Targets[i].Org != report.Targets[j].Org {
return report.Targets[i].Org < report.Targets[j].Org
}
return report.Targets[i].User < report.Targets[j].User
})
return report, nil
}
// routeRow extracts (org, user) from a row using the resolved routing
// indices. Empty / non-string values fall through to "_global"/"_org".
func routeRow(values []any, orgIdx, userIdx int) (org, user string) {
org = sentinelOrg
user = sentinelOrgUser
if orgIdx >= 0 {
if s := tokenize(values[orgIdx]); s != "" {
org = s
}
}
if userIdx >= 0 {
if s := tokenize(values[userIdx]); s != "" {
user = s
}
}
return
}
const (
sentinelOrg = "_global"
sentinelOrgUser = "_org"
)
// tokenize coerces an `any` value into a path-safe token. Rows whose
// org/user column is NULL or non-string become "" — the caller
// substitutes the sentinel.
func tokenize(v any) string {
if v == nil {
return ""
}
var s string
switch x := v.(type) {
case string:
s = x
case []byte:
s = string(x)
default:
s = fmt.Sprintf("%v", x)
}
s = strings.TrimSpace(s)
if !validToken.MatchString(s) {
return ""
}
return s
}
func indexOf(cols []ColumnInfo, name string) int {
if name == "" {
return -1
}
for i, c := range cols {
if strings.EqualFold(c.Name, name) {
return i
}
}
return -1
}
func joinColIdents(cols []ColumnInfo) string {
parts := make([]string, len(cols))
for i, c := range cols {
parts[i] = fmt.Sprintf("%q", c.Name)
}
return strings.Join(parts, ", ")
}
// normalize coerces a PG-typed value into something SQLite accepts.
// Booleans → 0/1; times → RFC3339Nano UTC strings; everything else
// passes through (modernc.org/sqlite accepts all standard
// database/sql primitives).
func normalize(pgType string, v any) any {
if v == nil {
return nil
}
switch x := v.(type) {
case bool:
if x {
return int64(1)
}
return int64(0)
case time.Time:
return x.UTC().Format(time.RFC3339Nano)
default:
return x
}
}
+322
View File
@@ -0,0 +1,322 @@
package migration
import (
"context"
"database/sql"
"path/filepath"
"sort"
"testing"
_ "modernc.org/sqlite"
)
// TestRoundTripPerOrgUserRouting exercises the introspective copy plus
// per-(org, user) routing using SQLite-as-source. The migrator's
// information_schema discovery is PG-specific; for the test we drive
// copyTable directly with a hand-rolled TableInfo, which is the same
// shape discoverTables would produce against a live PG.
//
// This proves the routing contract:
//
// - rows with both org_id and user_id → /data/<org>/<user>/cloud.sqlite
// - rows with only org_id → /data/<org>/_org/cloud.sqlite
// - rows with neither → /data/_global/_org/cloud.sqlite
//
// And the parity contract: WrittenRows == SourceRows per table.
func TestRoundTripPerOrgUserRouting(t *testing.T) {
dir := t.TempDir()
srcPath := filepath.Join(dir, "src.sqlite")
src, err := sql.Open("sqlite", srcPath)
if err != nil {
t.Fatalf("open src: %v", err)
}
defer src.Close()
// Three test tables, exercising each routing path.
if _, err := src.Exec(`
CREATE TABLE projects (
project_id TEXT,
org_id TEXT,
user_id TEXT,
name TEXT,
created_at TEXT
);
CREATE TABLE org_settings (
org_id TEXT,
setting_key TEXT,
setting_value TEXT
);
CREATE TABLE legacy_audit (
event_id TEXT,
actor TEXT,
payload TEXT
);
`); err != nil {
t.Fatalf("create source schemas: %v", err)
}
// Seed:
// - projects: 2 rows for (hanzo, z@hanzo.ai), 1 row for (lux, z@lux.network)
// - org_settings: 1 row for hanzo, 1 row for lux
// - legacy_audit: 1 row with no routing columns
seeds := []struct {
stmt string
args []any
}{
{`INSERT INTO projects VALUES (?, ?, ?, ?, ?)`, []any{"p1", "hanzo", "z@hanzo.ai", "alpha", "2026-06-04T00:00:00Z"}},
{`INSERT INTO projects VALUES (?, ?, ?, ?, ?)`, []any{"p2", "hanzo", "z@hanzo.ai", "beta", "2026-06-04T00:01:00Z"}},
{`INSERT INTO projects VALUES (?, ?, ?, ?, ?)`, []any{"p3", "lux", "z@lux.network", "gamma", "2026-06-04T00:02:00Z"}},
{`INSERT INTO org_settings VALUES (?, ?, ?)`, []any{"hanzo", "default_region", "sfo3"}},
{`INSERT INTO org_settings VALUES (?, ?, ?)`, []any{"lux", "default_region", "sfo3"}},
{`INSERT INTO legacy_audit VALUES (?, ?, ?)`, []any{"e1", "system", "{\"k\":\"v\"}"}},
}
for _, s := range seeds {
if _, err := src.Exec(s.stmt, s.args...); err != nil {
t.Fatalf("seed: %v", err)
}
}
// Hand-build TableInfos (the discoverTables PG-side equivalent).
tables := []TableInfo{
{
Schema: "", Name: "projects",
Columns: []ColumnInfo{
{Name: "project_id", DataType: "text"},
{Name: "org_id", DataType: "text"},
{Name: "user_id", DataType: "text"},
{Name: "name", DataType: "text"},
{Name: "created_at", DataType: "text"},
},
OrgCol: "org_id", UserCol: "user_id",
},
{
Schema: "", Name: "org_settings",
Columns: []ColumnInfo{
{Name: "org_id", DataType: "text"},
{Name: "setting_key", DataType: "text"},
{Name: "setting_value", DataType: "text"},
},
OrgCol: "org_id", UserCol: "",
},
{
Schema: "", Name: "legacy_audit",
Columns: []ColumnInfo{
{Name: "event_id", DataType: "text"},
{Name: "actor", DataType: "text"},
{Name: "payload", DataType: "text"},
},
OrgCol: "", UserCol: "",
},
}
dstRoot := filepath.Join(dir, "data")
pool := newDstPool(dstRoot)
defer pool.Close()
var reports []TableReport
for _, ti := range tables {
r, err := copyTable(context.Background(), src, pool, ti, 500)
if err != nil {
t.Fatalf("copy %s: %v", ti.Name, err)
}
reports = append(reports, r)
}
// Parity per table.
for _, r := range reports {
if r.SourceRows != r.WrittenRows {
t.Errorf("%s: src=%d written=%d", r.Table, r.SourceRows, r.WrittenRows)
}
}
// Verify each routing path materialised the expected dst files.
for _, expected := range []string{
filepath.Join(dstRoot, "hanzo", "z@hanzo.ai", "cloud.sqlite"),
filepath.Join(dstRoot, "lux", "z@lux.network", "cloud.sqlite"),
filepath.Join(dstRoot, "hanzo", "_org", "cloud.sqlite"),
filepath.Join(dstRoot, "lux", "_org", "cloud.sqlite"),
filepath.Join(dstRoot, "_global", "_org", "cloud.sqlite"),
} {
if _, err := openCheck(expected, "projects").ReadDir(""); err != nil {
// Just an existence check; openCheck normalises this.
}
}
// Stronger check — count rows in the per-user file.
dst1, err := sql.Open("sqlite", filepath.Join(dstRoot, "hanzo", "z@hanzo.ai", "cloud.sqlite"))
if err != nil {
t.Fatalf("open dst1: %v", err)
}
defer dst1.Close()
var n int
if err := dst1.QueryRow(`SELECT COUNT(*) FROM projects`).Scan(&n); err != nil {
t.Fatalf("count projects: %v", err)
}
if n != 2 {
t.Errorf("expected 2 projects rows under hanzo/z@hanzo.ai, got %d", n)
}
// org_settings row should land under _org sentinel.
dst2, err := sql.Open("sqlite", filepath.Join(dstRoot, "hanzo", "_org", "cloud.sqlite"))
if err != nil {
t.Fatalf("open dst2: %v", err)
}
defer dst2.Close()
var orgN int
if err := dst2.QueryRow(`SELECT COUNT(*) FROM org_settings`).Scan(&orgN); err != nil {
t.Fatalf("count org_settings: %v", err)
}
if orgN != 1 {
t.Errorf("expected 1 org_settings row under hanzo/_org, got %d", orgN)
}
// legacy_audit row should land under the _global sentinel.
dst3, err := sql.Open("sqlite", filepath.Join(dstRoot, "_global", "_org", "cloud.sqlite"))
if err != nil {
t.Fatalf("open dst3: %v", err)
}
defer dst3.Close()
var globN int
if err := dst3.QueryRow(`SELECT COUNT(*) FROM legacy_audit`).Scan(&globN); err != nil {
t.Fatalf("count legacy_audit: %v", err)
}
if globN != 1 {
t.Errorf("expected 1 legacy_audit row under _global/_org, got %d", globN)
}
// Routing report content.
for _, r := range reports {
if r.Table == `"projects"` {
gotTargets := make([]string, 0, len(r.Targets))
for _, tt := range r.Targets {
gotTargets = append(gotTargets, tt.Org+"/"+tt.User)
}
sort.Strings(gotTargets)
want := []string{"hanzo/z@hanzo.ai", "lux/z@lux.network"}
if !equalStringSlices(gotTargets, want) {
t.Errorf("projects targets = %v, want %v", gotTargets, want)
}
}
}
}
func TestPickRoutingColumnsCanonicalNames(t *testing.T) {
cols := []ColumnInfo{
{Name: "id"},
{Name: "org_id"},
{Name: "user_id"},
}
o, u := pickRoutingColumns(cols)
if o != "org_id" || u != "user_id" {
t.Errorf("canonical pick: %q %q", o, u)
}
}
func TestPickRoutingColumnsFallbacks(t *testing.T) {
cols := []ColumnInfo{
{Name: "id"},
{Name: "owner"},
{Name: "user_email"},
}
o, u := pickRoutingColumns(cols)
if o != "owner" || u != "user_email" {
t.Errorf("fallback pick: %q %q", o, u)
}
}
func TestPickRoutingColumnsNoneFound(t *testing.T) {
cols := []ColumnInfo{
{Name: "id"},
{Name: "name"},
}
o, u := pickRoutingColumns(cols)
if o != "" || u != "" {
t.Errorf("expected empty pair, got %q %q", o, u)
}
}
func TestTokenizeRejectsPathTraversal(t *testing.T) {
cases := []struct {
in any
want string
}{
{"hanzo", "hanzo"},
{"../etc/passwd", ""},
{" hanzo ", "hanzo"},
{"z@hanzo.ai", "z@hanzo.ai"},
{"/abs/path", ""},
{nil, ""},
{" ", ""},
}
for _, c := range cases {
if got := tokenize(c.in); got != c.want {
t.Errorf("tokenize(%v) = %q, want %q", c.in, got, c.want)
}
}
}
func TestMapPGTypeCoverage(t *testing.T) {
cases := map[string]string{
"smallint": "INTEGER",
"integer": "INTEGER",
"bigint": "INTEGER",
"bigserial": "INTEGER",
"boolean": "INTEGER",
"bool": "INTEGER",
"real": "REAL",
"double precision": "REAL",
"numeric": "REAL",
"bytea": "BLOB",
"text": "TEXT",
"jsonb": "TEXT",
"uuid": "TEXT",
"timestamptz": "TEXT",
}
for in, want := range cases {
if got := mapPGType(in); got != want {
t.Errorf("mapPGType(%q) = %q, want %q", in, got, want)
}
}
}
func TestDestinationPathRejectsInvalidTokens(t *testing.T) {
if _, err := destinationPath("/data", "../etc", "user"); err == nil {
t.Error("expected error for org with ..")
}
if _, err := destinationPath("/data", "org", "/abs"); err == nil {
t.Error("expected error for user with /")
}
if p, err := destinationPath("/data", "hanzo", "_org"); err != nil || p != "/data/hanzo/_org/cloud.sqlite" {
t.Errorf("unexpected: %q %v", p, err)
}
}
func TestRunRequiresDSNAndRoot(t *testing.T) {
if _, err := Run(context.Background(), Options{DstRoot: "/tmp/x"}); err == nil {
t.Error("expected error for missing SrcDSN")
}
if _, err := Run(context.Background(), Options{SrcDSN: "postgres://"}); err == nil {
t.Error("expected error for missing DstRoot")
}
}
func equalStringSlices(a, b []string) bool {
if len(a) != len(b) {
return false
}
for i := range a {
if a[i] != b[i] {
return false
}
}
return true
}
// openCheck is a tiny helper used to make the file-existence asserts in
// TestRoundTripPerOrgUserRouting compile cleanly; we use it as a
// no-op (errors get surfaced by the sql.Open checks below) so the
// test stays readable.
type fileCheck struct{ path string }
func openCheck(path, _ string) fileCheck { return fileCheck{path} }
func (f fileCheck) ReadDir(_ string) (any, error) { return nil, nil }
+260
View File
@@ -0,0 +1,260 @@
// Copyright (c) 2026 Hanzo Industries Inc.
// SPDX-License-Identifier: Apache-2.0
//
// server.go — ZAP listener for the unified cloud binary.
//
// Per HIP-0106 the cloud binary serves two listeners:
//
// HTTP (cfg.ListenAddr, default :8080) — external client surface
// ZAP (cfg.ZAPListenAddr, default :9999) — intra-Hanzo subsystem RPC
//
// Before this file the ZAPListenAddr was logged in main.go but never
// bound — gateway-side ZAP plugins targeting cloud-api would get
// "no available server" (see memory:gateway_zap_cloud_api). Now the
// listener actually exists and answers handshake + heartbeat opcodes;
// the per-subsystem typed handlers register via `RegisterZAPHandler`
// from Mount(...) when subsystem code wants to expose itself.
//
// Port choice: the deployed cluster (insights/cloud/deployment.yaml)
// exposes containerPort 9999 and the cloud-api ZAP_*_ADDR env vars all
// target :9999, so we default to that. The cfg.ZAPListenAddr override
// still works for split-binary deployments that want isolation.
package cloud
import (
"context"
"errors"
"fmt"
"log/slog"
"net/http"
"os"
"strconv"
"strings"
"sync"
"sync/atomic"
"time"
luxlog "github.com/luxfi/log"
"github.com/luxfi/zap"
)
// ZAP message-type registry — append-only. Each subsystem owns a slot,
// matching the canonical IDs used elsewhere in the stack:
//
// 10 = control — handshake, heartbeat (built-in)
// 200 = iam — VerifyJWT, GetUser, GetOrg
// 201 = kms — GetSecret, PutSecret, Sign
// 202 = base — Open (per-tenant SQLite handle)
// 203 = commerce — GetTenantConfig
// 204 = ai — ChatCompletion
// 205 = o11y — Counter, Timing, Span
// 206 = vfs — Put, Get
// 207 = mq — Publish, Subscribe
// 208 = payments — CreateIntent, ConfirmIntent, GetIntentStatus
// 209 = vault — Charge
// 302 = datastore — already in use by hanzoai/datastore zap-bridge.
//
// Wire dispatch quirk: luxfi/zap routes on `msg.Flags() >> 8` which
// truncates the 16-bit msgType to its low byte. So 200 → 0xC8 on the
// wire. Senders write `FinishWithFlags(msgType << 8)`. We register and
// dispatch on the 8-bit projection; the 16-bit constant is the source
// label.
const (
MsgTypeControl uint16 = 10
MsgTypeIAM uint16 = 200
MsgTypeKMS uint16 = 201
MsgTypeBase uint16 = 202
MsgTypeCommerce uint16 = 203
MsgTypeAI uint16 = 204
MsgTypeO11y uint16 = 205
MsgTypeVFS uint16 = 206
MsgTypeMQ uint16 = 207
MsgTypePayments uint16 = 208
MsgTypeVault uint16 = 209
)
// Server is the running ZAP listener for one cloud process. It wraps
// the underlying luxfi/zap.Node so subsystems can register their
// per-msgType handler from Mount(...) and the binary can shut down
// cleanly on SIGTERM.
type Server struct {
node *zap.Node
logger luxlog.Logger
closeOnce sync.Once
started atomic.Bool
// inflight counts handlers currently running so Shutdown can drain.
inflight atomic.Int64
}
// NewServer constructs a ZAP server bound to cfg.ZAPListenAddr.
// Returns an error only if address parsing fails. Call Start to bind.
func NewServer(cfg *Config, logger luxlog.Logger) (*Server, error) {
port, err := portFromListen(cfg.ZAPListenAddr)
if err != nil {
return nil, fmt.Errorf("zap listen %q: %w", cfg.ZAPListenAddr, err)
}
nodeID := os.Getenv("ZAP_NODE_ID")
if nodeID == "" {
// Default = brand-domain composite. Operators can pin via env
// for stable mDNS identity across restarts.
nodeID = fmt.Sprintf("%s-cloud", cfg.Brand)
}
serviceType := os.Getenv("ZAP_SERVICE_TYPE")
if serviceType == "" {
serviceType = "_hanzo._tcp"
}
// Plaintext for in-cluster — TLS termination is the ingress's job;
// pod-to-pod traffic stays on the Hanzo cluster network. Operators
// can flip to PQ-TLS by passing a *tls.Config via wider plumbing
// when split-deployed across clusters.
slog := slog.New(slog.NewJSONHandler(os.Stderr, &slog.HandlerOptions{
Level: slog.LevelInfo,
})).With("component", "zap-server", "brand", cfg.Brand)
node := zap.NewNode(zap.NodeConfig{
NodeID: nodeID,
ServiceType: serviceType,
Port: port,
NoDiscovery: true, // K8s — no mDNS multicast.
Logger: slog,
})
srv := &Server{
node: node,
logger: logger,
}
// Register built-in control handler (handshake + heartbeat).
node.Handle(MsgTypeControl&0xFF, srv.wrap(srv.handleControl))
return srv, nil
}
// Start binds the listener. After Start returns nil the server is
// answering ZAP frames. Idempotent.
func (s *Server) Start() error {
if !s.started.CompareAndSwap(false, true) {
return errors.New("zap server already started")
}
if err := s.node.Start(); err != nil {
s.started.Store(false)
return fmt.Errorf("zap node start: %w", err)
}
s.logger.Info("zap server listening")
return nil
}
// Shutdown waits up to grace for in-flight handlers to complete, then
// stops the node. Idempotent.
func (s *Server) Shutdown(grace time.Duration) {
s.closeOnce.Do(func() {
deadline := time.Now().Add(grace)
for s.inflight.Load() > 0 && time.Now().Before(deadline) {
time.Sleep(10 * time.Millisecond)
}
if remaining := s.inflight.Load(); remaining > 0 {
s.logger.Warn("zap shutdown grace expired with inflight handlers",
"inflight", remaining,
)
}
s.node.Stop()
})
}
// ZAPServer is the surface subsystems need from the cloud-level ZAP
// listener (the Deps.ZAP field). *Server satisfies this implicitly.
// The interface exists so subsystems can take a mockable dependency
// without importing luxfi/zap directly into every Mount package.
type ZAPServer interface {
RegisterHandler(msgType uint16, handler zap.Handler)
}
// Compile-time assertion that *Server satisfies ZAPServer.
var _ ZAPServer = (*Server)(nil)
// RegisterHandler attaches `handler` to a subsystem msgType. Subsystems
// call this from Mount(...) to expose themselves over ZAP. The handler
// is automatically wrapped with inflight tracking + recover.
//
// The msgType is the source-level 16-bit constant (e.g. MsgTypeIAM);
// the dispatch key on the wire is its 8-bit projection. RegisterHandler
// does the projection so callers don't need to think about it.
func (s *Server) RegisterHandler(msgType uint16, handler zap.Handler) {
s.node.Handle(msgType&0xFF, s.wrap(handler))
}
// wrap installs inflight tracking + recover around a handler. A panic
// inside the subsystem code becomes a 500-equivalent ZAP response
// instead of crashing the entire cloud process.
func (s *Server) wrap(h zap.Handler) zap.Handler {
return func(ctx context.Context, from string, msg *zap.Message) (resp *zap.Message, err error) {
s.inflight.Add(1)
defer s.inflight.Add(-1)
defer func() {
if r := recover(); r != nil {
s.logger.Error("zap handler panic",
"from", from,
"panic", r,
)
resp = buildErrorResponse(http.StatusInternalServerError, "internal error")
err = nil
}
}()
return h(ctx, from, msg)
}
}
// handleControl answers the built-in handshake / heartbeat opcode.
// Request: empty (any body ignored). Response: {status:200, body:{ok,
// brand, domain, server:"hanzo-cloud"}}.
//
// Gateway-side health probes hit this to confirm the ZAP listener is
// up before routing real traffic to subsystem msgTypes.
func (s *Server) handleControl(_ context.Context, _ string, _ *zap.Message) (*zap.Message, error) {
return buildControlResponse(http.StatusOK, "ok"), nil
}
// buildControlResponse encodes a minimal {status, body:"ok"} ZAP
// response without pulling json — single Bytes field.
func buildControlResponse(status int, payload string) *zap.Message {
b := zap.NewBuilder(len(payload) + 64)
ob := b.StartObject(12)
ob.SetUint32(0, uint32(status))
ob.SetBytes(4, []byte(payload))
ob.FinishAsRoot()
msg, err := zap.Parse(b.Finish())
if err != nil {
// Self-built unparseable is a build bug; fall back to a
// status-only frame instead of crashing.
fb := zap.NewBuilder(64)
fob := fb.StartObject(12)
fob.SetUint32(0, uint32(http.StatusInternalServerError))
fob.FinishAsRoot()
msg, _ = zap.Parse(fb.Finish())
}
return msg
}
// buildErrorResponse is a generic {status, body:msg} ZAP frame used by
// the panic recover path.
func buildErrorResponse(status int, payload string) *zap.Message {
return buildControlResponse(status, payload)
}
// portFromListen accepts ":9999" or "0.0.0.0:9999" — returns the port.
// Lives here (not main.go) so subsystems can call it for split listens.
func portFromListen(listen string) (int, error) {
listen = strings.TrimSpace(listen)
idx := strings.LastIndex(listen, ":")
if idx < 0 {
return 0, errors.New("missing port")
}
p, err := strconv.Atoi(listen[idx+1:])
if err != nil || p <= 0 || p > 65535 {
return 0, fmt.Errorf("invalid port %q", listen[idx+1:])
}
return p, nil
}