@oneie/claude 0.7.0 → 0.9.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 (263) hide show
  1. package/agents/abm-strategist.md +89 -0
  2. package/agents/ads-meta.md +97 -0
  3. package/agents/analyst.md +173 -0
  4. package/agents/architect.md +280 -0
  5. package/agents/brand-guardian.md +88 -0
  6. package/agents/brand-strategist.md +92 -0
  7. package/agents/campaign-content.md +90 -0
  8. package/agents/campaign-email.md +88 -0
  9. package/agents/campaign-sms.md +87 -0
  10. package/agents/campaign-social.md +87 -0
  11. package/agents/cco.md +99 -0
  12. package/agents/ceo.md +106 -0
  13. package/agents/chairman.md +120 -0
  14. package/agents/cmo.md +101 -0
  15. package/agents/community-greeter.md +89 -0
  16. package/agents/community-moderator.md +92 -0
  17. package/agents/compliance.md +92 -0
  18. package/agents/copywriter.md +100 -0
  19. package/agents/creative-strategist.md +95 -0
  20. package/agents/cro.md +98 -0
  21. package/agents/cto.md +267 -0
  22. package/agents/customer-interviewer.md +93 -0
  23. package/agents/customer-researcher.md +89 -0
  24. package/agents/customer-success-manager.md +90 -0
  25. package/agents/customer-trainer.md +90 -0
  26. package/agents/cxo.md +100 -0
  27. package/agents/demand-creator.md +89 -0
  28. package/agents/demo-mover.md +83 -0
  29. package/agents/demo-specialist.md +89 -0
  30. package/agents/demo-thai-family-law.md +87 -0
  31. package/agents/designer.md +112 -0
  32. package/agents/discovery-caller.md +98 -0
  33. package/agents/doctor.md +139 -0
  34. package/agents/educate-coach.md +100 -0
  35. package/agents/elevate-tutor.md +83 -0
  36. package/agents/email-lifecycle-marketer.md +91 -0
  37. package/agents/engage-specialist.md +99 -0
  38. package/agents/events-coordinator.md +90 -0
  39. package/agents/foundation-builder.md +94 -0
  40. package/agents/funnel-architect.md +89 -0
  41. package/agents/gift-creator.md +100 -0
  42. package/agents/google-ads.md +103 -0
  43. package/agents/guide.md +292 -0
  44. package/agents/helpdesk-dispatcher.md +88 -0
  45. package/agents/hook-specialist.md +91 -0
  46. package/agents/identify-optimizer.md +101 -0
  47. package/agents/implementer.md +305 -0
  48. package/agents/incident-commander.md +120 -0
  49. package/agents/insights-lead.md +93 -0
  50. package/agents/journey-runner.md +113 -0
  51. package/agents/linkedin-ads.md +123 -0
  52. package/agents/live-sales-chat.md +90 -0
  53. package/agents/market-researcher.md +88 -0
  54. package/agents/media-buyer.md +96 -0
  55. package/agents/movers-customer-researcher.md +95 -0
  56. package/agents/movers-foundation-builder.md +96 -0
  57. package/agents/movers-market-researcher.md +97 -0
  58. package/agents/movers-pricing-strategist.md +171 -0
  59. package/agents/nurture-architect.md +99 -0
  60. package/agents/offer-architect.md +92 -0
  61. package/agents/onboarder.md +222 -0
  62. package/agents/onboarding-specialist.md +92 -0
  63. package/agents/operations-dashboard.md +98 -0
  64. package/agents/perf-engineer.md +348 -0
  65. package/agents/playbook-writer.md +71 -0
  66. package/agents/plg-strategist.md +91 -0
  67. package/agents/positioning-architect.md +88 -0
  68. package/agents/press-officer.md +89 -0
  69. package/agents/pricing-strategist.md +94 -0
  70. package/agents/privacy-officer.md +92 -0
  71. package/agents/referral-manager.md +91 -0
  72. package/agents/refine-analyst.md +102 -0
  73. package/agents/release-manager.md +261 -0
  74. package/agents/renewals-upsell-rep.md +90 -0
  75. package/agents/review-engineer.md +327 -0
  76. package/agents/rewards-steward.md +82 -0
  77. package/agents/sales-call-coach.md +94 -0
  78. package/agents/sales-closer.md +98 -0
  79. package/agents/security-auditor.md +313 -0
  80. package/agents/sell-closer.md +101 -0
  81. package/agents/share-amplifier.md +99 -0
  82. package/agents/social-media-manager.md +92 -0
  83. package/agents/storyteller.md +250 -0
  84. package/agents/strategist.md +83 -0
  85. package/agents/strategy-aligner.md +94 -0
  86. package/agents/support-agent.md +90 -0
  87. package/agents/tagger.md +245 -0
  88. package/agents/tech-writer.md +216 -0
  89. package/agents/test-engineer.md +243 -0
  90. package/agents/tiktok-ads.md +105 -0
  91. package/agents/tracking-engineer.md +92 -0
  92. package/agents/upsell-strategist.md +101 -0
  93. package/agents/voice.md +85 -0
  94. package/agents/w4-tools.md +153 -0
  95. package/agents/w4-verify.md +20 -138
  96. package/agents/workflow-optimiser.md +84 -0
  97. package/commands/close.md +814 -160
  98. package/commands/create.md +2 -2
  99. package/commands/deploy.md +554 -175
  100. package/commands/do.md +119 -109
  101. package/commands/fast.md +67 -0
  102. package/commands/improve.md +2 -2
  103. package/commands/one.md +418 -0
  104. package/commands/see.md +1 -1
  105. package/commands/sync.md +1 -1
  106. package/commands/tasks.md +222 -0
  107. package/commands/vespio.md +110 -0
  108. package/commands/vespio.remote.md +227 -0
  109. package/hooks/hooks.json +25 -79
  110. package/hooks/lib/governor-escape-match.sh +88 -0
  111. package/hooks/lib/hook.sh +4 -13
  112. package/hooks/lib/signal.sh +9 -2
  113. package/hooks/scripts/branch-pin.sh +6 -0
  114. package/hooks/scripts/config-protect.sh +6 -0
  115. package/hooks/scripts/do-outcome-gate.sh +19 -2
  116. package/hooks/scripts/git-add-guard.sh +43 -2
  117. package/hooks/scripts/governor-escape.sh +96 -0
  118. package/hooks/scripts/load-guard.sh +127 -0
  119. package/hooks/scripts/post-edit-check.sh +36 -29
  120. package/hooks/scripts/session-start.sh +34 -80
  121. package/hooks/scripts/task-complete-verify.sh +46 -40
  122. package/package.json +1 -1
  123. package/rules/documentation.md +9 -0
  124. package/scripts/ad-copy-lint.sh +656 -0
  125. package/scripts/agentverse-audit.sh +256 -0
  126. package/scripts/asi-walk.sh +435 -0
  127. package/scripts/astro-build-cached.sh +143 -0
  128. package/scripts/blocks-manifest-cached.sh +100 -0
  129. package/scripts/blocks-manifest.mjs +497 -0
  130. package/scripts/blocks-ratchet.sh +116 -0
  131. package/scripts/blocks-render-probe.mjs +529 -0
  132. package/scripts/blocks-usage.mjs +334 -0
  133. package/scripts/chat-context-check.sh +89 -0
  134. package/scripts/close-metrics.sh +558 -0
  135. package/scripts/close-owner.sh +268 -0
  136. package/scripts/db-sync-lock-check.sh +116 -0
  137. package/scripts/deploy-dev.sh +35 -0
  138. package/scripts/deploy-emit.sh +298 -0
  139. package/scripts/deploy-gate-check.sh +128 -0
  140. package/scripts/deploy-ready.sh +78 -0
  141. package/scripts/deploy-record.sh +605 -0
  142. package/scripts/deploy.sh +1273 -0
  143. package/scripts/do-auto.sh +598 -48
  144. package/scripts/do-brief.sh +113 -0
  145. package/scripts/do-close.sh +1137 -0
  146. package/scripts/do-commit.sh +75 -0
  147. package/scripts/do-consumer-sweep.sh +18 -1
  148. package/scripts/do-cycle-shape-check.sh +160 -0
  149. package/scripts/do-decide.sh +476 -0
  150. package/scripts/do-derive-check.sh +436 -0
  151. package/scripts/do-fleet.sh +106 -28
  152. package/scripts/do-folder.sh +10 -1
  153. package/scripts/do-next.sh +106 -0
  154. package/scripts/do-orchestrate.sh +17 -5
  155. package/scripts/do-plan-json.mjs +201 -0
  156. package/scripts/do-plan-json.sh +8 -0
  157. package/scripts/do-preflight.sh +117 -0
  158. package/scripts/do-project.sh +157 -0
  159. package/scripts/do-prove-selftest.sh +108 -0
  160. package/scripts/do-prove.sh +295 -23
  161. package/scripts/do-rank.py +31 -1
  162. package/scripts/do-recon-cache.sh +7 -1
  163. package/scripts/do-recon-pack.sh +196 -0
  164. package/scripts/do-reconcile.sh +121 -4
  165. package/scripts/do-signal.sh +280 -23
  166. package/scripts/do-smoke.sh +18 -1
  167. package/scripts/do-test-gate.sh +80 -0
  168. package/scripts/do-tick.sh +102 -0
  169. package/scripts/do-tier.sh +6 -0
  170. package/scripts/do-triage.sh +182 -0
  171. package/scripts/do-ui-gate.sh +1 -1
  172. package/scripts/do-w4-gates.sh +451 -0
  173. package/scripts/do-walk.sh +12 -1
  174. package/scripts/env-sync.sh +173 -0
  175. package/scripts/factory-brief-check.sh +330 -0
  176. package/scripts/factory-check.sh +68 -14
  177. package/scripts/factory-close-check.sh +257 -0
  178. package/scripts/factory-emit.sh +211 -0
  179. package/scripts/factory-executor-check.mjs +353 -0
  180. package/scripts/factory-peak.sh +301 -0
  181. package/scripts/factory-repo.sh +118 -3
  182. package/scripts/factory-review-check.mjs +61 -0
  183. package/scripts/factory-ship.sh +61 -0
  184. package/scripts/factory-tasks-check.sh +18 -1
  185. package/scripts/factory-turn.sh +326 -0
  186. package/scripts/factory-walk.sh +396 -0
  187. package/scripts/factory-width.sh +57 -0
  188. package/scripts/fade-toxic.sh +4 -3
  189. package/scripts/fixtures/factory-brief-real.md +44 -0
  190. package/scripts/fixtures/triage-dupe.md +5 -0
  191. package/scripts/fleet-manifest.mjs +108 -0
  192. package/scripts/fleet-status.sh +110 -0
  193. package/scripts/full-suite-paths-check.sh +144 -0
  194. package/scripts/gate-reaper-check.sh +98 -0
  195. package/scripts/gate-reaper.sh +125 -0
  196. package/scripts/gate-run.sh +73 -0
  197. package/scripts/gc-content-check.sh +140 -0
  198. package/scripts/gen-dev-config.py +20 -0
  199. package/scripts/govern-bound-check.sh +60 -0
  200. package/scripts/govern-claims-check.sh +233 -0
  201. package/scripts/govern-mem-check.sh +290 -0
  202. package/scripts/governor-doors-check.sh +362 -0
  203. package/scripts/governor-escape-check.sh +171 -0
  204. package/scripts/health.sh +413 -0
  205. package/scripts/id-inventory.mjs +418 -0
  206. package/scripts/land.sh +551 -0
  207. package/scripts/lib/gc-finished.sh +77 -0
  208. package/scripts/lib/govern.sh +361 -0
  209. package/scripts/lib/govern.ts +756 -0
  210. package/scripts/lighthouse-run.sh +187 -0
  211. package/scripts/livekit-live-check.sh +61 -0
  212. package/scripts/livekit-ratchet.sh +46 -0
  213. package/scripts/load-guard-check.sh +49 -0
  214. package/scripts/machine-check.sh +102 -0
  215. package/scripts/machine-watch.sh +177 -0
  216. package/scripts/one-agents.mjs +415 -0
  217. package/scripts/one-resume.sh +78 -0
  218. package/scripts/orphan-baseline.json +182 -0
  219. package/scripts/orphan-modules.mjs +179 -0
  220. package/scripts/pr-body.sh +335 -0
  221. package/scripts/preview-fd-check.sh +289 -0
  222. package/scripts/promise-manifest.mjs +24 -1
  223. package/scripts/release.sh +322 -0
  224. package/scripts/roles-check.sh +946 -0
  225. package/scripts/sdk-build-cached.sh +64 -0
  226. package/scripts/signal-watch.sh +241 -0
  227. package/scripts/skills-publish.sh +94 -0
  228. package/scripts/speed-cache-check.sh +173 -0
  229. package/scripts/speed-check.mjs +907 -0
  230. package/scripts/speed-parity-check.sh +648 -0
  231. package/scripts/speed-waterfall-check.sh +355 -0
  232. package/scripts/substrate-env-parity.mjs +156 -0
  233. package/scripts/tasks-claim-race.mjs +108 -0
  234. package/scripts/tasks-loop.sh +185 -0
  235. package/scripts/test-cached.sh +255 -0
  236. package/scripts/test-full.sh +87 -0
  237. package/scripts/test-honesty.mjs +137 -0
  238. package/scripts/test-lanes.sh +166 -0
  239. package/scripts/test-speed.sh +94 -0
  240. package/scripts/triage-shape-check.sh +149 -0
  241. package/scripts/tsc-cached.sh +179 -0
  242. package/scripts/typedb-flake-check.sh +197 -0
  243. package/scripts/urls-lint.sh +15 -0
  244. package/scripts/verify-fast.sh +445 -0
  245. package/scripts/vespio-sync.sh +149 -0
  246. package/scripts/wf-check.mjs +104 -1
  247. package/scripts/worktree-preview.sh +879 -0
  248. package/scripts/worktree-up.sh +208 -0
  249. package/skills/livekit-agents/SKILL.md +285 -0
  250. package/skills/livekit-agents/references/freshness-rules.md +168 -0
  251. package/skills/shadcn/SKILL.md +1 -1
  252. package/skills/signal/SKILL.md +0 -1
  253. package/skills/voice/SKILL.md +94 -6
  254. package/skills/voice/corpus-check.sh +87 -0
  255. package/hooks/scripts/compact-hint.sh +0 -35
  256. package/hooks/scripts/gate-guard.sh +0 -83
  257. package/hooks/scripts/read-tracker.sh +0 -26
  258. package/hooks/scripts/session-end-verify.sh +0 -51
  259. package/hooks/scripts/stop-reflect.sh +0 -140
  260. package/hooks/scripts/sync-priority-todo.sh +0 -57
  261. package/hooks/scripts/sync-todo-docs.sh +0 -46
  262. package/hooks/scripts/tool-signal.sh +0 -48
  263. package/scripts/do-tasks-bridge.py +0 -366
@@ -0,0 +1,361 @@
1
+ #!/usr/bin/env bash
2
+ # govern.sh — machine-wide concurrency governor for heavy build gates.
3
+ #
4
+ # WHY: N concurrent Claude Code sessions each run `bun run verify`
5
+ # (tsc --noEmit + vitest over 875 files). Nothing bounded them, so 6 tsc and
6
+ # 3 vitest pools ran at once on a 10-core/24GB box -> load 57, swap full,
7
+ # ~26 MB/s of swapins. Each gate then took 18 min instead of 2, so sessions
8
+ # timed out and spawned MORE. This library breaks that cycle.
9
+ #
10
+ # macOS has NO flock(1) and NO timeout(1) — both are GNU coreutils. Every
11
+ # primitive is built from mkdir(2) atomicity instead.
12
+ #
13
+ # ─────────────────────────────────────────────────────────────────────────────
14
+ # THIS FILE IS NOW A SHIM. The mechanics live in lib/govern.ts (Bun).
15
+ #
16
+ # § GATES item 5 of text/factory-do.md: the DESIGN was proven — slots, bound,
17
+ # claims, the two memo keys, four-state gates. The RUNTIME was the recurring
18
+ # defect. bash 3.2 on macOS has no flock, no timeout, no BASHPID; `set -m`
19
+ # needs job control; a watchdog subshell cannot own the `sleep` it forks (21
20
+ # orphaned `sleep 1800` on the box at once, 2026-09-04); and the
21
+ # `find | sort -z | xargs` pipeline plus zsh-vs-bash word splitting produced
22
+ # four separate measured bugs in one day. Every one of those lives in a
23
+ # MECHANISM, not in a decision. The mechanisms moved to govern.ts; the
24
+ # decisions did not change.
25
+ #
26
+ # The FUNCTION NAMES, ARGUMENTS and EXIT CODES below are unchanged, because
27
+ # ~65 callers source this file (gate-run.sh, do-fleet.sh, tsc-cached.sh,
28
+ # do-reconcile.sh, machine-check.sh, fleet-status.sh, do-commit.sh,
29
+ # factory-width.sh, gate-reaper.sh, do-preflight.sh, hooks/load-guard.sh,
30
+ # hooks/session-start.sh, and the six governor proofs). None of them changed.
31
+ #
32
+ # WHAT DELIBERATELY STAYS IN BASH — the stub seams:
33
+ # _gv_alive (kill -0)
34
+ # _gv_vm_stat / _gv_swapusage / _gv_memsize (vm_stat, sysctl)
35
+ # Three of the six governor proofs override these AS BASH FUNCTIONS to drive a
36
+ # synthetic machine or a gutted reaper (govern-mem-check.sh's whole fixture
37
+ # table; govern-claims-check.sh's R1/R2 red proof). They are one syscall and one
38
+ # exec each — none of the runtime defects above touches them — so leaving them
39
+ # here costs nothing and is what keeps those red proofs honest. The shim feeds
40
+ # their output to govern.ts: vm_stat text on stdin, and, for the claim reads, an
41
+ # explicit alive-set computed through _gv_alive.
42
+ #
43
+ # THE OWNER PID is the CALLING SHELL ($$), never the short-lived bun process: a
44
+ # lock whose owner exits the instant it is taken is reaped by the next
45
+ # contender, which would silently invert governor-doors-check.sh's re-entrancy
46
+ # RED half.
47
+ #
48
+ # Source it, don't exec it: . "$(dirname "$0")/lib/govern.sh"
49
+
50
+ GOVERN_DIR="${GOVERN_DIR:-${TMPDIR:-/tmp}/one-govern}"
51
+ export GOVERN_DIR
52
+ mkdir -p "$GOVERN_DIR" 2>/dev/null || true
53
+
54
+ # Heavy gates allowed to run at once, machine-wide, across all sessions and
55
+ # worktrees. 10 cores: 2 gates leaves headroom for editors + dev servers.
56
+ GOVERN_MAX_GATES="${GOVERN_MAX_GATES:-2}"
57
+ export GOVERN_MAX_GATES
58
+
59
+ # ── locating the port ────────────────────────────────────────────────────────
60
+ # BASH_SOURCE is unset under zsh, which this lib is sourced into. $0 is the
61
+ # fallback there. GOVERN_TS overrides both.
62
+ if [ -n "${BASH_SOURCE:-}" ]; then
63
+ _GOVERN_LIB_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" 2>/dev/null && pwd)"
64
+ else
65
+ _GOVERN_LIB_DIR="$(cd "$(dirname "$0")" 2>/dev/null && pwd)"
66
+ fi
67
+ GOVERN_TS="${GOVERN_TS:-$_GOVERN_LIB_DIR/govern.ts}"
68
+
69
+ # Resolve bun ONCE. A hook fired by Claude Code does not necessarily inherit a
70
+ # login PATH, and the one memory arm that actually BLOCKS (hooks/load-guard.sh)
71
+ # fails OPEN when the probe cannot answer — so an unresolvable bun would
72
+ # silently stop a guard from guarding. No absolute user path is hardcoded: this
73
+ # file is classified `portable` and factory-repo.sh --check-portability greps it
74
+ # for monorepo paths.
75
+ if [ -z "${GOVERN_BUN:-}" ]; then
76
+ GOVERN_BUN="$(command -v bun 2>/dev/null || true)"
77
+ if [ -z "$GOVERN_BUN" ]; then
78
+ for _c in "${BUN_INSTALL:-$HOME/.bun}/bin/bun" \
79
+ "$HOME/.bun/bin/bun" \
80
+ "$HOME/.local/share/mise/shims/bun" \
81
+ "$HOME/.local/share/mise/installs/bun/latest/bin/bun" \
82
+ /opt/homebrew/bin/bun /usr/local/bin/bun; do
83
+ [ -x "$_c" ] && { GOVERN_BUN="$_c"; break; }
84
+ done
85
+ fi
86
+ [ -n "$GOVERN_BUN" ] || echo "[govern] WARNING: bun not found — the governor cannot run (set GOVERN_BUN)" >&2
87
+ fi
88
+
89
+ # _gov <subcommand> … — the one door to the port.
90
+ _gov() { "$GOVERN_BUN" "$GOVERN_TS" "$@"; }
91
+
92
+ _gv_log() { [ -n "${GOVERN_DEBUG:-}" ] && echo "[govern] $*" >&2; return 0; }
93
+
94
+ # _gv_alive <pid> — is that pid still running?
95
+ # STUB SEAM: govern-claims-check.sh R1/R2 overrides this to prove the claim
96
+ # reaper is what the evaporation checks are testing.
97
+ _gv_alive() { [ -n "${1:-}" ] && kill -0 "$1" 2>/dev/null; }
98
+ _GV_ALIVE_CANON="$(declare -f _gv_alive 2>/dev/null || true)"
99
+
100
+ # ── locks · slots ────────────────────────────────────────────────────────────
101
+ # mkdir(2) is the arbiter; the owner recorded is THIS shell.
102
+
103
+ # gate_lock <name> [wait_secs] — take a named singleton lock.
104
+ # exit 0 = acquired (caller MUST call gate_unlock)
105
+ # exit 1 = someone else holds it and still does after wait_secs
106
+ gate_lock() {
107
+ local name="$1"; local wait_s="${2:-0}"
108
+ if GOVERN_OWNER_PID=$$ _gov lock "$name" "$wait_s"; then
109
+ GOVERN_HELD="${GOVERN_HELD:-} $name"
110
+ return 0
111
+ fi
112
+ return 1
113
+ }
114
+
115
+ gate_unlock() {
116
+ GOVERN_OWNER_PID=$$ _gov unlock "$1" >/dev/null 2>&1
117
+ return 0
118
+ }
119
+
120
+ # gate_slot [wait_secs] — take one of the effective slots. This is the cap that
121
+ # makes "many Claude sessions" safe: session 3+ queues instead of piling more
122
+ # tsc onto a thrashing box. The effective cap is min(GOVERN_MAX_GATES,
123
+ # gate_headroom) — a static config must never authorise more than memory can
124
+ # fund (measured 2026-08-31: settings said 4, headroom said 2, and 4 won —
125
+ # load 82, gates taking 19:34 instead of ~2 min).
126
+ gate_slot() {
127
+ local wait_s="${1:-900}" _s
128
+ _s="$(GOVERN_OWNER_PID=$$ _gov slot "$wait_s")" || return 1
129
+ [ -n "$_s" ] || return 1
130
+ GOVERN_SLOT="$_s"
131
+ GOVERN_HELD="${GOVERN_HELD:-} $_s"
132
+ return 0
133
+ }
134
+
135
+ gate_slot_release() { [ -n "${GOVERN_SLOT:-}" ] && gate_unlock "$GOVERN_SLOT"; GOVERN_SLOT=""; return 0; }
136
+
137
+ # gate_release_all — drop every lock this shell holds. Wire to a trap so a
138
+ # killed/timed-out gate never leaves a lock behind.
139
+ gate_release_all() {
140
+ local n
141
+ for n in ${GOVERN_HELD:-}; do gate_unlock "$n"; done
142
+ gate_slot_release
143
+ return 0
144
+ }
145
+
146
+ # run_bounded <secs> <cmd...> — run cmd with a hard wall-clock cap, killing the
147
+ # whole PROCESS GROUP on timeout. Replaces the missing timeout(1).
148
+ #
149
+ # The process group is the point: `bun run verify` spawns bash -> bun -> node
150
+ # -> N vitest forks. Killing the shell alone reparents all of them to launchd,
151
+ # which is exactly how this repo leaked orphaned verify trees.
152
+ #
153
+ # The bash watchdog this replaces failed twice, both measured: it inherited the
154
+ # caller's stdout (then stderr), so `$(run_bounded …)` and `… 2>&1 | tail` hung
155
+ # for the FULL timeout after the command had answered; and `kill $watch_pid`
156
+ # reaped the subshell but not the `sleep` it forked (21 orphaned `sleep 1800`,
157
+ # ppid 1, on the box at once). govern.ts uses an in-process timer — it forks
158
+ # nothing and holds no fd — so neither can recur.
159
+ run_bounded() { _gov run-bounded "$@"; }
160
+
161
+ # ─────────────────────────────────────────────────────────────────────────────
162
+ # MEMORY PROBE — what is actually available, not what feels available.
163
+ #
164
+ # THE DEFECT THIS REPLACES (measured 2026-09-03, three independent samples):
165
+ # every memory decision in this harness read `memory_pressure`'s "System-wide
166
+ # memory free percentage" and multiplied it by hw.memsize. That figure is a
167
+ # PRESSURE signal: macOS counts reclaimable memory — file cache, purgeable, and
168
+ # pages it has already compressed — as "free". Same box, same second:
169
+ #
170
+ # memory_pressure "free percentage" 74% -> 24 * 74/100 = 17 GB
171
+ # vm_stat Pages free 21032 -> 0.32 GB (1.3% of 24)
172
+ # vm.swapusage 9400 M of 10240 M in use
173
+ # old gate_headroom 7 ("room for 7 more cycles")
174
+ #
175
+ # The honest quantities are in vm_stat: free + purgeable + min(file-backed,
176
+ # inactive). NO SWAP TERM, deliberately — swap in use is a scar, not a signal:
177
+ # macOS does not release swap files promptly, so a box that thrashed an hour ago
178
+ # still reads ~9 GB used, and charging for that would serialise an idle machine.
179
+ #
180
+ # The arithmetic is in govern.ts; the three wrappers below stay here because
181
+ # govern-mem-check.sh overrides them to feed the probe a synthetic machine.
182
+ _gv_vm_stat() { vm_stat 2>/dev/null; }
183
+ _gv_swapusage() { sysctl -n vm.swapusage 2>/dev/null; }
184
+ _gv_memsize() { sysctl -n hw.memsize 2>/dev/null; }
185
+
186
+ _gv_num() { case "${1:-}" in ''|*[!0-9]*) return 1 ;; *) printf '%s' "$1" ;; esac; }
187
+
188
+ # gate_mem_avail_mb — available RAM in MB on stdout. Returns non-zero and prints
189
+ # NOTHING when any field is unreadable: a broken sensor must never silently
190
+ # serialise the fleet.
191
+ gate_mem_avail_mb() { _gv_vm_stat | _gov mem-avail-mb; }
192
+
193
+ # gate_price_mb — what ONE gate slot actually costs in RAM, derived from the
194
+ # LIVE fork count rather than a stale constant (vitest maxWorkers went 4 -> 8 and
195
+ # test-lanes.sh runs TWO drivers in one slot, so the same gate had two different
196
+ # prices depending on who launched it — that drift IS the defect). Constants
197
+ # measured 2026-09-03 over 125 fork / 65 driver samples. All overridable; an
198
+ # explicit GOVERN_GB_PER_CYCLE is still the operator's override and wins.
199
+ gate_price_mb() { _gov price-mb; }
200
+
201
+ # gate_pressure — 0 if the machine has headroom, 1 if it is already thrashing.
202
+ # Unreadable sensor -> 0: never block on a broken probe.
203
+ gate_pressure() {
204
+ local _ms
205
+ _ms="$(_gv_memsize)" || _ms=""
206
+ _gv_vm_stat | GOVERN_MEMSIZE="$_ms" _gov pressure
207
+ }
208
+
209
+ # gate_headroom — how many concurrent heavy CYCLES this box can afford right
210
+ # now. >= 1 always (do-fleet.sh clamps to this with no floor of its own, so a 0
211
+ # would launch nothing at all); 99 when memory cannot be read.
212
+ gate_headroom() { _gv_vm_stat | _gov headroom; }
213
+
214
+ # gate_mem_report — one legible line of the honest numbers, for the sites a
215
+ # HUMAN reads (machine-check, fleet-status, do-preflight). Never on a hot path.
216
+ # Emits: avail_mb=<n> total_mb=<n> avail_pct=<n> swap_used_mb=<n> price_mb=<n> slots=<n>
217
+ gate_mem_report() {
218
+ local _ms _sw
219
+ _ms="$(_gv_memsize 2>/dev/null)" || _ms=""
220
+ _sw="$(_gv_swapusage 2>/dev/null)" || _sw=""
221
+ _gv_vm_stat | GOVERN_MEMSIZE="$_ms" GOVERN_SWAPUSAGE="$_sw" _gov mem-report
222
+ }
223
+
224
+ # tsc_tree_fingerprint <folder> [<extra-dir>...] — ONE hash of everything tsc
225
+ # READS for <folder>, keyed BY CONTENT, never by mtime. Run from the repo root.
226
+ #
227
+ # Two checkouts of one commit have identical bytes and different mtimes, so the
228
+ # old `stat -f '%m %N'` key made N worktrees each pay a full tsc and write their
229
+ # own stamp (28 unshared stamps, measured 2026-09-03). Same bytes ⇒ same key, in
230
+ # any checkout; a doc edit moves nothing.
231
+ #
232
+ # The two callers — tsc-cached.sh and do-reconcile.sh `types` — MUST both use
233
+ # this function: they share the `tsc-<folder>.<fp>` namespace on purpose, and a
234
+ # second key derivation is a second definition that silently splits the memo.
235
+ # The CALLER names the extra dirs (the folders that resolve a workspace
236
+ # package's types out of its dist) — this library is `portable` and names no
237
+ # monorepo path.
238
+ tsc_tree_fingerprint() {
239
+ [ -n "${1:-}" ] || return 1
240
+ _gov fingerprint "$@"
241
+ }
242
+
243
+ # gate_sweep_stale — drop locks whose owner is gone. The lock reaper only fires
244
+ # when someone CONTENDS, so a session that died holding a slot would shrink the
245
+ # effective cap until the next contender happened along. Run at session start.
246
+ # Echoes the number swept.
247
+ gate_sweep_stale() { _gov sweep-stale; }
248
+
249
+ # ─────────────────────────────────────────────────────────────────────────────
250
+ # CLAIMS — a machine-wide registry of who is working on WHICH REGION right now.
251
+ #
252
+ # WHY: do-fleet's conflict registry was `LOCK_FILE="$(mktemp)"` — process-local.
253
+ # Nine concurrent fleet invocations held nine private maps and could not see
254
+ # each other, so two fleets picked the same region and did the work twice.
255
+ #
256
+ # It is NOT a queue and there is NO coordinator. A worker that finds its region
257
+ # claimed takes the next candidate instead of waiting — contention costs a
258
+ # re-rank, never a wait, so there is nothing to deadlock.
259
+ #
260
+ # EVAPORATION — a claim expires with no human in the loop, two ways: the owner
261
+ # pid is dead, or the lease expired (GOVERN_CLAIM_TTL_SECS, default 90 min;
262
+ # p100 observed fleet duration is 79 min). Both fire on the READ path, so the
263
+ # next contender reclaims dead ground without anyone sweeping first.
264
+ # gate_sweep_stale only matches `lock-*` and will never see these; claim_sweep
265
+ # is the equivalent for claims.
266
+
267
+ GOVERN_CLAIMS_DIR="${GOVERN_CLAIMS_DIR:-$GOVERN_DIR/claims}"
268
+ GOVERN_CLAIM_TTL_SECS="${GOVERN_CLAIM_TTL_SECS:-5400}" # 90 min
269
+ export GOVERN_CLAIMS_DIR GOVERN_CLAIM_TTL_SECS
270
+
271
+ # _gv_claim_key <region> — a readable, collision-free directory name.
272
+ # STAYS IN BASH: `cksum` is the POSIX CRC (length-appended, final complement),
273
+ # not zlib's crc32, and re-deriving it in TS would be a second definition of a
274
+ # mapping govern-claims-check.sh reads straight off disk. Readable matters —
275
+ # `ls $GOVERN_DIR/claims` is meant to be the map a human reads — and the cksum
276
+ # suffix restores the injectivity that sanitising destroys (a/b vs a_b).
277
+ _gv_claim_key() {
278
+ local r="$1" safe sum
279
+ safe=$(printf '%s' "$r" | tr -c 'A-Za-z0-9._-' '_' | cut -c1-64)
280
+ sum=$(printf '%s' "$r" | cksum | awk '{print $1}')
281
+ printf '%s.%s' "$safe" "$sum"
282
+ }
283
+
284
+ # _gv_claim_env — how the claim commands learn who is alive.
285
+ #
286
+ # NORMAL PATH: nothing. govern.ts asks the kernel itself, at the instant it
287
+ # contends. That is not an optimisation, it is a correctness requirement — a
288
+ # pre-computed alive-set is a SNAPSHOT, and 12 workers racing one region each
289
+ # snapshot an empty registry, each conclude the winner's pid is "not alive",
290
+ # each reap it and each take the region. Measured here on the first port:
291
+ # govern-claims-check C1 reported 12 winners of 12.
292
+ #
293
+ # STUBBED PATH: when the caller has overridden _gv_alive (govern-claims-check's
294
+ # R1/R2 red proof does exactly this, to prove the evaporation checks are testing
295
+ # the reaper), the shell's answer must win. Detected by comparing the function
296
+ # body against the one this file defined, so no caller has to opt in.
297
+ _gv_alive_stubbed() { [ "$(declare -f _gv_alive 2>/dev/null || true)" != "$_GV_ALIVE_CANON" ]; }
298
+
299
+ # Sets/exports the two vars govern.ts reads. Called before every claim command.
300
+ _gv_claim_prep() {
301
+ GOVERN_ALIVE_SET=0; GOVERN_ALIVE_PIDS=""
302
+ export GOVERN_ALIVE_SET GOVERN_ALIVE_PIDS
303
+ _gv_alive_stubbed || return 0
304
+ local p out=""
305
+ while IFS= read -r p; do
306
+ [ -n "$p" ] || continue
307
+ _gv_alive "$p" && out="$out,$p"
308
+ done <<EOF
309
+ $(_gov claim-pids 2>/dev/null)
310
+ EOF
311
+ GOVERN_ALIVE_SET=1; GOVERN_ALIVE_PIDS="${out#,}"
312
+ return 0
313
+ }
314
+
315
+ # claim_take <region> [slug] — deposit a claim on a region.
316
+ # 0 = it is yours (freshly taken, or you already held it)
317
+ # 1 = a live, in-lease worker holds it — REROUTE, do not wait
318
+ # mkdir(2) is the arbiter: two workers racing one region, exactly one wins.
319
+ claim_take() {
320
+ _gv_claim_prep
321
+ GOVERN_OWNER_PID=$$ _gov claim-take "$(_gv_claim_key "$1")" "$1" "${2:-}"
322
+ }
323
+
324
+ # claim_owner <region> — echo "<slug> <pid>" of the LIVE owner, else nothing.
325
+ # Reaps before reading: a dead owner's claim must never read as held.
326
+ claim_owner() {
327
+ _gv_claim_prep
328
+ GOVERN_OWNER_PID=$$ _gov claim-owner "$(_gv_claim_key "$1")"
329
+ }
330
+
331
+ # claim_release <region> — drop a claim you own. Never touches another's.
332
+ claim_release() {
333
+ GOVERN_OWNER_PID=$$ _gov claim-release "$(_gv_claim_key "$1")" >/dev/null 2>&1
334
+ return 0
335
+ }
336
+
337
+ # claim_release_all — drop every claim this shell holds. Wire it to the EXIT
338
+ # trap: a clean exit must free its ground immediately, so the 90-min TTL stays
339
+ # the exception path (crash/kill) and never the normal one.
340
+ #
341
+ # NOTE it keys on the plain shell pid while claim_take/claim_release key on
342
+ # ${GOVERN_CLAIM_PID:-$$}. That asymmetry is in the bash original and is
343
+ # preserved verbatim — normalising it during a port would change behaviour no
344
+ # proof covers.
345
+ claim_release_all() {
346
+ GOVERN_OWNER_PID=$$ _gov claim-release-all >/dev/null 2>&1
347
+ return 0
348
+ }
349
+
350
+ # claim_list — every LIVE claim as "region<TAB>slug<TAB>pid". Reaps as it walks.
351
+ claim_list() {
352
+ _gv_claim_prep
353
+ GOVERN_OWNER_PID=$$ _gov claim-list
354
+ }
355
+
356
+ # claim_sweep — reap every dead/expired claim. Echoes the number swept.
357
+ # gate_sweep_stale's counterpart; safe to call at session start.
358
+ claim_sweep() {
359
+ _gv_claim_prep
360
+ GOVERN_OWNER_PID=$$ _gov claim-sweep
361
+ }