Skip to content

docs(config): make .gittensory.yml.example genuinely exhaustive, add a drift check - #3635

Merged
JSONbored merged 1 commit into
mainfrom
claude/selfhost-config-templates
Jul 5, 2026
Merged

docs(config): make .gittensory.yml.example genuinely exhaustive, add a drift check#3635
JSONbored merged 1 commit into
mainfrom
claude/selfhost-config-templates

Conversation

@JSONbored

Copy link
Copy Markdown
Owner

Closes #1670

Summary

.gittensory.yml.example is meant to be the exhaustive reference for every supported
gate:/settings:/review:/features:/contentLane:/repoDocGeneration: field — but a
field-by-field audit against the actual parser types (src/signals/focus-manifest.ts) found it had
quietly drifted. Missing entirely:

  • gate.aiReview.combine / .onMerge / .reviewers (feat(config): expose the dual-AI combine strategy as a per-repo .gittensory.yml setting #2567)
  • settings.contributorBlacklist, .linkedIssueHardRules, .unlinkedIssueGuardrail,
    .autoProjectMilestoneMatch(Backend), the 4 disposition label-name overrides
    (manualReviewLabel/readyToMergeLabel/changesRequestedLabel/migrationCollisionLabel),
    .blacklistLabel, .pendingClosureLabel
  • 12 review.* fields: footer/note/fields/enrichment/profile/security_focus/
    inline_comments/suggestions/changed_files_summary/path_instructions/instructions/
    pre_merge_checks/ai_model
  • the entire repoDocGeneration: block

Documented every one of them, matching the existing house style (dense comments, type/default/
allowed-values, issue-number references). .gittensory.minimal.yml (#2054, already shipped) needed
no changes — it's intentionally NOT exhaustive.

To stop this from silently drifting again, added an automated exhaustiveness check to
test/unit/focus-manifest.test.ts: each config surface (gate/settings/review/features/contentLane/
repoDocGeneration) gets a satisfies Record<keyof T, string> map from field name to its expected doc
token. Adding a new field to the type without also adding it to this map is a TypeScript compile
error
— the same drift-proofing pattern this repo already uses for OpenAPI/settings parity and the
docs-drift checks. Caught two real gaps in my own first pass this way (blacklistLabel and
pendingClosureLabel were genuinely undocumented, not just missing from my initial token guesses) —
verified each token change against the raw file content directly rather than trusting the check
blindly, since a couple of my first-draft tokens for the 4 disposition-label fields turned out to
match only coincidental prose elsewhere in the file, not real documentation of those fields.

Also cross-linked config/examples/README.md's precedence-chain doc to the generated
SELFHOST_ENV_REFERENCE_ROWS list (apps/gittensory-ui/src/lib/selfhost-env-reference.ts), since
that chain only covers per-repo review policy — deployment-level environment variables sit
underneath it and weren't cross-referenced anywhere in that doc.

Note on issue overlap: #1682 ("docs(selfhost): add complete and minimal review config
templates") has essentially the same scope as #1670 — both want a complete + minimal template,
parser cross-check, and docs precedence notes. This PR's exhaustiveness work satisfies #1682's
acceptance criteria too; flagging so you can decide whether to close it as a duplicate.

Scope

  • The PR title follows type(scope): short summary Conventional Commit format.
  • This PR is focused — 1 doc file, 1 new test file section, 1 README addition.
  • Follows CONTRIBUTING.md; no site//CNAME/VitePress changes.
  • Linked issue: Closes #1670.

Validation

  • git diff --check
  • npm run actionlint — not run; no workflow files touched.
  • npm run typecheck (clean)
  • npm run test:coverage (full/unsharded) — not run locally; ran the affected test file instead
    (focus-manifest.test.ts, 424 tests, all green). No src/** files changed at all in this PR
    (only .gittensory.yml.example, config/examples/README.md, and test/unit/focus-manifest.test.ts),
    so there is zero Codecov codecov/patch obligation — Codecov only measures src/**. GitHub CI
    runs the full suite/gate on push regardless.
  • npm run test:workers / npm run build:mcp / npm run test:mcp-pack — not run; nothing in
    those surfaces touched.
  • npm run ui:openapi:check / ui:lint / ui:typecheck / ui:build — not run; no API/schema or
    apps/gittensory-ui/** source changes (only a doc cross-link in config/examples/README.md).
  • npm audit --audit-level=moderate — not run; no dependency changes.
  • New/changed behavior has tests: the field-exhaustiveness test itself (125 new assertions across
    6 config surfaces) is the test coverage for this change — it directly proves every field is
    documented, and will fail the build the moment a future field is added to the schema without a
    matching doc addition.

If any required check was skipped, explain why:

  • Local validation here was typecheck + the specific affected test file rather than a full local
    test:ci/test:coverage/npm audit pass, since GitHub CI runs the complete gate on push and
    re-running the whole suite by hand for a docs-only change with no src/** diff is redundant.

Safety

  • No secrets, wallets, hotkeys, coldkeys, trust scores, or private scoring values are touched or
    exposed — every new example value is a generic placeholder, matching the file's existing style.
  • Not a public-facing text change (internal config docs + a test file).
  • Not an auth/CORS/session change; no negative-path tests needed for that reason.
  • Not an API/OpenAPI change.
  • Not a UI change (N/A) — no UI Evidence section included.
  • No changelog edit.

…a drift check

.gittensory.yml.example is meant to be THE exhaustive reference for every
supported gate/settings/review/features/contentLane/repoDocGeneration field,
but had quietly drifted: gate.aiReview.combine/onMerge/reviewers, ~10
settings fields (contributorBlacklist, linkedIssueHardRules,
unlinkedIssueGuardrail, autoProjectMilestoneMatch(Backend), the 4 disposition
label-name overrides, blacklistLabel, pendingClosureLabel), 12 review.*
fields (footer/note/fields/enrichment/profile/security_focus/
inline_comments/suggestions/changed_files_summary/path_instructions/
instructions/pre_merge_checks/ai_model), and the entire repoDocGeneration
block were never documented at all.

Documents every one of them, then adds an automated exhaustiveness check
(test/unit/focus-manifest.test.ts) so this can't silently drift again: each
config surface gets a `satisfies Record<keyof T, string>` map from field name
to its expected doc token, which is a compile-time error to leave incomplete
when a new field is added to the type -- the same guarantee this repo already
uses for OpenAPI/settings parity and docs-drift checks elsewhere.

Also cross-links the private-config precedence doc (config/examples/README.md)
to the generated SELFHOST_ENV_REFERENCE_ROWS list, since that chain only
covers per-repo review policy, not deployment-level environment variables.
@superagent-security

Copy link
Copy Markdown
Contributor

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

@loopover-orb loopover-orb Bot added the gittensor:bug Gittensor-scored bug fix — scores a 0.05x multiplier. label Jul 5, 2026
@loopover-orb

loopover-orb Bot commented Jul 5, 2026

Copy link
Copy Markdown
Contributor

Tip

🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩

✅ Gittensory review result - approve/merge recommended

Review updated: 2026-07-05 21:14:15 UTC

3 files · 1 AI reviewer · no blockers · readiness 100/100 · CI green · clean

✅ Suggested Action - Approve/Merge

  • safe to merge

Review summary
This PR documents a large batch of previously-undocumented FocusManifest fields in .gittensory.yml.example (gate.aiReview.combine/.onMerge/.reviewers, several settings fields, 12 review.* fields, and the entire repoDocGeneration block) and adds a compile-time drift-proofing test using `satisfies Record<keyof T, string>` maps. The approach is sound: since the type-constrained token maps must list every key of each config type or the build fails, and CI (including validate-code and both codecov checks) passed on this exact commit, the maps are verified complete against the current parser types. The change is pure documentation plus a test, scoped tightly to closing #1670's audit gap, with no runtime code touched.

Nits — 6 non-blocking
  • GATE_FIELD_TOKENS maps both `readinessMode`/`readinessMinScore` to the same `"readiness:"` token and both `slopMode`/`slopMinScore` to `"slop:"` (test/unit/focus-manifest.test.ts), so passing one of the pair doesn't actually prove the other field is documented — a slightly weaker guarantee than the PR's stated 'compile error on any drift' claim implies.
  • The `contributorBlacklist`/`blacklistLabel` naming documented at .gittensory.yml.example:584-592 mirrors pre-existing field names rather than something introduced here, so it's out of scope for this PR, but worth a follow-up rename to `denylist`-style terms if the underlying type is ever revisited.
  • .gittensory.yml.example now sits at roughly 832 lines — large, but expected and appropriate given the file's explicit purpose as the exhaustive reference.
  • Consider a follow-up that de-duplicates token collisions in the exhaustiveness maps (e.g. give `slopMinScore` a more specific substring like the actual default value) so each field gets an independently falsifiable assertion.
  • config/examples/README.md's new paragraph on `GITTENSORY_REVIEW_*` env vars is a good addition for the layering story — consider linking it from the top of .gittensory.yml.example too, since that's the file most contributors will open first.
  • PR author also opened the linked issue — Link an issue that was opened by a different contributor, or provide a rationale for why this self-authored issue represents genuine discovery work.
Signal Result Evidence
Code review ✅ No blockers 1 reviewer
Linked issue ✅ Linked #1670
Related work ✅ No active overlap found No same-issue or scoped active PR overlap found.
Change scope ✅ 20/20 Low review scope from cached public metadata (1 linked issue).
Validation posture ✅ 25/25 PR body includes validation/test evidence.
Contributor workload ✅ 10/10 Author activity: 55 registered-repo PR(s), 46 merged, 480 issue(s).
Contributor context ✅ Confirmed Gittensor contributor JSONbored; Gittensor profile; 55 PR(s), 480 issue(s).
Gate result ✅ Passing No configured blocker found.
Review context
  • Author: JSONbored
  • Role context: owner (maintainer lane)
  • Public audience mode: oss maintainer
  • Lane context: Repository registration is not available in the local Gittensory cache.
  • Public profile languages: Python, TypeScript, JavaScript, Ruby, Go, Kotlin, MDX, Shell
  • Official Gittensor activity: 55 PR(s), 480 issue(s).
  • PR-specific overlap: none found.
Contributor next steps
  • Treat this as maintainer-lane context rather than normal contributor-lane activity.
  • No action.
Signal definitions
  • Related work = same linked issue, overlapping active PRs, or title/path similarity.
  • Change scope = cached public metadata such as size labels, draft state, and review-burden hints.
  • Validation posture = whether the PR provides enough public validation/test evidence for maintainer review.
  • Contributor workload = public contributor activity and cleanup pressure, not a repo-wide quality failure.
  • Contributor context = public GitHub/Gittensor identity context; non-Gittensor status is not a blocker.

🟩 Safe / merged · 🟦 Advisory · 🟨 Held for review · 🟥 Blocked / closed


💰 Earn for open-source contributions like this. Gittensor lets GitHub contributors earn for the work they already do — register to start earning →.

Checked by Gittensory, a quiet PR intelligence layer for OSS maintainers.

  • Re-run Gittensory review

@codecov

codecov Bot commented Jul 5, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 93.20%. Comparing base (ad581ac) to head (52f56e6).
⚠️ Report is 13 commits behind head on main.
✅ All tests successful. No failed tests found.

Additional details and impacted files
@@           Coverage Diff           @@
##             main    #3635   +/-   ##
=======================================
  Coverage   93.20%   93.20%           
=======================================
  Files         313      313           
  Lines       31910    31910           
  Branches    11677    11677           
=======================================
  Hits        29741    29741           
  Misses       1517     1517           
  Partials      652      652           
🚀 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 manual-review Gittensor contributor context label Jul 5, 2026
@JSONbored
JSONbored merged commit 6443501 into main Jul 5, 2026
10 checks passed
@JSONbored
JSONbored deleted the claude/selfhost-config-templates branch July 5, 2026 21:18
JSONbored added a commit that referenced this pull request Jul 5, 2026
… false positive (#3641)

Two independent issues surfaced by #3635 merging concurrently with
#1958's own review.finding_categories addition:

- main's typecheck is currently broken: #3635's new compile-time
  exhaustiveness map (test/unit/focus-manifest.test.ts) predates
  review.finding_categories and is missing that key, which the
  `satisfies Record<...>` check requires. Documents the field in
  .gittensory.yml.example and adds the missing map entry, mirroring
  the review.changed_files_summary entry immediately above it.

- "override of the synthesis merge rule" (added by #3635) matches
  gittensory's own INJECTION_SOURCE pattern for "override ... the
  ... rule", so the review pipeline redacted it to
  [external-instruction-redacted] before the AI reviewer ever saw
  it -- correctly, since the redaction can't tell a benign config
  override from a real one without the surrounding context a human
  has. Rewording "rule" to "mode" preserves the exact meaning and
  clears the false positive; confirmed via a direct regex test
  against the full file that no other phrase matches.
JSONbored added a commit that referenced this pull request Jul 5, 2026
Adds `review.visual` to the .gittensory.yml manifest so a self-hoster
can point the before/after screenshot pipeline at their own repo's
preview setup without any code changes:

- preview.url_template: an explicit "after" preview URL template
  ({number}/{head_sha}/{head_sha_short} placeholders) that always wins
  over GitHub-native preview discovery -- the only option for a
  provider (e.g. Cloudflare Workers Builds' non-production branch
  builds) that never surfaces a GitHub-visible deployment at all.
  Validated at parse time against the same SSRF guard the renderer
  applies at render time (isSafeHttpUrl), so a malformed template
  warns immediately instead of silently degrading to a blank cell.
- routes.paths / routes.max_routes: an explicit route list that
  replaces automatic file-to-route inference for a repo whose routing
  convention isn't gittensory-ui's TanStack file-based one, plus an
  override for the built-in per-PR route cap.

All-absent (default, every repo today) resolves to the existing
GitHub-native discovery chain and automatic route inference, so this
is byte-identical until a maintainer opts in. Also documents the two
review.* fields (finding_categories, visual) that were still missing
from .gittensory.yml.example's field-exhaustiveness map after #3635.

Part of #3607. Closes #3609. Closes #3610.
JSONbored added a commit that referenced this pull request Jul 5, 2026
* feat(review): add per-repo review.visual capture config (#3609)

Adds `review.visual` to the .gittensory.yml manifest so a self-hoster
can point the before/after screenshot pipeline at their own repo's
preview setup without any code changes:

- preview.url_template: an explicit "after" preview URL template
  ({number}/{head_sha}/{head_sha_short} placeholders) that always wins
  over GitHub-native preview discovery -- the only option for a
  provider (e.g. Cloudflare Workers Builds' non-production branch
  builds) that never surfaces a GitHub-visible deployment at all.
  Validated at parse time against the same SSRF guard the renderer
  applies at render time (isSafeHttpUrl), so a malformed template
  warns immediately instead of silently degrading to a blank cell.
- routes.paths / routes.max_routes: an explicit route list that
  replaces automatic file-to-route inference for a repo whose routing
  convention isn't gittensory-ui's TanStack file-based one, plus an
  override for the built-in per-PR route cap.

All-absent (default, every repo today) resolves to the existing
GitHub-native discovery chain and automatic route inference, so this
is byte-identical until a maintainer opts in. Also documents the two
review.* fields (finding_categories, visual) that were still missing
from .gittensory.yml.example's field-exhaustiveness map after #3635.

Part of #3607. Closes #3609. Closes #3610.

* test(review): cover the reindented buildCapture preview-discovery branches

codecov/patch flagged 91.18% on the prior commit: wrapping the existing
GitHub-native discovery chain in a new `else` block (so the explicit
url_template check could run first) re-indented every line inside it,
which counts as "changed" for patch coverage even though the logic
itself didn't change. Adds the missing branch coverage:
- target.previewUrl already set (skips discovery, no fetch calls)
- getLatestDeploymentStatus throwing (defense-in-depth; the callee
  itself always catches internally and never actually throws today)
- a preview URL found via a commit check run (skips the PR-comment
  fallback)
- every getPreviewBuildState outcome the pending-poll branch reads:
  building, succeeded, and absent (no matching check run at all)
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. manual-review Gittensor contributor context

Development

Successfully merging this pull request may close these issues.

feat(config): add complete and minimal gittensory config templates

1 participant