Skip to content

ci(core): add dependency-purity allowlist gate for gitlawb-core - #241

Merged
kevincodex1 merged 2 commits into
mainfrom
ci/gitlawb-core-dep-purity
Jul 22, 2026
Merged

kevincodex1 merged 2 commits into
mainfrom
ci/gitlawb-core-dep-purity

Conversation

@beardthelion

@beardthelion beardthelion commented Jul 22, 2026 •

Copy link
Copy Markdown
Collaborator

gitlawb-core is embedded by gl, git-remote-gitlawb, and the node daemon, so it needs to stay lean. This adds a CI gate that fails if its normal (non-dev, non-build) transitive dependency tree gains any crate not on an explicit allowlist.

The allowlist is exhaustive-by-construction: a new heavy dependency reds CI whether or not anyone thought to ban it, which a denylist can't do.

Files

  • ci/gitlawb-core-allowed-deps.txt: the 83 current normal deps, with the regeneration command and rationale in the header.
  • scripts/check-gitlawb-core-deps.sh: recompute the tree and diff it, hard-fail on a non-allowlisted crate, note-only on a stale (removed) allowlist entry.
  • .github/workflows/pr-checks.yml: a new hard-fail core-deps-purity job, mirroring the pinned action SHAs and style of the sibling jobs.

Verification

Ran the gate end to end: green on the current tree, red when tokio is added as a normal dependency of gitlawb-core (it names tokio plus its transitive crates and exits non-zero), green again after reverting. The checker snapshots and restores Cargo.lock, so a local run leaves no working-tree side effects.

Note on --locked

The checker deliberately does not pass --locked. The committed Cargo.lock currently lags the manifests (any plain cargo command refreshes it), so --locked would red this gate for lockfile-staleness reasons unrelated to core's dependencies. Refreshing the committed lockfile is a separate change.

Summary by CodeRabbit

  • New Features
    • Added an automated dependency validation gate for the core package to ensure only approved transitive dependencies are used.
    • CI now blocks builds when unapproved dependencies are detected.
  • Documentation
    • Added an allowlist of approved dependencies along with instructions for regenerating it.
  • Chores
    • Updated the continuous integration workflow to run the dependency purity check on Ubuntu with caching and a 15-minute timeout.

gitlawb-core is embedded by gl, git-remote-gitlawb, and the node daemon,
so it must stay lean. Add a CI gate that fails if its normal (non-dev,
non-build) transitive dependency tree gains any crate not on an explicit
allowlist.

The allowlist is exhaustive-by-construction: a new heavy dependency reds
CI whether or not anyone thought to ban it, which a denylist cannot do.
The checker resolves like the build/test jobs (no --locked, since the
committed lockfile can lag the manifests) and snapshots/restores
Cargo.lock so a local run leaves no working-tree side effects.

- ci/gitlawb-core-allowed-deps.txt: the 83 current normal deps, plus the
  regeneration command and rationale in the header
- scripts/check-gitlawb-core-deps.sh: recompute and diff; hard-fail on a
  non-allowlisted crate, note-only on a stale (removed) allowlist entry
- pr-checks.yml: new hard-fail core-deps-purity job, matching the pinned
  action SHAs and style of the sibling jobs
@coderabbitai

coderabbitai Bot commented Jul 22, 2026 •

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: a65bd8c6-a30d-48c4-b0af-11ef83ef79de

📥 Commits

Reviewing files that changed from the base of the PR and between e9d6aad and c0ad500.

📒 Files selected for processing (1)
  • ci/gitlawb-core-allowed-deps.txt
🚧 Files skipped from review as they are similar to previous changes (1)
  • ci/gitlawb-core-allowed-deps.txt

📝 Walkthrough

Walkthrough

The PR adds a documented dependency allowlist and validation script for gitlawb-core, then runs the check as a blocking Ubuntu CI job with Rust setup, caching, and a 15-minute timeout.

Changes

gitlawb-core dependency purity

Layer / File(s) Summary
Dependency allowlist and collection
ci/gitlawb-core-allowed-deps.txt, scripts/check-gitlawb-core-deps.sh
Defines permitted crates and computes the normalized normal dependency set while restoring Cargo.lock on exit.
Dependency comparison and results
scripts/check-gitlawb-core-deps.sh
Reports stale allowlist entries, fails on unallowlisted dependencies, and prints a success summary when the sets comply.
CI workflow integration
.github/workflows/pr-checks.yml
Adds the core-deps-purity Ubuntu job with Rust stable, a dedicated cargo cache, and a 15-minute timeout.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Sequence Diagram(s)

sequenceDiagram
  participant CI as core-deps-purity CI job
  participant Script as check-gitlawb-core-deps.sh
  participant Cargo as cargo tree
  participant Allowlist as gitlawb-core-allowed-deps.txt
  CI->>Script: Run dependency purity check
  Script->>Cargo: Compute normal gitlawb-core dependencies
  Script->>Allowlist: Read permitted crate names
  Script-->>CI: Report success or fail on offenders
Loading
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title is concise and accurately summarizes the new dependency-purity CI gate for gitlawb-core.
Description check ✅ Passed Covers the summary, rationale, file changes, verification, and lockfile caveat, though it does not follow the template's exact headings or issue reference.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch ci/gitlawb-core-dep-purity

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@ci/gitlawb-core-allowed-deps.txt`:
- Line 11: Update the allowlist comment describing new dependency behavior to
replace “reds CI” with “turns CI red,” preserving the rest of the wording
unchanged.

In `@scripts/check-gitlawb-core-deps.sh`:
- Around line 38-46: Update the current and allowed dependency command
substitutions in the script to avoid grep -v pipelines that return failure when
all lines are filtered under pipefail; use filtering that preserves successful
empty output. Also update the summary count near the dependency comparison to
report zero for an empty current value instead of counting it as one.
- Around line 39-42: Add --target all to the cargo tree command in
scripts/check-gitlawb-core-deps.sh and to the regeneration command documented in
ci/gitlawb-core-allowed-deps.txt, ensuring both dependency allowlist checks
include every Cargo target.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 639077bc-907e-4220-97d6-092dd8e675a5

📥 Commits

Reviewing files that changed from the base of the PR and between b484a24 and e9d6aad.

📒 Files selected for processing (3)
  • .github/workflows/pr-checks.yml
  • ci/gitlawb-core-allowed-deps.txt
  • scripts/check-gitlawb-core-deps.sh

# wired into the `core-deps-purity` job in .github/workflows/pr-checks.yml)
# fails if gitlawb-core's tree contains any crate not listed here.
#
# The allowlist is exhaustive-by-construction: a NEW dependency reds CI whether

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Fix the dependency-gate wording.

reds CI should be rewritten as turns CI red for grammatical correctness.

Proposed fix
-# of construction: a NEW dependency reds CI whether
+# of construction: a NEW dependency turns CI red whether
🧰 Tools
🪛 LanguageTool

[style] ~11-~11: Consider shortening this phrase to just ‘whether’, unless you mean ‘regardless of whether’.
Context: ...-construction: a NEW dependency reds CI whether # or not anyone thought to ban it, which a denyl...

(WHETHER)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@ci/gitlawb-core-allowed-deps.txt` at line 11, Update the allowlist comment
describing new dependency behavior to replace “reds CI” with “turns CI red,”
preserving the rest of the wording unchanged.

Source: Linters/SAST tools

Comment on lines +38 to +46
current="$(
cargo tree -p gitlawb-core --edges normal --prefix none --manifest-path "$ROOT/Cargo.toml" \
| sed -E 's/ v[0-9].*$//' \
| grep -v '^gitlawb-core$' \
| sort -u
)"

# Allowlist with comments and blank lines stripped.
allowed="$(grep -vE '^[[:space:]]*(#|$)' "$ALLOW" | sort -u)"

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

set -euo pipefail

printf '--- file outline ---\n'
git ls-files scripts/check-gitlawb-core-deps.sh
printf '\n--- relevant lines ---\n'
cat -n scripts/check-gitlawb-core-deps.sh | sed -n '1,140p'

printf '\n--- pipeline behavior probe ---\n'
tmpdir="$(mktemp -d)"
cat >"$tmpdir/probe.sh" <<'SH'
#!/usr/bin/env bash
set -o pipefail

probe() {
  label="$1"
  shift
  if out="$("$@")"; then
    printf '%s: ok, out=%q, status=%s\n' "$label" "$out" "$?"
  else
    st=$?
    printf '%s: fail, out=%q, status=%s\n' "$label" "$out" "$st"
  fi
}

probe grep_all_filtered bash -lc "printf 'a\nb\n' | grep -v . | cat"
probe grep_some_left bash -lc "printf 'a\nb\n' | grep -v '^a$' | cat"
probe sed_all_filtered bash -lc "printf 'a\nb\n' | sed '/./d' | cat"
probe count_empty bash -lc "current=''; if [ -n \"\$current\" ]; then dep_count=\"\$(printf '%s\n' \"\$current\" | wc -l | tr -d ' ')\"; else dep_count=0; fi; printf 'dep_count=%s\n' \"\$dep_count\""
probe count_nonempty bash -lc "current='x
y'; if [ -n \"\$current\" ]; then dep_count=\"\$(printf '%s\n' \"\$current\" | wc -l | tr -d ' ')\"; else dep_count=0; fi; printf 'dep_count=%s\n' \"\$dep_count\""
SH
bash "$tmpdir/probe.sh"

Repository: Gitlawb/node

Length of output: 241


🏁 Script executed:

set -euo pipefail
cat -n scripts/check-gitlawb-core-deps.sh | sed -n '1,140p'
python3 - <<'PY'
import subprocess, textwrap, os, tempfile, pathlib

def run(cmd):
    p = subprocess.run(cmd, shell=True, executable='/bin/bash', stdout=subprocess.PIPE, stderr=subprocess.STDOUT, text=True)
    print(f"$ {cmd}\nstatus={p.returncode}\n{p.stdout}")

run("bash -lc \"set -o pipefail; printf 'a\\nb\\n' | grep -v . | cat\"")
run("bash -lc \"set -o pipefail; printf 'a\\nb\\n' | grep -v '^a$' | cat\"")
run("bash -lc \"set -o pipefail; printf 'a\\nb\\n' | sed '/./d' | cat\"")
run("bash -lc \"current=''; if [ -n \\\"$current\\\" ]; then dep_count=\\\"$(printf '%s\\n' \\\"$current\\\" | wc -l | tr -d ' ')\\\"; else dep_count=0; fi; printf 'dep_count=%s\\n' \\\"$dep_count\\\"\"")
PY

Repository: Gitlawb/node

Length of output: 3942


🏁 Script executed:

python3 - <<'PY'
import subprocess, textwrap

cases = [
    ("grep pipeline, all filtered", r"""bash -lc 'set -euo pipefail; current="$(printf "gitlawb-core\n" | grep -v "^gitlawb-core$" | sort -u)"; printf "current=%q\n" "$current"'"""),
    ("grep pipeline, one dep remains", r"""bash -lc 'set -euo pipefail; current="$(printf "gitlawb-core\nfoo\n" | grep -v "^gitlawb-core$" | sort -u)"; printf "current=%q\n" "$current"'"""),
    ("count empty current", r"""bash -lc 'current=""; printf "%s\n" "$current" | wc -l | tr -d " "'"""),
]
for label, cmd in cases:
    p = subprocess.run(cmd, shell=True, executable="/bin/bash", stdout=subprocess.PIPE, stderr=subprocess.STDOUT, text=True)
    print(f"== {label} ==")
    print(f"status={p.returncode}")
    print(p.stdout)
PY

Repository: Gitlawb/node

Length of output: 291


Avoid grep -v in these command substitutions. With set -o pipefail, current/allowed can fail when the filter removes every line, and the summary count prints 1 for an empty current value. scripts/check-gitlawb-core-deps.sh:38-46,71

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@scripts/check-gitlawb-core-deps.sh` around lines 38 - 46, Update the current
and allowed dependency command substitutions in the script to avoid grep -v
pipelines that return failure when all lines are filtered under pipefail; use
filtering that preserves successful empty output. Also update the summary count
near the dependency comparison to report zero for an empty current value instead
of counting it as one.

Comment on lines +39 to +42
cargo tree -p gitlawb-core --edges normal --prefix none --manifest-path "$ROOT/Cargo.toml" \
| sed -E 's/ v[0-9].*$//' \
| grep -v '^gitlawb-core$' \
| sort -u

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf '\n== files ==\n'
git ls-files scripts/check-gitlawb-core-deps.sh ci/gitlawb-core-allowed-deps.txt

printf '\n== script excerpt ==\n'
cat -n scripts/check-gitlawb-core-deps.sh | sed -n '30,55p'

printf '\n== allowlist excerpt ==\n'
cat -n ci/gitlawb-core-allowed-deps.txt | sed -n '1,40p'

Repository: Gitlawb/node

Length of output: 3420


🌐 Web query:

cargo tree --target all default host target dependencies documentation

💡 Result:

The cargo tree command in Rust is used to visualize the dependency graph of a project [1][2]. By default, when no target is specified, cargo tree displays the dependencies for the host platform [1][3]. The --target flag allows you to filter the dependency graph based on a specific target triple [1][4]. When you provide the value all—specifically using --target all—cargo tree includes all platform-specific dependencies in the graph, regardless of the host platform [1][2]. This is particularly useful for identifying dependencies that are only pulled in when building for specific operating systems or architectures (e.g., dependencies guarded by platform-specific cfg attributes) [5].

Citations:


🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf '\n== cargo tree help (if available) ==\n'
cargo tree --help | sed -n '1,220p'

Repository: Gitlawb/node

Length of output: 142


🏁 Script executed:

#!/bin/bash
set -euo pipefail

python3 - <<'PY'
from pathlib import Path
for p in [Path("scripts/check-gitlawb-core-deps.sh"), Path("ci/gitlawb-core-allowed-deps.txt")]:
    print(f"\n### {p}")
    text = p.read_text()
    for needle in ["--target all", "cargo tree -p gitlawb-core", "Regenerate (from repo root"]:
        print(needle, "=>", needle in text)
PY

Repository: Gitlawb/node

Length of output: 142


🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf '\n== references ==\n'
rg -n "gitlawb-core-allowed-deps|check-gitlawb-core-deps|cargo tree -p gitlawb-core" -S .

printf '\n== package metadata relevant to target-specific deps ==\n'
cat -n Cargo.toml | sed -n '1,220p'

Repository: Gitlawb/node

Length of output: 142


Include all Cargo targets in the dependency allowlist check.

cargo tree here only walks the host platform, so target-specific crates can bypass the allowlist. Add --target all to the checker and the regeneration command in ci/gitlawb-core-allowed-deps.txt.

📍 Affects 2 files
  • scripts/check-gitlawb-core-deps.sh#L39-L42 (this comment)
  • ci/gitlawb-core-allowed-deps.txt#L19-L23
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@scripts/check-gitlawb-core-deps.sh` around lines 39 - 42, Add --target all to
the cargo tree command in scripts/check-gitlawb-core-deps.sh and to the
regeneration command documented in ci/gitlawb-core-allowed-deps.txt, ensuring
both dependency allowlist checks include every Cargo target.

Source: MCP tools

@beardthelion beardthelion added crate:core gitlawb-core — identity, certs, encrypt, DID/UCAN kind:ci CI, release, or packaging pipeline labels Jul 22, 2026
Proc-macro helper for curve25519-dalek (already allowlisted). Newer cargo
versions list it under `cargo tree --edges normal` while older ones do not;
the allowlist is a superset so it passes on both. Caught by core-deps-purity
on the first CI run of this branch.
@kevincodex1
kevincodex1 merged commit 9ca94c4 into main Jul 22, 2026
17 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

crate:core gitlawb-core — identity, certs, encrypt, DID/UCAN kind:ci CI, release, or packaging pipeline

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants