Skip to content

test: derive the no-user-specific-data needles from the running machine - #155

Merged
justin13888 merged 1 commit into
masterfrom
refactor/131-derive-user-needles-from-env
Oct 3, 2026
Merged

justin13888 merged 1 commit into
masterfrom
refactor/131-derive-user-needles-from-env

Conversation

@justin13888

Copy link
Copy Markdown
Contributor

Summary

  • src/testing.rs: the invariant-5 guard no longer stores anyone's identity. Its needles were one developer's account names and mount path held as string fragments, which is itself user-specific data in the repository, and it scanned src/ only.
    • user_specific_needles(on_ci, account, home, checkout) derives the needles from the running machine's $USER (whole word), $HOME and the checkout path (CARGO_MANIFEST_DIR) (anywhere), lowercased, a trailing / dropped. An account name under 4 characters and a path with fewer than 2 named components (/, /root) are skipped as too short to identify anyone. On CI (CI set and non-empty) there are none: a hosted runner's account identifies nobody, and its name (runner) occurs as a whole word in ci.yml, release-plz.yml, CHANGELOG.md and several sources, so the scan would fail on ordinary prose.
    • user_specific_offences takes the needles as an argument, so the Rule::Anywhere and Rule::WholeWord tests are driven by a synthetic machine (quillon, /home/quillon, /srv/build/quillon/bx) rather than real values.
    • no_user_specific_literal_survives_under_src becomes no_user_specific_literal_survives_in_a_tracked_file: it reads every file git ls-files -z lists (this one included, since it no longer holds the needles), skipping only the authors line of Cargo.toml.
    • contains_token now requires a word boundary on both sides of an account name, not only before it.
    • New tests: the derivation, the too-short skips, the CI case, and the Cargo.toml authors exemption (and that the exemption is that line only).
  • src/env_guard.rs: a doc comment's reference to the renamed test is updated.

Validation

  • mise run format — no change after the fixer
  • mise run lint (cargo clippy --all-targets -- -D warnings) — pass
  • cargo test — pass (2040 lib tests, 14 ignored; all integration suites pass)
  • CI=1 cargo test --lib testing:: — 22 passed
  • USER=justin cargo test --lib tracked_file — pass (the Cargo.toml authors line is exempt)
  • USER=runner cargo test --lib tracked_file (not CI) — fails as intended, naming .github/workflows/ci.yml, release-plz.yml, CHANGELOG.md and more; this is the evidence for the CI decision
  • mise run line-check — no file newly over 3743 lines
  • hk pre-push gate, including mise run coverage, run by git push — pass

Coverage gaps

  • On CI the repository-wide scan runs with no needles, so it is enforced only where a developer's machine runs the suite (locally, and through hk's pre-push gate). The matching rules themselves run on CI through the synthetic tests.
  • An account name that is itself an ordinary word (say mark) will match prose as a whole word. Nothing in the repository can tell that apart from the name, and no test covers it.
  • tracked_files needs git and a work tree. Run outside one, the test fails rather than scanning nothing.

Risks and rollout

  • Test-only change. No CLI, config, or on-disk surface is affected.

Decisions taken

  1. Where the needles come from
    Taken: the environment of the machine running the test (accepted unrebutted)
    Rejected: a fixed list in the repository - that list is the violation
    Reverses: restore the fixed list
  2. Needles on CI
    Taken: none when CI is set and non-empty
    Rejected: deriving them from the runner - USER=runner makes the scan fail on ci.yml, release-plz.yml, CHANGELOG.md and sources that use "runner" as an ordinary word, and the runner's identity is nobody's
    Reverses: drop the on_ci early return in user_specific_needles
  3. Word boundary for an account name
    Taken: no alphanumeric on either side
    Rejected: leading boundary only - the name now comes from whatever machine runs the test, and a short name is the start of many words (mark/markdown, will/willing)
    Reverses: drop the trailing-character check in contains_token
  4. What counts as too short
    Taken: an account name under 4 characters, and a path with fewer than 2 named components
    Rejected: no threshold - a 3-letter name, or /root, matches all over ordinary text and identifies no person
    Reverses: change SHORTEST_ACCOUNT_NAME / FEWEST_PATH_COMPONENTS
  5. What is read
    Taken: every file git ls-files lists, whatever is in the working tree outside them is not
    Rejected: walking the directory - untracked files like coverage output and local tool state would be scanned
    Reverses: replace tracked_files with a directory walk

Closes #131

The guard stored one developer's account names and mount path as string
fragments, which is itself the user-specific data invariant 5 forbids, and
it read src/ only. Derive the needles at test time from $USER, $HOME and
the checkout path, skipping ones too short to identify anyone and none on
CI, and scan every git-tracked file except Cargo.toml's authors line.

Closes #131
@justin13888 justin13888 added the de-slop Repository cleanup: documentation, structure, and test adequacy label Oct 3, 2026
@justin13888
justin13888 merged commit a917d1a into master Oct 3, 2026
5 checks passed
@justin13888
justin13888 deleted the refactor/131-derive-user-needles-from-env branch October 3, 2026 14:39
@github-actions github-actions Bot mentioned this pull request Oct 3, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

de-slop Repository cleanup: documentation, structure, and test adequacy

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Hold invariant 5 without storing anyone's identity in the repository

1 participant