|
| 1 | +--- |
| 2 | +canonical-url: https://gist.githubusercontent.com/subtleGradient/baf6fbf62c39ff434894f6676a1b1e28/raw/88eb4866b3e71692192a8cb037ea791ec1a0d0f0/thing-golf.AGENTS.md |
| 3 | +--- |
| 4 | + |
| 5 | +# Thing Golf v3.1 – Fear/Pain Aware PR Scoring (TS Monorepos) |
| 6 | + |
| 7 | +Target: future AI/LLM selves with tools (git diff, FS, AST, config parsers). |
| 8 | +Domain: TypeScript monorepo PRs. |
| 9 | + |
| 10 | +--- |
| 11 | + |
| 12 | +## 0. Core Idea |
| 13 | + |
| 14 | +Don’t measure lines or characters. |
| 15 | + |
| 16 | +Measure **how much more dangerous, heavy, chaotic, betraying, and controlling** the repo becomes when a PR is merged. |
| 17 | + |
| 18 | +- Unit: **ThingBadness** |
| 19 | +- Baseline: **0 = neutral** |
| 20 | +- **Higher is always worse.** Negative changes are good (they remove badness). |
| 21 | + |
| 22 | +--- |
| 23 | + |
| 24 | +## 1. Thing |
| 25 | + |
| 26 | +A **Thing** is one named concept delta in the PR. |
| 27 | + |
| 28 | +Examples (each is a separate Thing): |
| 29 | + |
| 30 | +- New / changed / deleted exported function, const, type, interface, class, enum, component. |
| 31 | +- New / removed module that is imported somewhere. |
| 32 | +- New / removed workspace package. |
| 33 | +- New / removed dependency in `package.json`. |
| 34 | +- New / changed / removed HTTP route or RPC handler. |
| 35 | +- New / changed / removed CLI command or subcommand. |
| 36 | +- New / changed / removed DB migration file. |
| 37 | +- New / changed / removed CI workflow, job, or matrix axis. |
| 38 | +- New / changed / removed env var usage (`process.env.*` etc). |
| 39 | +- New / changed / removed test file or top-level test suite. |
| 40 | +- New / changed / removed doc page or major section. |
| 41 | + |
| 42 | +**Granularity rule:** count by **named unit**, not by lines. |
| 43 | + |
| 44 | +Each Thing has: |
| 45 | + |
| 46 | +- `change` ∈ { `NEW`, `MODIFY`, `DELETE` } |
| 47 | + |
| 48 | +--- |
| 49 | + |
| 50 | +## 2. Good vs Bad Slices |
| 51 | + |
| 52 | +We slice Things along **monotonic good/bad axes**. |
| 53 | + |
| 54 | +For every slice: |
| 55 | + |
| 56 | +- **Left = good direction** (less fear/pain). |
| 57 | +- **Right = bad direction** (more fear/pain). |
| 58 | +- Scoring only adds when a Thing leans to the **right** side. |
| 59 | + |
| 60 | +### 2.1 The slices (labels + intuition) |
| 61 | + |
| 62 | +1. **Safety vs Explosiveness** |
| 63 | + - Left: **Safe** – unlikely to cause surprising breakage. |
| 64 | + - Right: **Explosive** – likely to blow up prod or create landmines. |
| 65 | + |
| 66 | +2. **Lightness vs Legacy Burden** |
| 67 | + - Left: **Lighter** – fewer obligations in the future. |
| 68 | + - Right: **Heavier** – more long-term stuff to maintain. |
| 69 | + |
| 70 | +3. **Clarity vs Chaos** |
| 71 | + - Left: **Clearer** – easier to understand and reason about. |
| 72 | + - Right: **Chaotic** – harder to understand; more tangled. |
| 73 | + |
| 74 | +4. **Trustworthy vs Betraying** |
| 75 | + - Left: **Trustworthy** – increases others’ ability to rely on the system and on you. |
| 76 | + - Right: **Betraying** – sets people up to be burned or misled. |
| 77 | + |
| 78 | +5. **Freedom vs Control-Freak** |
| 79 | + - Left: **Freer** – more healthy autonomy and flexibility. |
| 80 | + - Right: **Control-Freak** – more rigid knobs, micro-config, coupling. |
| 81 | + |
| 82 | +--- |
| 83 | + |
| 84 | +## 3. Fear/Pain meaning |
| 85 | + |
| 86 | +Tie each bad side to human needs: |
| 87 | + |
| 88 | +- **Explosive** → attacks **certainty** and **significance** |
| 89 | + (“If this explodes, I look incompetent and everything is on fire.”) |
| 90 | + |
| 91 | +- **Heavier** → attacks **freedom** and **variety** |
| 92 | + (“I’ll spend my life servicing this instead of choosing what to work on.”) |
| 93 | + |
| 94 | +- **Chaotic** → attacks **certainty** |
| 95 | + (“I can’t even tell what this does anymore.”) |
| 96 | + |
| 97 | +- **Betraying** → attacks **connection** and **significance** |
| 98 | + (“People will stop trusting me / us if this blows up or leaks.”) |
| 99 | + |
| 100 | +- **Control-Freak** → attacks **freedom** and **variety** |
| 101 | + (“I need a ritual and 7 flags just to touch this.”) |
| 102 | + |
| 103 | +--- |
| 104 | + |
| 105 | +## 4. Slice Table (with examples) |
| 106 | + |
| 107 | +All examples are TS monorepo PR deltas. |
| 108 | + |
| 109 | +| Slice label | Left label (good) | Right label (bad) | Left examples (good side) | Right examples (bad side) | |
| 110 | +| --- | --- | --- | --- | --- | |
| 111 | +| **Safety vs Explosiveness** | **Safe** | **Explosive** | Adding tests for existing behavior; making a dangerous CLI command safer (extra confirmation); adding idempotency to an endpoint; adding runtime guards on inputs | Adding a new public API without tests; adding a destructive CLI subcommand; introducing a breaking DB migration on a critical table; removing validation to “fix” performance | |
| 112 | +| **Lightness vs Legacy Burden** | **Lighter** | **Heavier** | Deleting unused modules; removing dead feature flags; removing unused dependencies; replacing 3 overlapping libs with 1 | Adding a new workspace package; adding a new long-term feature flag; introducing another cross-cutting util used everywhere; adding a new persistent queue/topic/cron | |
| 113 | +| **Clarity vs Chaos** | **Clearer** | **Chaotic** | Splitting a God-object into well-named focused modules; adding clear docs; adding tests that document edge cases; consistent renames to better names | Adding a “misc.ts” dumping ground; adding `any` casts that bypass types; adding branches without docs or tests; mixing unrelated concerns into one mega-file or mega-util | |
| 114 | +| **Trustworthy vs Betraying** | **Trustworthy** | **Betraying** | Fixing flaky tests; making CI more honest (no hiding failures); improving health checks; clarifying error messages | Marking flaky tests `skip` to get green CI; logging PII in plain text; adding a “debug backdoor” endpoint; silently ignoring errors to “keep it running” | |
| 115 | +| **Freedom vs Control-Freak** | **Freer** | **Control-Freak** | Simplifying config (one typed config object instead of 12 envs); collapsing redundant feature flags; removing unnecessary CI steps; loosening over-strict rules that block harmless work | Adding yet another boolean env flag; adding per-team, per-region, per-tenant special cases; coupling many modules to one central “manager”; adding blocking approvals for trivial changes | |
| 116 | + |
| 117 | +--- |
| 118 | + |
| 119 | +## 5. Scoring Model |
| 120 | + |
| 121 | +For each Thing `T`, we compute **five per-axis contributions**: |
| 122 | + |
| 123 | +- `SafetyBad(T)` ∈ ℤ (≥ 0) |
| 124 | +- `BurdenBad(T)` ∈ ℤ (can be negative if we remove burden) |
| 125 | +- `ChaosBad(T)` ∈ ℤ (≥ 0, can be negative if we remove chaos) |
| 126 | +- `BetrayalBad(T)` ∈ ℤ (≥ 0) |
| 127 | +- `ControlFreakBad(T)` ∈ ℤ (≥ 0, can be negative if we remove control) |
| 128 | + |
| 129 | +### 5.1 Base by change kind (Legacy Burden) |
| 130 | + |
| 131 | +This axis captures **past vs future load**: |
| 132 | + |
| 133 | +- `NEW` → `BurdenBad += +2` |
| 134 | +- `MODIFY` → `BurdenBad += 0` |
| 135 | +- `DELETE` → `BurdenBad += -2` |
| 136 | + |
| 137 | +All other axes default to `0` unless the Thing has properties that push it rightward. |
| 138 | + |
| 139 | +### 5.2 Heuristic bumps per axis |
| 140 | + |
| 141 | +These are simple, monotonic “badness” rules: |
| 142 | + |
| 143 | +#### Safety vs Explosiveness |
| 144 | + |
| 145 | +- If Thing touches **runtime behavior in prod** (code path that executes in prod, DB schema/data, routing, CLI used in prod): |
| 146 | + - `SafetyBad += 1` |
| 147 | +- If Thing is **destructive** (delete/update bulk data, destructive CLI, risky migration): |
| 148 | + - `SafetyBad += 2` |
| 149 | +- If Thing **removes safety** (removes validation, removes error handling, bypasses types with `any`): |
| 150 | + - `SafetyBad += 2` |
| 151 | +- If Thing **adds explicit safety** (new validation, circuit breaker, idempotency, rollback path): |
| 152 | + - `SafetyBad += -1` (safer) |
| 153 | + |
| 154 | +#### Lightness vs Legacy Burden |
| 155 | + |
| 156 | +Already covered by NEW/MODIFY/DELETE, plus: |
| 157 | + |
| 158 | +- If Thing is a new **public runtime surface** (exported API, route, CLI command, queue/cron): |
| 159 | + - `BurdenBad += 2` |
| 160 | +- If Thing is a new **cross-cutting dependency** (kitchen sink util, new global manager, new global config): |
| 161 | + - `BurdenBad += 2` |
| 162 | +- If Thing **removes** such a surface or dependency: |
| 163 | + - `BurdenBad += -2` |
| 164 | + |
| 165 | +#### Clarity vs Chaos |
| 166 | + |
| 167 | +- If Thing **adds structure** (more precise types, strict TS, clear module boundaries, better naming, docs/tests that document behavior): |
| 168 | + - `ChaosBad += -1` |
| 169 | +- If Thing **punches holes in structure** (casts to `any`, “misc.ts”, dumping unrelated behaviors together, magic strings, ad-hoc conditionals): |
| 170 | + - `ChaosBad += +2` |
| 171 | +- If Thing **multiplies branches** without documentation/tests: |
| 172 | + - `ChaosBad += +1` |
| 173 | + |
| 174 | +#### Trustworthy vs Betraying |
| 175 | + |
| 176 | +- If Thing **makes signals more honest** (fix flakiness, make CI reflect truth, better error messages, stronger invariants): |
| 177 | + - `BetrayalBad += -1` |
| 178 | +- If Thing **lies or hides failure** (skip tests to get green, swallow errors, ignore results silently): |
| 179 | + - `BetrayalBad += +2` |
| 180 | +- If Thing **puts user/team at risk** (PII logging, backdoors, silent data loss): |
| 181 | + - `BetrayalBad += +3` |
| 182 | + |
| 183 | +#### Freedom vs Control-Freak |
| 184 | + |
| 185 | +- If Thing **removes unnecessary knobs** (fewer flags, simpler config, fewer approval gates, less centralization): |
| 186 | + - `ControlFreakBad += -1` |
| 187 | +- If Thing **adds knobs and approvals** (new env flags, new mandatory approvals, central manager that everything must go through): |
| 188 | + - `ControlFreakBad += +1` (small), up to `+3` for very heavy centralization. |
| 189 | +- If Thing **deeply couples** many modules to one “god” object: |
| 190 | + - `ControlFreakBad += +2` |
| 191 | + |
| 192 | +--- |
| 193 | + |
| 194 | +## 6. Per-Thing and PR-Level Scores |
| 195 | + |
| 196 | +For each Thing `T`: |
| 197 | + |
| 198 | +```text |
| 199 | +ThingBadness(T) = w_safety * SafetyBad(T) |
| 200 | + + w_burden * BurdenBad(T) |
| 201 | + + w_chaos * ChaosBad(T) |
| 202 | + + w_betrayal * BetrayalBad(T) |
| 203 | + + w_control * ControlFreakBad(T) |
0 commit comments