Skip to content

refactor(selfhost): dual-read .loopover.yml config filename alongside .gittensory.yml - #5566

Merged
JSONbored merged 1 commit into
mainfrom
loopover/config-filename-dual-read
Jul 13, 2026
Merged

refactor(selfhost): dual-read .loopover.yml config filename alongside .gittensory.yml#5566
JSONbored merged 1 commit into
mainfrom
loopover/config-filename-dual-read

Conversation

@JSONbored

Copy link
Copy Markdown
Owner

Summary

Both the self-host per-repo config loader (src/selfhost/private-config.ts) and the public-repo focus-manifest loader (src/signals/focus-manifest-loader.ts) now try every .loopover.{yml,yaml,json} candidate, at every location, before any .gittensory.{yml,yaml,json} candidate — an existing repo/self-hoster with only the legacy filename keeps working byte-identical, and a new-brand file at the same location wins outright over a stale legacy one sitting next to it. src/review/guardrail-config.ts's config-as-code guardrail globs gain the same 6 new-brand entries so a .loopover.yml edit gets the identical contributor-hold protection a .gittensory.yml edit already gets.

Fixes a real latent bug found while extending the candidate list: the flat {owner}__{repo}.<ext> fallback path was built via base.slice(".gittensory".length), a magic-number slice that would have silently produced garbage paths (".loopover.yml".slice(11)"ml") once a 13-character new-brand basename was prepended. Replaced with a brand-agnostic CONFIG_EXTENSIONS constant derived positionally.

Also fixes two gaps caught during verification, neither in the original scope:

  • packages/gittensory-engine/src/review/guardrail-config.ts — a hand-duplicated, CI-enforced twin of the src/ file above (scripts/check-engine-parity.ts) that had drifted after only the src/ copy was updated.
  • packages/gittensory-engine/src/objective-anchor.ts's CONFIG_FILENAMES set (feeds anti-slop/objective-anchor change-kind scoring) still only recognized the legacy filename; added the new-brand entry plus a new vitest-side test, since this file's own change-kind logic is otherwise covered almost exclusively by its node:test suite, which Codecov's vitest-based coverage can't see.

Updates every self-hosting docs page, the config-generator UI's rendered filename, and README/CONTRIBUTING/example templates to present the new filename as canonical while noting the legacy one still works.

Deliberately unchanged

  • docker-compose.yml's ./gittensory-config volume mount and the gittensory-config/ example directory name — a hard bind path, not a graceful-fallback read. Renaming it would silently mount a new, empty directory for anyone still using the stock default, with no error to surface.
  • The .gittensory.yml/.gittensory.yml.example template files themselves.
  • scripts/gittensory-config-lint.ts's CLI default (explicit-arg tool, not a silent runtime path).

Test plan

  • New precedence tests covering legacy-only, new-brand-only (all 3 extensions), and new-wins-over-legacy at both per-repo and global-root locations, including a mixed-extension case.
  • Fixed 4 pre-existing tests (queue-2.test.ts, queue-4.test.ts) whose fetch mocks used a permissive catch-all that no longer faithfully modeled a real GitHub 404 once new-brand candidates are tried first — this was a real behavior change the reorder exposed, not a cosmetic update.
  • scripts/check-engine-parity.ts — confirmed passing after porting the guardrail-globs fix into the engine twin (was failing before the fix, with 4 real test failures).
  • New test/unit/engine-objective-anchor-config-classification.test.ts, verified via targeted coverage inspection that it genuinely exercises CONFIG_FILENAMES.has() for both filenames (not just a module-load-time hit).
  • Full npm run test:ci gate green (twice — before and after rebasing onto a moved origin/main).
  • npm audit --audit-level=moderate — 0 vulnerabilities.

Closes #4773.

… .gittensory.yml

Both the self-host per-repo config loader (src/selfhost/private-config.ts)
and the public-repo focus-manifest loader (src/signals/focus-manifest-loader.ts)
now try every .loopover.{yml,yaml,json} candidate, at every location, before
any .gittensory.{yml,yaml,json} candidate -- an existing repo/self-hoster
with only the legacy filename keeps working byte-identical, and a new-brand
file at the same location wins outright over a stale legacy one sitting
next to it. src/review/guardrail-config.ts's config-as-code guardrail globs
gain the same 6 new-brand entries so a .loopover.yml edit gets the identical
contributor-hold protection a .gittensory.yml edit already gets.

Fixes a real latent bug found while extending the candidate list: the flat
{owner}__{repo}.<ext> fallback path was built via
`base.slice(".gittensory".length)`, a magic-number slice that would have
silently produced garbage paths (".loopover.yml".slice(11) -> "ml") once a
13-character new-brand basename was prepended. Replaced with a
brand-agnostic CONFIG_EXTENSIONS constant derived positionally.

Also fixes two gaps the diff's own verification caught, neither in the
originally-scoped file list:
- packages/gittensory-engine/src/review/guardrail-config.ts -- a
  hand-duplicated, CI-enforced twin of the src/ file above
  (scripts/check-engine-parity.ts) that had drifted after only the src/
  copy was updated.
- packages/gittensory-engine/src/objective-anchor.ts's CONFIG_FILENAMES set
  (feeds anti-slop/objective-anchor change-kind scoring) still only
  recognized the legacy filename; added the new-brand entry plus a new
  vitest-side test, since this file's own change-kind logic is otherwise
  covered almost exclusively by its node:test suite, which Codecov's
  vitest-based coverage can't see.

Updates every self-hosting docs page, the config-generator UI's rendered
filename, and README/CONTRIBUTING/example templates to present the new
filename as canonical while noting the legacy one still works.

Deliberately unchanged: docker-compose.yml's ./gittensory-config volume
mount and the gittensory-config/ example directory name (a hard bind path,
not a graceful-fallback read -- renaming it would silently mount a new,
empty directory for anyone still using the stock default, with no error to
surface); the .gittensory.yml/.gittensory.yml.example template files
themselves; scripts/gittensory-config-lint.ts's CLI default (explicit-arg
tool, not a silent runtime path).

Closes #4773.
@superagent-security

Copy link
Copy Markdown
Contributor

Superagent didn't find any vulnerabilities or security issues in this PR.

@cloudflare-workers-and-pages

Copy link
Copy Markdown

Deploying with  Cloudflare Workers  Cloudflare Workers

The latest updates on your project. Learn more about integrating Git with Workers.

Status Name Latest Commit Preview URL Updated (UTC)
✅ Deployment successful!
View logs
gittensory-ui c717075 Commit Preview URL

Branch Preview URL
Jul 13 2026, 05:49 AM

@JSONbored
JSONbored merged commit 0798d02 into main Jul 13, 2026
16 checks passed
@JSONbored
JSONbored deleted the loopover/config-filename-dual-read branch July 13, 2026 05:50
@codecov

codecov Bot commented Jul 13, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 94.96%. Comparing base (6ecd26a) to head (c717075).
⚠️ Report is 1 commits behind head on main.
✅ All tests successful. No failed tests found.

Additional details and impacted files
@@            Coverage Diff             @@
##             main    #5566      +/-   ##
==========================================
+ Coverage   94.91%   94.96%   +0.04%     
==========================================
  Files         572      572              
  Lines       45369    45370       +1     
  Branches    14680    14680              
==========================================
+ Hits        43064    43087      +23     
+ Misses       1571     1532      -39     
- Partials      734      751      +17     
Flag Coverage Δ
shard-1 44.12% <0.00%> (-0.05%) ⬇️
shard-2 35.72% <100.00%> (+0.13%) ⬆️
shard-3 32.16% <100.00%> (-0.09%) ⬇️
shard-4 32.92% <0.00%> (+0.10%) ⬆️
shard-5 31.88% <0.00%> (+<0.01%) ⬆️
shard-6 43.90% <0.00%> (-0.01%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

Files with missing lines Coverage Δ
packages/gittensory-engine/src/objective-anchor.ts 24.16% <ø> (+18.33%) ⬆️
...s/gittensory-engine/src/review/guardrail-config.ts 100.00% <ø> (ø)
src/review/guardrail-config.ts 100.00% <ø> (ø)
src/selfhost/private-config.ts 100.00% <100.00%> (ø)
src/signals/focus-manifest-loader.ts 99.18% <ø> (ø)
🚀 New features to boost your workflow:
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@loopover-orb loopover-orb Bot added the gittensor:bug Gittensor-scored bug fix — scores a 0.05x multiplier. label Jul 13, 2026
This was referenced Jul 13, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

gittensor:bug Gittensor-scored bug fix — scores a 0.05x multiplier.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Self-host config filename migration

1 participant