opencode-thrum-pro 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (101) hide show
  1. package/assets/commands/thrum-_deviations-protocol.md +87 -0
  2. package/assets/commands/thrum-_generator-idempotency-protocol.md +15 -0
  3. package/assets/commands/thrum-_project-rules-protocol.md +18 -0
  4. package/assets/commands/thrum-_snapshot-protocol.md +265 -0
  5. package/assets/commands/thrum-_stamp-protocol.md +112 -0
  6. package/assets/commands/thrum-_verify-before-write-protocol.md +27 -0
  7. package/assets/commands/thrum-inbox.md +22 -0
  8. package/assets/commands/thrum-load-context.md +17 -0
  9. package/assets/commands/thrum-overview.md +17 -0
  10. package/assets/commands/thrum-prime.md +30 -0
  11. package/assets/commands/thrum-quickstart.md +14 -0
  12. package/assets/commands/thrum-reply.md +28 -0
  13. package/assets/commands/thrum-restart-extended.md +195 -0
  14. package/assets/commands/thrum-restart.md +293 -0
  15. package/assets/commands/thrum-send.md +31 -0
  16. package/assets/commands/thrum-sleep-extended.md +186 -0
  17. package/assets/commands/thrum-sleep.md +212 -0
  18. package/assets/commands/thrum-team.md +12 -0
  19. package/assets/commands/thrum-update-project.md +259 -0
  20. package/assets/commands/thrum-wait.md +14 -0
  21. package/assets/skills/adversarial-critique/SKILL.md +242 -0
  22. package/assets/skills/brainstorm-queue-aware/SKILL.md +167 -0
  23. package/assets/skills/brainstorm-steward/SKILL.md +181 -0
  24. package/assets/skills/choosing-subagent-models/SKILL.md +244 -0
  25. package/assets/skills/closing-findings-while-warm/SKILL.md +104 -0
  26. package/assets/skills/configure-roles/SKILL.md +229 -0
  27. package/assets/skills/coordinator-assessing-agent-completion/SKILL.md +205 -0
  28. package/assets/skills/coordinator-assessing-agent-completion/scan.py +117 -0
  29. package/assets/skills/coordinator-branch-split-on-block/SKILL.md +168 -0
  30. package/assets/skills/coordinator-context-monitoring/SKILL.md +674 -0
  31. package/assets/skills/coordinator-dispatching-work/SKILL.md +288 -0
  32. package/assets/skills/coordinator-hotpath-merge-gate/SKILL.md +522 -0
  33. package/assets/skills/coordinator-interacting-with-the-owner/SKILL.md +171 -0
  34. package/assets/skills/coordinator-maintaining-memory/SKILL.md +89 -0
  35. package/assets/skills/coordinator-managing-state-and-lifecycle/SKILL.md +192 -0
  36. package/assets/skills/coordinator-merging-code/SKILL.md +331 -0
  37. package/assets/skills/coordinator-philosophy-merge-gate/SKILL.md +442 -0
  38. package/assets/skills/coordinator-plan-reconcile-gate/SKILL.md +198 -0
  39. package/assets/skills/coordinator-post-restart-sweep/SKILL.md +135 -0
  40. package/assets/skills/coordinator-running-autonomous-feature-development/SKILL.md +199 -0
  41. package/assets/skills/coordinator-running-brainstorm-cycles/SKILL.md +654 -0
  42. package/assets/skills/coordinator-running-review-cycles/SKILL.md +153 -0
  43. package/assets/skills/coordinator-single-responsibility-merge-gate/SKILL.md +14 -0
  44. package/assets/skills/diagnosing-fleet-and-daemon/SKILL.md +255 -0
  45. package/assets/skills/efficient-multi-agent-research/SKILL.md +177 -0
  46. package/assets/skills/fixing-documentation-errors/SKILL.md +258 -0
  47. package/assets/skills/implementer-maintaining-memory/SKILL.md +84 -0
  48. package/assets/skills/implementer-orchestrating-execution/SKILL.md +125 -0
  49. package/assets/skills/implementer-receiving-dispatch/SKILL.md +127 -0
  50. package/assets/skills/implementer-receiving-review-feedback/SKILL.md +125 -0
  51. package/assets/skills/implementer-status-and-handoff/SKILL.md +150 -0
  52. package/assets/skills/implementer-tdd-and-quality/SKILL.md +99 -0
  53. package/assets/skills/memory-audit-recover/SKILL.md +153 -0
  54. package/assets/skills/memory-curate/SKILL.md +139 -0
  55. package/assets/skills/memory-maintenance/SKILL.md +87 -0
  56. package/assets/skills/memory-read-discipline/SKILL.md +164 -0
  57. package/assets/skills/memory-search-advanced/SKILL.md +217 -0
  58. package/assets/skills/memory-write-discipline/SKILL.md +135 -0
  59. package/assets/skills/orchestrate/SKILL.md +795 -0
  60. package/assets/skills/persistent-watcher-archetype/SKILL.md +225 -0
  61. package/assets/skills/prime-agent/SKILL.md +92 -0
  62. package/assets/skills/project-hotpath-gate/SKILL.md +255 -0
  63. package/assets/skills/project-philosophy/SKILL.md +418 -0
  64. package/assets/skills/project-philosophy/resources/philosophy-template.md +155 -0
  65. package/assets/skills/project-philosophy/resources/reliability-class-library.md +653 -0
  66. package/assets/skills/project-setup/SKILL.md +1007 -0
  67. package/assets/skills/project-setup/resources/implementation-agent.md +826 -0
  68. package/assets/skills/researcher-answering-queries/SKILL.md +100 -0
  69. package/assets/skills/researcher-investigating/SKILL.md +152 -0
  70. package/assets/skills/researcher-maintaining-memory/SKILL.md +176 -0
  71. package/assets/skills/state-migration/SKILL.md +54 -0
  72. package/assets/skills/thrum/SKILL.md +161 -0
  73. package/assets/skills/thrum/resources/ANTI_PATTERNS.md +132 -0
  74. package/assets/skills/thrum/resources/BOUNDARIES.md +56 -0
  75. package/assets/skills/thrum/resources/CLI_REFERENCE.md +1066 -0
  76. package/assets/skills/thrum/resources/IDENTITY.md +49 -0
  77. package/assets/skills/thrum/resources/LISTENER_PATTERN.md +64 -0
  78. package/assets/skills/thrum/resources/MESSAGING.md +163 -0
  79. package/assets/skills/thrum/resources/TMUX_SESSIONS.md +118 -0
  80. package/assets/skills/thrum/resources/WORKTREES.md +117 -0
  81. package/assets/skills/thrum-memory/SKILL.md +138 -0
  82. package/assets/skills/trace-spec-to-plan/SKILL.md +104 -0
  83. package/assets/skills/trace-spec-to-plan/resources/sweep-agent-prompt.md +57 -0
  84. package/assets/skills/update-queue/SKILL.md +149 -0
  85. package/assets/skills/using-the-queue/SKILL.md +172 -0
  86. package/assets/skills/using-thrum-state/SKILL.md +104 -0
  87. package/assets/skills/verify-against-plan/SKILL.md +323 -0
  88. package/assets/skills/verify-against-source/SKILL.md +237 -0
  89. package/assets/skills/watcher-archetype/SKILL.md +84 -0
  90. package/assets/skills/writing-durable-markdown/SKILL.md +66 -0
  91. package/dist/hooks/block-sync-cd.d.ts +9 -0
  92. package/dist/hooks/block-sync-cd.js +71 -0
  93. package/dist/hooks/block-sync-cd.test.d.ts +1 -0
  94. package/dist/hooks/block-sync-cd.test.js +61 -0
  95. package/dist/hooks/shell-env.d.ts +8 -0
  96. package/dist/hooks/shell-env.js +22 -0
  97. package/dist/index.d.ts +6 -0
  98. package/dist/index.js +25 -0
  99. package/dist/installer.d.ts +2 -0
  100. package/dist/installer.js +86 -0
  101. package/package.json +49 -0
@@ -0,0 +1,522 @@
1
+ ---
2
+ name: coordinator-hotpath-merge-gate
3
+ description: "Use when ABOUT TO START a hot-path Pass-3 gate - a gate has been dispatched to you, you are picking up a queued gate, you are the Gate Runner beginning a gate, you are about to walk hot-path lenses - and when a coordinator is about to run git merge after dual review came back clean. Loads the gate-runner restart rule (restart at ~50 percent, at a seam BETWEEN gates) plus the hot-path and perf lenses read from .thrum/hotpath-gate.json. Trigger-scoped lenses skip on a mechanical zero-match against the configured trigger directories, paired with a firing positive control, for branches touching RPC handlers, projection writers, storage openers, sync code, peer dial paths, or daemon boot paths - not CLI helpers, tests-only, docs, or website. Any lens flagged always_run in the config runs on EVERY commit regardless of directory, including the master-giant-process batch-decomposition lens."
4
+ ---
5
+
6
+ # Coordinator: Hot-Path Merge Gate
7
+
8
+ ## Before you start this gate — restart if you cannot finish it
9
+
10
+ **Finish the gate you are in. Never restart mid-gate.** A finding that exists only
11
+ in your context is one restart from gone.
12
+
13
+ **Then restart at the seam — after the report is delivered, before taking anything
14
+ else.** Do not carry context across a gate boundary.
15
+
16
+ **Do not START a new gate above ~50% context.** A full dual gate costs roughly 14%.
17
+ Starting one you cannot finish is how a gate ends thin on its own verdict.
18
+
19
+ **Why the boundary is the gate and not a number - a gate runner is static.** Each gate
20
+ is scoped, evidenced, and delivered self-contained; State.md carries what must persist.
21
+ Nothing accumulates across gates, so context held past a gate boundary buys nothing and
22
+ costs money.
23
+
24
+ **This is NOT the orchestrator rule.** An orchestrator is building something and its
25
+ context is the work - it pushes through until its current plan is implemented and
26
+ restarts then, at 30% or at 60%. Interrupting an implementation to hit a number is the
27
+ wrong move. A gate is short and self-contained, so its boundary comes often and costs
28
+ nothing to take.
29
+
30
+ **The coordinator may overrule either rule for a sustained campaign** - a push to get trunk
31
+ green, an incident, a release cutover - where continuity across many units is worth more than
32
+ a clean seam. That is an explicit decision, stated at the time. It is never drift.
33
+
34
+ **Measure by pane, in the same command block that reports the number.** A figure carried
35
+ forward from earlier in the session is a memory, not a measurement.
36
+
37
+
38
+
39
+ ## Why this is a separate pass, not a philosophy-gate lens
40
+
41
+ `coordinator-philosophy-merge-gate` catches general structural anti-patterns
42
+ (raw `exec.Command`, shell passthrough, SRP violations). This gate catches
43
+ **hot-path/perf-specific** anti-patterns — silent fail-open, unconditional
44
+ writes in dual-source paths, shared-resource poisoning, pattern divergence,
45
+ coincidence- detector tests, incomplete-class-fixes, dead-row pre-filter gaps,
46
+ and peer-dial circuit-breaker gaps — that the philosophy gate does not cover.
47
+ See the config's per-lens `context` prose for the project's incident history and
48
+ what the philosophy gate caught vs. missed.
49
+
50
+ Where the two gates overlap (subprocess-in-hot-path,
51
+ dispatch-goroutine-blocking, pattern divergence, coincidence-tests), this gate
52
+ goes deeper with specific detection rules. If the philosophy gate already
53
+ flagged a finding, this gate should **upgrade** it with the deeper analysis, not
54
+ duplicate it. The coordinator consolidates findings from both gates into one
55
+ numbered list.
56
+
57
+ ## Config-driven design
58
+
59
+ This skill reads `.thrum/hotpath-gate.json` at invocation time. The config
60
+ provides:
61
+
62
+ - **Trigger directories** — which directories in the diff activate this gate
63
+ - **Pattern fields** — grep strings, function names for automated triage
64
+ - **Reference patterns** — established working patterns to check divergence
65
+ against
66
+ - **Context prose** — incident descriptions, fix patterns for the LLM reviewer's
67
+ judgment
68
+
69
+ The lenses below are codebase-agnostic. All project-specific values come from
70
+ the config. The companion `project-hotpath-gate` skill generates/updates the
71
+ config from codebase inspection (like `project-philosophy` generates
72
+ `.thrum/philosophy.md`). If no config exists, fail with guidance to run
73
+ `project-hotpath-gate` first.
74
+
75
+ **How to apply: DISPATCH THIS GATE TO THE GATE RUNNER. Do not walk the lenses in
76
+ your own context.**
77
+
78
+ The gate runner is a standing agent whose entire purpose is to hold gate work
79
+ OUTSIDE the coordinator's context — resolve the current one from `thrum team` by
80
+ its `gate` ROLE, never by a remembered name. It runs the lenses in an ephemeral worktree, produces
81
+ a verdict, and tears the worktree down. **You read `.thrum/hotpath-gate.json` to
82
+ build the dispatch, then you consolidate the verdict and decide. You do not run
83
+ the lenses.**
84
+
85
+ **This is the default for EVERY diff size.** Diff size changes what you ask for;
86
+ it never changes who runs it. A coordinator that walks the lenses inline burns
87
+ the one resource it cannot replace and leaves no durable verdict artifact.
88
+
89
+ **Only run it yourself when there is NO gate-role agent available**, and say so
90
+ explicitly in the merge record so the gap is visible rather than invisible.
91
+
92
+ **Verdicts are artifacts:** the runner saves them to
93
+ `dev-docs/gate-reports/<ISO-week>/<date>/<gate-slug>/` and commits them BEFORE
94
+ removing any worktree. A verdict that exists only in a message cannot be audited
95
+ later.
96
+
97
+ ## Gate dispatch preamble
98
+
99
+ Mandatory checklist handed to the GATE RUNNER (and to any sub-agent it spawns in
100
+ turn) at dispatch time. Each
101
+ rule below currently lives only as prose warnings scattered through
102
+ `dev-docs/hotpath-gate-efficacy.md` and gets re-learned per session — hand this
103
+ list to the sub-agent verbatim at dispatch time instead of relying on it
104
+ rediscovering these the hard way:
105
+
106
+ 1. Read code via `git show <target-sha>:<path>`, NEVER the working tree — tree
107
+ state != the SHA under review.
108
+ 2. Build/test ONLY in a throwaway detached worktree
109
+ (`git worktree add <tmp> <sha> --detach`), never the shared checkout.
110
+ 3. RUN any test you make a claim about — never judge from reading it.
111
+ 4. Diff against `merge-base`, never two-dot against tip — a two-dot diff
112
+ against tip pulls in unrelated lines from sibling branches and
113
+ manufactures a false regression signal.
114
+ 5. Run `git merge-base --is-ancestor` as an explicit gate condition (the
115
+ fast-forward check) — git silently deduplicates content-identical commits
116
+ on both sides of a rebase, so a tree that "builds clean" can still be
117
+ carrying dupes instead of the real content.
118
+ 6. Run full-package `-race`, not targeted `-run` — a targeted race run misses
119
+ cross-test races.
120
+ 7. Build+test the MERGED-tree result as a SEPARATE condition — neither gate
121
+ currently runs a build of the actual post-merge tree; a clean pre-merge
122
+ build/test does not prove the merged result compiles or passes.
123
+ 8. Use `rm -r`, NEVER `rm -rf`, and use `git worktree remove --force` to drop a
124
+ worktree. A broad `ask` rule on `rm -rf *` outranks any narrow `/tmp` allow,
125
+ so `rm -rf` raises a human permission prompt EVERY time regardless of path —
126
+ it stalls gate sub-agents mid-run waiting on a keystroke. `rm -r` runs free. Do NOT widen the ask rule
127
+ to work around this; that entry is the only deletion protection on the box.
128
+ 9. Check the discriminator before picking a scratch path, don't assume from
129
+ the platform: `[ -L /tmp ]`. macOS (symlink) — create throwaway worktrees
130
+ under `/private/tmp`; a worktree under `/tmp` false-FAILs worktree-ancestor
131
+ tests via the symlink, producing a confident wrong gate result. Linux (real
132
+ dir) — `/tmp` is correct; `/private/tmp` may not exist there and must not
133
+ be created.
134
+ 10. Your report reaches the coordinator ONLY as your final returned text.
135
+ Side-channel output is discarded. Put the whole verdict in the return value.
136
+ 11. **NEVER run `git stash`, `git checkout`, `git reset`, or any working-tree
137
+ mutation in the SHARED repo.** Do read-only inspection there (`git show
138
+ <sha>:<path>`, `git log`, `git diff`) and do every build/test in a throwaway
139
+ detached worktree. `git stash` is a SINGLE SHARED STACK across every
140
+ worktree of a repo, so "cleaning up after myself" can strand or clobber
141
+ another agent's live work; and the shared repo is POPULATED — live agents
142
+ hold uncommitted `State.md` they are actively re-authoring.
143
+ If you believe you must mutate the shared tree, STOP and report instead —
144
+ that is always a finding, never a step.
145
+ 12. **TEAR DOWN YOUR THROWAWAY WORKTREE WHEN THE GATE ENDS — after two checks,
146
+ in this order.** A required final step, not cleanup etiquette. Each
147
+ abandoned worktree pins its HEAD commit against `gc` and adds a
148
+ `.git/worktrees` admin entry, so the object store grows monotonically.
149
+ Before removing:
150
+ (a) `git -C <wt> status --porcelain` — if NON-EMPTY, **STOP and report it
151
+ instead of removing.** Uncommitted work in a throwaway worktree exists
152
+ NOWHERE else; this is the category that actually loses work.
153
+ (b) `git branch -a --contains $(git -C <wt> rev-parse HEAD)` — if EMPTY,
154
+ HEAD is a gate-produced merge reachable from no ref and removal orphans
155
+ it. Usually fine (a gate merge is reproducible by redoing it) but say so
156
+ in your report rather than doing it silently.
157
+ Then `git worktree remove --force <wt>`.
158
+
159
+ ## Trigger-directory skip logic
160
+
161
+ Before walking the lenses, check if the diff touches any directory in
162
+ `config.trigger_directories`. If not, skip the trigger-scoped lenses and run
163
+ only the philosophy gate — EXCEPT any lens carrying `"always_run": true` in its
164
+ config entry (see `lens_scope_semantics` in the config), which still runs on
165
+ every diff regardless of trigger directories. If the config has no
166
+ `trigger_directories`, fail with guidance to run `project-hotpath-gate`.
167
+
168
+ ## Delta re-gate continuity — walk the whole branch, read the whole function
169
+
170
+ **Why:** A commit introducing a lock can be an ancestor of a delta-re-gate's
171
+ base and never appear in any walked diff, even when a later commit edits the
172
+ gating condition on that call. Root cause: the gate is delta-scoped. The diff
173
+ hunk showing the edited condition never revealed the enclosing locked span
174
+ above it.
175
+
176
+ **Rules:**
177
+
178
+ - The FIRST gate run on a branch walks `merge-base(target, tip)..tip`, NOT a
179
+ recent delta.
180
+ - A delta re-gate MUST state the prior gated SHA and assert continuity:
181
+ `prior-gated-sha == delta-base`, verified via `git merge-base --is-ancestor`
182
+ or direct SHA equality. If the prior-gated SHA is NOT the delta base,
183
+ re-walk from `merge-base` — there is unwalked history between the two.
184
+ - Lens 1 (subprocess hot path) and Lens 2 (dispatch-blocking) greps run at
185
+ changed-FILE scope, then READ THE FULL ENCLOSING FUNCTION — a diff hunk
186
+ inside a locked span cannot show you the `Lock()` above it. A changed line
187
+ whose semantics depend on a lock/defer/subprocess further up the function is
188
+ only visible at function scope, never at hunk scope.
189
+
190
+ ## Lens 1 — Subprocess in the per-request hot path
191
+
192
+ **Why:** The single most recurring wedge class. Per-request or per-heartbeat
193
+ work that forks a subprocess, compounding under fleet scale.
194
+
195
+ **Relationship to philosophy gate:** Cross-refs Philosophy Lens 1 (raw
196
+ `exec.Command` in daemon code) — goes deeper by checking per-RPC path membership
197
+ and mitigation patterns.
198
+
199
+ **How to apply:** Read `config.lenses.subprocess_hot_path`. Grep changed files
200
+ for `subprocess_patterns`. For each hit, check if the calling function is
201
+ reachable from a `hot_path_indicators` function in a `hot_path_files` path —
202
+ follow one call-level into changed helpers (subprocess calls may live one call
203
+ below the handler). If yes, verify three mitigations: (1)
204
+ `pre_flight_guard_pattern` before the fork, (2) `non_blocking_read_pattern`
205
+ before blocking extraction, (3) consider `native_alternatives`. Read the
206
+ `context` prose.
207
+
208
+ **Severity:** Missing all three mitigations on a new hot-path subprocess call —
209
+ **BLOCKING**.
210
+
211
+ **Triage:**
212
+ `git diff main...HEAD --name-only | xargs grep -ln '{subprocess_patterns}'`
213
+
214
+ ## Lens 2 — Dispatch-goroutine-blocking on expensive work
215
+
216
+ **Why:** Blocking the request-dispatch goroutine on expensive I/O starves other
217
+ requests. A shared lock held across I/O is the overarching contention point.
218
+
219
+ **Relationship to philosophy gate:** Cross-refs Philosophy Lens 10d (cost gate:
220
+ shared lock across I/O or drain) — goes deeper by checking
221
+ Peek+background-refresh and lock-hold-time minimization.
222
+
223
+ **How to apply:** Read `config.lenses.dispatch_blocking`. For any new/changed
224
+ handler: does it acquire a `lock_patterns` lock? Is I/O performed under the
225
+ lock? Is the lock released before `post_commit_pattern` work? For new caches: is
226
+ there a `cache_peek_pattern`? Is extraction moved to
227
+ `background_detach_pattern`? Is there `singleflight_pattern` coalescing? For
228
+ per-item loops: batched or per-item lock? Also check: does a new scheduler/cron
229
+ job emit durable-lane events at a rate that could saturate the write pool? Read
230
+ the `context` prose.
231
+
232
+ **Severity:** New handler holds lock across I/O, or lacks Peek+background for
233
+ expensive cacheable data — **BLOCKING**.
234
+
235
+ **Triage:** `git diff main...HEAD --name-only | xargs grep -n '{lock_patterns}'`
236
+
237
+ ## Lens 3 — Silent fail-open instead of fail-closed
238
+
239
+ **Why:** Missing/mismatched data silently falls through to wrong-but-plausible
240
+ data instead of erroring. The second most common wedge class.
241
+
242
+ **Relationship to philosophy gate:** No philosophy.md equivalent — new pattern.
243
+
244
+ **How to apply:** Read `config.lenses.silent_fail_open`. For any function
245
+ resolving identity/path/state: does it have a fallback when the target is
246
+ missing? Does the fallback return a _different_ identity/path than requested?
247
+ For identity resolution: does it hard-error on mismatch (check
248
+ `identity_validation_patterns`)? For liveness computation: does it use
249
+ `canonical_predicate` or compute ad-hoc? For file writes to shared resources:
250
+ does it use `append_patterns` instead of truncate-with-guard? Read the `context`
251
+ prose.
252
+
253
+ **Severity:** Silently adopts wrong data on missing/mismatched input —
254
+ **BLOCKING**. Falls back to default without erroring — **IMPORTANT**.
255
+
256
+ **Triage:**
257
+ `git diff main...HEAD --name-only | xargs grep -n '{fallback_patterns}'`
258
+
259
+ ## Lens 4 — Unconditional write in a shared dual-source path
260
+
261
+ **Why:** A shared apply path handling both local writes AND sync-merged events.
262
+ Writers without timestamp guards allow older sync events to clobber newer local
263
+ edits.
264
+
265
+ **Relationship to philosophy gate:** No philosophy.md equivalent — new pattern.
266
+
267
+ **How to apply:** Read `config.lenses.unconditional_write_dual_source`. For any
268
+ new/changed writer in `shared_apply_path`: does it use
269
+ `unconditional_write_patterns` (e.g. `INSERT OR REPLACE`, bare
270
+ `UPDATE`/`DELETE`)? Must use `conflict_guard_patterns`. Are side effects gated
271
+ on `side_effect_gating_pattern` (e.g. `RowsAffected() > 0`)? Does it mirror
272
+ `reference_guarded_writers`? Read the `context` prose.
273
+
274
+ **Severity:** Writer in shared apply path lacks conflict guards — **BLOCKING**.
275
+ Side effects not gated on RowsAffected — **BLOCKING**.
276
+
277
+ **Triage:**
278
+ `git diff main...HEAD --name-only | xargs grep -n '{unconditional_write_patterns}'`
279
+
280
+ ## Lens 5 — Shared-resource poisoning by an auxiliary code path
281
+
282
+ **Why:** A secondary code path (backup, CLI helper, hook) mutates a shared
283
+ resource in a way that corrupts the primary path's state. Looks correct in
284
+ isolation.
285
+
286
+ **Relationship to philosophy gate:** No philosophy.md equivalent — new pattern.
287
+
288
+ **How to apply:** Read `config.lenses.shared_resource_poisoning`. For any
289
+ resource open in a non-primary path: does it use `read_write_db_open_patterns`
290
+ when the consumer only reads? Must use `read_only_db_open`. Follow
291
+ `reference_read_only` pattern. Check `wal_checkpoint_patterns` — any
292
+ `PRAGMA wal_checkpoint` or explicit checkpoint call on the daemon path. Check
293
+ `raw_sql_patterns` — raw `db.Query`/`db.Exec` bypasses `safedb_wrapper`'s 522/
294
+ malformed retry. For file writes to shared resources: does it use
295
+ `append_patterns`? Must use truncate-with-ownership-guard or
296
+ `atomic_write_patterns`. Read the `context` prose.
297
+
298
+ **Severity:** Auxiliary path opens shared resource read-write when read-only
299
+ suffices — **BLOCKING**. Raw `sql.DB` on daemon path bypassing safedb —
300
+ **BLOCKING**. Writes to shared file without ownership guard — **BLOCKING**.
301
+
302
+ **Triage:**
303
+ `git diff main...HEAD --name-only | xargs grep -n '{read_write_db_open_patterns}|{wal_checkpoint_patterns}|{raw_sql_patterns}'`
304
+
305
+ ## Lens 6 — Pattern divergence from established working pattern
306
+
307
+ **Why:** A new feature introduces a code path that omits a pattern the existing
308
+ code already got right — because the pattern wasn't enforced structurally.
309
+
310
+ **Relationship to philosophy gate:** Partial thematic overlap with Philosophy
311
+ Lenses 10b (naming test) and 10d (cost gate) — but this lens is about structural
312
+ pattern mirroring, not naming or cost. No duplication risk.
313
+
314
+ **How to apply:** Read `config.lenses.pattern_divergence.reference_patterns`.
315
+ For each reference pattern, check if the diff introduces a new code path that
316
+ should follow it. Does the new code match the `check` description? Does it use
317
+ `current_pattern` (not `legacy_pattern` where one is specified)? Is there a
318
+ `tripwire_test`? Read each pattern's `context` prose.
319
+
320
+ **Severity:** Divergence from a proven-incident reference pattern (in the
321
+ config's `reference_patterns` list) — **BLOCKING**. Divergence from a convention
322
+ not in the proven-incident list — **IMPORTANT**.
323
+
324
+ **Triage:** For each reference pattern, grep changed files for its
325
+ `legacy_pattern` (if present) or its `current_pattern` to verify usage.
326
+
327
+ ## Lens 7 — Coincidence-detector test
328
+
329
+ **Why:** Green tests that don't assert the actual invariant provide false
330
+ confidence at merge time — worse than no tests.
331
+
332
+ **Relationship to philosophy gate:** Partial thematic overlap with Philosophy
333
+ Lens 6 (trusting documented behavior) — but this lens is about trusting
334
+ **tests** that pass without proving the invariant, not trusting comments/docs.
335
+ No duplication risk.
336
+
337
+ **How to apply:** Read `config.lenses.coincidence_detector_tests`. For any new
338
+ test (files matching `test_file_pattern`): does it assert the actual invariant
339
+ (not just "no error")? Would it fail if the behavior were wrong? Does it rely on
340
+ ambient shell state? For regression tests: does it assert the specific fix? Is
341
+ it a tripwire (check `tripwire_patterns`)? For tests using only
342
+ `assertion_free_patterns`: flag as potentially coincidence-detecting. For
343
+ modified tests: was an assertion weakened? Read the `context` prose.
344
+
345
+ **Severity:** Test would pass even if the behavior it claims to test were broken
346
+ — **IMPORTANT**. A regression test that doesn't assert the specific anti-pattern
347
+ is prevented — **IMPORTANT**. A coincidence-detector test that is the **sole
348
+ regression guard** for a previously-fixed Category A–F wedge — **BLOCKING**.
349
+
350
+ **Triage:**
351
+ `git diff main...HEAD --name-only | grep '{test_file_pattern}' | xargs grep -l '{tripwire_patterns}'`
352
+
353
+ ## Lens 8 — Incomplete-class-fix: enumerate-all-siblings
354
+
355
+ **Why:** A fix that guards a SUBSET of writers to a shared resource, leaving
356
+ siblings via other code paths unguarded. The unguarded sibling silently retains
357
+ the bug.
358
+
359
+ **Relationship to philosophy gate:** No philosophy.md equivalent — new pattern.
360
+
361
+ **How to apply:** Read `config.lenses.incomplete_class_fix.shared_resources`.
362
+ For any fix touching a shared-resource writer: does the fix NAME the sites it
363
+ touches? Does it PROVE there is no N+1? Run the `grep` pattern in `directory` to
364
+ enumerate ALL write sites. Diff against what the fix touched — any gap is a
365
+ sibling. Acceptable proof: grep enumeration with each site accounted for,
366
+ compile-time tripwire, or cited enumeration comment. Read the `context` prose.
367
+
368
+ **Severity:** Fix touches a shared-resource writer without enumerating all
369
+ siblings — **BLOCKING**.
370
+
371
+ **Triage:** For each shared_resource, run its `grep` in its `directory` to
372
+ enumerate all write sites; diff against what the fix touched.
373
+
374
+ ## Lens 9 — Dead-row pre-filter before per-row cost
375
+
376
+ **Why:** A per-row-expensive hot-path loop (subprocess / DB / IO per candidate)
377
+ that admits dead/retired/non-live rows into the candidate set. Dead rows incur
378
+ the full per-row cost (which fails anyway), starving the dispatch goroutine.
379
+ This was the ACTUAL root cause of the gitctx cold-cache fork-storm.
380
+
381
+ **Relationship to philosophy gate:** No philosophy.md equivalent — new pattern.
382
+
383
+ **How to apply:** Read `config.lenses.dead_row_prefilter`. For any new/changed
384
+ candidate query or per-row loop in a hot path: does the candidate selection use
385
+ `candidate_query_patterns` (e.g. `ended_at IS NULL`, open-session alone) as the
386
+ liveness proxy? This is WEAKER than the `canonical_predicate`
387
+ (`phaseFor`/`PhaseOf`). The candidate set MUST be pre-filtered to live agents
388
+ (phases in `live_phases`) with existing worktrees (`worktree_exists_check`)
389
+ BEFORE any per-row cost. A candidate query selecting on open-session alone,
390
+ feeding a per-row-expensive loop, is this anti-pattern. Read the `context`
391
+ prose.
392
+
393
+ **Severity:** Candidate query uses a weaker liveness proxy than the canonical
394
+ predicate, feeding a per-row-expensive loop — **BLOCKING**.
395
+
396
+ **Triage:**
397
+ `git diff main...HEAD --name-only | xargs grep -n '{candidate_query_patterns}'`
398
+
399
+ ## Lens 10 — Peer-dial circuit-breaker for dispatch-reachable network calls
400
+
401
+ **Why:** A synchronous peer/network call (peer dial, cross-daemon RPC,
402
+ wait_pairing) reachable from a dispatch/fanout handler with no deadline AND no
403
+ circuit-breaker stalls the dispatch goroutine when the peer is unreachable or
404
+ stale.
405
+
406
+ **Relationship to philosophy gate:** No philosophy.md equivalent — new pattern.
407
+
408
+ **How to apply:** Read `config.lenses.peer_dial_circuit_breaker`. For any
409
+ new/changed peer call matching `peer_call_patterns`: is it reachable from a
410
+ `dispatch_handler_patterns` function? If yes, verify two mitigations: (1)
411
+ deadline- bounded via `timeout_patterns` (`context.WithTimeout`/`WithDeadline`),
412
+ AND (2) circuit-broken via `circuit_breaker_patterns` so an unreachable/stale
413
+ peer never stalls dispatch. A timeout alone is insufficient — a dead peer still
414
+ occupies a slot until the timeout fires. Read the `context` prose.
415
+
416
+ **Severity:** Peer call reachable from dispatch with no timeout AND no
417
+ circuit-breaker — **BLOCKING**. Peer call with timeout but no circuit-breaker —
418
+ **IMPORTANT**.
419
+
420
+ **Triage:**
421
+ `git diff main...HEAD --name-only | xargs grep -n '{peer_call_patterns}'`
422
+
423
+ ## Cross-gate consolidation with the philosophy gate
424
+
425
+ This gate runs **in parallel** with `coordinator-philosophy-merge-gate` (both
426
+ are Pass 3, after dual review is clean, before `git merge`). The coordinator
427
+ runs both independently and consolidates findings from both into one numbered
428
+ list.
429
+
430
+ **Overlap rule:** If the philosophy gate already flagged a finding (e.g., raw
431
+ `exec.Command` in daemon code), this gate should **upgrade** it with the deeper
432
+ hot-path-specific analysis (is it in a per-RPC path? Is there a pre-flight
433
+ guard? Is there a Peek+background-refresh?), not duplicate it.
434
+
435
+ **Skip rule:** Skip the trigger-scoped lenses if the diff touches no configured
436
+ trigger directories — but any lens with `"always_run": true` in the config
437
+ still runs regardless of directories touched. Never skip the philosophy gate.
438
+ Skip everything, including always-run lenses, only for trivial diffs (one-line
439
+ config, typo, test-only).
440
+
441
+ ## Scope discipline (gate-wide)
442
+
443
+ This gate governs NEW work unconditionally and EXISTING code only on a
444
+ fix-on-contact basis — don't carve out an unrelated existing violation because
445
+ you noticed it while reviewing an adjacent change. Note incidental finds in the
446
+ merge report as "touch-soon" candidates if they are actively wedging something;
447
+ otherwise leave them.
448
+
449
+ ## If it fails
450
+
451
+ Send it back as a normal review finding — same channel as dual-review output,
452
+ folded into the same numbered list if dual review is still open, or as its own
453
+ short reply if dual review already passed. Cite the offending function/file,
454
+ which lens it failed, and the config value that triggered the finding.
455
+
456
+ ## Efficacy tracking (v1 acceptance requirement)
457
+
458
+ After every gate run, record the outcome in `dev-docs/hotpath-gate-efficacy.md`
459
+ (created lazily on first run). This is a durable, committed, grep-queryable log
460
+ that measures v1's real-world efficacy so we can iterate to v2 with data.
461
+
462
+ **Format (structured header):** a structured header line, with
463
+ essay content moved to an indented notes block underneath it:
464
+
465
+ ```
466
+ - YYYY-MM-DD | lens=<hpN,phN,...> | bead=<id> | merged=<sha> | gate=<hotpath|philosophy|both> | outcome=<OUTCOME>
467
+ notes: branch=<branch>, lenses_run=10, findings=B:N I:N M:N, FALSE_POSITIVE=<0|N>. <brief prose>
468
+ ```
469
+
470
+ `lens=<hpN,phN,...>` names the specific lens numbers that were load-bearing for
471
+ the outcome (not just "10"), each prefixed by its gate — `hp<n>` for a
472
+ hotpath-gate.json lens, `ph<n>` for a philosophy.md anti-pattern.
473
+ `FALSE_POSITIVE=0` is recorded explicitly even on a clean/uneventful run ("no
474
+ findings overturned on pushback this run") so the zero is a measurement, not an
475
+ absence.
476
+
477
+ **Coverage mandate:** a row is required for EVERY trigger-dir merge — not just
478
+ gates the coordinator itself runs. This includes SKIPPED-with-evidence rows and
479
+ orchestrator-run merges; the log measures gate COVERAGE, not just
480
+ coordinator-run outcomes. Do not fabricate a per-merge outcome you cannot
481
+ verify — if a past merge is missing a row and the outcome can't be
482
+ reconstructed, record a single honest coverage-gap note instead of inventing
483
+ rows.
484
+
485
+ **Outcomes:**
486
+
487
+ | Outcome | Meaning |
488
+ | ----------------------- | ---------------------------------------------------------- |
489
+ | `CLEAN` | Gate ran, zero findings, merge proceeded |
490
+ | `REAL_DEFECT` | Gate caught a genuine hot-path/perf anti-pattern |
491
+ | `FALSE_POSITIVE` | Gate flagged something correct — record which lens and why |
492
+ | `SLIPPED` | A wedge occurred AFTER merge that the gate did not catch |
493
+ | `SKIPPED_WITH_EVIDENCE` | Gate deliberately skipped (no trigger dirs), evidence cited |
494
+
495
+ **Retrospective reclassification:** When triaging a new wedge or incident, grep
496
+ `dev-docs/hotpath-gate-efficacy.md` for the merged branch/date. If the gate
497
+ previously logged `CLEAN` for that branch, append a follow-up line referencing
498
+ the original entry:
499
+ `- YYYY-MM-DD | branch=<branch> | RECLASSIFIED: CLEAN->SLIPPED | notes=<what the gate missed + which lens should have caught it>`.
500
+ This closes the feedback loop — a `CLEAN` that later becomes `SLIPPED` is the
501
+ most valuable data point for v2 lens improvement.
502
+
503
+ Review the log quarterly (or after any `SLIPPED` outcome) to identify config
504
+ gaps and lens improvements for the next version.
505
+
506
+ ## Reference
507
+
508
+ - `.thrum/hotpath-gate.json` — project-specific config (trigger directories,
509
+ patterns, reference functions, incident prose)
510
+ - `project-hotpath-gate` — the companion builder skill that generates/reconciles
511
+ the config (analog of `project-philosophy`)
512
+ - `dev-docs/brainstorms/hotpath-merge-gate/` — the locked brainstorm (evidence,
513
+ gap analysis, lens details, decisions)
514
+ - `coordinator-philosophy-merge-gate` — the companion general-structural gate
515
+ (runs in parallel)
516
+ - `.thrum/philosophy.md` — canonical source for general anti-patterns (cross-
517
+ referenced by Lenses 1–2, 6–7 where they overlap)
518
+ - `dev-docs/hotpath-gate-efficacy.md` — running efficacy log (created lazily on
519
+ first gate run, appended after each run)
520
+
521
+ <!-- THRUM-GATE: stage=skill next=review -->
522
+ <!-- THRUM-REVIEW: stage=skill verdict=Ready:Yes cycle=2 date=2026-07-10 -->