docs(config): make .gittensory.yml.example genuinely exhaustive, add a drift check - #3635
Conversation
…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 didn't find any vulnerabilities or security issues in this PR. |
|
Tip 🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩 ✅ Gittensory review result - approve/merge recommendedReview updated: 2026-07-05 21:14:15 UTC
✅ Suggested Action - Approve/Merge
Review summary Nits — 6 non-blocking
Review context
Contributor next steps
Signal definitions
🟩 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.
|
Codecov Report✅ All modified and coverable lines are covered by tests. 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:
|
… 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.
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.
* 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)
Closes #1670
Summary
.gittensory.yml.exampleis meant to be the exhaustive reference for every supportedgate:/settings:/review:/features:/contentLane:/repoDocGeneration:field — but afield-by-field audit against the actual parser types (
src/signals/focus-manifest.ts) found it hadquietly 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,.pendingClosureLabelreview.*fields:footer/note/fields/enrichment/profile/security_focus/inline_comments/suggestions/changed_files_summary/path_instructions/instructions/pre_merge_checks/ai_modelrepoDocGeneration:blockDocumented every one of them, matching the existing house style (dense comments, type/default/
allowed-values, issue-number references).
.gittensory.minimal.yml(#2054, already shipped) neededno 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 doctoken. 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 (
blacklistLabelandpendingClosureLabelwere 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 generatedSELFHOST_ENV_REFERENCE_ROWSlist (apps/gittensory-ui/src/lib/selfhost-env-reference.ts), sincethat 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
type(scope): short summaryConventional Commit format.CONTRIBUTING.md; nosite//CNAME/VitePress changes.Closes #1670.Validation
git diff --checknpm 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). Nosrc/**files changed at all in this PR(only
.gittensory.yml.example,config/examples/README.md, andtest/unit/focus-manifest.test.ts),so there is zero Codecov
codecov/patchobligation — Codecov only measuressrc/**. GitHub CIruns the full suite/gate on push regardless.
npm run test:workers/npm run build:mcp/npm run test:mcp-pack— not run; nothing inthose surfaces touched.
npm run ui:openapi:check/ui:lint/ui:typecheck/ui:build— not run; no API/schema orapps/gittensory-ui/**source changes (only a doc cross-link inconfig/examples/README.md).npm audit --audit-level=moderate— not run; no dependency changes.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:
test:ci/test:coverage/npm auditpass, since GitHub CI runs the complete gate on push andre-running the whole suite by hand for a docs-only change with no
src/**diff is redundant.Safety
exposed — every new example value is a generic placeholder, matching the file's existing style.
UI Evidencesection included.