Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
43 commits
Select commit Hold shift + click to select a range
f511eab
refactor(node): split gitlawb-node into lib+bin so integration tests …
Jul 12, 2026
f240af4
test(node): real-node deny harness rig + INV-8 unsigned-push case (U2…
Jul 12, 2026
6ca940b
test(node): INV-1 owner-gate deny case over the real stack (U6)
Jul 12, 2026
54ceb0d
test(node): INV-2 read + content-addressed withhold deny cases (U5b, U7)
Jul 12, 2026
c3b25fb
test(node): INV-2 replication-path deny case over git-upload-pack (U8)
Jul 12, 2026
216982a
ci(node): run the real-node deny harness on every PR
Jul 12, 2026
746b76f
test(node): cover the deny-assertion guard branches (U4)
Jul 12, 2026
2cfbcba
test(node): full-stack owner-gate deny cases for 5 high-value mutations
Jul 12, 2026
532627f
style(node): cargo fmt the deny-harness sources
Jul 12, 2026
30672cf
Address PR review feedback (#194)
Jul 13, 2026
fb8685d
fix(node): remove a failed first-write key file; verify key mode afte…
Jul 14, 2026
e3eac37
fix(node): publish the identity key atomically and wait a real deadline
beardthelion Jul 15, 2026
688b506
fix(node): recover key publish from stale temps, make it durable; joi…
Jul 16, 2026
de21c64
test(node): let the partial-final reader wait out the fsynced publish…
Jul 16, 2026
8df9561
fix(node): fall back to a direct create_new publish when hard_link fa…
Jul 19, 2026
2b37daf
test(node): abort the server task in TestNode::drop (#194)
Jul 19, 2026
bea3158
chore: sync Cargo.lock with the 0.5.1 workspace manifests
Jul 19, 2026
89a8d18
test(node): surface axum::serve's result through TestNode::shutdown (…
Jul 19, 2026
48ce8af
fix(node): verify key file mode before writing PEM bytes at both crea…
Jul 19, 2026
ce21a84
docs(node): state the real shutdown-grace contract and lock it with a…
Jul 19, 2026
09bfe36
test(node): close review gaps on the key-publish fallback and Drop ab…
Jul 19, 2026
33ea63b
fix(node): recover identity-key fallback fsync failure and abort wedg…
Jul 20, 2026
88616b2
test(node): invariant deny-prober (driven registry + completeness cro…
beardthelion Jul 22, 2026
1720c38
fix(node): bracket the fallback identity-key publish with a durable m…
Jul 21, 2026
3229022
fix(node): recover a crash-interrupted fallback key publish at boot
Jul 21, 2026
e43f4d2
fix(node): make the fallback marker removal a commit check for stalle…
Jul 21, 2026
64aa15e
fix(node): sweep stale key-publish markers on every healthy boot
Jul 21, 2026
e673271
fix(node): make recovery claims complete, releasable, and themselves …
Jul 21, 2026
a713d45
test(node): cover the quarantine-exhaustion arm and pin recovery latency
Jul 21, 2026
c1d1532
fix(node): protect live recoveries from the sweep and restore hijacke…
Jul 21, 2026
8d33fbc
fix(node): keep no-clobber on the quarantine restore and scope cleanu…
Jul 21, 2026
0ebdd1a
fix(node): hand post-write publish failures to boot recovery, stamp c…
Jul 21, 2026
159f04c
fix(node): key recovery claims by process nonce and harden the freshn…
Jul 21, 2026
8501285
fix(node): adopt stranded quarantined identities and age-gate claim s…
Jul 21, 2026
0955504
fix(node): bound quarantine adoption, expire orphan claims, align the…
Jul 21, 2026
facc024
fix(node): sweep every healthy return, supersede outcompeted quaranti…
Jul 22, 2026
dd1a934
fix(node): supersede on every Lost arm, heartbeat live claims, retire…
Jul 22, 2026
32903c4
fix(node): order supersede before consume, retire quarantine forensic…
Jul 22, 2026
c61be61
Merge remote-tracking branch 'origin/main' into feat/real-node-deny-h…
Jul 22, 2026
14de621
test(node): drive the #113 read/owner gates in the deny-harness fence
Jul 22, 2026
8d81cbe
test(node): harden deny-harness so its guarantees can't pass vacuously
Jul 22, 2026
996e1b3
test(node): close two vacuity holes in the shutdown-completeness guard
Jul 22, 2026
8f7af96
Merge origin/main into feat/real-node-deny-harness (reintegrate curre…
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
10 changes: 10 additions & 0 deletions .github/workflows/pr-checks.yml
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,16 @@ jobs:
DATABASE_URL: postgres://postgres:postgres@localhost:5432/gitlawb_test
run: cargo test --workspace

# The real-node deny harness is behind the `test-harness` feature (so its
# spawn surface never compiles into the production binary), which means
# `--workspace` above skips it. Run it explicitly so the trust-boundary
# regression cases (INV-1/INV-2/INV-8) execute on every PR. Uses the same
# Postgres service; `#[sqlx::test]` provisions an isolated DB per test.
- name: cargo test (real-node deny harness)
env:
DATABASE_URL: postgres://postgres:postgres@localhost:5432/gitlawb_test
run: cargo test -p gitlawb-node --features test-harness --test deny_harness

build-release:
name: build --release
runs-on: ubuntu-latest
Expand Down
27 changes: 27 additions & 0 deletions crates/gitlawb-node/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,28 @@ edition.workspace = true
rust-version.workspace = true
license.workspace = true

[lib]
name = "gitlawb_node"
path = "src/lib.rs"

[[bin]]
name = "gitlawb-node"
path = "src/main.rs"

# Exposes the `test_harness` spawn surface (src/test_harness.rs) to the
# real-node deny-harness integration crate. Off by default so the production
# binary never compiles test-only boot code. Enable with
# `cargo test -p gitlawb-node --features test-harness`.
[features]
test-harness = []

# Only builds when `test-harness` is enabled; otherwise skipped (not an error),
# so `cargo test --workspace` without the feature stays green.
[[test]]
name = "deny_harness"
path = "tests/deny_harness.rs"
required-features = ["test-harness"]

[dependencies]
gitlawb-core = { path = "../gitlawb-core" }
ed25519-dalek = { workspace = true }
Expand Down Expand Up @@ -77,3 +95,12 @@ libp2p-dns = { version = "0.44.0", features = ["tokio"] }
[dev-dependencies]
mockito = "1"
tempfile = "3"
# test-util enables tokio::test(start_paused): the delayed claim re-sweep
# test drives the real CLAIM_SWEEP_MIN_AGE-plus-margin sleep on paused time.
tokio = { workspace = true, features = ["test-util"] }
# Used by the deny-harness integration crate (tests/deny_harness.rs): the
# #[sqlx::test] macro for an ephemeral per-test pool, and reqwest as the real
# HTTP client that drives deny paths over the socket.
sqlx = { version = "0.8", features = ["postgres", "runtime-tokio-rustls", "macros", "migrate"] }
reqwest = { workspace = true }
hex = "0.4"
6 changes: 4 additions & 2 deletions crates/gitlawb-node/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -162,8 +162,10 @@ pub struct Config {
pub metrics_addr: String,

/// Maximum time to wait for in-flight requests to drain on shutdown, in
/// seconds. After this elapses, the server returns 503 to anything still
/// in flight and exits. Default: 30s.
/// seconds. On the shutdown signal the server stops accepting new
/// connections and gives in-flight requests this long to complete; at
/// expiry it abandons whatever remains (clients observe a closed
/// connection, not an error response) and exits. Default: 30s.
#[arg(long, env = "GITLAWB_SHUTDOWN_GRACE_SECS", default_value_t = 30)]
pub shutdown_grace_secs: u64,

Expand Down
4 changes: 2 additions & 2 deletions crates/gitlawb-node/src/db/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -255,7 +255,7 @@ impl Db {
&self.pool
}

#[cfg(test)]
#[cfg(any(test, feature = "test-harness"))]
pub fn for_testing(pool: PgPool) -> Self {
Self { pool }
}
Expand All @@ -264,7 +264,7 @@ impl Db {
/// provisions an empty per-test database, so DB-backed tests must run this
/// before seeding. Reuses the production `migrate()` path (the advisory lock
/// is harmless on an isolated test DB and migrations are idempotent).
#[cfg(test)]
#[cfg(any(test, feature = "test-harness"))]
pub(crate) async fn run_migrations(&self) -> Result<()> {
self.migrate().await
}
Expand Down
2 changes: 1 addition & 1 deletion crates/gitlawb-node/src/git/repo_store.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ pub struct RepoStore {
}

impl RepoStore {
#[cfg(test)]
#[cfg(any(test, feature = "test-harness"))]
pub fn for_testing(repos_dir: PathBuf, pool: PgPool) -> Self {
Self {
repos_dir,
Expand Down
Loading
Loading