Repository navigation
chore(policy): remove employer name from current files; hashed employer-data gate - #27
Merged
Merged
Conversation
Blocked terms are committed only as SHA-256 hashes; the scanner hashes every word and adjacent-word phrase in tracked files and paths, honors an optional BLOCKED_TERMS env var, skips only generated junk dirs, and exits 2 when the hash file is missing, empty, or malformed. Co-authored-by: Jeff Otterson <Jott2121@users.noreply.github.com>
…ta wording Co-authored-by: Jeff Otterson <Jott2121@users.noreply.github.com>
Drops the literal pattern and the path/byline exclusions; the edit hook calls the same scanner. Co-authored-by: Jeff Otterson <Jott2121@users.noreply.github.com>
…mption The committed hash list stays the fail-closed base. EMPLOYER_MARKERS adds a case-insensitive regex alternation on top; an invalid one fails the scan. The only exclusions are now the hash file and generated junk dirs. Co-authored-by: Jeff Otterson <Jott2121@users.noreply.github.com>
It reads .github/ and scripts/, which mutmut does not copy; the normal pytest jobs still run it, same as test_guard_shell.py. Co-authored-by: Jeff Otterson <Jott2121@users.noreply.github.com>
🧪 Mutation score: 99%Crucible injected 1171 real defects into
Show the survivorsCoverage measures what ran. This measures what would be caught. crucible · no model, no API key, $0 |
Jott2121
marked this pull request as ready for review
October 11, 2026 16:59
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This removes an employer reference from the current files. Older commits still contain it; a history rewrite is out of scope by the owner's choice.
What
AGENTS.md,.cursor/rules/00-core-principles.mdc,.cursor/BUGBOT.md,.cursor/hooks/format-and-scan.sh,.github/workflows/ci.yml. All five came from the setup PR (chore: add Cursor agent setup and receipt checks #26), which is already merged. New wording: never add anything from an employer's systems, workforce data, internal URLs, documents, or proprietary/export-controlled material.no-employer-datagate working and fail-closed without the literal name in the repo:.github/blocked-terms.sha256stores only SHA-256 hashes of the normalized blocked terms (lowercase words joined by single spaces), each followed by its word count. There are 4 entries: the name, the two-word name, the concatenated form, and the abbreviation.scripts/scan_blocked_terms.py(stdlib only) hashes every word and adjacent-word phrase in every tracked file and file path, and fails on any match. It reports a hit aspath:lineplus a hash prefix, never the matched text.EMPLOYER_MARKERSenv var / Actions secret: a regex alternation matched case-insensitively on top of the hashes. It is additive only. With no secret set, the hash list still catches the name.EMPLOYER_MARKERSdoesn't compile, or if a target can't be read..cursor/,AGENTS.md, and.github/, and dropped the author-byline lines. All of that is gone. Now the whole tracked tree is scanned, includingexperiments/,paper/, fixtures,AGENTS.md,.cursor/, and.github/. The only exclusions are the hash file itself and generated junk dirs (.git,node_modules,build,dist,__pycache__,.venv,mutants). The test fixtures are created at runtime in temp dirs and are never tracked.format-and-scan.shnow calls the same scanner. A scanner error also logs a warning. The secret-key patterns are unchanged.verify-receiptsstep 3 now runs the scanner. BUGBOT now treats loosening the hash file or scanner as blocking.pyproject.toml: added--ignore=tests/test_scan_blocked_terms.pyto the mutmut test selection. The test reads.github/andscripts/, which aren't in mutmut's sandbox. Same precedent astest_guard_shell.py; the normal pytest jobs still run it.Employer-name check
mainat b99e4a6. After, on this branch: empty output..cursor/BUGBOT.md:9: the employer abbreviation, in a list of blocked names. Removed.docs/assets/demo.gif,paper/crucible-paper.pdf: binary matches only. They are those two bytes occurring inside compressed image/stream data. Text extracted from both paper PDFs with pypdf has no employer reference.paper/*.txt, the paper drafts and PDFs,experiments/, docs, and fixtures. The paper bylines read "(Independent)" or a university affiliation, which is not the employer, so they were left as is.How verified
Scanner tests (
python -m pytest tests/test_scan_blocked_terms.py -v): 18 passed. Highlights:test_clean_tree_passes: whole repo, exit 0.test_hashed_word_planted_in_temp_file_is_caught,test_hashed_two_word_phrase_matches_across_punctuation_and_lines: terms planted in temp files, caught, and not echoed.test_employer_markers_regex_adds_terms_without_echoing_them,test_unset_employer_markers_still_enforces_hashes.test_whole_tree_mode_scans_data_policy_and_config_folders_and_paths: hits inresults/,fixtures/(path),AGENTS.md,.cursor/,.github/.test_hash_file_itself_is_not_scanned,test_generated_junk_dirs_are_skipped,test_export_control_marker_is_caught,test_whole_words_only.EMPLOYER_MARKERSset) / malformed hash file, invalid regex, and unreadable target all exit 2.test_scanner_source_needs_no_self_exemption,test_ci_runs_scanner_with_optional_secret.Against the real committed hashes, I planted each form of the actual name in
/tmp/plant.txt(outside the repo) with no secret set:Each run exited 1. A file with
LM Studio and LLM and LMSexits 0. Clean tree:scan_blocked_terms: clean (799 files, 4 hashed terms), exit 0.CI on 115f887, all green:
scan_blocked_terms: clean (799 files, 4 hashed terms))verify-receipts result (
.cursor/skills/verify-receipts/SKILL.md)ruff check src tests: pass (exit 0)python -m pytest -q -m "not slow" --cov --cov-report=term-missing --cov-fail-under=90: pass. 476 passed, 9 deselected, coverage 95.54% (run at 418bc0a; the only later change is the mutmut ignore line inpyproject.toml).python -m pytest -q -m slow: pass. 9 passed, 472 deselected.python scripts/check_receipts.py:receipts ok(H1 b=105 c=0 p=4.9×10⁻³²; E-B1 0.783 [0.592, 0.935]; E-B2 0.178 [0.039, 0.347]).python3 scripts/scan_blocked_terms.py: clean, exit 0.--cov-fail-under90, pyprojectfail_under90, and mutationfail-under"95" are all unchanged. No tests skipped or removed.Numbers changed
None. The README badge and
AGENTS.mdsay 462 tests, butmainalready collects 467, so that was stale before this PR. This PR adds 18 (485 total). I left the count as is to keep this PR to one intent.Risks / limits
xNAMEy) is not caught. The concatenated two-word form is hashed separately for that reason.git grep -I.EMPLOYER_MARKERSis optional. If the owner wants extra terms, add an Actions secret namedEMPLOYER_MARKERS. Nothing is required for this PR to be green.Not done
mainbefore this fix; it doesn't edit them.