fix(chronometer): resolve git history for subdirectory scans - #2977
Merged
Conversation
The git gate was `(self.root / ".git").exists()`, and `.git` only exists at the repository root -- any scan rooted at a SUBDIRECTORY of a repo (galaxyscope path/to/repo/src, every keyword-rosetta corpus folder) silently lost the whole temporal pipeline: the mtime fallback fired, a fresh checkout's uniform mtimes tripped the TEMPORAL COLLAPSE guard, and every file read the neutral (stability 50, churn 0). - Gate on `git rev-parse --is-inside-work-tree` instead: resolves upward from any subdirectory; a linked worktree's `.git` FILE pointer passes identically; a non-git directory lands in the OS-walk fallback exactly as before. - The history stream gains `--relative -- .`: from a subdirectory, `git log --name-only` emits repo-relative paths while `git ls-files` emits cwd-relative ones, so the churn/mtime maps would have been keyed differently from both the tracked-files denominator and the scanner's scan-root-relative rel_path. Both flags are byte-identical no-ops at the repository root. - The 50% early-exit stopped a 6-file corpus folder after mapping 3 files; full coverage at or below 200 tracked files, monorepo math unchanged above. - Determinism-sensitive harnesses opt out EXPLICITLY now: the golden-crucible test sets GITGALAXY_DISABLE_GIT_HISTORY=1 (config key CHRONOMETER_CONFIG.DISABLE_GIT_HISTORY also honoured) -- before this fix it got temporal neutrality by accident of the broken root check. Both golden legs verified byte-identical (full_precision and zero_dependency venvs, 1 passed each). Closes #2976 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01JaGQfW7WGbGXg54iyBg23j
Contributor
The dead-key audit requires a read key to be written somewhere: DISABLE_GIT_HISTORY joins CHRONOMETER_CONFIG's defaults (False), and the GITGALAXY_DISABLE_GIT_HISTORY env var joins the audit ALLOWLIST on the GITGALAXY_LICENSE_KEY precedent. ruff format reflows the gate condition. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01JaGQfW7WGbGXg54iyBg23j
squid-protocol
marked this pull request as ready for review
September 12, 2026 00:52
squid-protocol
added a commit
that referenced
this pull request
Sep 12, 2026
…l fix (#2980) The README and validation.md consistency sections update to the post-#2977/ kr#130 scoreboard: 56 chartable metrics (54 >=80% in band), open-defect share still 0/2632. Both gain the expansion-on-demand proof point: the corpus's first security-lens plant (one identical secret, every language) read a uniform risk_secrets_risk across all 44 lens-covered languages in a single screened change, with the two data-format exceptions and the measured length dependence ledgered and filed the same day (#2978, #2979); validation.md also notes the commit-age context group now reads measured git history (#2976). Claude-Session: https://claude.ai/code/session_01JaGQfW7WGbGXg54iyBg23j Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
Closed
24 tasks
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.
Closes #2976
Chronometer._initialize_history_scangated git on(self.root / ".git").exists()— true only at a repository root. Any subdirectory scan (galaxyscope repo/src, every keyword-rosetta corpus folder) silently lost the entire temporal pipeline to the mtime fallback + TEMPORAL COLLAPSE guard: neutral(stability 50, churn 0)on every file. This is why the rosetta corpus readsrisk_stabilityflat 50 /risk_churn0 in all 46 languages.The fix (one layer, chronometer only)
git rev-parse --is-inside-work-tree— resolves upward from any subdir; worktree.gitfile pointers pass; non-git dirs keep the exact fallback.--relative -- .on the history stream — from a subdir,git log --name-onlyemits repo-relative paths whilegit ls-filesemits cwd-relative ones; the maps would be keyed differently from both the denominator and the scanner'srel_path. Both flags are byte-identical no-ops at the repo root.GITGALAXY_DISABLE_GIT_HISTORY=1env (orCHRONOMETER_CONFIG.DISABLE_GIT_HISTORY) forces the neutral fallback. The golden-crucible test sets it — it scans a subdirectory of a pinned checkout whose git history is not part of the measured structure, and previously got neutrality only by accident of the broken root check.Verification
keyword-rosetta/data/python: before — collapse warning, 0 files mapped,is_git_tracked: False; after — 6/6 files mapped, real commits/authors/mtimes. Neutral mode reproduces pre-fix values exactly (span pegged to 1y, churn 0).pytest -k "chrono or temporal or churn or stability": 10 passed.🤖 Generated with Claude Code
https://claude.ai/code/session_01JaGQfW7WGbGXg54iyBg23j