Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
63 commits
Select commit Hold shift + click to select a range
34df1fd
feat(node): add per-IP write-surface rate brake and apply to write_ro…
beardthelion Jul 13, 2026
74e05be
feat(node): extend the per-IP write brake to the remaining write sinks
beardthelion Jul 13, 2026
6fded6e
test(node): adversarial TrustedProxy verification through the write b…
beardthelion Jul 13, 2026
e6324d2
feat(node): purge-spam admin subcommand for the empty-burst cleanup
beardthelion Jul 13, 2026
285d7c7
fix(review): make purge-spam empty-check reject git-discovery reads
beardthelion Jul 13, 2026
090019d
fix(review): normalization-consistent purge, brake helper, CLI + cove…
beardthelion Jul 13, 2026
dfd4f6c
test(review): close the reasoned-not-run gaps by execution
beardthelion Jul 13, 2026
0135419
fix(node): reject path-traversal repo names in purge-spam before remo…
beardthelion Jul 15, 2026
a0fcbb0
fix(node): delete child rows transactionally in delete_repo_by_id
beardthelion Jul 15, 2026
fde9cfe
fix(node): reap write_rate_limiter in the periodic cleanup loop
beardthelion Jul 15, 2026
15522d5
fix(node): hold the per-repo advisory lock across purge recheck+delete
beardthelion Jul 15, 2026
1fcca0d
fix(node): count purge-spam disk-removal failures separately from del…
beardthelion Jul 15, 2026
d9eebd2
fix(node): warn on unparseable rate-limit env vars instead of silentl…
beardthelion Jul 15, 2026
6325402
docs(node): document GITLAWB_IPFS_API/TIGRIS_BUCKET/METRICS_ADDR/SHUT…
beardthelion Jul 15, 2026
bfbe502
test(node): exercise the dry-run guard with a real on-disk candidate …
beardthelion Jul 15, 2026
cdb102e
style(node): cargo fmt for the #196 fix set
beardthelion Jul 15, 2026
4df79f2
fix(node): pin the writer's advisory-lock connection in RepoWriteGuard
beardthelion Jul 15, 2026
68c1f5c
refactor(node): introduce ObjectStore trait seam over TigrisClient
beardthelion Jul 15, 2026
3c1ceb8
fix(node): make purge-spam Tigris-authoritative and archive-deleting
beardthelion Jul 15, 2026
cf669bb
fix(review): don't hold/leak the pool connection in acquire_write
beardthelion Jul 15, 2026
dde5ea9
fix(node): make advisory-lock guards drop-safe and reorder acquire_write
beardthelion Jul 16, 2026
b94d440
fix(node): complete a fully-received push after client disconnect
beardthelion Jul 16, 2026
e4c4161
fix(node): serialize archive uploads under the per-repo advisory lock
beardthelion Jul 16, 2026
6ba698c
fix(node): let purge-spam reach repos that exist only as archives
beardthelion Jul 16, 2026
9f7757c
refactor(node): dedup limiter setup + write-brake test driver; fix .e…
beardthelion Jul 16, 2026
2a78524
docs(node): drop the .env.example shutdown-grace entry #196 added (#196)
beardthelion Jul 19, 2026
c4b337b
fix(node): give advisory-lock guards a dedicated pool and bound the r…
beardthelion Jul 19, 2026
4934646
fix(node): advertise a window-derived Retry-After on rate-limit 429s …
beardthelion Jul 19, 2026
0c279c9
fix(node): skip slug-scoped purge cascade when a mirror row shares th…
beardthelion Jul 19, 2026
86a8228
fix(node): fail closed classifying the purge target directory (#196)
beardthelion Jul 20, 2026
bf2a54e
fix(node): run the push completion tail in the disconnect-surviving t…
beardthelion Jul 20, 2026
c24b541
fix(node): tombstone bounties when their repo is purged (#196)
beardthelion Jul 20, 2026
3baa9ed
fix(node): serialize create_repo against the purge advisory lock (#196)
beardthelion Jul 20, 2026
9916bca
test(node): prove purge deletes at MAX_CONNECTIONS=1 with the split p…
beardthelion Jul 20, 2026
8f3d643
fix(node): fail the push when the durable upload times out, don't 200…
beardthelion Jul 20, 2026
d1e596e
fix(node): tombstone bounties under both owner forms on purge (#196)
beardthelion Jul 20, 2026
ce5dcc3
fix(node): fail closed on a symlink at the purge target (#196)
beardthelion Jul 20, 2026
7dc7be2
fix(node): retry-after on the push-advert 429, and create_repo locks …
beardthelion Jul 20, 2026
d2ba14e
fix(node): correct the create-pool and bounty-tombstone remediations …
beardthelion Jul 20, 2026
5a46ef6
fix(node): close the durable-upload data-loss class on every write pa…
beardthelion Jul 20, 2026
2fa9fa3
chore: merge main (iCaptcha PoW + gl retry tests) into feat/write-sin…
beardthelion Jul 21, 2026
16517f8
refactor(node): route the per-DID 429 through the shared too_many_req…
beardthelion Jul 21, 2026
ba572b3
fix(node): init's background upload waits out the creator's advisory …
beardthelion Jul 21, 2026
859240b
fix(node): roll back the local issue ref before unlock when the durab…
beardthelion Jul 21, 2026
c07435d
fix(node): fork publishes only after a durable upload, serialized on …
beardthelion Jul 21, 2026
2ad1c79
fix(node): read-path downloads publish under the purge lock, without …
beardthelion Jul 21, 2026
b2ca5a7
fix(node): bound every under-lock object-store call and dedup the upl…
beardthelion Jul 21, 2026
fa4322c
fix(node): harden the read-path download against cancellation, stale …
beardthelion Jul 21, 2026
c3d6e73
fix(node): keep the fork's unbounded work out of the target-lock span…
beardthelion Jul 21, 2026
03ef9b5
refactor(node): move read-path download coordination into a repo_stor…
beardthelion Jul 21, 2026
4408d27
fix(node): bound acquire_write's download and free the download-map e…
beardthelion Jul 21, 2026
a12f21a
fix(node): roll back the fork mirror and archive on late clone/insert…
beardthelion Jul 21, 2026
556aa31
fix(node): serialize repo purge cascade with mirror ingest via adviso…
beardthelion Jul 22, 2026
1d8c281
fix(node): roll back local ref on failed durable upload (close/merge/…
beardthelion Jul 22, 2026
1d0d3d2
fix(node): tie cancelled cold-download cleanup to blocking extraction
beardthelion Jul 22, 2026
03cd81e
chore(node): fmt + clippy cleanup for the #196 fixes
beardthelion Jul 22, 2026
9152178
fix(node): never let a failed ref snapshot become a delete-all rollba…
beardthelion Jul 22, 2026
296704f
fix(node): slug-lock every peer-ingest writer and drive the real inge…
beardthelion Jul 22, 2026
1e79ae5
fix(node): own cold-download cleanup in a spawned task so handler can…
beardthelion Jul 22, 2026
ce25bba
refactor(node): delegate issue ref helpers to the store ref primitives
beardthelion Jul 22, 2026
4329b2a
Merge origin/main into feat/write-sink-brake-coverage (reintegrate cu…
beardthelion Jul 22, 2026
d755180
fix(node): slug-lock arweave anchor writes; fail closed when the pre-…
beardthelion Jul 22, 2026
e6f4b2f
fix(node): close review residuals: coalesce cold downloads to one in-…
beardthelion Jul 22, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 30 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,16 @@ GITLAWB_PUBLIC_URL=https://your-node.example.com
# ── Server ────────────────────────────────────────────────────────────────
GITLAWB_HOST=0.0.0.0
GITLAWB_PORT=7545
# Optional address to bind a Prometheus /metrics exposition endpoint on (e.g.
# 127.0.0.1:9091). Leave empty (default) to disable. Bind to localhost or a
# private interface — the metrics endpoint is unauthenticated.
GITLAWB_METRICS_ADDR=

# ── Storage ───────────────────────────────────────────────────────────────
GITLAWB_REPOS_DIR=/data/repos
# Tigris (S3-compatible) bucket for repo storage. Leave empty (default) to
# disable Tigris and use local-only storage.
GITLAWB_TIGRIS_BUCKET=

# PostgreSQL connection URL. Required.
# When using the bundled docker-compose, this is wired automatically.
Expand All @@ -26,6 +33,12 @@ DATABASE_URL=postgresql://gitlawb:changeme@localhost:5432/gitlawb
# connections open lazily. Size against the DB server's max_connections,
# remembering admin tooling opens its own pool.
GITLAWB_DB_MAX_CONNECTIONS=20
# Maximum connections in the dedicated advisory-lock pool (separate from the
# pool above). Each in-flight repo write pins one connection here for its whole
# lifetime, so size it to peak concurrent distinct-repo writers — keeping it
# separate is what stops a push burst from starving request handlers. Keep
# (main pool + lock pool) within the DB server's max_connections.
GITLAWB_DB_LOCK_POOL_MAX_CONNECTIONS=32
Comment thread
coderabbitai[bot] marked this conversation as resolved.
# Seconds a request waits for a pool connection before failing with 503.
GITLAWB_DB_ACQUIRE_TIMEOUT_SECS=5
# Upper bound on each startup connect+migrate attempt, in seconds. Keep it
Expand All @@ -39,6 +52,9 @@ GITLAWB_DB_RETRY_INITIAL_SECS=5
GITLAWB_DB_RETRY_MAX_SECS=60

# ── IPFS pinning (Pinata) ─────────────────────────────────────────────────
# URL of a local IPFS/Kubo node HTTP API (e.g. http://127.0.0.1:5001). Leave
# empty (default) to disable local IPFS.
GITLAWB_IPFS_API=
# Get a JWT at https://app.pinata.cloud/developers/api-keys
GITLAWB_PINATA_JWT=
GITLAWB_PINATA_UPLOAD_URL=https://uploads.pinata.cloud/v3/files
Expand Down Expand Up @@ -127,6 +143,20 @@ GITLAWB_PUSH_RATE_LIMIT=600
# the client IP. 0 disables. Default 120.
GITLAWB_CREATE_RATE_LIMIT=120

# ── Write rate limiting (non-creation authenticated writes) ───────────────
# Max non-creation write requests per client IP per hour: issue/PR comments,
# labels, stars, merges, protect/unprotect, replicas, visibility, tasks,
# bounties, profile, and all GraphQL HTTP requests. The brake wraps the whole
# /graphql route, so queries and the playground GET consume this bucket too, not
# only mutations (GraphQL WebSocket subscriptions are excluded). Its own bucket,
# separate from the creation and push brakes. Uses GITLAWB_TRUSTED_PROXY to
# resolve the client IP.
# NOTE: this is a per-IP aggregate across ALL those write actions, so behind a
# shared NAT/egress IP (or with GITLAWB_TRUSTED_PROXY unset) many users collapse
# onto one bucket — raise this for automation-heavy or multi-user single-IP
# deployments. 0 disables. Default 600.
GITLAWB_WRITE_RATE_LIMIT=600

# ── Peer-sync rate limiting (per client IP, uses GITLAWB_TRUSTED_PROXY below) ─
# /api/v1/peers/announce and /api/v1/sync/notify accept unsigned requests from
# known peers and run at higher frequency, so a generous bucket. Separate from
Expand Down
12 changes: 7 additions & 5 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions crates/gitlawb-node/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ path = "src/main.rs"

[dependencies]
gitlawb-core = { path = "../gitlawb-core" }
async-trait = "0.1"
ed25519-dalek = { workspace = true }
base64 = { workspace = true }
tokio = { workspace = true }
Expand Down
Loading