@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,110 @@
|
|
|
1
|
+
# /vespio — the standing sync fleet
|
|
2
|
+
|
|
3
|
+
```
|
|
4
|
+
██╗ ██╗███████╗███████╗██████╗ ██╗ ██████╗
|
|
5
|
+
██║ ██║██╔════╝██╔════╝██╔══██╗██║██╔═══██╗
|
|
6
|
+
██║ ██║█████╗ ███████╗██████╔╝██║██║ ██║ one-ie ──▶ vespio
|
|
7
|
+
╚██╗ ██╔╝██╔══╝ ╚════██║██╔═══╝ ██║██║ ██║ one way · manifest-driven
|
|
8
|
+
╚████╔╝ ███████╗███████║██║ ██║╚██████╔╝
|
|
9
|
+
╚═══╝ ╚══════╝╚══════╝╚═╝ ╚═╝ ╚═════╝
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
Keep `apps/vespio` current with the tools it can actually use. One word to see
|
|
13
|
+
the gap, close it, and push.
|
|
14
|
+
|
|
15
|
+
**Vespio is not a smaller monorepo.** It is an agency tree — `clients/`, `site/`,
|
|
16
|
+
`web/`, `ai/`, `packages/`. There is no `schema/`, no `pay/`, no `channels/`, and
|
|
17
|
+
no `text/` promise layer. Most of one-ie's harness hard-asserts against a tree
|
|
18
|
+
vespio does not have. So the interesting question was never *"how do we copy
|
|
19
|
+
everything"* — it is *"what is portable, and who decides?"*
|
|
20
|
+
|
|
21
|
+
---
|
|
22
|
+
|
|
23
|
+
## 0 · The manifest decides — there is no second list
|
|
24
|
+
|
|
25
|
+
`.claude/scripts/factory-repo.sh` already classifies every script:
|
|
26
|
+
|
|
27
|
+
| bucket | means | ships to vespio |
|
|
28
|
+
|---|---|---|
|
|
29
|
+
| `portable` | no monorepo path, no credential read | **yes** |
|
|
30
|
+
| `needs-env` | wants `ONE_ENV_FILE`, or names paths that degrade to no-ops | **yes** |
|
|
31
|
+
| `monorepo-only` | hard-asserts against THIS tree; refuses without it | **never** |
|
|
32
|
+
| *unclassified* | nobody has decided yet | **never — silence is not a licence** |
|
|
33
|
+
|
|
34
|
+
`vespio-sync.sh` reads that manifest rather than keeping its own copy. Two lists
|
|
35
|
+
drift; one cannot. Adding a script to `.claude/scripts/` therefore means adding a
|
|
36
|
+
manifest line — `factory-repo.sh --check-portability` names every script that
|
|
37
|
+
still has none, and `/vespio` prints them so they cannot rot in silence.
|
|
38
|
+
|
|
39
|
+
**The `needs-env` bucket was classified against the FACTORY tree, not vespio's.**
|
|
40
|
+
Same three buckets, different destination. When a `needs-env` script misbehaves in
|
|
41
|
+
vespio, that is a reclassification, not a bug — fix the manifest.
|
|
42
|
+
|
|
43
|
+
---
|
|
44
|
+
|
|
45
|
+
## 1 · Run it
|
|
46
|
+
|
|
47
|
+
```bash
|
|
48
|
+
bash .claude/scripts/vespio-sync.sh --check # read-only: missing · drifted
|
|
49
|
+
bash .claude/scripts/vespio-sync.sh # copy, then show the diff
|
|
50
|
+
bash .claude/scripts/vespio-sync.sh --commit # copy + commit (never pushes)
|
|
51
|
+
git -C ../apps/vespio push origin main # the human step, always separate
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
`--check` costs nothing. Run it first and last.
|
|
55
|
+
|
|
56
|
+
**Pull before you sync.** Vespio's `main` drifts behind `origin/main` — it was
|
|
57
|
+
9 commits behind on 2026-08-26. Syncing onto a stale local tree and pushing is
|
|
58
|
+
the one irreversible mistake available here.
|
|
59
|
+
|
|
60
|
+
```bash
|
|
61
|
+
git -C ../apps/vespio fetch origin && git -C ../apps/vespio pull --ff-only origin main
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
---
|
|
65
|
+
|
|
66
|
+
## 2 · What ships, and what is held back on purpose
|
|
67
|
+
|
|
68
|
+
Held back is a **decision**, not an oversight. Record the reason or it will be
|
|
69
|
+
"fixed" by the next person.
|
|
70
|
+
|
|
71
|
+
| Held back | Why |
|
|
72
|
+
|---|---|
|
|
73
|
+
| `deploy.md` · `db-sync.md` · `release.md` | the 5-service pipeline; vespio ships a site |
|
|
74
|
+
| `one.md` | nine fleets over `text/*.md` docs that do not exist here |
|
|
75
|
+
| `oo-push.md` · `rag.md` | monorepo-specific surfaces |
|
|
76
|
+
| skills `typedb` `sdk` `mcp` `cli` `puck` `promise-*` | need `schema/`, `packages/`, or the promise layer |
|
|
77
|
+
| every `monorepo-only` script | by manifest |
|
|
78
|
+
|
|
79
|
+
`cp -RL`, not `cp -R`: `.claude/skills/livekit-agents` is a **symlink out of the
|
|
80
|
+
tree** and would land in vespio as a dangling link.
|
|
81
|
+
|
|
82
|
+
---
|
|
83
|
+
|
|
84
|
+
## 3 · Staging law — the neighbour's work is not yours
|
|
85
|
+
|
|
86
|
+
Vespio carries uncommitted `clients/*/data/lifecycles/*.toml` edits that belong to
|
|
87
|
+
somebody else. A harness sync must never carry them.
|
|
88
|
+
|
|
89
|
+
- `git add .claude` — explicit path, always.
|
|
90
|
+
- Never `git add -A`, never `git add .`, never `git commit -a`.
|
|
91
|
+
- Commit and push are **separate breaths**. Show the file list, then push.
|
|
92
|
+
|
|
93
|
+
---
|
|
94
|
+
|
|
95
|
+
## 4 · Standing state
|
|
96
|
+
|
|
97
|
+
**`.env.local.bak` is TRACKED in vespio and contains a real `ONE_API_KEY`.**
|
|
98
|
+
It entered at `b931b69` and `.gitignore` covers `.env.local` but not the `.bak`.
|
|
99
|
+
Untracking it forward is safe and done; **the key is still in git history and must
|
|
100
|
+
be rotated** — that is an operator action, not a fleet's. Do not attempt a history
|
|
101
|
+
rewrite on a shared remote.
|
|
102
|
+
|
|
103
|
+
---
|
|
104
|
+
|
|
105
|
+
## Don't
|
|
106
|
+
|
|
107
|
+
- Don't sync while a fleet is mid-write in vespio. Land the board, don't widen it.
|
|
108
|
+
- Don't hand-edit vespio's `.claude/` — it is generated output. Change one-ie, sync.
|
|
109
|
+
- Don't ship an unclassified script. Classify it in the manifest first.
|
|
110
|
+
- Don't push in the same breath as the commit. Look at the file list.
|
|
@@ -0,0 +1,227 @@
|
|
|
1
|
+
# /vespio — start the fleet
|
|
2
|
+
|
|
3
|
+
```
|
|
4
|
+
██╗ ██╗███████╗███████╗██████╗ ██╗ ██████╗
|
|
5
|
+
██║ ██║██╔════╝██╔════╝██╔══██╗██║██╔═══██╗
|
|
6
|
+
██║ ██║█████╗ ███████╗██████╔╝██║██║ ██║ probe · fan out · join
|
|
7
|
+
╚██╗ ██╔╝██╔══╝ ╚════██║██╔═══╝ ██║██║ ██║ no conductor · no collisions
|
|
8
|
+
╚████╔╝ ███████╗███████║██║ ██║╚██████╔╝
|
|
9
|
+
╚═══╝ ╚══════╝╚══════╝╚═╝ ╚═╝ ╚═════╝
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
One word to start work on this repo. `/vespio` prices the box, shows the board,
|
|
13
|
+
and names the one next move.
|
|
14
|
+
|
|
15
|
+
**This is the vespio-side command.** The harness here is generated output, synced
|
|
16
|
+
one-way from the `one-ie` monorepo. You cannot sync from inside this clone, and
|
|
17
|
+
you are not meant to — see § 4.
|
|
18
|
+
|
|
19
|
+
---
|
|
20
|
+
|
|
21
|
+
## 0 · First run, once per clone
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
bun install
|
|
25
|
+
mkdir -p text # the loop's working directory
|
|
26
|
+
cp data/docs/templates/template-todo.md text/ # the frontmatter contract
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
**`text/` is not optional.** `/do` reads and writes `text/<slug>-todo.md` — the
|
|
30
|
+
command names that path 38 times. A fresh clone has no `text/`, so the loop exits
|
|
31
|
+
before it starts. This is the step nobody guesses, which is why it is step one.
|
|
32
|
+
|
|
33
|
+
---
|
|
34
|
+
|
|
35
|
+
## 1 · Price the box BEFORE you fan out
|
|
36
|
+
|
|
37
|
+
The binding constraint is **memory, not cores**. A cycle costs roughly 2GB
|
|
38
|
+
(vitest driver + forks + tsc + node). On a 10-core/24GB box, `cores - 2` would
|
|
39
|
+
authorise 8 concurrent worktrees — about 16GB of gates before your editor, your
|
|
40
|
+
session and the OS get a byte.
|
|
41
|
+
|
|
42
|
+
```bash
|
|
43
|
+
bash .claude/scripts/machine-check.sh --watch # load · swap DIRECTION · orphans
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
**Read swap direction, not the swapin counter.** Swapins spike during recovery
|
|
47
|
+
too. Thrash is pages going *out* while free memory shrinks.
|
|
48
|
+
|
|
49
|
+
Everything heavy goes through the governor:
|
|
50
|
+
|
|
51
|
+
```bash
|
|
52
|
+
bash .claude/scripts/gate-run.sh <label> -- <cmd>
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
A raw `vitest` bypasses it and `hook:load-guard` blocks it. macOS ships neither
|
|
56
|
+
`flock(1)` nor `timeout(1)` — `lib/govern.sh` rebuilds both out of `mkdir(2)`
|
|
57
|
+
atomicity and bash job control. That absence is the whole reason the wrapper
|
|
58
|
+
exists.
|
|
59
|
+
|
|
60
|
+
---
|
|
61
|
+
|
|
62
|
+
## 2 · Run a cycle
|
|
63
|
+
|
|
64
|
+
```bash
|
|
65
|
+
bash .claude/scripts/do-tier.sh # what tier is this REALLY? run it first
|
|
66
|
+
/do <client-or-feature> # the spine, tier-pruned
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
Run `do-tier.sh` against the real file list **before** writing a plan. It is the
|
|
70
|
+
repo's own sizer, and it will often tell you that a job you were about to give
|
|
71
|
+
nine cycles is a FIX. Believe it.
|
|
72
|
+
|
|
73
|
+
**Every branch lives in a worktree cut from `main`:**
|
|
74
|
+
|
|
75
|
+
```bash
|
|
76
|
+
bash .claude/scripts/do-auto.sh <slug> --setup-only
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
Never switch HEAD in the shared tree — `hook:branch-pin` blocks it, and
|
|
80
|
+
concurrent sessions would otherwise pull each other onto the wrong branch.
|
|
81
|
+
|
|
82
|
+
---
|
|
83
|
+
|
|
84
|
+
## 2b · The fleet — fan out, but only after you measure
|
|
85
|
+
|
|
86
|
+
**Explicit opt-in.** A fleet spawns many agents and costs real tokens. Never
|
|
87
|
+
infer it. Say `ultracode`, or ask for a fleet in your own words, or run
|
|
88
|
+
`/vespio fleet` — otherwise work solo.
|
|
89
|
+
|
|
90
|
+
### Measure first, or nine fleets agree on a wrong premise
|
|
91
|
+
|
|
92
|
+
Fleets given identical facts cannot drift. Fleets given only a task description
|
|
93
|
+
will. So build ONE measurement pack before you launch anything, and paste it
|
|
94
|
+
**verbatim** into every fleet prompt.
|
|
95
|
+
|
|
96
|
+
```bash
|
|
97
|
+
bash .claude/scripts/machine-check.sh # what the box can afford
|
|
98
|
+
bash .claude/scripts/do-tier.sh # what tier the work really is
|
|
99
|
+
node .claude/scripts/chrome.mjs <url> --text # what a page ACTUALLY renders
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
A pack is live probes, never file reads. **Declared is not wired is not
|
|
103
|
+
configured is not reachable is not working from where the code runs.** Every
|
|
104
|
+
launch-blocking finding worth having comes from a probe; none would have been
|
|
105
|
+
caught by reading source.
|
|
106
|
+
|
|
107
|
+
### The board
|
|
108
|
+
|
|
109
|
+
One fleet per client node, plus the shared surfaces. Each owns its own tree, so
|
|
110
|
+
they cannot collide on a write:
|
|
111
|
+
|
|
112
|
+
```
|
|
113
|
+
clients/alice clients/mover site/
|
|
114
|
+
clients/elitemoversca clients/moverchat ai/agents/
|
|
115
|
+
clients/family-rentals clients/movers-demo packages/
|
|
116
|
+
clients/maestromovers clients/servicio-express
|
|
117
|
+
clients/themoverlist clients/therooferlist
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
**Writers get a worktree; read-only and doc-only fleets do not need one.**
|
|
121
|
+
|
|
122
|
+
```bash
|
|
123
|
+
bash .claude/scripts/do-fleet.sh # rank + launch, memory-priced
|
|
124
|
+
bash .claude/scripts/do-auto.sh <slug> --setup-only # one worktree by hand
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
`do-fleet.sh` prices concurrency in **memory, not cores**, and names the binding
|
|
128
|
+
constraint on its ranking line. It only ever lowers the count.
|
|
129
|
+
|
|
130
|
+
### Claim before you forage
|
|
131
|
+
|
|
132
|
+
Two fleets picking the same job is the failure worktrees do **not** prevent —
|
|
133
|
+
worktrees stop write races, nothing stops duplicated *selection*. Read the
|
|
134
|
+
claims first. A claim is an evaporating lease, not a mutex: a dead worker's
|
|
135
|
+
claim expires, where a mutex would deadlock.
|
|
136
|
+
|
|
137
|
+
```
|
|
138
|
+
ant radio here
|
|
139
|
+
─── ───── ────
|
|
140
|
+
deposit ──────────▶ transmit ─────────▶ claim the region
|
|
141
|
+
read the trail ────▶ carrier sense ──────▶ read claims first
|
|
142
|
+
evaporate ─────────▶ timeout ─────────▶ the lease expires
|
|
143
|
+
alarm ──────────▶ jam ─────────▶ warn the path
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
**Exclusion for files and machine gates; stigmergy for task selection.** For
|
|
147
|
+
machine resources use `gate_lock` — `mkdir(2)` is atomic; a read-then-write is
|
|
148
|
+
not.
|
|
149
|
+
|
|
150
|
+
### Four prompt rules, each bought with a real mistake
|
|
151
|
+
|
|
152
|
+
- **Never spend a client's money to prove a point.** One audit billed real API
|
|
153
|
+
credit demonstrating a hole it had already proven from code. Once the door is
|
|
154
|
+
open, reason from source — and say in the prompt that you did.
|
|
155
|
+
- **Never simulate a run and report it as one.** Say so and STOP. A fabricated
|
|
156
|
+
run report poisons every decision downstream of it.
|
|
157
|
+
- **Give a legitimate "no change needed" exit**, or a fleet will punch a hole in
|
|
158
|
+
something that worked to make a page prettier.
|
|
159
|
+
- **Name the forbidden sentence.** Have each fleet quote verbatim the
|
|
160
|
+
client-facing sentences that would be FALSE, so nobody ships one by accident.
|
|
161
|
+
|
|
162
|
+
### Then join
|
|
163
|
+
|
|
164
|
+
**One fleet folds the others' findings back into a single doc.** Nine fleets
|
|
165
|
+
that never reconcile are nine opinions. Kill any fleet the moment its premise
|
|
166
|
+
dies — a fleet still building against a design you changed is worse than no
|
|
167
|
+
fleet.
|
|
168
|
+
|
|
169
|
+
---
|
|
170
|
+
|
|
171
|
+
## 3 · The law
|
|
172
|
+
|
|
173
|
+
1. **Probe before you read.** A file that exists is not a page that renders, and
|
|
174
|
+
a route that returns 200 is not a route that landed — a signed-out
|
|
175
|
+
`/u/<slug>/*` redirects to `/signin`, which renders 200 with no console
|
|
176
|
+
errors. A route counts as proven only if the run **ended** on the path you
|
|
177
|
+
asked for.
|
|
178
|
+
2. **Default REFUTED.** No quoted stopping line means not proven. Say "not
|
|
179
|
+
proven" rather than "probably fine".
|
|
180
|
+
3. **Two instances of one defect shape means fix the seam, never the sites.**
|
|
181
|
+
4. **Never simulate a run and report it as one.** If you cannot execute for real,
|
|
182
|
+
say so and stop.
|
|
183
|
+
5. **"No change needed" is a legitimate exit.** Say it rather than inventing work.
|
|
184
|
+
6. **Name the forbidden sentence.** For anything a client will read, quote
|
|
185
|
+
verbatim the sentences that would be false, so nobody ships one by accident.
|
|
186
|
+
|
|
187
|
+
---
|
|
188
|
+
|
|
189
|
+
## 4 · Where the harness comes from
|
|
190
|
+
|
|
191
|
+
`.claude/` in this repo is **generated output**, synced one-way from the `one-ie`
|
|
192
|
+
monorepo by `vespio-sync.sh` — which is classified `monorepo-only` and
|
|
193
|
+
deliberately does **not** ship here. So:
|
|
194
|
+
|
|
195
|
+
- **Never hand-edit `.claude/`.** The next sync overwrites it. If something is
|
|
196
|
+
wrong or missing, say so in `space:vespio`; it gets fixed upstream and
|
|
197
|
+
re-synced.
|
|
198
|
+
- **A manifest decides what ships**, not taste. Every upstream script is
|
|
199
|
+
classified `portable`, `needs-env`, or `monorepo-only`, and an *unclassified*
|
|
200
|
+
script does not ship — silence is not a licence.
|
|
201
|
+
- **What is deliberately absent:** the five-service deploy pipeline, the `text/`
|
|
202
|
+
promise layer, and the `schema/`-dependent skills (`typedb`, `sdk`, `mcp`,
|
|
203
|
+
`cli`, `puck`, `promise-*`). None of them have a tree to assert against here.
|
|
204
|
+
Their absence is a decision, not a gap.
|
|
205
|
+
|
|
206
|
+
---
|
|
207
|
+
|
|
208
|
+
## 5 · Talk to the other side
|
|
209
|
+
|
|
210
|
+
```bash
|
|
211
|
+
.claude/scripts/cc-connect.sh listen # once per session
|
|
212
|
+
/chat # read
|
|
213
|
+
/chat "message" # send
|
|
214
|
+
```
|
|
215
|
+
|
|
216
|
+
Inbox on the web: **one.ie/u/vespio/in**
|
|
217
|
+
|
|
218
|
+
---
|
|
219
|
+
|
|
220
|
+
## Don't
|
|
221
|
+
|
|
222
|
+
- Don't hand-edit `.claude/` — it is generated. Change it upstream.
|
|
223
|
+
- Don't run a raw `vitest`. Use `gate-run.sh`, or the governor cannot see you.
|
|
224
|
+
- Don't blanket-stage. Concurrent sessions mean a neighbour's uncommitted work
|
|
225
|
+
gets swept into your commit. Stage by explicit path, always.
|
|
226
|
+
- Don't switch HEAD in the shared tree. Branch work goes in a worktree.
|
|
227
|
+
- Don't plan in days or weeks. Tasks, then waves, then cycles.
|
package/hooks/hooks.json
CHANGED
|
@@ -37,6 +37,27 @@
|
|
|
37
37
|
"command": "bash \"$CLAUDE_PLUGIN_ROOT/hooks/scripts/git-add-guard.sh\"",
|
|
38
38
|
"timeout": 5000,
|
|
39
39
|
"blocking": true
|
|
40
|
+
},
|
|
41
|
+
{
|
|
42
|
+
"id": "hook:branch-pin",
|
|
43
|
+
"type": "command",
|
|
44
|
+
"command": "bash \"$CLAUDE_PLUGIN_ROOT/hooks/scripts/branch-pin.sh\"",
|
|
45
|
+
"timeout": 5000,
|
|
46
|
+
"blocking": true
|
|
47
|
+
},
|
|
48
|
+
{
|
|
49
|
+
"id": "hook:load-guard",
|
|
50
|
+
"type": "command",
|
|
51
|
+
"command": "bash \"$CLAUDE_PLUGIN_ROOT/hooks/scripts/load-guard.sh\"",
|
|
52
|
+
"timeout": 5000,
|
|
53
|
+
"blocking": true
|
|
54
|
+
},
|
|
55
|
+
{
|
|
56
|
+
"id": "hook:governor-escape",
|
|
57
|
+
"type": "command",
|
|
58
|
+
"command": "bash \"$CLAUDE_PLUGIN_ROOT/hooks/scripts/governor-escape.sh\"",
|
|
59
|
+
"timeout": 5000,
|
|
60
|
+
"blocking": true
|
|
40
61
|
}
|
|
41
62
|
]
|
|
42
63
|
},
|
|
@@ -55,42 +76,17 @@
|
|
|
55
76
|
{
|
|
56
77
|
"matcher": "Edit|Write|MultiEdit",
|
|
57
78
|
"hooks": [
|
|
58
|
-
{
|
|
59
|
-
"id": "hook:gate-guard",
|
|
60
|
-
"type": "command",
|
|
61
|
-
"command": "bash \"$CLAUDE_PLUGIN_ROOT/hooks/scripts/gate-guard.sh\"",
|
|
62
|
-
"timeout": 5000,
|
|
63
|
-
"blocking": true
|
|
64
|
-
},
|
|
65
79
|
{
|
|
66
80
|
"id": "hook:config-protect",
|
|
67
81
|
"type": "command",
|
|
68
82
|
"command": "bash \"$CLAUDE_PLUGIN_ROOT/hooks/scripts/config-protect.sh\"",
|
|
69
83
|
"timeout": 5000,
|
|
70
84
|
"blocking": true
|
|
71
|
-
},
|
|
72
|
-
{
|
|
73
|
-
"id": "hook:compact-hint",
|
|
74
|
-
"type": "command",
|
|
75
|
-
"command": "bash \"$CLAUDE_PLUGIN_ROOT/hooks/scripts/compact-hint.sh\"",
|
|
76
|
-
"timeout": 3000,
|
|
77
|
-
"blocking": false
|
|
78
85
|
}
|
|
79
86
|
]
|
|
80
87
|
}
|
|
81
88
|
],
|
|
82
89
|
"PostToolUse": [
|
|
83
|
-
{
|
|
84
|
-
"matcher": "Read",
|
|
85
|
-
"hooks": [
|
|
86
|
-
{
|
|
87
|
-
"id": "hook:read-tracker",
|
|
88
|
-
"type": "command",
|
|
89
|
-
"command": "bash \"$CLAUDE_PLUGIN_ROOT/hooks/scripts/read-tracker.sh\"",
|
|
90
|
-
"timeout": 3000
|
|
91
|
-
}
|
|
92
|
-
]
|
|
93
|
-
},
|
|
94
90
|
{
|
|
95
91
|
"matcher": "Write|Edit",
|
|
96
92
|
"hooks": [
|
|
@@ -99,24 +95,6 @@
|
|
|
99
95
|
"type": "command",
|
|
100
96
|
"command": "bash \"$CLAUDE_PLUGIN_ROOT/hooks/scripts/post-edit-check.sh\"",
|
|
101
97
|
"timeout": 15000
|
|
102
|
-
},
|
|
103
|
-
{
|
|
104
|
-
"id": "hook:priority-todo",
|
|
105
|
-
"type": "command",
|
|
106
|
-
"command": "bash \"$CLAUDE_PLUGIN_ROOT/hooks/scripts/sync-priority-todo.sh\"",
|
|
107
|
-
"timeout": 10000,
|
|
108
|
-
"blocking": false
|
|
109
|
-
}
|
|
110
|
-
]
|
|
111
|
-
},
|
|
112
|
-
{
|
|
113
|
-
"matcher": "Write|Edit|MultiEdit",
|
|
114
|
-
"hooks": [
|
|
115
|
-
{
|
|
116
|
-
"id": "hook:sync-todo-docs",
|
|
117
|
-
"type": "command",
|
|
118
|
-
"command": "bash \"$CLAUDE_PLUGIN_ROOT/hooks/scripts/sync-todo-docs.sh\"",
|
|
119
|
-
"timeout": 5000
|
|
120
98
|
}
|
|
121
99
|
]
|
|
122
100
|
},
|
|
@@ -155,17 +133,6 @@
|
|
|
155
133
|
"blocking": true
|
|
156
134
|
}
|
|
157
135
|
]
|
|
158
|
-
},
|
|
159
|
-
{
|
|
160
|
-
"matcher": "*",
|
|
161
|
-
"hooks": [
|
|
162
|
-
{
|
|
163
|
-
"id": "hook:tool-signal",
|
|
164
|
-
"type": "command",
|
|
165
|
-
"command": "bash \"$CLAUDE_PLUGIN_ROOT/hooks/scripts/tool-signal.sh\"",
|
|
166
|
-
"timeout": 3000
|
|
167
|
-
}
|
|
168
|
-
]
|
|
169
136
|
}
|
|
170
137
|
],
|
|
171
138
|
"TaskCompleted": [
|
|
@@ -187,18 +154,11 @@
|
|
|
187
154
|
"matcher": "*",
|
|
188
155
|
"hooks": [
|
|
189
156
|
{
|
|
190
|
-
"id": "hook:
|
|
191
|
-
"type": "command",
|
|
192
|
-
"command": "bash \"$CLAUDE_PLUGIN_ROOT/hooks/scripts/session-end-verify.sh\"",
|
|
193
|
-
"timeout": 30000,
|
|
194
|
-
"blocking": false
|
|
195
|
-
},
|
|
196
|
-
{
|
|
197
|
-
"id": "hook:stop-reflect",
|
|
157
|
+
"id": "hook:auto-continue",
|
|
198
158
|
"type": "command",
|
|
199
|
-
"command": "bash \"$CLAUDE_PLUGIN_ROOT/hooks/scripts/
|
|
200
|
-
"timeout":
|
|
201
|
-
"blocking":
|
|
159
|
+
"command": "bash \"$CLAUDE_PLUGIN_ROOT/hooks/scripts/auto-continue.sh\"",
|
|
160
|
+
"timeout": 5000,
|
|
161
|
+
"blocking": true
|
|
202
162
|
},
|
|
203
163
|
{
|
|
204
164
|
"id": "hook:staff-cleanup",
|
|
@@ -206,13 +166,6 @@
|
|
|
206
166
|
"command": "bun \"$CLAUDE_PLUGIN_ROOT/hooks/scripts/cleanup.ts\"",
|
|
207
167
|
"timeout": 3000,
|
|
208
168
|
"blocking": false
|
|
209
|
-
},
|
|
210
|
-
{
|
|
211
|
-
"id": "hook:priority-todo-stop",
|
|
212
|
-
"type": "command",
|
|
213
|
-
"command": "bash \"$CLAUDE_PLUGIN_ROOT/hooks/scripts/sync-priority-todo.sh\"",
|
|
214
|
-
"timeout": 10000,
|
|
215
|
-
"blocking": false
|
|
216
169
|
}
|
|
217
170
|
]
|
|
218
171
|
}
|
|
@@ -227,13 +180,6 @@
|
|
|
227
180
|
"command": "bash \"$CLAUDE_PLUGIN_ROOT/hooks/scripts/session-start.sh\"",
|
|
228
181
|
"timeout": 5000,
|
|
229
182
|
"blocking": false
|
|
230
|
-
},
|
|
231
|
-
{
|
|
232
|
-
"id": "hook:priority-todo-start",
|
|
233
|
-
"type": "command",
|
|
234
|
-
"command": "bash \"$CLAUDE_PLUGIN_ROOT/hooks/scripts/sync-priority-todo.sh\"",
|
|
235
|
-
"timeout": 10000,
|
|
236
|
-
"blocking": false
|
|
237
183
|
}
|
|
238
184
|
]
|
|
239
185
|
}
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# governor-escape-match.sh — ONE definition of "this command escapes the governor".
|
|
3
|
+
#
|
|
4
|
+
# Sourced by BOTH .claude/hooks/governor-escape.sh (the enforcement) and
|
|
5
|
+
# .claude/scripts/governor-escape-check.sh (the proof). load-guard.sh and
|
|
6
|
+
# load-guard-check.sh keep two copies of their regex; that is a drift bug
|
|
7
|
+
# waiting to happen and this file exists so this guard never has one.
|
|
8
|
+
#
|
|
9
|
+
# SCOPE — deliberately the four ESCAPE HATCHES, not every heavy command.
|
|
10
|
+
#
|
|
11
|
+
# 1. `bun run verify:raw` web/package.json — the ungoverned verify
|
|
12
|
+
# 2. `bun run test:raw` web/package.json — a bare `vitest run`
|
|
13
|
+
# 3. a directly-typed `vitest` / `npx vitest` / `bunx vitest`
|
|
14
|
+
# 4. `GOVERN_DISABLE=1` or `CI=1` in front of a gate
|
|
15
|
+
# (gate-run.sh:26 execs straight through on either)
|
|
16
|
+
#
|
|
17
|
+
# A bare `tsc --noEmit` or `astro check` is NOT here on purpose. Those are
|
|
18
|
+
# ordinary heavy commands with legitimate uses; hook:load-guard already denies
|
|
19
|
+
# them once the box is saturated. Denying them unconditionally would be the
|
|
20
|
+
# false positive that gets this hook switched off, which is worse than not
|
|
21
|
+
# having it. Do not "fix" that.
|
|
22
|
+
#
|
|
23
|
+
# Contract:
|
|
24
|
+
# gov_escape_kind "<command string>"
|
|
25
|
+
# prints env|raw|vitest and returns 0 -> this command escapes the governor
|
|
26
|
+
# prints nothing and returns 1 -> it does not
|
|
27
|
+
|
|
28
|
+
# Command POSITION: start of a line, or just after a shell operator, allowing a
|
|
29
|
+
# run of leading VAR=value assignments. Anchoring here is what stops the guard
|
|
30
|
+
# firing on a command that merely NAMES an escape -- a `git commit -m` whose
|
|
31
|
+
# message quotes it, a `grep` looking for it, a `sed` reading package.json.
|
|
32
|
+
GOV_POS='(^|[;&|(]|&&|\|\|)[[:space:]]*'
|
|
33
|
+
GOV_ENV='([A-Za-z_][A-Za-z0-9_]*=[^[:space:]]*[[:space:]]+)*'
|
|
34
|
+
|
|
35
|
+
# 4. an env bypass sitting at command position...
|
|
36
|
+
GOV_RE_ENVPOS="${GOV_POS}${GOV_ENV}(GOVERN_DISABLE|CI)="
|
|
37
|
+
# ...in front of something that is actually a gate. Both halves must hold, so
|
|
38
|
+
# `GOVERN_DISABLE=1 ls` and `CI=1 bun run build` are left alone.
|
|
39
|
+
GOV_RE_GATETOKEN='(vitest|gate-run\.sh|tsc[[:space:]]+--noEmit|astro[[:space:]]+check|playwright[[:space:]]+test|(bun|npm|pnpm|yarn)[[:space:]]+run[[:space:]]+(verify|test|typecheck|check))'
|
|
40
|
+
|
|
41
|
+
# 1+2. any `:raw` package script -- their entire purpose is bypassing the cap.
|
|
42
|
+
GOV_RE_RAW="${GOV_POS}${GOV_ENV}(bun|npm|pnpm|yarn)[[:space:]]+run[[:space:]]+[A-Za-z0-9:_.-]*:raw([[:space:]]|\$)"
|
|
43
|
+
|
|
44
|
+
# 3. vitest invoked directly, however it is reached.
|
|
45
|
+
GOV_RE_VITEST="${GOV_POS}${GOV_ENV}((bunx|npx|pnpm[[:space:]]+dlx|bun[[:space:]]+x|yarn[[:space:]]+dlx)[[:space:]]+)?([A-Za-z0-9_./-]*/)?vitest([[:space:]]|\$)"
|
|
46
|
+
|
|
47
|
+
# A heredoc BODY is data, not commands, and `grep -E '^...'` anchors per LINE --
|
|
48
|
+
# so `cat > f <<'EOF'` whose body has a line starting with an escape would match
|
|
49
|
+
# on `^`. Writing a doc or a script that quotes an escape is exactly the innocent
|
|
50
|
+
# act this guard must not refuse. Drop heredoc bodies before matching.
|
|
51
|
+
_gov_strip_heredocs() {
|
|
52
|
+
awk '
|
|
53
|
+
term != "" { if ($0 == term) term = ""; next }
|
|
54
|
+
{
|
|
55
|
+
if (match($0, /<<-?[[:space:]]*("[^"]+"|\047[^\047]+\047|[A-Za-z_][A-Za-z0-9_]*)/)) {
|
|
56
|
+
t = substr($0, RSTART, RLENGTH)
|
|
57
|
+
sub(/^<<-?[[:space:]]*/, "", t)
|
|
58
|
+
gsub(/["\047]/, "", t)
|
|
59
|
+
term = t
|
|
60
|
+
}
|
|
61
|
+
print
|
|
62
|
+
}
|
|
63
|
+
'
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
gov_escape_kind() {
|
|
67
|
+
local cmd
|
|
68
|
+
cmd="$(printf '%s' "${1:-}" | _gov_strip_heredocs)"
|
|
69
|
+
[ -n "$cmd" ] || return 1
|
|
70
|
+
|
|
71
|
+
# ORDER MATTERS. The env bypass is checked FIRST, because
|
|
72
|
+
# `GOVERN_DISABLE=1 bash gate-run.sh verify -- …` turns the governor itself
|
|
73
|
+
# into a plain exec -- it is an escape even though it names gate-run.sh.
|
|
74
|
+
if printf '%s' "$cmd" | grep -qE "$GOV_RE_ENVPOS" \
|
|
75
|
+
&& printf '%s' "$cmd" | grep -qE "$GOV_RE_GATETOKEN"; then
|
|
76
|
+
printf 'env'; return 0
|
|
77
|
+
fi
|
|
78
|
+
|
|
79
|
+
# Governed -- gate-run.sh takes the slot, bounds the wall clock and reaps the
|
|
80
|
+
# process group, so whatever it wraps is not an escape.
|
|
81
|
+
# Known limit: this is a whole-command carve-out (the same one load-guard.sh:39
|
|
82
|
+
# makes), so `vitest run x && bash gate-run.sh …` reads as governed.
|
|
83
|
+
printf '%s' "$cmd" | grep -q 'gate-run\.sh' && return 1
|
|
84
|
+
|
|
85
|
+
printf '%s' "$cmd" | grep -qE "$GOV_RE_RAW" && { printf 'raw'; return 0; }
|
|
86
|
+
printf '%s' "$cmd" | grep -qE "$GOV_RE_VITEST" && { printf 'vitest'; return 0; }
|
|
87
|
+
return 1
|
|
88
|
+
}
|
package/hooks/lib/hook.sh
CHANGED
|
@@ -7,14 +7,13 @@
|
|
|
7
7
|
|
|
8
8
|
# ── Runtime toggles ──────────────────────────────────────────────────────────
|
|
9
9
|
#
|
|
10
|
-
# ECC_DISABLED_HOOKS=hook:
|
|
10
|
+
# ECC_DISABLED_HOOKS=hook:git-add-guard,hook:post-edit
|
|
11
11
|
# Comma-separated hook IDs to skip. Useful in CI or setup scripts.
|
|
12
12
|
#
|
|
13
13
|
# ECC_HOOK_PROFILE=minimal|standard (default: standard)
|
|
14
|
-
# minimal — skips
|
|
14
|
+
# minimal — skips the post-edit lint
|
|
15
15
|
# standard — all hooks active
|
|
16
|
-
|
|
17
|
-
# Per-hook disable: ECC_GATEGUARD=off (alias for hook:gate-guard)
|
|
16
|
+
|
|
18
17
|
|
|
19
18
|
is_hook_disabled() {
|
|
20
19
|
local id="$1"
|
|
@@ -35,19 +34,11 @@ is_hook_disabled() {
|
|
|
35
34
|
case "$profile" in
|
|
36
35
|
minimal)
|
|
37
36
|
case "$id" in
|
|
38
|
-
hook:
|
|
37
|
+
hook:post-edit) return 0 ;;
|
|
39
38
|
esac
|
|
40
39
|
;;
|
|
41
40
|
esac
|
|
42
41
|
|
|
43
|
-
# Per-hook env aliases
|
|
44
|
-
case "$id" in
|
|
45
|
-
hook:gate-guard)
|
|
46
|
-
local v="${ECC_GATEGUARD:-}"
|
|
47
|
-
[[ "$v" =~ ^(0|off|false|disabled|disable)$ ]] && return 0
|
|
48
|
-
;;
|
|
49
|
-
esac
|
|
50
|
-
|
|
51
42
|
return 1 # not disabled — run
|
|
52
43
|
}
|
|
53
44
|
|
package/hooks/lib/signal.sh
CHANGED
|
@@ -15,7 +15,14 @@
|
|
|
15
15
|
# Contract: one.ie/web/src/lib/resolvers/subscriptions.ts (world:announce · subscriptions:register)
|
|
16
16
|
# Point ONE_API_URL at https://one.ie to broadcast into the live world instead of local dev.
|
|
17
17
|
|
|
18
|
-
|
|
18
|
+
# The world is https://one.ie — the same door the factory executor and
|
|
19
|
+
# do-signal.sh post to. Until 2026-09-05 this defaulted to localhost:4321, so
|
|
20
|
+
# every session:start / session:intent signal landed in the operator's local
|
|
21
|
+
# dev D1 (matched 0) or nowhere when no dev server was up. ONE_API_URL still
|
|
22
|
+
# overrides for local work. Measured the same day: the prod door answers in
|
|
23
|
+
# 1.3-2.0s (D1 in APAC, TypeDB in Virginia — text/factory-do.md § GATES ›
|
|
24
|
+
# Signals), so the cap below is 8s, not the 2s that dropped every post.
|
|
25
|
+
_one_world_url() { printf '%s' "${ONE_API_URL:-https://one.ie}/api/ask/world:announce"; }
|
|
19
26
|
|
|
20
27
|
# Where the service credential lives — hooks don't reliably inherit a login shell's
|
|
21
28
|
# exports, so read straight out of the web env file (same pattern do-signal.sh
|
|
@@ -90,7 +97,7 @@ emit_world() {
|
|
|
90
97
|
hdr+=(--config "$authcfg")
|
|
91
98
|
fi
|
|
92
99
|
|
|
93
|
-
( curl -sS -o /dev/null --max-time
|
|
100
|
+
( curl -sS -o /dev/null --max-time "${ONE_WORLD_TIMEOUT:-8}" -X POST "$(_one_world_url)" \
|
|
94
101
|
"${hdr[@]}" -d "$payload" >/dev/null 2>&1
|
|
95
102
|
[ -n "$authcfg" ] && rm -f "$authcfg" ) &
|
|
96
103
|
return 0
|
|
@@ -22,6 +22,12 @@ source "$CLAUDE_PROJECT_DIR/.claude/hooks/lib/hook.sh"
|
|
|
22
22
|
is_hook_disabled "hook:branch-pin" && exit 0
|
|
23
23
|
|
|
24
24
|
PAYLOAD="${1:-}"
|
|
25
|
+
# Claude Code delivers the hook payload on STDIN; argv stays first so any
|
|
26
|
+
# caller that passes it positionally still works. Bounded read: a bare $(cat)
|
|
27
|
+
# would hang forever on a tty or an idle pipe, freezing every Bash call.
|
|
28
|
+
if [[ -z "$PAYLOAD" && ! -t 0 ]]; then
|
|
29
|
+
IFS= read -r -d '' -t 2 PAYLOAD <&0 || true
|
|
30
|
+
fi
|
|
25
31
|
[[ -z "$PAYLOAD" ]] && exit 0
|
|
26
32
|
|
|
27
33
|
TOOL=$(printf '%s' "$PAYLOAD" | jq -r '.tool_name // empty' 2>/dev/null)
|
|
@@ -15,6 +15,12 @@ source "$CLAUDE_PROJECT_DIR/.claude/hooks/lib/hook.sh"
|
|
|
15
15
|
is_hook_disabled "hook:config-protect" && exit 0
|
|
16
16
|
|
|
17
17
|
PAYLOAD="${1:-}"
|
|
18
|
+
# Claude Code delivers the hook payload on STDIN; argv stays first so any
|
|
19
|
+
# caller that passes it positionally still works. Bounded read: a bare $(cat)
|
|
20
|
+
# would hang forever on a tty or an idle pipe, freezing every Bash call.
|
|
21
|
+
if [[ -z "$PAYLOAD" && ! -t 0 ]]; then
|
|
22
|
+
IFS= read -r -d '' -t 2 PAYLOAD <&0 || true
|
|
23
|
+
fi
|
|
18
24
|
[[ -z "$PAYLOAD" ]] && exit 0
|
|
19
25
|
|
|
20
26
|
TOOL=$(printf '%s' "$PAYLOAD" | jq -r '.tool_name // empty' 2>/dev/null)
|