@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.
- package/agents/abm-strategist.md +89 -0
- package/agents/ads-meta.md +97 -0
- package/agents/analyst.md +173 -0
- package/agents/architect.md +280 -0
- package/agents/brand-guardian.md +88 -0
- package/agents/brand-strategist.md +92 -0
- package/agents/campaign-content.md +90 -0
- package/agents/campaign-email.md +88 -0
- package/agents/campaign-sms.md +87 -0
- package/agents/campaign-social.md +87 -0
- package/agents/cco.md +99 -0
- package/agents/ceo.md +106 -0
- package/agents/chairman.md +120 -0
- package/agents/cmo.md +101 -0
- package/agents/community-greeter.md +89 -0
- package/agents/community-moderator.md +92 -0
- package/agents/compliance.md +92 -0
- package/agents/copywriter.md +100 -0
- package/agents/creative-strategist.md +95 -0
- package/agents/cro.md +98 -0
- package/agents/cto.md +267 -0
- package/agents/customer-interviewer.md +93 -0
- package/agents/customer-researcher.md +89 -0
- package/agents/customer-success-manager.md +90 -0
- package/agents/customer-trainer.md +90 -0
- package/agents/cxo.md +100 -0
- package/agents/demand-creator.md +89 -0
- package/agents/demo-mover.md +83 -0
- package/agents/demo-specialist.md +89 -0
- package/agents/demo-thai-family-law.md +87 -0
- package/agents/designer.md +112 -0
- package/agents/discovery-caller.md +98 -0
- package/agents/doctor.md +139 -0
- package/agents/educate-coach.md +100 -0
- package/agents/elevate-tutor.md +83 -0
- package/agents/email-lifecycle-marketer.md +91 -0
- package/agents/engage-specialist.md +99 -0
- package/agents/events-coordinator.md +90 -0
- package/agents/foundation-builder.md +94 -0
- package/agents/funnel-architect.md +89 -0
- package/agents/gift-creator.md +100 -0
- package/agents/google-ads.md +103 -0
- package/agents/guide.md +292 -0
- package/agents/helpdesk-dispatcher.md +88 -0
- package/agents/hook-specialist.md +91 -0
- package/agents/identify-optimizer.md +101 -0
- package/agents/implementer.md +305 -0
- package/agents/incident-commander.md +120 -0
- package/agents/insights-lead.md +93 -0
- package/agents/journey-runner.md +113 -0
- package/agents/linkedin-ads.md +123 -0
- package/agents/live-sales-chat.md +90 -0
- package/agents/market-researcher.md +88 -0
- package/agents/media-buyer.md +96 -0
- package/agents/movers-customer-researcher.md +95 -0
- package/agents/movers-foundation-builder.md +96 -0
- package/agents/movers-market-researcher.md +97 -0
- package/agents/movers-pricing-strategist.md +171 -0
- package/agents/nurture-architect.md +99 -0
- package/agents/offer-architect.md +92 -0
- package/agents/onboarder.md +222 -0
- package/agents/onboarding-specialist.md +92 -0
- package/agents/operations-dashboard.md +98 -0
- package/agents/perf-engineer.md +348 -0
- package/agents/playbook-writer.md +71 -0
- package/agents/plg-strategist.md +91 -0
- package/agents/positioning-architect.md +88 -0
- package/agents/press-officer.md +89 -0
- package/agents/pricing-strategist.md +94 -0
- package/agents/privacy-officer.md +92 -0
- package/agents/referral-manager.md +91 -0
- package/agents/refine-analyst.md +102 -0
- package/agents/release-manager.md +261 -0
- package/agents/renewals-upsell-rep.md +90 -0
- package/agents/review-engineer.md +327 -0
- package/agents/rewards-steward.md +82 -0
- package/agents/sales-call-coach.md +94 -0
- package/agents/sales-closer.md +98 -0
- package/agents/security-auditor.md +313 -0
- package/agents/sell-closer.md +101 -0
- package/agents/share-amplifier.md +99 -0
- package/agents/social-media-manager.md +92 -0
- package/agents/storyteller.md +250 -0
- package/agents/strategist.md +83 -0
- package/agents/strategy-aligner.md +94 -0
- package/agents/support-agent.md +90 -0
- package/agents/tagger.md +245 -0
- package/agents/tech-writer.md +216 -0
- package/agents/test-engineer.md +243 -0
- package/agents/tiktok-ads.md +105 -0
- package/agents/tracking-engineer.md +92 -0
- package/agents/upsell-strategist.md +101 -0
- package/agents/voice.md +85 -0
- package/agents/w4-tools.md +153 -0
- package/agents/w4-verify.md +20 -138
- package/agents/workflow-optimiser.md +84 -0
- package/commands/close.md +814 -160
- package/commands/create.md +2 -2
- package/commands/deploy.md +554 -175
- package/commands/do.md +119 -109
- package/commands/fast.md +67 -0
- package/commands/improve.md +2 -2
- package/commands/one.md +418 -0
- package/commands/see.md +1 -1
- package/commands/sync.md +1 -1
- package/commands/tasks.md +222 -0
- package/commands/vespio.md +110 -0
- package/commands/vespio.remote.md +227 -0
- package/hooks/hooks.json +25 -79
- package/hooks/lib/governor-escape-match.sh +88 -0
- package/hooks/lib/hook.sh +4 -13
- package/hooks/lib/signal.sh +9 -2
- package/hooks/scripts/branch-pin.sh +6 -0
- package/hooks/scripts/config-protect.sh +6 -0
- package/hooks/scripts/do-outcome-gate.sh +19 -2
- package/hooks/scripts/git-add-guard.sh +43 -2
- package/hooks/scripts/governor-escape.sh +96 -0
- package/hooks/scripts/load-guard.sh +127 -0
- package/hooks/scripts/post-edit-check.sh +36 -29
- package/hooks/scripts/session-start.sh +34 -80
- package/hooks/scripts/task-complete-verify.sh +46 -40
- package/package.json +1 -1
- package/rules/documentation.md +9 -0
- package/scripts/ad-copy-lint.sh +656 -0
- package/scripts/agentverse-audit.sh +256 -0
- package/scripts/asi-walk.sh +435 -0
- package/scripts/astro-build-cached.sh +143 -0
- package/scripts/blocks-manifest-cached.sh +100 -0
- package/scripts/blocks-manifest.mjs +497 -0
- package/scripts/blocks-ratchet.sh +116 -0
- package/scripts/blocks-render-probe.mjs +529 -0
- package/scripts/blocks-usage.mjs +334 -0
- package/scripts/chat-context-check.sh +89 -0
- package/scripts/close-metrics.sh +558 -0
- package/scripts/close-owner.sh +268 -0
- package/scripts/db-sync-lock-check.sh +116 -0
- package/scripts/deploy-dev.sh +35 -0
- package/scripts/deploy-emit.sh +298 -0
- package/scripts/deploy-gate-check.sh +128 -0
- package/scripts/deploy-ready.sh +78 -0
- package/scripts/deploy-record.sh +605 -0
- package/scripts/deploy.sh +1273 -0
- package/scripts/do-auto.sh +598 -48
- package/scripts/do-brief.sh +113 -0
- package/scripts/do-close.sh +1137 -0
- package/scripts/do-commit.sh +75 -0
- package/scripts/do-consumer-sweep.sh +18 -1
- package/scripts/do-cycle-shape-check.sh +160 -0
- package/scripts/do-decide.sh +476 -0
- package/scripts/do-derive-check.sh +436 -0
- package/scripts/do-fleet.sh +106 -28
- package/scripts/do-folder.sh +10 -1
- package/scripts/do-next.sh +106 -0
- package/scripts/do-orchestrate.sh +17 -5
- package/scripts/do-plan-json.mjs +201 -0
- package/scripts/do-plan-json.sh +8 -0
- package/scripts/do-preflight.sh +117 -0
- package/scripts/do-project.sh +157 -0
- package/scripts/do-prove-selftest.sh +108 -0
- package/scripts/do-prove.sh +295 -23
- package/scripts/do-rank.py +31 -1
- package/scripts/do-recon-cache.sh +7 -1
- package/scripts/do-recon-pack.sh +196 -0
- package/scripts/do-reconcile.sh +121 -4
- package/scripts/do-signal.sh +280 -23
- package/scripts/do-smoke.sh +18 -1
- package/scripts/do-test-gate.sh +80 -0
- package/scripts/do-tick.sh +102 -0
- package/scripts/do-tier.sh +6 -0
- package/scripts/do-triage.sh +182 -0
- package/scripts/do-ui-gate.sh +1 -1
- package/scripts/do-w4-gates.sh +451 -0
- package/scripts/do-walk.sh +12 -1
- package/scripts/env-sync.sh +173 -0
- package/scripts/factory-brief-check.sh +330 -0
- package/scripts/factory-check.sh +68 -14
- package/scripts/factory-close-check.sh +257 -0
- package/scripts/factory-emit.sh +211 -0
- package/scripts/factory-executor-check.mjs +353 -0
- package/scripts/factory-peak.sh +301 -0
- package/scripts/factory-repo.sh +118 -3
- package/scripts/factory-review-check.mjs +61 -0
- package/scripts/factory-ship.sh +61 -0
- package/scripts/factory-tasks-check.sh +18 -1
- package/scripts/factory-turn.sh +326 -0
- package/scripts/factory-walk.sh +396 -0
- package/scripts/factory-width.sh +57 -0
- package/scripts/fade-toxic.sh +4 -3
- package/scripts/fixtures/factory-brief-real.md +44 -0
- package/scripts/fixtures/triage-dupe.md +5 -0
- package/scripts/fleet-manifest.mjs +108 -0
- package/scripts/fleet-status.sh +110 -0
- package/scripts/full-suite-paths-check.sh +144 -0
- package/scripts/gate-reaper-check.sh +98 -0
- package/scripts/gate-reaper.sh +125 -0
- package/scripts/gate-run.sh +73 -0
- package/scripts/gc-content-check.sh +140 -0
- package/scripts/gen-dev-config.py +20 -0
- package/scripts/govern-bound-check.sh +60 -0
- package/scripts/govern-claims-check.sh +233 -0
- package/scripts/govern-mem-check.sh +290 -0
- package/scripts/governor-doors-check.sh +362 -0
- package/scripts/governor-escape-check.sh +171 -0
- package/scripts/health.sh +413 -0
- package/scripts/id-inventory.mjs +418 -0
- package/scripts/land.sh +551 -0
- package/scripts/lib/gc-finished.sh +77 -0
- package/scripts/lib/govern.sh +361 -0
- package/scripts/lib/govern.ts +756 -0
- package/scripts/lighthouse-run.sh +187 -0
- package/scripts/livekit-live-check.sh +61 -0
- package/scripts/livekit-ratchet.sh +46 -0
- package/scripts/load-guard-check.sh +49 -0
- package/scripts/machine-check.sh +102 -0
- package/scripts/machine-watch.sh +177 -0
- package/scripts/one-agents.mjs +415 -0
- package/scripts/one-resume.sh +78 -0
- package/scripts/orphan-baseline.json +182 -0
- package/scripts/orphan-modules.mjs +179 -0
- package/scripts/pr-body.sh +335 -0
- package/scripts/preview-fd-check.sh +289 -0
- package/scripts/promise-manifest.mjs +24 -1
- package/scripts/release.sh +322 -0
- package/scripts/roles-check.sh +946 -0
- package/scripts/sdk-build-cached.sh +64 -0
- package/scripts/signal-watch.sh +241 -0
- package/scripts/skills-publish.sh +94 -0
- package/scripts/speed-cache-check.sh +173 -0
- package/scripts/speed-check.mjs +907 -0
- package/scripts/speed-parity-check.sh +648 -0
- package/scripts/speed-waterfall-check.sh +355 -0
- package/scripts/substrate-env-parity.mjs +156 -0
- package/scripts/tasks-claim-race.mjs +108 -0
- package/scripts/tasks-loop.sh +185 -0
- package/scripts/test-cached.sh +255 -0
- package/scripts/test-full.sh +87 -0
- package/scripts/test-honesty.mjs +137 -0
- package/scripts/test-lanes.sh +166 -0
- package/scripts/test-speed.sh +94 -0
- package/scripts/triage-shape-check.sh +149 -0
- package/scripts/tsc-cached.sh +179 -0
- package/scripts/typedb-flake-check.sh +197 -0
- package/scripts/urls-lint.sh +15 -0
- package/scripts/verify-fast.sh +445 -0
- package/scripts/vespio-sync.sh +149 -0
- package/scripts/wf-check.mjs +104 -1
- package/scripts/worktree-preview.sh +879 -0
- package/scripts/worktree-up.sh +208 -0
- package/skills/livekit-agents/SKILL.md +285 -0
- package/skills/livekit-agents/references/freshness-rules.md +168 -0
- package/skills/shadcn/SKILL.md +1 -1
- package/skills/signal/SKILL.md +0 -1
- package/skills/voice/SKILL.md +94 -6
- package/skills/voice/corpus-check.sh +87 -0
- package/hooks/scripts/compact-hint.sh +0 -35
- package/hooks/scripts/gate-guard.sh +0 -83
- package/hooks/scripts/read-tracker.sh +0 -26
- package/hooks/scripts/session-end-verify.sh +0 -51
- package/hooks/scripts/stop-reflect.sh +0 -140
- package/hooks/scripts/sync-priority-todo.sh +0 -57
- package/hooks/scripts/sync-todo-docs.sh +0 -46
- package/hooks/scripts/tool-signal.sh +0 -48
- 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
|
+
}
|