Skip to content

fix(repo): purge PR #178 WIP dump and stop git escaping into the real repository - #201

Merged
marlonsc merged 6 commits into
developfrom
bugfix/purge-pr178-wip-dump
Aug 11, 2026
Merged

fix(repo): purge PR #178 WIP dump and stop git escaping into the real repository#201
marlonsc merged 6 commits into
developfrom
bugfix/purge-pr178-wip-dump

Conversation

@marlon-costa-dc

@marlon-costa-dc marlon-costa-dc commented Aug 10, 2026

Copy link
Copy Markdown
Collaborator

Why

CI has been red on develop. The failure surfaced as a linker error, but the
linker was a symptom.

.cargo/config.toml pins linker = "clang" with -fuse-ld=mold. GitHub
runners have no mold, so run 31430407703 failed at exit code 2 with even
libc, serde, quote and proc-macro2 build scripts unable to link. CI was
executing under a build contract that exists only on one workstation.

That file reached develop through PR #178 ("Recovery/mcb sanitized wip"),
which merged 619 files / +135,696 lines without review. Its lineage is
entirely chore(checkpoint): temporary work-in-progress snapshot and
chore(emergency): checkpoint worktree before cleanup — machine configuration
and session residue versioned as if it were source.

What this changes

1. Purge the dump and close the barrier that let it in (54ae30a6d)

Untracked, kept on disk:

Class Files
Machine-local config .cargo/, .vscode/, .waza.yaml, opencode.jsonc
Tool output 6 × *violations*.txt, qlty.*.sarif, build_err.txt, clippy_output.txt, validate_output.txt, test_003_warnings.txt, pr116_comments.txt, staged_files.txt, coverage/lcov.info
Artifacts libdefine_validator_test.rlib, data/vectors/, tests/mcb.2026-02-10 (server stdout), test_file.txt
Scratch tmp_sisyphus_test.txt, .beads.gate.lock
Superseded docs context/ — parallel tree outside the docs/ SSOT, documenting dill and figment, both removed by ADR-050 / ADR-051

.gitignore carried an explicit !.vscode/settings.json exception forcing
personal editor state to be tracked, plus a dead !.github/workflows/release.yml
rule for a file long renamed to release-binaries.yml. Both corrected; every
purged class now has a blocking rule, each anchored with a leading / so test
fixtures that legitimately ship their own .cargo/ or context/ stay tracked.

Verified by an empty git status --untracked-files=all.

2. Stop test and validation code from escaping into the real repository
(282f1fa8e, 582196b7a, e4761a80b, 338300c8c)

Removing .cargo/config.toml let the pre-push gate run properly for the first
time, and it immediately caught a second, deeper defect.

git resolves GIT_DIR, GIT_WORK_TREE, GIT_INDEX_FILE, GIT_CONFIG,
GIT_OBJECT_DIRECTORY and GIT_COMMON_DIR ahead of both the working
directory and the -C flag
. Any code invoking git from inside a git
operation — a hook, a rebase, a merge — is silently redirected onto the
surrounding repository.

The decisive symptom: a git commit inside a test TempDir executed this
repository's
pre-commit pipeline — running the project's Python suite and
reformatting a source file from within a unit test.

Fixed at the shared owner (run_git), then the three consumers that had
duplicated the logic with a raw Command::new("git").

One of them is a production defect, not a test concern:
mcb-validate::run_context::enumerate_with_git passed -C workspace_root but
inherited GIT_DIR overrode it, so the validator listed files from the wrong
repository when invoked from the pre-commit path where that variable is set.

Evidence

RED → GREEN under the exact failing condition (hook environment exported):

Suite Before After
mcb-providers vcs 10 failed 17 passed (22.68s → 0.07s)
mcb-server e2e golden 13 failed 20 passed
mcb-server e2e gap_fixes 1 failed 6 passed
mcb-server integration vcs 4 failed 7 passed
mcb-validate run_context 1 failed 2 passed

Full gate MCB_MODEL_ID=test-model bash scripts/lib/mcb.sh run cargo test --workspace --all-targetsexit 0, 1759 tests ok, 0 failures.

Push accepted with the complete pre-push chain green: ruff, mypy, 67 pytest,
cargo fmt --check, clippy -D warnings, workspace tests, doc tests,
validate quick, guard: clean.

Baseline control: origin/develop @ 04ed18520 in a clean worktree ran
mcb-server e2e = 145 passed — confirming these failures were the environment
leak surfacing once the gate could run, not regressions introduced here.

Net

−82,144 LOC.

Refs: mcb-okll, mcb-k5yl


Summary by cubic

Removes the accidental PR #178 WIP dump and hardens git isolation so CI runs reliably and tests don’t affect the real repo. Restores green CI, fixes a production validation bug, and removes ~82k lines of junk and machine-local files.

  • Bug Fixes

    • Removed .cargo/config.toml that pinned clang/-fuse-ld=mold, which broke GitHub runner linking.
    • Stopped git from escaping into the host repo by clearing GIT_* vars and disabling hooks/system/global config in the shared run_git helper and in mcb-validate::enumerate_with_git (production fix).
    • Updated tests to use the shared helper and added unit tests verifying helper isolation; VCS e2e/integration tests now pass under hook environments.
    • Outcome: CI green; validator inventories the correct workspace.
  • Refactors

    • Purged machine-local config, tool outputs, artifacts, scratch logs, and the parallel context/ docs tree.
    • Anchored .gitignore rules at repo root and removed bad exceptions; verified clean status.
    • Net repo change: ~82k LOC removed.

Linear: aligns with mcb-okll (purge WIP dump) and mcb-k5yl (git isolation).

Written for commit 7ca73c1. Summary will update on new commits.

Review in cubic

Test User added 5 commits August 10, 2026 20:02
PR #178 ("Recovery/mcb sanitized wip") merged 619 files / +135,696 lines
into develop without review, versioning one workstation's configuration
and session residue as if it were source.

The live consequence was a red CI: .cargo/config.toml pins
linker = "clang" with -fuse-ld=mold, and mold does not exist on GitHub
runners, so run 31430407703 failed at exit code 2 with even libc, serde,
quote and proc-macro2 build scripts unable to link. The mold error was
the symptom; the disease is that CI ran under a build contract that only
exists on the operator machine.

Untrack, keeping files on disk:
- machine-local config: .cargo/, .vscode/, .waza.yaml, opencode.jsonc
- tool output: *violations*.txt (6), qlty.*.sarif, build_err.txt,
  clippy_output.txt, validate_output.txt, test_003_warnings.txt,
  pr116_comments.txt, staged_files.txt, coverage/lcov.info
- artifacts: libdefine_validator_test.rlib, data/vectors/,
  tests/mcb.2026-02-10 (server stdout), test_file.txt
- scratch: tmp_sisyphus_test.txt, .beads.gate.lock
- context/: parallel docs tree outside the docs/ SSOT that documented
  dill and figment, both removed by ADR-050 and ADR-051

Harden .gitignore, the barrier that let the dump in. It carried an
explicit !.vscode/settings.json exception forcing personal editor state
to be tracked, and a dead !.github/workflows/release.yml rule for a file
since renamed to release-binaries.yml. Both corrected, and each purged
class now has a blocking rule, verified by an empty
git status --untracked-files=all.

Net: -82,181 lines.

Refs: mcb-okll
run_git set current_dir but left the inherited git environment intact.
git resolves GIT_DIR, GIT_WORK_TREE, GIT_INDEX_FILE and GIT_CONFIG ahead
of the working directory, so whenever the suite ran inside a git
operation — a pre-commit or pre-push hook, a rebase, a merge — every
helper call was redirected from its TempDir onto the surrounding real
repository.

Reproduced by exporting only GIT_DIR before the suite: 10 of 17 vcs tests
fail with "could not lock config file /home/marlonsc/mcb/.git/config" and
"Unable to create .git/worktrees/purge-pr178-wip-dump/index.lock". The
decisive symptom is a TempDir `git commit` executing the real
repository's pre-commit pipeline, running the project's own Python suite
and reformatting a source file from inside a unit test.

run_git now clears the six inherited path variables, disables system and
global config, and points core.hooksPath at /dev/null, so a test
repository cannot reach outside itself or execute project tooling.

Same command and same exported GIT_DIR after the fix: 17 passed, and the
run drops from 22.68s to 0.07s now that tests no longer trigger the host
hook pipeline.

Covered by tests asserting the helper repository is self-contained,
carries its initial commit through git's own surface, and is not captured
by an ambient work tree — exercised through the public helper API, with
no process-wide environment mutation so the suite stays parallel-safe.

Refs: mcb-k5yl
test_gap2_vcs_list_repositories_discovers_repos drove git through its own
raw Command::new("git"), duplicating logic the domain test helper already
owns. That copy inherits GIT_DIR, GIT_WORK_TREE and GIT_INDEX_FILE, so
under a pre-push hook the fixture repository was created against the
surrounding repository instead of the temp dir, and the assertion found no
discovered repo.

Route the fixture through run_git, the single owner, which clears the
inherited variables and disables hooks and system/global config.

Reproduced with the hook environment exported: the test failed before and
now passes; gap_fixes_e2e is 6 passed under the same conditions.

Refs: mcb-k5yl
… helper

create_git_repo_fixture drove git through its own raw Command::new("git"),
the third copy of logic the domain test helper owns. That copy inherits
GIT_DIR, GIT_WORK_TREE and GIT_INDEX_FILE, so under a pre-push hook the
fixture was created against the surrounding repository and
test_vcs_index_repository_success plus the three
test_vcs_list_repositories_cases found no repository.

Route the fixture through run_git, the single owner, and set the commit
identity on the repository itself now that the helper no longer reads
global config.

Reproduced with the hook environment exported: the four tests failed
before and handlers::vcs_tests is now 7 passed under the same conditions.

Refs: mcb-k5yl
enumerate_with_git passed `-C workspace_root`, but git resolves GIT_DIR,
GIT_WORK_TREE, GIT_INDEX_FILE and GIT_COMMON_DIR ahead of `-C`. Whenever
validation runs from inside a git operation — a pre-commit hook, a rebase,
a merge — the inherited environment redirected `git ls-files` to the
surrounding repository, so the inventory described a different tree than
the one the caller asked about.

This is a production defect, not a test-only concern: validation is
invoked from the pre-commit path, exactly where the environment is set.

Clear the inherited variables before invoking git, so the inventory always
describes workspace_root.

The fixture in run_context_tests drove git through its own raw Command as
well; it now routes through the shared run_git helper.

Reproduced with the hook environment exported: the test failed before and
run_context_tests is now 2 passed under the same conditions.

Refs: mcb-k5yl
@coderabbitai

coderabbitai Bot commented Aug 10, 2026

Copy link
Copy Markdown

Warning

Review limit reached

@marlonsc, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 58 minutes

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: a57bf0bc-2cfd-4789-a205-460a09da741c

📥 Commits

Reviewing files that changed from the base of the PR and between 168e9ab and 7ca73c1.

⛔ Files ignored due to path filters (3)
  • .beads.gate.lock is excluded by !**/*.lock
  • data/vectors/mcp_chunks_integration_test_shards/shard_1.dat is excluded by !**/*.dat
  • data/vectors/mcp_chunks_test-mcb_shards/shard_1.dat is excluded by !**/*.dat
📒 Files selected for processing (76)
  • .cargo/audit.toml
  • .cargo/config.toml
  • .gitignore
  • .vscode/settings.json
  • .waza.yaml
  • build_err.txt
  • clippy_output.txt
  • context/README.md
  • context/core/agent-patterns.md
  • context/core/error-handling.md
  • context/core/sync-log.md
  • context/core/tool-usage.md
  • context/development/code-review.md
  • context/development/git-workflow.md
  • context/development/testing-patterns.md
  • context/external/README.md
  • context/external/async-trait.md
  • context/external/clap.md
  • context/external/dill.md
  • context/external/figment.md
  • context/external/git2.md
  • context/external/handlebars.md
  • context/external/langgraph-memory.md
  • context/external/linkme.md
  • context/external/mcb-main-libraries-reference.md
  • context/external/mcp-and-agents.md
  • context/external/moka.md
  • context/external/openai-agents-memory.md
  • context/external/rmcp.md
  • context/external/rocket.md
  • context/external/serde.md
  • context/external/sqlx.md
  • context/external/thiserror.md
  • context/external/tokio.md
  • context/external/tracing.md
  • context/external/tree-sitter.md
  • context/project-intelligence/architecture-boundaries.md
  • context/project-intelligence/clean-architecture.md
  • context/project-intelligence/conventions.md
  • context/project-intelligence/domain-concepts.md
  • context/project-intelligence/integrations.md
  • context/project-intelligence/modernization-audit.md
  • context/project-intelligence/project-state.md
  • context/project-intelligence/technical-patterns.md
  • context/project-intelligence/v0.2.1-history-and-pending-closure.md
  • context/project-intelligence/v0.2.1-history-and-pending.md
  • context/project-intelligence/v0.2.1-modernization-plan.md
  • coverage/lcov.info
  • crates/mcb-domain/src/utils/tests/git_helpers.rs
  • crates/mcb-domain/tests/unit/utils/git_helpers_tests.rs
  • crates/mcb-domain/tests/unit/utils/mod.rs
  • crates/mcb-providers/src/database/sqlite/test_file.txt
  • crates/mcb-server/tests/e2e/gap_fixes_e2e.rs
  • crates/mcb-server/tests/integration/handlers/vcs_tests.rs
  • crates/mcb-validate/src/run_context.rs
  • crates/mcb-validate/tests/unit/run_context_tests.rs
  • data/vectors/mcp_chunks_integration_test_index.json
  • data/vectors/mcp_chunks_integration_test_shards/shard_1.meta
  • data/vectors/mcp_chunks_test-mcb_index.json
  • data/vectors/mcp_chunks_test-mcb_shards/shard_1.meta
  • docs_violations.txt
  • impl_violations.txt
  • libdefine_validator_test.rlib
  • opencode.jsonc
  • pr116_comments.txt
  • qlty.check.current.sarif
  • qlty.smells.sarif
  • qual_violations.txt
  • qual_violations2.txt
  • quality_violations.txt
  • staged_files.txt
  • test_003_warnings.txt
  • tests/mcb.2026-02-10
  • tmp_sisyphus_test.txt
  • validate_output.txt
  • violations.txt

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

@qodo-code-review

qodo-code-review Bot commented Aug 10, 2026

Copy link
Copy Markdown
Contributor

PR Summary by Qodo

Purge accidental WIP dump; isolate spawned git from ambient repository state

🐞 Bug fix ⚙️ Configuration changes 🧪 Tests 🕐 40+ Minutes

Grey Divider

AI Description

• Remove machine-local configs/artifacts and harden .gitignore to prevent recurrence.
• Scope all spawned git invocations by clearing inherited GIT_* variables and disabling hooks.
• Add regression tests proving temp git repos cannot escape into the surrounding repository.
Diagram

graph TD
  ci["CI runner"] --> repo["Repo workspace"] --> invokers["Git invokers (tests/validate)"] --> gitcmd["git subprocess"] --> target["Intended dir"]
  repo --> gitignore[".gitignore"] --> blocked["Local dumps blocked"]
Loading
High-Level Assessment

The following are alternative approaches to this PR:

1. Pass explicit --git-dir/--work-tree to all git calls
  • ➕ Makes repository scoping explicit per invocation
  • ➕ Less reliance on process environment mutation
  • ➖ Verbose and easy to get wrong across many git command variants
  • ➖ Still needs hook/global-config suppression for safety
2. Use libgit2 (git2-rs) in tests instead of spawning git
  • ➕ Avoids git CLI environment precedence pitfalls entirely
  • ➕ No accidental hook execution
  • ➖ Bigger refactor and dependency surface
  • ➖ Behavior can diverge from real git CLI semantics that tests may depend on

Recommendation: The current approach (sanitizing inherited GIT_* and disabling hooks/config) is the best minimal, correct fix because it directly addresses git’s precedence rules while keeping existing CLI-based behavior. The added unit tests make the isolation contract enforceable going forward.

Files changed (8) +235 / -66

Bug fix (2) +46 / -3
git_helpers.rsHarden test git helper against inherited GIT_* and hooks/config +29/-2

Harden test git helper against inherited GIT_* and hooks/config

• Updates 'run_git' to clear inherited 'GIT_*' variables that can redirect operations into the surrounding repository. Disables system/global git config and hooks via 'GIT_CONFIG_NOSYSTEM', 'GIT_CONFIG_GLOBAL=/dev/null', and 'core.hooksPath=/dev/null'.

crates/mcb-domain/src/utils/tests/git_helpers.rs

run_context.rsPrevent inventory enumeration from leaking to ambient git repository +17/-1

Prevent inventory enumeration from leaking to ambient git repository

• Clears inherited 'GIT_*' variables before executing 'git -C <workspace_root> ls-files'. Ensures validation inventory always describes the configured workspace root, even when executed inside hooks/rebases/merges.

crates/mcb-validate/src/run_context.rs

Tests (5) +150 / -61
git_helpers_tests.rsAdd regression tests for git helper repository isolation +119/-0

Add regression tests for git helper repository isolation

• Introduces unit tests that simulate a hook-like environment by setting 'GIT_DIR'/'GIT_WORK_TREE'/etc. for a child git process. Verifies helper-created repos are self-contained and 'run_git' initializes only the directory it is given.

crates/mcb-domain/tests/unit/utils/git_helpers_tests.rs

mod.rsRegister git helper isolation tests +2/-0

Register git helper isolation tests

• Adds 'git_helpers_tests' to the unit test module tree so the new isolation tests run in CI.

crates/mcb-domain/tests/unit/utils/mod.rs

gap_fixes_e2e.rsUse isolated run_git for e2e repo setup +9/-20

Use isolated run_git for e2e repo setup

• Replaces direct 'git' subprocess calls with the shared 'run_git' helper when initializing and committing to a temp repo. Explicitly configures user.name/email in the temp repo to keep commits local and deterministic.

crates/mcb-server/tests/e2e/gap_fixes_e2e.rs

vcs_tests.rsUse isolated run_git for VCS handler fixtures +14/-26

Use isolated run_git for VCS handler fixtures

• Refactors git repo fixture creation to route all git commands through 'run_git', including repo-local author config. Prevents fixture setup from triggering or targeting the surrounding repository when tests run inside git operations.

crates/mcb-server/tests/integration/handlers/vcs_tests.rs

run_context_tests.rsBuild temp repos via shared isolated git helper +6/-15

Build temp repos via shared isolated git helper

• Switches test setup from raw 'Command::new("git")' to 'run_git' for 'init'/'add', aligning tests with the new isolation guarantees and avoiding ambient environment interference.

crates/mcb-validate/tests/unit/run_context_tests.rs

Other (1) +39 / -2
.gitignoreBlock machine-local dumps and fix stale allowlist rules +39/-2

Block machine-local dumps and fix stale allowlist rules

• Adds rooted ignore rules for machine-local configs, tool outputs (SARIF/violations/logs), compiled/test artifacts, captured runtime logs, scratch files, and the parallel 'context/' docs tree. Removes the forced-tracking exception for VSCode settings and updates the workflow allowlist entry to 'release-binaries.yml'.

.gitignore

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

2 issues found and verified against the latest diff

Confidence score: 4/5

  • In crates/mcb-domain/tests/unit/utils/git_helpers_tests.rs, the isolation check is currently vacuous because the child git process points to a non-existent GIT_DIR, so the assertion can pass without proving isolation; this could mask real repo-escape regressions in future changes — create the decoy git dir (or assert the command succeeds before evaluating output).
  • In crates/mcb-domain/src/utils/tests/git_helpers.rs, cleanup does not clear GIT_CONFIG_COUNT and related GIT_CONFIG_KEY_<n>/GIT_CONFIG_VALUE_<n> variables, so test-level git config injection can leak between tests and produce flaky or misleading results — explicitly unset the full injected env variable set during teardown.
Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="crates/mcb-domain/src/utils/tests/git_helpers.rs">

<violation number="1" location="crates/mcb-domain/src/utils/tests/git_helpers.rs:25">
P3: The stated goal is that a test repository can never reach outside itself, but the cleanup leaves git's environment-config injection variables uncleared. `GIT_CONFIG_COUNT` together with `GIT_CONFIG_KEY_<n>`/`GIT_CONFIG_VALUE_<n>` (and `GIT_CONFIG_PARAMETERS`) let an ambient environment feed config into every git invocation regardless of `-c`/repo config, so config from the surrounding hook environment (e.g. `core.hooksPath`, `safe.directory`, `user.*`) can still leak into the test repo. Worth clearing them alongside the six list entries for full isolation. If you're confident the CI/hook environment never sets these, this can be deferred, but it's the remaining vector for the environment leakage this PR targets.</violation>
</file>

<file name="crates/mcb-domain/tests/unit/utils/git_helpers_tests.rs">

<violation number="1" location="crates/mcb-domain/tests/unit/utils/git_helpers_tests.rs:49">
P2: The isolation test passes vacuously: the child git is pointed at a GIT_DIR (decoy.path()/decoy.git) that is never created, so it errors out (exit 128) with empty stdout and the assert `!seen.contains(decoy.path())` is satisfied regardless of whether the helpers actually isolate. The decoy needs to be a real git repository (e.g. initialized work tree with a valid GIT_DIR) so a leaking implementation would resolve toplevel to the decoy and fail the assert; otherwise a regression in run_git isolation ships undetected.</violation>
</file>

Shadow auto-approve: would not auto-approve because issues were found.

Re-trigger cubic

let output = Command::new("git")
.args(["rev-parse", "--show-toplevel"])
.current_dir(path)
.env("GIT_DIR", decoy.path().join("decoy.git"))

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2: The isolation test passes vacuously: the child git is pointed at a GIT_DIR (decoy.path()/decoy.git) that is never created, so it errors out (exit 128) with empty stdout and the assert !seen.contains(decoy.path()) is satisfied regardless of whether the helpers actually isolate. The decoy needs to be a real git repository (e.g. initialized work tree with a valid GIT_DIR) so a leaking implementation would resolve toplevel to the decoy and fail the assert; otherwise a regression in run_git isolation ships undetected.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At crates/mcb-domain/tests/unit/utils/git_helpers_tests.rs, line 49:

<comment>The isolation test passes vacuously: the child git is pointed at a GIT_DIR (decoy.path()/decoy.git) that is never created, so it errors out (exit 128) with empty stdout and the assert `!seen.contains(decoy.path())` is satisfied regardless of whether the helpers actually isolate. The decoy needs to be a real git repository (e.g. initialized work tree with a valid GIT_DIR) so a leaking implementation would resolve toplevel to the decoy and fail the assert; otherwise a regression in run_git isolation ships undetected.</comment>

<file context>
@@ -0,0 +1,119 @@
+    let output = Command::new("git")
+        .args(["rev-parse", "--show-toplevel"])
+        .current_dir(path)
+        .env("GIT_DIR", decoy.path().join("decoy.git"))
+        .env("GIT_WORK_TREE", decoy.path())
+        .env("GIT_INDEX_FILE", decoy.path().join("decoy.index"))
</file context>

/// Returns an error if the git command fails.
pub fn run_git(dir: &Path, args: &[&str]) -> TestResult<()> {
let output = Command::new("git")
const INHERITED_GIT_VARS: [&str; 6] = [

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P3: The stated goal is that a test repository can never reach outside itself, but the cleanup leaves git's environment-config injection variables uncleared. GIT_CONFIG_COUNT together with GIT_CONFIG_KEY_<n>/GIT_CONFIG_VALUE_<n> (and GIT_CONFIG_PARAMETERS) let an ambient environment feed config into every git invocation regardless of -c/repo config, so config from the surrounding hook environment (e.g. core.hooksPath, safe.directory, user.*) can still leak into the test repo. Worth clearing them alongside the six list entries for full isolation. If you're confident the CI/hook environment never sets these, this can be deferred, but it's the remaining vector for the environment leakage this PR targets.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At crates/mcb-domain/src/utils/tests/git_helpers.rs, line 25:

<comment>The stated goal is that a test repository can never reach outside itself, but the cleanup leaves git's environment-config injection variables uncleared. `GIT_CONFIG_COUNT` together with `GIT_CONFIG_KEY_<n>`/`GIT_CONFIG_VALUE_<n>` (and `GIT_CONFIG_PARAMETERS`) let an ambient environment feed config into every git invocation regardless of `-c`/repo config, so config from the surrounding hook environment (e.g. `core.hooksPath`, `safe.directory`, `user.*`) can still leak into the test repo. Worth clearing them alongside the six list entries for full isolation. If you're confident the CI/hook environment never sets these, this can be deferred, but it's the remaining vector for the environment leakage this PR targets.</comment>

<file context>
@@ -8,13 +8,40 @@ use std::path::Path;
 /// Returns an error if the git command fails.
 pub fn run_git(dir: &Path, args: &[&str]) -> TestResult<()> {
-    let output = Command::new("git")
+    const INHERITED_GIT_VARS: [&str; 6] = [
+        "GIT_DIR",
+        "GIT_WORK_TREE",
</file context>

@qodo-code-review

Copy link
Copy Markdown
Contributor

Code Review by Qodo

🐞 Bugs (3) 📘 Rule violations (0) 📜 Skill insights (0)

Grey Divider


Remediation recommended

1. Nonportable git null paths 🐞 Bug ☼ Reliability
Description
run_git() hardcodes /dev/null for GIT_CONFIG_GLOBAL and core.hooksPath, which makes behavior
platform-dependent (notably on Windows runners in CI) and can cause git commands in tests to fail or
behave inconsistently across OSes.
Code

crates/mcb-domain/src/utils/tests/git_helpers.rs[R41-44]

+        .env("GIT_CONFIG_NOSYSTEM", "1")
+        .env("GIT_CONFIG_GLOBAL", "/dev/null")
+        .arg("-c")
+        .arg("core.hooksPath=/dev/null")
Relevance

●●● Strong

Windows CI is a priority; avoiding /dev/null hardcoding prevents cross-platform git test flakiness.

PR-#105
PR-#103

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
The helper sets /dev/null as both the global config path and hooks path, and CI explicitly runs on
Windows. Tests now call run_git() for repo setup, so any OS-dependent behavior can surface as test
failures.

crates/mcb-domain/src/utils/tests/git_helpers.rs[35-48]
.github/workflows/ci-matrix.yml[107-112]
crates/mcb-server/tests/e2e/gap_fixes_e2e.rs[101-118]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
`run_git()` currently disables global/system config and hooks using hardcoded Unix paths (`/dev/null`). This is OS-dependent and can behave differently (or fail) on Windows/macOS/Linux.

## Issue Context
The helper is now used by multiple test suites, and CI includes a Windows job, so any OS-specific assumption here affects build/test reliability.

## Fix Focus Areas
- crates/mcb-domain/src/utils/tests/git_helpers.rs[24-55]

## Suggested fix
- Replace `GIT_CONFIG_GLOBAL=/dev/null` with a portable approach:
 - Option A: create an empty temp file inside `dir` (e.g. `dir/.gitconfig-empty`) and point `GIT_CONFIG_GLOBAL` to that path.
 - Option B: conditionalize the null device (`"NUL"` on Windows, `"/dev/null"` elsewhere).
- Replace `core.hooksPath=/dev/null` with a real empty directory:
 - Ensure a directory exists under `dir` (e.g. `dir/.mcb-empty-hooks/`) before invoking git, then set `core.hooksPath=<that-dir>`.
 - This avoids relying on `/dev/null` being a directory-like sink and stays portable.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


2. Git isolation test false-positive 🐞 Bug ⚙ Maintainability
Description
toplevel_seen_with_hook_environment() ignores the child git exit status and returns trimmed
stdout even on failure, so helper_repository_is_not_captured_by_ambient_git_environment can pass
with an empty stdout rather than actually proving isolation.
Code

crates/mcb-domain/tests/unit/utils/git_helpers_tests.rs[R53-55]

+        .output()?;
+
+    Ok(String::from_utf8_lossy(&output.stdout).trim().to_owned())
Relevance

●●● Strong

Team has accepted “fail fast / don’t silently succeed” test hardening; checking git exit status
matches that.

PR-#87

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
The helper returns stdout without checking output.status, and the main assertion only checks that
the returned string doesn’t contain the decoy path; empty output from a failing git invocation would
satisfy this condition.

crates/mcb-domain/tests/unit/utils/git_helpers_tests.rs[42-55]
crates/mcb-domain/tests/unit/utils/git_helpers_tests.rs[90-103]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The new isolation test can incorrectly pass when the injected hook-like environment causes `git rev-parse` to fail (non-zero status). Because the test does not assert success, stdout may be empty and still satisfy the negative assertion.

## Issue Context
These tests are meant to guard against regressions where helper git commands escape into the surrounding repository; a false-positive weakens that protection.

## Fix Focus Areas
- crates/mcb-domain/tests/unit/utils/git_helpers_tests.rs[42-105]

## Suggested fix
- In `toplevel_seen_with_hook_environment()`, check `output.status.success()` and return an error (including stderr) when it is not.
- If you truly want to allow “refuses” as a valid outcome, make that explicit and assert on the specific failure mode (e.g., expected stderr message), rather than silently treating any failure as success.
- Optionally strengthen the test by creating an actual decoy repo in `decoy` (via `run_git`) so a leaking implementation deterministically resolves to the decoy path and the assertion becomes meaningful.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools



Informational

3. Stale Cargo-config references 🐞 Bug ⚙ Maintainability
Description
After deleting .cargo/config.toml and adding /.cargo/ to .gitignore, multiple docs/comments
still state that .cargo/config.toml sets rustc-wrapper, job limits, and env vars, which is now
misleading for contributors and CI expectations.
Code

.cargo/config.toml[L3-6]

-# MANDATORY: sccache as the Rust compiler wrapper. Set here so EVERY cargo
-# invocation uses it, even when running `cargo check` / `cargo build` directly
-# without make. sccache eliminates redundant rebuilds across sessions.
-rustc-wrapper = "sccache"
Relevance

●●● Strong

Repo is purging machine-local config; updating stale guidance aligns docs/comments with new
contract.

PR-#106

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
Docs and build comments explicitly claim .cargo/config.toml configures sccache/jobs/env, while the
repo now ignores /.cargo/, indicating that guidance is no longer accurate for the current tree.

.gitignore[283-292]
custom.mk[8-11]
docs/developer/BENCHMARK.md[88-101]
docs/developer/SERENA.md[339-395]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
`.cargo/config.toml` is removed/blocked from git, but repo documentation and Make comments still describe it as an active configuration source (sccache wrapper, jobs, env vars). This misleads developers about how builds are configured now.

## Issue Context
The PR’s intent is to purge machine-local configuration; documentation should reflect the new source of truth (or remove the claim if there is no replacement).

## Fix Focus Areas
- custom.mk[8-11]
- docs/developer/BENCHMARK.md[88-101]
- docs/developer/SERENA.md[339-395]
- .gitignore[283-292]

## Suggested fix
- Update `custom.mk` comment to remove the claim that `.cargo/config.toml` sets `rustc-wrapper`.
- Update BENCHMARK.md / SERENA.md to either:
 - describe the new mechanism for these settings (if they still exist), or
 - explicitly state they were removed and why.
- Ensure any CI docs mentioning `.github/workflows/ci.yml` actually match the workflow configuration.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Grey Divider

Context used
✅ Compliance rules (platform): 13 rules
✅ Skills: flext-law

Grey Divider

Tip of the day
💡 Did you know, you can group findings by type and pick your Finding display, from Minimal to Full

More tips ↗ | Customize Qodo ↗ | Qodo docs ↗

Grey Divider

Qodo Logo

Comment on lines +41 to +44
.env("GIT_CONFIG_NOSYSTEM", "1")
.env("GIT_CONFIG_GLOBAL", "/dev/null")
.arg("-c")
.arg("core.hooksPath=/dev/null")

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.

Remediation recommended

1. Nonportable git null paths 🐞 Bug ☼ Reliability

run_git() hardcodes /dev/null for GIT_CONFIG_GLOBAL and core.hooksPath, which makes behavior
platform-dependent (notably on Windows runners in CI) and can cause git commands in tests to fail or
behave inconsistently across OSes.
Agent Prompt
## Issue description
`run_git()` currently disables global/system config and hooks using hardcoded Unix paths (`/dev/null`). This is OS-dependent and can behave differently (or fail) on Windows/macOS/Linux.

## Issue Context
The helper is now used by multiple test suites, and CI includes a Windows job, so any OS-specific assumption here affects build/test reliability.

## Fix Focus Areas
- crates/mcb-domain/src/utils/tests/git_helpers.rs[24-55]

## Suggested fix
- Replace `GIT_CONFIG_GLOBAL=/dev/null` with a portable approach:
  - Option A: create an empty temp file inside `dir` (e.g. `dir/.gitconfig-empty`) and point `GIT_CONFIG_GLOBAL` to that path.
  - Option B: conditionalize the null device (`"NUL"` on Windows, `"/dev/null"` elsewhere).
- Replace `core.hooksPath=/dev/null` with a real empty directory:
  - Ensure a directory exists under `dir` (e.g. `dir/.mcb-empty-hooks/`) before invoking git, then set `core.hooksPath=<that-dir>`.
  - This avoids relying on `/dev/null` being a directory-like sink and stays portable.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

Comment on lines +53 to +55
.output()?;

Ok(String::from_utf8_lossy(&output.stdout).trim().to_owned())

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.

Remediation recommended

2. Git isolation test false-positive 🐞 Bug ⚙ Maintainability

toplevel_seen_with_hook_environment() ignores the child git exit status and returns trimmed
stdout even on failure, so helper_repository_is_not_captured_by_ambient_git_environment can pass
with an empty stdout rather than actually proving isolation.
Agent Prompt
## Issue description
The new isolation test can incorrectly pass when the injected hook-like environment causes `git rev-parse` to fail (non-zero status). Because the test does not assert success, stdout may be empty and still satisfy the negative assertion.

## Issue Context
These tests are meant to guard against regressions where helper git commands escape into the surrounding repository; a false-positive weakens that protection.

## Fix Focus Areas
- crates/mcb-domain/tests/unit/utils/git_helpers_tests.rs[42-105]

## Suggested fix
- In `toplevel_seen_with_hook_environment()`, check `output.status.success()` and return an error (including stderr) when it is not.
- If you truly want to allow “refuses” as a valid outcome, make that explicit and assert on the specific failure mode (e.g., expected stderr message), rather than silently treating any failure as success.
- Optionally strengthen the test by creating an actual decoy repo in `decoy` (via `run_git`) so a leaking implementation deterministically resolves to the decoy path and the assertion becomes meaningful.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

Comment thread .cargo/config.toml
Comment on lines -3 to -6
# MANDATORY: sccache as the Rust compiler wrapper. Set here so EVERY cargo
# invocation uses it, even when running `cargo check` / `cargo build` directly
# without make. sccache eliminates redundant rebuilds across sessions.
rustc-wrapper = "sccache"

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.

Informational

3. Stale cargo-config references 🐞 Bug ⚙ Maintainability

After deleting .cargo/config.toml and adding /.cargo/ to .gitignore, multiple docs/comments
still state that .cargo/config.toml sets rustc-wrapper, job limits, and env vars, which is now
misleading for contributors and CI expectations.
Agent Prompt
## Issue description
`.cargo/config.toml` is removed/blocked from git, but repo documentation and Make comments still describe it as an active configuration source (sccache wrapper, jobs, env vars). This misleads developers about how builds are configured now.

## Issue Context
The PR’s intent is to purge machine-local configuration; documentation should reflect the new source of truth (or remove the claim if there is no replacement).

## Fix Focus Areas
- custom.mk[8-11]
- docs/developer/BENCHMARK.md[88-101]
- docs/developer/SERENA.md[339-395]
- .gitignore[283-292]

## Suggested fix
- Update `custom.mk` comment to remove the claim that `.cargo/config.toml` sets `rustc-wrapper`.
- Update BENCHMARK.md / SERENA.md to either:
  - describe the new mechanism for these settings (if they still exist), or
  - explicitly state they were removed and why.
- Ensure any CI docs mentioning `.github/workflows/ci.yml` actually match the workflow configuration.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

@marlonsc
marlonsc merged commit b997eb6 into develop Aug 11, 2026
8 of 9 checks passed
@marlonsc
marlonsc deleted the bugfix/purge-pr178-wip-dump branch August 11, 2026 00:11
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants