# Pins intentional per-repo customizations to installed Loom surfaces so
# `resync-installed.sh` (a routine `chore(loom): resync installed surfaces`
# commit) never overwrites them with upstream Loom's template. One relative
# path per line (relative to .loom/, e.g. "hooks/foo.sh", "roles/bar.md",
# "commands/loom/mine.md"); blank lines and `#` comments are ignored. See
# resync-installed.sh's header comment ("Local-override convention") for the
# full path-shape reference.
#
# NOTE: `scripts/tests/ci-wired.txt` (and its sibling `ci-excluded.txt`) does
# NOT belong in this list, and never has — it is upstream Loom's own CI
# manifest for upstream Loom's own test suite, has zero effect on this repo's
# CI (no workflow here calls `run-ci-suites.sh`), and pinning it would freeze
# it against upstream's own future additions. If you're here because a
# locally-added `.loom/scripts/tests/test-*.sh` suite needs CI wiring, see
# `.loom/docs/local-test-suite-wiring.md` instead (issue #1532).

# #606: champion-epic.md carries a local-only "Re-approval Guard and Rejection
# Idempotency" section (originally #532/#533) that stops duplicate Phase 1
# issue creation on an already-approved epic (epic #375 had its Phase 1
# created three times — #379-381, #376-378, #529-531 — before this guard
# existed) and caps unrevised-rejection loops (#520, rejected 3x with
# identical feedback) with an N=2 escalation to loom:operator-only. This
# section was never upstreamed into rjwalters/loom's own champion-epic.md
# template, so an unpinned resync silently reverted it once already (commit
# 71d46d0, 2026-08-05) — this pin is what prevents a recurrence. If the
# upstream Loom project ever adopts an equivalent mechanism, this pin can be
# dropped and the file resynced normally.
commands/loom/champion-epic.md

# #662: champion.md's Priority 4 (epic-discovery) query carries a local-only
# 5-clause `select()` exclusion filter (loom:evaluating/loom:operator-only/
# loom:blocked/loom:issue/loom:building), matching the filter already used by
# Priorities 2/3, added by #609 (closing #608) so that already-escalated
# epics (e.g. epic #520, repeatedly rejected and capped to
# loom:operator-only) stop being re-surfaced by Champion on every pass. This
# filter was never upstreamed into rjwalters/loom's own champion.md template,
# so an unpinned resync silently reverted it once already (commit 1ae78c6,
# 2026-08-09) — this pin is what prevents a recurrence. If the upstream Loom
# project ever adopts an equivalent filter, this pin can be dropped and the
# file resynced normally.
commands/loom/champion.md

# #668: curator.md/judge.md/doctor.md's "Stale `loom:curating`/`loom:reviewing`/
# `loom:treating` Claim Check" sections carry a local-only "Frozen-Timeline
# Fallback" -- a `RECLAIM_MARKER`/`RECLAIM_COUNT` cross-check plus a
# `gh issue|pr view --json labels,updatedAt` ground-truth read -- added after a
# live-verified false-positive livelock on issue #509 (2026-08-10): a real
# label toggle was confirmed via `gh issue view --json labels`, but
# `/events`/`/timeline` kept returning the same stale `labeled` event for
# several minutes, so `CLAIMED_AT` never advanced and the same "Reclaiming
# stale claim..." comment fired 30+ times. This mitigation was never
# upstreamed into rjwalters/loom's own templates, so an unpinned resync would
# silently drop it and reintroduce the livelock. If the upstream Loom project
# ever adopts an equivalent mitigation, these pins can be dropped and the
# files resynced normally.
commands/loom/curator.md
commands/loom/judge.md
commands/loom/doctor.md

# #1292: hermit-patterns.md's `stateless_ceremony` AST detector carries two
# local-only exclusions added by #1288 (closing #920) — exclusion 4 skips
# custom exception subclasses (base name ending in Error/Exception/Warning,
# which must be classes to be raised/caught) and exclusion 5 skips declarative
# data containers (classes whose body is only class-level `AnnAssign`
# annotations, e.g. dataclasses). Without them the detector was a 100%
# false-positive generator on this tree (107 hits, all false; 8 after the
# fix), which is the recurring-waste failure #920 was filed to end. These
# exclusions were never upstreamed into rjwalters/loom's own
# hermit-patterns.md template (which still has only exclusions 1-3), so an
# unpinned resync would silently revert them and restore the false-positive
# rate with no signal — the same reversion that already happened to #606
# (commit 71d46d0) and #662 (commit 1ae78c6). If the upstream Loom project
# ever adopts an equivalent exclusion, this pin can be dropped and the file
# resynced normally.
commands/loom/hermit-patterns.md

# #1316: scripts/lib/forge-helpers.sh's forge_merge_pr()/forge_auto_merge()
# and scripts/merge-pr.sh's native `loom-daemon forge auto-merge` fallback
# carry a local-only App-installation permission-scope 403 retry (originally
# #1308, closing #1293): forge_merge_pr()/forge_auto_merge() route their `gh
# api` calls through forge_gh_perm_safe (fresh installation-token retry on a
# 403 "not accessible by integration"), and merge-pr.sh's native path detects
# that same 403 via is_app_permission_error() and falls through to the
# (fixed) shell forge_auto_merge path instead of just retrying the native
# binary call again. This fix was never upstreamed into rjwalters/loom's own
# templates, so an unpinned resync silently reverted it once already (commit
# 1edbd2b, "chore: resync installed Loom surfaces") even though #1308 had
# already merged to main — the same reversion pattern as #606/#662/#1292.
# These pins are what prevent a recurrence. If the upstream Loom project ever
# adopts an equivalent retry, these pins can be dropped and the files
# resynced normally.
scripts/lib/forge-helpers.sh
scripts/merge-pr.sh

# #1356: verdict-staleness-guard.sh (and its test) carry a local-only fix
# dropping the nonexistent `merged` field from its `gh pr view --json` request
# and deriving merged-ness from `state == "MERGED"` instead. `gh pr view` has
# no `merged` field and `gh` validates the field list up front, so upstream's
# `--json headRefOid,labels,state,merged` fails the WHOLE call with
# `Unknown JSON field: "merged"` on every currently shipping `gh` (reproduced
# on 2.96.0 and 2.98.0) — which silently darkened step 0 of every Judge pass
# (the Stale-Verdict Sweep) and Champion's verdict-freshness check for every
# verdict-bearing PR. The companion test stubs `gh`'s field-list validation so
# the regression cannot return. This fix was never upstreamed into
# rjwalters/loom's own templates, so an unpinned resync would silently revert
# it — the same reversion that already happened to #606 (commit 71d46d0),
# #662 (commit 1ae78c6), and #1316 (commit 1edbd2b). If the upstream Loom
# project ever adopts an equivalent fix, these pins can be dropped and the
# files resynced normally.
scripts/verdict-staleness-guard.sh
scripts/tests/test-verdict-staleness-guard.sh

# #1546: scripts/dep-recheck-fingerprint.sh's FORMULA_VERSION guard (originally
# #1544/#1545, commit a6f9997) — a literal `FORMULA_VERSION="v1"` constant
# folded into every `dep-recheck`/`operator-premise` marker alongside
# CONCLUSION_HASH so a consumer (check-dep-recheck-idempotency.sh) can tell
# "the hash formula changed under us" apart from "the dependency state
# changed" and never misread the former as the latter — was reverted wholesale
# by an unpinned resync (commit 090cd9c, ~51 minutes after #1545 merged), and
# a second resync landed one minute later (commit fdc5018) compounding the
# damage: it added a brand new `named-dependency` subcommand on top of the
# already-reverted base without restoring the guard, so the file ended up with
# MORE functionality than #1545 shipped but WITHOUT the fix #1545 added. This
# guard was never upstreamed into rjwalters/loom's own dep-recheck-fingerprint.sh
# template (klayout-tools is the only consumer of curator.md's versioned
# `<!-- curator:dep-recheck:<version>:<hash> -->` marker format), so an
# unpinned resync will keep reverting it indefinitely — the same reversion
# pattern as #606/#662/#1292/#1316/#1356. These pins are what prevent a third
# occurrence. If the upstream Loom project ever adopts an equivalent
# formula-version guard, these pins can be dropped and the files resynced
# normally.
scripts/dep-recheck-fingerprint.sh
scripts/tests/test-dep-recheck-fingerprint.sh

# #1749: champion-pr-merge.md carries a local-only propagation from a held
# PR's `loom:operator` state onto the issue(s) it would close — when the
# merge-risk hold (criterion #2) or the critical-file hold (criterion #3)
# applies `loom:operator` to a PR, the linked issue(s) (via
# `closingIssuesReferences`) are marked `loom:blocked` with a machine-
# parseable `Blocked by #<PR>` comment, and the release paths remove it again.
# Without this, the daemon's work-finder kept re-dispatching a no-op sweep on
# the issue every cycle even though its sole open PR was already held for
# human merge (`loom-daemon`'s `PARK_LABELS` hard-skips `loom:blocked`, but
# had no signal that the issue was, transitively, also stuck on a human) —
# confirmed recurring three times on issue #1651 / PR #1659 before this fix.
# This was never upstreamed into rjwalters/loom's own champion-pr-merge.md /
# label-state-machine.md templates, so an unpinned resync would silently drop
# it — the same reversion pattern as #606/#662/#1292/#1316/#1356/#1546/#1674.
# If the upstream Loom project ever adopts an equivalent propagation, these
# pins can be dropped and the files resynced normally.
commands/loom/champion-pr-merge.md
docs/label-state-machine.md

# #1674: builder-pr.md carries a local-only "Quoting a `Closes #N`-shaped
# example inside a PR body closes an UNRELATED issue" section (added after
# the 2026-09-11 incident where PR #1671's inline-code-quoted illustrative
# example — `(Closes #1600)`, describing a *different* issue's checklist
# wording — was matched by GitHub's plain-text auto-close scanner anyway and
# falsely closed issue #1600, still-open implementation PR and all). The
# section documents the convention (break the keyword/#N adjacency in quoted
# example text) and points at the new `check-pr-body-closing-keywords.sh`
# guard. This was never upstreamed into rjwalters/loom's own builder-pr.md
# template, so an unpinned resync would silently drop it — the same
# reversion pattern as #606/#662/#1292/#1316/#1356/#1546. If the upstream
# Loom project ever adopts an equivalent section, this pin can be dropped and
# the file resynced normally.
commands/loom/builder-pr.md
