Skip to content
Back to skills

Project Hotpath Gate

ASecurity

Use when a project needs its hot-path gate configuration established or updated - the canonical config at .thrum/hotpath-gate.json defining trigger directories, per-concept detection patterns, and incident prose for the coordinator-hotpath-merge-gate skill. Detects every language present in the repo and drives detection off the shared reliability-class library, so the generated config is real for Go, Python, JS/TS, Rust, or any mix. First invocation generates from project inspection; subseque...

  • 2 stars
  • 0 votes
  • 0 copies
  • 0 views
  • Added November 7, 2026
toolspythonrustgobashdockergitapidatabasesecurity

Works with

  • cli
  • api

Security analysis

A100/100

Scanned November 7, 2026

npx -y skills add thrum-team/thrum-pro --skill project-hotpath-gate --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Project Hotpath Gate?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Project Hotpath Gate
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/thrum-team-project-hotpath-gate/badge)](https://www.skillsdirectory.com/skills/thrum-team-project-hotpath-gate)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: project-hotpath-gate
description: "Use when a project needs its hot-path gate configuration established or updated - the canonical config at .thrum/hotpath-gate.json defining trigger directories, per-concept detection patterns, and incident prose for the coordinator-hotpath-merge-gate skill. Detects every language present in the repo and drives detection off the shared reliability-class library, so the generated config is real for Go, Python, JS/TS, Rust, or any mix. First invocation generates from project inspection; subsequent invocations reconcile against current project state and propose diffs."
---

# Project Hot-Path Gate

## Canonical path

`.thrum/hotpath-gate.json` — the single authoritative location.
`coordinator-hotpath-merge-gate` reads from this path only.

## Run modes and dispatch order

On every invocation, dispatch in this order. Earlier branches short-circuit
later ones.

1. **First-run** (config absent) — generate a new `.thrum/hotpath-gate.json`
   from project inspection. Optionally accept seeded prose context (incident
   descriptions, fix patterns) from the invoker.
2. **Re-run-unchanged** (config present, matches current project state) — report
   "hotpath-gate.json is current; no changes needed" and exit without writing.
3. **Re-run-evolved** (config present, project has drifted) — compute a
   sectional diff, present for approval, write only on confirmation.

Load the /thrum:generator-idempotency-protocol skill and follow it.

> **Note: human-in-the-loop required.** This skill uses interactive prompts for
> first-run incident-prose seeding and re-run-evolved diff approval. It cannot
> run unattended in CI.

## First-run mode

Triggered when `.thrum/hotpath-gate.json` does not exist.

### Step 1: Census the repo's languages

Detect every language present — a repo can carry more than one:

- Manifest files at the repo root or in each workspace: `go.mod` (Go),
  `package.json` (JS/TS), `pyproject.toml`/`requirements.txt`/`setup.py`
  (Python), `Cargo.toml` (Rust).
- `git ls-files` extension histogram, as a cross-check and as the sole signal
  where no manifest exists in a subtree.
- A language is detected when it has a manifest, or its tracked-file share
  clears 5%.

Record every detected language as `languages_detected`. A repo clearing the
threshold for more than one language is polyglot: every detected language's
probe pack runs in Step 3, not just the largest one.

### Step 2: Detect trigger directories

Scan for hot-path code using each detected language's own route/handler/RPC
idiom:

```bash
# Go
grep -rlE 'func Handle|func.*Handler|http\.Handle|rpc\.' --include='*.go'
# Python
grep -rlE '@app\.(route|get|post|put|delete|patch)|@router\.' --include='*.py'
# JS/TS
grep -rlE "app\.(get|post|put|delete|patch)\(|router\.(get|post|put|delete|patch)\(" --include='*.ts' --include='*.js'
```

Also scan for projection/writer, storage/DB, sync, and listener/boot
directories, using each language's own idiom for those shapes (a database
open call, a background sync loop, a process-boot entrypoint). Collapse
subdirectories under their parent when the parent already matches. Record the
deduplicated list as `trigger_directories`.

### Step 3: Walk the reliability class library

Read `../project-philosophy/resources/reliability-class-library.md`, shared
with `project-philosophy`. Walk every class tagged `Consumers: ... hotpath` —
each names the lens it feeds and, where relevant, a hot-path facet within that
lens.

For each such class and each language recorded in `languages_detected`, run
the probe the library gives that class for that language, scoped to that
language's own files within `trigger_directories` from Step 2 — a language
with no hot-path directories of its own contributes no findings, even if it
clears the repo-wide detection threshold. Where the library marks a language
"none" or "open gap" for a class — this includes Go for some classes, such
as the security concepts that don't apply to a perimeter-protected daemon —
that language contributes no finding for that class and the walk moves to
the next one.

A class whose `**Consumers:**` line names hotpath with no facet parenthetical
IS its lens — e.g. Class 8 is the `silent_fail_open` lens. Record its matches
into that lens's primary pattern field (the array of distinct
patterns/identifiers actually found in the repo). A class with zero matches
for a given language is not an error — record it as walked-and-not-found, and
continue.

A class whose `**Consumers:**` line names a hot-path facet in parentheses
enriches the named lens's `context` field with the adapted finding. Where
that class's own probe is the only detection the lens has for its primary
pattern field, also record matches there (Class 1 into `subprocess_hot_path`,
Class 5 into `dispatch_blocking` and `peer_dial_circuit_breaker`). The one
exception is Class 2: `async_io_decoupling` carries its own independent,
incident-derived detection for its primary fields, so Class 2 enriches
`context` only and never touches a primary field.

A lens's secondary refinement fields (pre-flight guard patterns, native
alternatives, and similar) populate only where a class gives a probe for
them; a field with no probe for the detected language is left absent rather
than guessed at.

`async_io_decoupling`'s own primary fields (goroutine/boot-stage/cancellation
patterns and dropped-context params) come from a Go-only detection pass
independent of the class library, scoped to `trigger_directories`:

```bash
grep -rnE 'go func|go bootstage\.Run' --include='*.go'
grep -rnE 'bootstage\.Run|OnReady|SetOnReady|DependsOn|Await\(' --include='*.go'
grep -rnE 'CompactAll|MergeGroup|filepath\.Walk|os\.ReadDir|io\.Copy' --include='*.go'
grep -rnE 'ctx\.Done\(\)|ctx\.Err\(\)|r\.Beat\(|context\.WithoutCancel' --include='*.go'
grep -rn '_ context\.Context' --include='*.go'
```

Record these as `io_work_patterns`, `boot_and_coupling_patterns`,
`async_discipline_patterns`, and `dropped_ctx_pattern` respectively. No
equivalent probe exists yet for other languages; the fields are absent there
rather than guessed at.

### Step 4: Accept seeded prose context

Use `AskUserQuestion` for per-lens prose seeding. Prefer sequential
category→item questions (one prompt per lens, ≤4 options each) over packing
every lens into a single prompt.

Prompt the invoker for incident descriptions, fix patterns, and
project-specific nuances for each lens. These become the `context` prose
fields in the config.

If the invoker has no incident prose to seed (first-time setup on a new
project), leave the `context` fields as empty strings with a
`<!-- TODO: seed with incident history -->` comment. The gate skill still
functions without prose context — it just provides less guidance to the
reviewer.

### Step 5: Generate `.thrum/hotpath-gate.json`

Assemble all discovered values into the JSON structure and write to
`.thrum/hotpath-gate.json`. Ensure the file is not gitignored (add a `!`
exception in `.gitignore` if needed, following the `.thrum/philosophy.md`
pattern).

Only emit `embed_aware_skip` for a language with a compiled-in-bundle concept
and a derivable reachability command (Go's `go:embed` is the current
example). Omit the field for a language with no such concept rather than
writing a placeholder.

If Step 3 found zero matching lenses across every detected language, do not
write an empty-but-valid config — see the scaffold/refuse behavior in
`## Zero-match handling` below.

Announce the path and summarize what was discovered per language, including
which reliability classes were found vs. walked-and-not-found.

## Zero-match handling

The generator never writes a config with an empty `lenses` object. When Step
3 finds no matching lens across every detected language:

- **Default:** write a scaffold marked at the top level with
  `_UNAUTHORED_SCAFFOLD: true`. Populate `trigger_directories` from a
  language-neutral serving heuristic — route decorators, files matching
  `*proxy*`/`*server*`/`*api*`, a `Dockerfile` with `EXPOSE`/`CMD`, and
  detected entrypoints. Add a commented TODO stub per reliability-library
  concept, keyed to the files the heuristic found.
- **Alternative, offered interactively:** refuse to write the file, with a
  message naming which languages were detected and why no lens matched.

No downstream consumer relies on a zero-lens config meaning "clean" — a
generator run either produces real findings, an explicit scaffold, or a
refusal.

## Re-run-unchanged mode

Triggered when `.thrum/hotpath-gate.json` exists.

### Step 1: Read the existing config

Read `.thrum/hotpath-gate.json` in full. Parse all lens sections.

### Step 2: Sanity-check against current project state

Re-run the detection steps from first-run mode, but compare rather than write:

- Are the `languages_detected` still correct? Any new language crossing the
  threshold?
- Are the `trigger_directories` still correct? Any new directories with
  hot-path code?
- Does each lens's primary pattern field still match what Step 3 finds? Any
  new patterns per language?
- Are the `reference_patterns` still accurate? Any new established patterns?

Each check is a boolean "matches" vs. "differs".

### Step 3: If nothing differs — no-op exit

Print: `.thrum/hotpath-gate.json` is current; no changes needed.

### Step 4: If anything differs — hand off to evolved mode

## Re-run-evolved mode

Triggered when the config exists AND the unchanged-mode sanity check flagged
drift.

> **Never silently overwrite.** The config may contain hand-seeded incident
> prose that must survive every re-run. A write without explicit confirmation is
> a bug.

### Step 1: Detect drift

Four drift categories:

- **New or removed languages** — a language crossing or falling below the
  detection threshold
- **New trigger directories** — new directories with hot-path code not in the
  config
- **New patterns** — new matches for an existing lens, per language
- **New reference patterns** — new established working patterns or tripwire
  tests

### Step 2: Compute a proposed diff

Present drift as a readable sectional diff. Each item should have:

- The detected change in plain language
- A proposed edit (addition / removal / update to a config field)
- A one-line rationale

### Step 3: Present for approval

Present the diff. On approval, apply edits in-place, preserving surrounding
content. Append a provenance comment:
`// updated YYYY-MM-DD via project-hotpath-gate re-run-evolved`.

On decline — do NOT write. Record the skipped proposal for future runs.

## Test impact selection plan (per-merge gate)

Owner ruling, verbatim: "default ON as soon as it lands, no side-by-side; safety net = daily full gate + a load/regression test before deploy".

Run the per-merge test lanes through the repository's test-impact-selection plan wrapper (the gate role's documented
command, taking `--base`, `--head` and `--lane`), not the bare full-lane runner. It runs the plan, prints the `TIS_PLAN` line, and passes `--producer-rc` to the runner. Quote the `TIS_PLAN` line in the
verdict. FULL (`decision=FULL RUN`) is the normal fallback: a plan error or any fail-closed reason runs the whole lane.
For a per-landing gate, a FULL RUN fallback means the full NON-race lane, never race-all.

## Reference

- `.thrum/hotpath-gate.json` — the config file this skill generates
- `../project-philosophy/resources/reliability-class-library.md` — the shared
  reliability class library; every `Consumers: ... hotpath` class and its
  per-language probes drive Step 3
- `coordinator-hotpath-merge-gate` — the gate skill that reads this config
- `project-philosophy` — the sibling skill that generates `.thrum/philosophy.md`
  (this skill follows the same generate-first / reconcile-on-reinvoke pattern;
  run both at the same onboarding moment)

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.