From 745888422082d2f0337570291291432e3274b517 Mon Sep 17 00:00:00 2001 From: JSONbored <49853598+JSONbored@users.noreply.github.com> Date: Sun, 12 Jul 2026 06:26:57 -0700 Subject: [PATCH 1/2] fix(config): stop documenting the retired blockedPaths key as a live feature blockedPaths was fully retired from the FocusManifest parser in #2974 (2026-07-04) -- it produces zero findings and is not enforceable under any gate.manifestPolicy mode. That retirement commit missed the two checked-in bootstrap templates (.gittensory.yml.example, config/examples/gittensory.full.yml), which kept documenting it with example values and false claims that it feeds guidance/becomes an enforceable blocker. This is very likely why all 3 live self-hosted repos still carry a dead blockedPaths: [] key today. Fixes the false claims in both templates (byte-synced, both edited identically), fixes the self-hosting docs page's self-contradicting paragraph, and extends config-templates.test.ts to also run lintManifestText (the only function with the retired-field check) so a retired field reintroduced into a shipped template fails CI automatically going forward -- the previous zero-warnings test used the lenient parser, which structurally cannot catch this class of bug. Also removes the dead "manifest_blocked_path" string from processors.ts's policyCodes Set (no producer has emitted that code since the retirement). Refs #5294 --- .gittensory.yml.example | 25 ++++++++----------- .../docs.self-hosting-configuration.tsx | 12 ++++----- config/examples/gittensory.full.yml | 25 ++++++++----------- src/queue/processors.ts | 1 - test/unit/config-templates.test.ts | 13 ++++++++++ test/unit/queue-2.test.ts | 7 +++--- 6 files changed, 44 insertions(+), 39 deletions(-) diff --git a/.gittensory.yml.example b/.gittensory.yml.example index d76e7049e1..e354ff6d9f 100644 --- a/.gittensory.yml.example +++ b/.gittensory.yml.example @@ -48,24 +48,21 @@ # ---------------------------------------------------------------------------- # 1. FOCUS / GUARDRAILS (focus manifest) # ---------------------------------------------------------------------------- -# Declares the repo's work areas and off-limits paths. wantedPaths/blockedPaths feed advisory-only -# guidance findings; testExpectations/linkedIssuePolicy feed manifest_missing_tests and -# manifest_linked_issue_required, which — when `gate.manifestPolicy: block` is set below — can become -# enforceable blockers. Hard path HOLDS are a separate mechanism: settings.hardGuardrailGlobs, below. +# Declares the repo's work areas. wantedPaths feeds advisory-only guidance findings; +# testExpectations/linkedIssuePolicy feed manifest_missing_tests and manifest_linked_issue_required, +# which — when `gate.manifestPolicy: block` is set below — can become enforceable blockers. Hard path +# HOLDS are a separate mechanism: settings.hardGuardrailGlobs, below. # Work areas the maintainer wants. PRs touching these are preferred/encouraged. # Glob list. Default: [] (no preference). wantedPaths: - "src/**" -# Paths off-limits to contributors — CONTRIBUTOR-FACING GUIDANCE ONLY. Touching one surfaces in -# onboarding guidance and gittensory's own risk-reason commentary; it never blocks, holds, or produces -# a gate finding, even under gate.manifestPolicy: block. The only mechanism that actually holds a PR -# for a touched path is settings.hardGuardrailGlobs, below. -# Glob list. Default: [] (nothing listed). -blockedPaths: - - "vendor/**" - - ".github/workflows/**" +# blockedPaths is LEGACY and fully retired (#2974, 2026-07-04): the FocusManifest parser no longer +# reads this key at all, it produces zero findings, and it is not enforceable under any +# gate.manifestPolicy mode. A key left over from an older config has no runtime effect other than a +# migration warning from `npm run selfhost:config-lint`. Use settings.hardGuardrailGlobs below for +# real, enforceable path-based holds. # Labels the maintainer prefers on incoming PRs; a missing preferred label is # surfaced (never blocks). String list. Default: []. @@ -269,8 +266,8 @@ gate: mergeReadiness: off # Manifest-policy gate. When `block`, this repo's declared policy from - # section 1 (blockedPaths, required linked issue, testExpectations) becomes - # an enforceable blocker. Independent of mergeReadiness. + # section 1 (required linked issue, testExpectations) becomes an + # enforceable blocker. Independent of mergeReadiness. # off | advisory | block. Default: off. manifestPolicy: off diff --git a/apps/gittensory-ui/src/routes/docs.self-hosting-configuration.tsx b/apps/gittensory-ui/src/routes/docs.self-hosting-configuration.tsx index 601349a67b..7da2bb8bb1 100644 --- a/apps/gittensory-ui/src/routes/docs.self-hosting-configuration.tsx +++ b/apps/gittensory-ui/src/routes/docs.self-hosting-configuration.tsx @@ -605,15 +605,13 @@ features:

blockedPaths (top-level, alongside wantedPaths) is{" "} - contributor-facing guidance only — it never blocks, holds, or produces a - gate finding. A touched path surfaces in contributor onboarding guidance and in - gittensory's own risk-reason commentary, but the gate itself never enforces it.{" "} + fully retired (#2974) — the FocusManifest parser no longer reads this key at + all, it produces zero findings, and it is not enforceable under any{" "} + gate.manifestPolicy mode. Setting it in a config produces only a migration + warning from npm run selfhost:config-lint, nothing else.{" "} The only mechanism that actually holds a PR for a touched path is{" "} settings.hardGuardrailGlobs (config-as-code only, described above) — a - would-merge PR that touches a configured guardrail glob is held for manual review regardless - of blockedPaths. A legacy top-level blockedPaths that once acted - as an enforcement mechanism is retired; setting it produces a migration warning pointing at{" "} - settings.hardGuardrailGlobs. Default [] (nothing listed). + would-merge PR that touches a configured guardrail glob is held for manual review.

settings anti-abuse block

diff --git a/config/examples/gittensory.full.yml b/config/examples/gittensory.full.yml index db42c3d608..6c5091006d 100644 --- a/config/examples/gittensory.full.yml +++ b/config/examples/gittensory.full.yml @@ -62,24 +62,21 @@ # ---------------------------------------------------------------------------- # 1. FOCUS / GUARDRAILS (focus manifest) # ---------------------------------------------------------------------------- -# Declares the repo's work areas and off-limits paths. wantedPaths/blockedPaths feed advisory-only -# guidance findings; testExpectations/linkedIssuePolicy feed manifest_missing_tests and -# manifest_linked_issue_required, which — when `gate.manifestPolicy: block` is set below — can become -# enforceable blockers. Hard path HOLDS are a separate mechanism: settings.hardGuardrailGlobs, below. +# Declares the repo's work areas. wantedPaths feeds advisory-only guidance findings; +# testExpectations/linkedIssuePolicy feed manifest_missing_tests and manifest_linked_issue_required, +# which — when `gate.manifestPolicy: block` is set below — can become enforceable blockers. Hard path +# HOLDS are a separate mechanism: settings.hardGuardrailGlobs, below. # Work areas the maintainer wants. PRs touching these are preferred/encouraged. # Glob list. Default: [] (no preference). wantedPaths: - "src/**" -# Paths off-limits to contributors — CONTRIBUTOR-FACING GUIDANCE ONLY. Touching one surfaces in -# onboarding guidance and gittensory's own risk-reason commentary; it never blocks, holds, or produces -# a gate finding, even under gate.manifestPolicy: block. The only mechanism that actually holds a PR -# for a touched path is settings.hardGuardrailGlobs, below. -# Glob list. Default: [] (nothing listed). -blockedPaths: - - "vendor/**" - - ".github/workflows/**" +# blockedPaths is LEGACY and fully retired (#2974, 2026-07-04): the FocusManifest parser no longer +# reads this key at all, it produces zero findings, and it is not enforceable under any +# gate.manifestPolicy mode. A key left over from an older config has no runtime effect other than a +# migration warning from `npm run selfhost:config-lint`. Use settings.hardGuardrailGlobs below for +# real, enforceable path-based holds. # Labels the maintainer prefers on incoming PRs; a missing preferred label is # surfaced (never blocks). String list. Default: []. @@ -283,8 +280,8 @@ gate: mergeReadiness: off # Manifest-policy gate. When `block`, this repo's declared policy from - # section 1 (blockedPaths, required linked issue, testExpectations) becomes - # an enforceable blocker. Independent of mergeReadiness. + # section 1 (required linked issue, testExpectations) becomes an + # enforceable blocker. Independent of mergeReadiness. # off | advisory | block. Default: off. manifestPolicy: off diff --git a/src/queue/processors.ts b/src/queue/processors.ts index eca651be86..58de1a6252 100644 --- a/src/queue/processors.ts +++ b/src/queue/processors.ts @@ -7317,7 +7317,6 @@ async function maybeApplyManifestPolicyGate( hasNoIssueRationale: hasClearNoIssueRationale(args.pr), }); const policyCodes = new Set([ - "manifest_blocked_path", "manifest_linked_issue_required", "manifest_missing_tests", ]); diff --git a/test/unit/config-templates.test.ts b/test/unit/config-templates.test.ts index c30e7eb3ed..d5dd0600e7 100644 --- a/test/unit/config-templates.test.ts +++ b/test/unit/config-templates.test.ts @@ -9,6 +9,7 @@ import { resolveReviewPromptOverrides, reviewConfigToJson, } from "../../src/signals/focus-manifest"; +import { lintManifestText } from "../../src/selfhost/config-lint"; // #1682: self-host operators need discoverable, copy-paste templates under config/examples/ that // parse cleanly, stay in sync with the canonical root files, and keep the minimal starter safe. @@ -51,6 +52,18 @@ describe("config/examples review templates (#1682)", () => { expect(manifest.features.rag).toBeNull(); }); + // #5294 (drift-audit roadmap #5270): parseFocusManifestContent above is the LENIENT parser (never + // warns on an unrecognized/retired top-level field by design) -- it structurally cannot catch a + // retired field like the old `blockedPaths` example creeping back into these shipped templates. + // lintManifestText is the ONLY function with the retired-field check (config-lint.ts's + // RETIRED_FIELD_MIGRATION_WARNINGS); assert it separately so a retired field reintroduced here fails + // CI instead of only being caught by eye. + it("lints gittensory.full.yml with zero warnings, including no retired top-level fields", () => { + const result = lintManifestText(readConfigExample("gittensory.full.yml")); + expect(result.warnings).toEqual([]); + expect(result.ok).toBe(true); + }); + it("documents every shipped review.auto_review eligibility knob in gittensory.full.yml (#2055)", () => { const full = readConfigExample("gittensory.full.yml"); for (const field of ["skip_labels", "skip_docs_only", "max_added_lines", "max_files"]) { diff --git a/test/unit/queue-2.test.ts b/test/unit/queue-2.test.ts index c13ac3f7f2..da4d86428d 100644 --- a/test/unit/queue-2.test.ts +++ b/test/unit/queue-2.test.ts @@ -3524,9 +3524,10 @@ describe("queue processors", () => { }); // #4607 (maybeApplyManifestPolicyGate extraction): buildFocusManifestGuidance can produce findings whose - // code is NOT one of the three enforceable manifest-policy codes (manifest_blocked_path / - // manifest_linked_issue_required / manifest_missing_tests) -- e.g. manifest_off_focus, when wantedPaths is - // configured and no changed path matches it. Those non-enforceable findings must be filtered out before + // code is NOT one of the two enforceable manifest-policy codes (manifest_linked_issue_required / + // manifest_missing_tests -- manifest_blocked_path was retired #2974/removed from this Set #5294) -- e.g. + // manifest_off_focus, when wantedPaths is configured and no changed path matches it. Those non-enforceable + // findings must be filtered out before // ever reaching the advisory/gate, never published alongside an enforceable one from the same pass. it("filters out a non-enforceable manifest finding (manifest_off_focus) while still surfacing an enforceable one", async () => { const env = createTestEnv({ GITHUB_APP_PRIVATE_KEY: await generatePrivateKeyPem() }); From b34d2417754231d82f1c0d6806ae47897450ff2e Mon Sep 17 00:00:00 2001 From: JSONbored <49853598+JSONbored@users.noreply.github.com> Date: Sun, 12 Jul 2026 06:56:21 -0700 Subject: [PATCH 2/2] fix(ui): prettier formatting for the blockedPaths retirement doc fix CI's ui:lint caught formatting the earlier commit's editor didn't apply. No content change, whitespace wrapping only. --- .../src/routes/docs.self-hosting-configuration.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/gittensory-ui/src/routes/docs.self-hosting-configuration.tsx b/apps/gittensory-ui/src/routes/docs.self-hosting-configuration.tsx index 7da2bb8bb1..a77a772954 100644 --- a/apps/gittensory-ui/src/routes/docs.self-hosting-configuration.tsx +++ b/apps/gittensory-ui/src/routes/docs.self-hosting-configuration.tsx @@ -605,8 +605,8 @@ features:

blockedPaths (top-level, alongside wantedPaths) is{" "} - fully retired (#2974) — the FocusManifest parser no longer reads this key at - all, it produces zero findings, and it is not enforceable under any{" "} + fully retired (#2974) — the FocusManifest parser no longer reads this key + at all, it produces zero findings, and it is not enforceable under any{" "} gate.manifestPolicy mode. Setting it in a config produces only a migration warning from npm run selfhost:config-lint, nothing else.{" "} The only mechanism that actually holds a PR for a touched path is{" "}