refactor(selfhost): dual-read .loopover.yml config filename alongside .gittensory.yml - #5566
Merged
Merged
Conversation
… .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.
Contributor
|
Superagent didn't find any vulnerabilities or security issues in this PR. |
Deploying with
|
| 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 |
Codecov Report✅ All modified and coverable lines are covered by tests. 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
Flags with carried forward coverage won't be shown. Click here to find out more.
🚀 New features to boost your workflow:
|
This was referenced Jul 13, 2026
Closed
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.
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.ymledit gets the identical contributor-hold protection a.gittensory.ymledit already gets.Fixes a real latent bug found while extending the candidate list: the flat
{owner}__{repo}.<ext>fallback path was built viabase.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-agnosticCONFIG_EXTENSIONSconstant 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 thesrc/file above (scripts/check-engine-parity.ts) that had drifted after only thesrc/copy was updated.packages/gittensory-engine/src/objective-anchor.ts'sCONFIG_FILENAMESset (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 itsnode:testsuite, 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-configvolume mount and thegittensory-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..gittensory.yml/.gittensory.yml.exampletemplate files themselves.scripts/gittensory-config-lint.ts's CLI default (explicit-arg tool, not a silent runtime path).Test plan
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).test/unit/engine-objective-anchor-config-classification.test.ts, verified via targeted coverage inspection that it genuinely exercisesCONFIG_FILENAMES.has()for both filenames (not just a module-load-time hit).npm run test:cigate green (twice — before and after rebasing onto a movedorigin/main).npm audit --audit-level=moderate— 0 vulnerabilities.Closes #4773.