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
f6a5b2f
feat(node): add per-IP write-surface rate brake and apply to write_ro…
Jul 13, 2026
7d680dc
feat(node): extend the per-IP write brake to the remaining write sinks
Jul 13, 2026
665b4ff
test(node): adversarial TrustedProxy verification through the write b…
Jul 13, 2026
69a98cf
feat(node): purge-spam admin subcommand for the empty-burst cleanup
Jul 13, 2026
13e59b4
fix(review): make purge-spam empty-check reject git-discovery reads
Jul 13, 2026
458fe50
fix(review): normalization-consistent purge, brake helper, CLI + cove…
Jul 13, 2026
27b4a2a
test(review): close the reasoned-not-run gaps by execution
Jul 13, 2026
98150db
fix(node): reject path-traversal repo names in purge-spam before remo…
beardthelion Jul 15, 2026
1688bdc
fix(node): delete child rows transactionally in delete_repo_by_id
beardthelion Jul 15, 2026
4943430
fix(node): reap write_rate_limiter in the periodic cleanup loop
beardthelion Jul 15, 2026
1305167
fix(node): hold the per-repo advisory lock across purge recheck+delete
beardthelion Jul 15, 2026
aab70ec
fix(node): count purge-spam disk-removal failures separately from del…
beardthelion Jul 15, 2026
cecca67
fix(node): warn on unparseable rate-limit env vars instead of silentl…
beardthelion Jul 15, 2026
f4d5bec
docs(node): document GITLAWB_IPFS_API/TIGRIS_BUCKET/METRICS_ADDR/SHUT…
beardthelion Jul 15, 2026
6da0cf5
test(node): exercise the dry-run guard with a real on-disk candidate …
beardthelion Jul 15, 2026
ffdc167
style(node): cargo fmt for the #196 fix set
beardthelion Jul 15, 2026
010c625
fix(node): pin the writer's advisory-lock connection in RepoWriteGuard
Jul 15, 2026
c192c1f
refactor(node): introduce ObjectStore trait seam over TigrisClient
Jul 15, 2026
2155c95
fix(node): make purge-spam Tigris-authoritative and archive-deleting
Jul 15, 2026
8842272
fix(review): don't hold/leak the pool connection in acquire_write
Jul 15, 2026
1d011be
fix(node): make advisory-lock guards drop-safe and reorder acquire_write
Jul 16, 2026
2f679d0
fix(node): complete a fully-received push after client disconnect
Jul 16, 2026
c3fedad
fix(node): serialize archive uploads under the per-repo advisory lock
Jul 16, 2026
f3cf6fc
fix(node): let purge-spam reach repos that exist only as archives
Jul 16, 2026
2b10fa0
refactor(node): dedup limiter setup + write-brake test driver; fix .e…
Jul 16, 2026
ed7489e
docs(node): drop the .env.example shutdown-grace entry #196 added (#196)
Jul 19, 2026
de16ed5
fix(node): give advisory-lock guards a dedicated pool and bound the r…
Jul 19, 2026
bbfdf2b
fix(node): advertise a window-derived Retry-After on rate-limit 429s …
Jul 19, 2026
773cd75
fix(node): skip slug-scoped purge cascade when a mirror row shares th…
Jul 19, 2026
4860e52
fix(node): fail closed classifying the purge target directory (#196)
Jul 20, 2026
2ceec12
fix(node): run the push completion tail in the disconnect-surviving t…
Jul 20, 2026
308530f
fix(node): tombstone bounties when their repo is purged (#196)
Jul 20, 2026
97bf91a
fix(node): serialize create_repo against the purge advisory lock (#196)
Jul 20, 2026
02343b4
test(node): prove purge deletes at MAX_CONNECTIONS=1 with the split p…
Jul 20, 2026
15435e3
fix(node): fail the push when the durable upload times out, don't 200…
Jul 20, 2026
9e75c5a
fix(node): tombstone bounties under both owner forms on purge (#196)
Jul 20, 2026
2a3d9e8
fix(node): fail closed on a symlink at the purge target (#196)
Jul 20, 2026
90048b1
fix(node): retry-after on the push-advert 429, and create_repo locks …
Jul 20, 2026
2ca205c
fix(node): correct the create-pool and bounty-tombstone remediations …
Jul 20, 2026
eef62d7
fix(node): close the durable-upload data-loss class on every write pa…
Jul 20, 2026
b55647a
chore: merge main (iCaptcha PoW + gl retry tests) into feat/write-sin…
Jul 21, 2026
31b1754
refactor(node): route the per-DID 429 through the shared too_many_req…
Jul 21, 2026
4e785c0
fix(node): init's background upload waits out the creator's advisory …
Jul 21, 2026
2d52589
fix(node): roll back the local issue ref before unlock when the durab…
Jul 21, 2026
2a0d6f7
fix(node): fork publishes only after a durable upload, serialized on …
Jul 21, 2026
bf640db
fix(node): read-path downloads publish under the purge lock, without …
Jul 21, 2026
ed88bb6
fix(node): bound every under-lock object-store call and dedup the upl…
Jul 21, 2026
3341cac
fix(node): harden the read-path download against cancellation, stale …
Jul 21, 2026
5e3e98b
fix(node): keep the fork's unbounded work out of the target-lock span…
Jul 21, 2026
41f6dce
refactor(node): move read-path download coordination into a repo_stor…
Jul 21, 2026
22ce83b
fix(node): bound acquire_write's download and free the download-map e…
Jul 21, 2026
8d2fec1
fix(node): roll back the fork mirror and archive on late clone/insert…
Jul 21, 2026
3c07adc
fix(node): serialize repo purge cascade with mirror ingest via adviso…
Jul 22, 2026
9631acb
fix(node): roll back local ref on failed durable upload (close/merge/…
Jul 22, 2026
eea14cd
fix(node): tie cancelled cold-download cleanup to blocking extraction
Jul 22, 2026
0b30fa0
chore(node): fmt + clippy cleanup for the #196 fixes
Jul 22, 2026
1aa8d18
fix(node): never let a failed ref snapshot become a delete-all rollba…
Jul 22, 2026
42c51e8
fix(node): slug-lock every peer-ingest writer and drive the real inge…
Jul 22, 2026
39b002f
fix(node): own cold-download cleanup in a spawned task so handler can…
Jul 22, 2026
f1574ed
refactor(node): delegate issue ref helpers to the store ref primitives
Jul 22, 2026
5626e59
Merge origin/main into feat/write-sink-brake-coverage (reintegrate cu…
Jul 22, 2026
ff8515e
fix(node): slug-lock arweave anchor writes; fail closed when the pre-…
Jul 22, 2026
93d9a10
fix(node): close review residuals: coalesce cold downloads to one in-…
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
Loading