@oneie/claude 0.8.0 → 0.10.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/.claude-plugin/plugin.json +1 -1
- package/agents/abm-strategist.md +67 -1
- package/agents/ads-meta.md +67 -1
- package/agents/analyst.md +67 -1
- package/agents/animator.md +108 -0
- package/agents/architect.md +269 -20
- package/agents/brand-guardian.md +67 -1
- package/agents/brand-strategist.md +67 -1
- package/agents/campaign-content.md +67 -1
- package/agents/campaign-email.md +67 -1
- package/agents/campaign-sms.md +67 -1
- package/agents/campaign-social.md +67 -1
- package/agents/cco.md +83 -2
- package/agents/ceo.md +108 -11
- package/agents/chairman.md +197 -0
- package/agents/cmo.md +82 -2
- package/agents/community-greeter.md +67 -1
- package/agents/community-moderator.md +67 -1
- package/agents/compliance.md +67 -1
- package/agents/copywriter.md +67 -1
- package/agents/creative-strategist.md +67 -1
- package/agents/cro.md +81 -1
- package/agents/cto.md +266 -28
- package/agents/customer-interviewer.md +67 -1
- package/agents/customer-researcher.md +67 -1
- package/agents/customer-success-manager.md +67 -1
- package/agents/customer-trainer.md +67 -1
- package/agents/cxo.md +82 -1
- package/agents/demand-creator.md +67 -1
- package/agents/demo-mover.md +67 -1
- package/agents/demo-specialist.md +67 -1
- package/agents/demo-thai-family-law.md +67 -1
- package/agents/designer.md +67 -1
- package/agents/discovery-caller.md +67 -1
- package/agents/doctor.md +269 -0
- package/agents/educate-coach.md +67 -1
- package/agents/elevate-tutor.md +67 -1
- package/agents/email-lifecycle-marketer.md +67 -1
- package/agents/engage-specialist.md +67 -1
- package/agents/events-coordinator.md +67 -1
- package/agents/foundation-builder.md +67 -1
- package/agents/funnel-architect.md +67 -1
- package/agents/gift-creator.md +67 -1
- package/agents/google-ads.md +67 -1
- package/agents/guide.md +67 -1
- package/agents/helpdesk-dispatcher.md +67 -1
- package/agents/hook-specialist.md +67 -1
- package/agents/identify-optimizer.md +67 -1
- package/agents/implementer.md +313 -45
- package/agents/incident-commander.md +67 -1
- package/agents/insights-lead.md +87 -1
- package/agents/journey-runner.md +67 -1
- package/agents/linkedin-ads.md +67 -1
- package/agents/live-sales-chat.md +67 -1
- package/agents/market-researcher.md +67 -1
- package/agents/media-buyer.md +67 -1
- package/agents/memory-keeper.md +195 -0
- package/agents/movers-customer-researcher.md +67 -1
- package/agents/movers-foundation-builder.md +67 -1
- package/agents/movers-market-researcher.md +67 -1
- package/agents/movers-pricing-strategist.md +67 -1
- package/agents/nurture-architect.md +67 -1
- package/agents/offer-architect.md +67 -1
- package/agents/onboarder.md +67 -1
- package/agents/onboarding-specialist.md +67 -1
- package/agents/operations-dashboard.md +87 -1
- package/agents/perf-engineer.md +333 -37
- package/agents/playbook-writer.md +67 -1
- package/agents/plg-strategist.md +67 -1
- package/agents/positioning-architect.md +67 -1
- package/agents/press-officer.md +67 -1
- package/agents/pricing-strategist.md +67 -1
- package/agents/privacy-officer.md +67 -1
- package/agents/referral-manager.md +67 -1
- package/agents/refine-analyst.md +67 -1
- package/agents/release-manager.md +446 -39
- package/agents/renewals-upsell-rep.md +67 -1
- package/agents/review-engineer.md +319 -45
- package/agents/rewards-steward.md +67 -1
- package/agents/sales-call-coach.md +67 -1
- package/agents/sales-closer.md +67 -1
- package/agents/security-auditor.md +343 -48
- package/agents/sell-closer.md +67 -1
- package/agents/share-amplifier.md +67 -1
- package/agents/social-media-manager.md +67 -1
- package/agents/storyteller.md +301 -0
- package/agents/strategist.md +67 -1
- package/agents/strategy-aligner.md +67 -1
- package/agents/support-agent.md +67 -1
- package/agents/tagger.md +327 -0
- package/agents/tech-writer.md +195 -22
- package/agents/test-engineer.md +398 -29
- package/agents/tiktok-ads.md +67 -1
- package/agents/tracking-engineer.md +67 -1
- package/agents/trailkeeper.md +181 -0
- package/agents/upsell-strategist.md +67 -1
- package/agents/voice.md +67 -1
- package/agents/w1-recon.md +1 -1
- package/agents/w2-decide.md +1 -1
- package/agents/w3-edit.md +8 -2
- package/agents/w4-verify.md +13 -0
- package/agents/workflow-optimiser.md +81 -1
- package/commands/close.md +916 -160
- package/commands/deploy.md +102 -724
- package/commands/do.md +58 -2
- package/commands/sweep.md +159 -0
- package/commands/tasks.md +222 -0
- package/hooks/scripts/dev-only.sh +135 -0
- package/hooks/scripts/git-add-guard.sh +37 -2
- package/hooks/scripts/session-start.sh +32 -4
- package/package.json +1 -1
- package/rules/scripts.md +85 -0
- package/scripts/CLAUDE.md +315 -0
- package/scripts/ad-copy-lint.sh +656 -0
- package/scripts/agent-actor-parity.sh +129 -0
- package/scripts/blocks-manifest-cached.sh +100 -0
- package/scripts/chat-context-check.sh +89 -0
- package/scripts/chrome.mjs +18 -0
- package/scripts/close-metrics.sh +587 -0
- package/scripts/close-owner.sh +326 -0
- package/scripts/db-sync-lock-check.sh +116 -0
- package/scripts/deploy-emit.sh +311 -0
- package/scripts/deploy-gate-check.sh +155 -0
- package/scripts/deploy-ready.sh +78 -0
- package/scripts/deploy-record.sh +605 -0
- package/scripts/deploy-schema-check.sh +58 -0
- package/scripts/deploy.sh +393 -243
- package/scripts/do-auto.sh +127 -26
- package/scripts/do-board.sh +429 -0
- package/scripts/do-close.sh +1184 -0
- package/scripts/do-consumer-sweep.sh +18 -1
- package/scripts/do-decide.sh +476 -0
- package/scripts/do-fleet.sh +8 -2
- package/scripts/do-plan-json.mjs +110 -12
- package/scripts/do-prove-selftest.sh +108 -0
- package/scripts/do-prove.sh +86 -10
- package/scripts/do-rank.py +200 -3
- package/scripts/do-reconcile.sh +73 -12
- package/scripts/do-signal.sh +101 -23
- package/scripts/do-smoke.sh +18 -1
- package/scripts/do-w4-gates.sh +11 -1
- package/scripts/do-world-check.sh +153 -0
- package/scripts/download-stats.sh +172 -0
- package/scripts/factory-brief-check.sh +330 -0
- package/scripts/factory-check.sh +18 -1
- 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 +71 -0
- package/scripts/factory-review-check.mjs +61 -0
- package/scripts/factory-tasks-check.sh +18 -1
- package/scripts/fixtures/factory-brief-real.md +44 -0
- package/scripts/flywheel-outcome.sh +63 -0
- package/scripts/gate-reaper-check.sh +98 -0
- package/scripts/gate-reaper.sh +9 -0
- package/scripts/gate-watchdog.sh +619 -0
- package/scripts/gc-content-check.sh +142 -0
- package/scripts/gh-traffic-capture.sh +153 -0
- package/scripts/govern-order-check.sh +202 -0
- package/scripts/governor-doors-check.sh +86 -5
- package/scripts/health.sh +448 -0
- package/scripts/id-inventory.mjs +418 -0
- package/scripts/incident.sh +212 -0
- package/scripts/land.sh +755 -45
- package/scripts/lib/gc-finished.sh +77 -0
- package/scripts/livekit-ratchet.sh +18 -1
- package/scripts/machine-check.sh +1 -1
- package/scripts/memory-index-budget.sh +79 -0
- package/scripts/npm-downloads.sh +109 -0
- package/scripts/one-agents.mjs +204 -8
- package/scripts/one-resume.sh +31 -3
- package/scripts/pr-body.sh +335 -0
- package/scripts/preview-fd-check.sh +289 -0
- package/scripts/redirect-lint.sh +169 -0
- package/scripts/release.sh +40 -6
- package/scripts/resume-lost-sessions.sh +68 -0
- package/scripts/shoot-pages.mjs +140 -0
- package/scripts/signal-meta-backfill.ts +451 -0
- package/scripts/signal-watch.sh +63 -6
- package/scripts/speed-cache-check.sh +12 -2
- package/scripts/sweep.sh +426 -0
- package/scripts/task-titles-dump.ts +101 -0
- package/scripts/test-cached.sh +47 -10
- package/scripts/test-lanes.sh +14 -0
- package/scripts/thread-name-backfill.ts +215 -0
- package/scripts/triage-shape-check.sh +149 -0
- package/scripts/tsc-cached.sh +155 -8
- package/scripts/typedb-flake-check.sh +3 -1
- package/scripts/urls-lint.sh +8 -0
- package/scripts/verify-board-doors.sh +80 -0
- package/scripts/verify-fast.sh +159 -6
- package/scripts/worktree-up.sh +21 -3
- package/skills/astro/SKILL.md +9 -3
- package/skills/astro/optimize-performance.md +3 -2
- package/skills/cloudflare/SKILL.md +3 -2
- package/skills/cloudflare-security-audit/AI-AND-LLM.md +83 -0
- package/skills/cloudflare-security-audit/ATTACK-CLASSES.md +130 -0
- package/skills/cloudflare-security-audit/CLIENT-SIDE.md +83 -0
- package/skills/cloudflare-security-audit/CLOUD-AND-DEPLOYMENT.md +86 -0
- package/skills/cloudflare-security-audit/DATA-ISOLATION-AND-LIFECYCLE.md +84 -0
- package/skills/cloudflare-security-audit/DESKTOP-MOBILE-AND-LOCAL-IPC.md +89 -0
- package/skills/cloudflare-security-audit/HUNTING.md +251 -0
- package/skills/cloudflare-security-audit/LICENSE +21 -0
- package/skills/cloudflare-security-audit/MEMORY-SAFETY-AND-BINARY.md +101 -0
- package/skills/cloudflare-security-audit/PROTOCOLS-RPC-AND-MESSAGING.md +81 -0
- package/skills/cloudflare-security-audit/PROVENANCE.md +78 -0
- package/skills/cloudflare-security-audit/RECONNAISSANCE.md +156 -0
- package/skills/cloudflare-security-audit/RESOURCE-EXHAUSTION-AND-AVAILABILITY.md +78 -0
- package/skills/cloudflare-security-audit/SKILL.md +192 -0
- package/skills/cloudflare-security-audit/SUPPLY-CHAIN-AND-RELEASE.md +73 -0
- package/skills/cloudflare-security-audit/VALIDATION-AND-REPORTING.md +186 -0
- package/skills/cloudflare-security-audit/WEB-PROTOCOL-AND-AUTH.md +105 -0
- package/skills/cloudflare-security-audit/report-schema.json +461 -0
- package/skills/cloudflare-security-audit/validate-coverage-ledger.cjs +872 -0
- package/skills/cloudflare-security-audit/validate-coverage-ledger.test.cjs +740 -0
- package/skills/cloudflare-security-audit/validate-findings.cjs +773 -0
- package/skills/cloudflare-security-audit/validate-findings.test.cjs +652 -0
- package/skills/deploy/REFERENCE.md +713 -0
- package/skills/deploy/SKILL.md +140 -0
- package/skills/fleet-audit/SKILL.md +58 -0
- package/skills/meeting/SKILL.md +220 -0
- package/skills/planning/SKILL.md +256 -0
- package/skills/shadcn/SKILL.md +1 -1
- package/skills/typedb/SKILL.md +7 -0
- package/skills/voice/SKILL.md +94 -6
- package/skills/voice/corpus-check.sh +87 -0
- package/templates/template-agent.md +7 -1
- package/templates/template-feature.md +9 -0
- package/templates/template-todo.md +29 -0
|
@@ -9,6 +9,23 @@
|
|
|
9
9
|
# default: prints one command per matched rule (no execution)
|
|
10
10
|
# --exec: also runs each printed command; any non-zero exit fails the sweep
|
|
11
11
|
set -euo pipefail
|
|
12
|
+
|
|
13
|
+
# _GATE — route a heavy compute through the machine governor. A gate_lock only
|
|
14
|
+
# dedupes IDENTICAL work; a SLOT is what bounds N worktrees each running one of
|
|
15
|
+
# these at once (measured 2026-09-07: three concurrent 2.5GB typecheckers, every
|
|
16
|
+
# lock uncontended, load 171). Empty when already inside a gate, so a nested call
|
|
17
|
+
# inherits the outer slot rather than taking a second one.
|
|
18
|
+
#
|
|
19
|
+
# Resolves gate-run.sh from its OWN directory, deliberately: an earlier version
|
|
20
|
+
# keyed off $ROOT and got inserted above the line that sets it, so _GATE was
|
|
21
|
+
# silently empty and every call ran ungoverned -- a fail-OPEN, which is the exact
|
|
22
|
+
# defect this preamble exists to close.
|
|
23
|
+
_GATE=()
|
|
24
|
+
if [ "${GOVERN_IN_GATE:-0}" != "1" ]; then
|
|
25
|
+
_GR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)/gate-run.sh"
|
|
26
|
+
[ -f "$_GR" ] && _GATE=( bash "$_GR" "compute:$(basename "${BASH_SOURCE[0]}")" -- )
|
|
27
|
+
fi
|
|
28
|
+
|
|
12
29
|
cd "$(dirname "${BASH_SOURCE[0]}")/../.." || exit 2
|
|
13
30
|
|
|
14
31
|
EXEC=false
|
|
@@ -63,7 +80,7 @@ for f in "${FILES[@]}"; do
|
|
|
63
80
|
[ -z "$cmd" ] && continue
|
|
64
81
|
echo "[consumer-sweep] $f → $cmd"
|
|
65
82
|
if $EXEC; then
|
|
66
|
-
|
|
83
|
+
"${_GATE[@]}" bash -c "$cmd" || { echo "[consumer-sweep] FAIL: consumer command failed for $f: $cmd" >&2; rc=1; }
|
|
67
84
|
fi
|
|
68
85
|
done <<< "$cmds"
|
|
69
86
|
done
|
|
@@ -0,0 +1,476 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# do-decide.sh — the layer between "a leg is open" and "a human is asked".
|
|
3
|
+
#
|
|
4
|
+
# manifest: needs-env
|
|
5
|
+
# Reads GATEWAY_API_KEY through ONE_ENV_FILE, exactly as do-close.sh does.
|
|
6
|
+
# Its one network call is a PURE READ (world:route decide:true — zero side
|
|
7
|
+
# effects, zero tokens, no delivery, no mark). The writer half (mark/warn) is
|
|
8
|
+
# the settle path, and it writes strength 1 only.
|
|
9
|
+
#
|
|
10
|
+
# WHY IT EXISTS. /close closed what it could and filed a row for the rest. Every
|
|
11
|
+
# row named a command and waited for a person — including the rows whose answer
|
|
12
|
+
# was never in doubt. A blocker that resolves the same way every time is not a
|
|
13
|
+
# decision; it is a chore with a human bolted to it. And a blocker that IS a
|
|
14
|
+
# decision was filed as bare prose: "gate unrun", no options, no recommendation,
|
|
15
|
+
# no cost. So the person had to re-derive the fork every time.
|
|
16
|
+
#
|
|
17
|
+
# THE CONTRACT, in one line: for every open leg, name the fork, rank the options,
|
|
18
|
+
# recommend one, and TAKE it when — and only when — the substrate has already
|
|
19
|
+
# watched that choice come good five times.
|
|
20
|
+
#
|
|
21
|
+
# CONFIDENCE IS MEASURED, NOT ASSERTED, AND IT IS NOT MINE.
|
|
22
|
+
# The oracle is the substrate's own routing verdict — `world:route decide:true`
|
|
23
|
+
# (subscriptions.ts:672), the deterministic TS twin of 0043_route_verdict.tql:
|
|
24
|
+
#
|
|
25
|
+
# highway best >= 5 (HARDEN_STRENGTH) AND best >= 2 x second -> ACT
|
|
26
|
+
# classified a candidate, but not a proven one -> RECOMMEND
|
|
27
|
+
# ceo no candidate at all -> RECOMMEND
|
|
28
|
+
#
|
|
29
|
+
# where `best` is SUM(strength) - SUM(resistance) over `claw_paths` rows from
|
|
30
|
+
# `tag:one:decide:close:<id>` to each option, and a path stops being a candidate
|
|
31
|
+
# at all once resistance >= 0.2 x strength. Measured against production
|
|
32
|
+
# 2026-09-09, the whole loop in three calls:
|
|
33
|
+
#
|
|
34
|
+
# 0 marks -> {"reason":"ceo","receiver":null,"rung":3}
|
|
35
|
+
# 5 marks of strength 1-> {"reason":"highway","receiver":"optionA","rung":1}
|
|
36
|
+
# + 1 warn -> {"reason":"ceo","receiver":null,"rung":3}
|
|
37
|
+
#
|
|
38
|
+
# So the first five times a fork appears, a person answers it. After that the
|
|
39
|
+
# substrate has the base rate and /close acts. One bad outcome takes the
|
|
40
|
+
# authority away again on the very next run. That is the root CLAUDE.md's "human
|
|
41
|
+
# gates that auto-skip when trust earns it", applied to close blockers, using the
|
|
42
|
+
# mechanism G4 already uses for the auto-ship gate (text/factory-do.md).
|
|
43
|
+
#
|
|
44
|
+
# WHY strength 1, ALWAYS. rankCandidates sums strength; it cannot tell 5 marks of
|
|
45
|
+
# 1 from 1 mark of 5. HARDEN_STRENGTH = 5 is therefore a de-facto n>=5 SAMPLE
|
|
46
|
+
# floor only while every writer on `tag:one:decide:close:*` writes 1. This script
|
|
47
|
+
# is that sole writer and `--self-test` pins it. A future writer that marks these
|
|
48
|
+
# sources with strength > 1 turns a single event into a highway — don't.
|
|
49
|
+
#
|
|
50
|
+
# WHY AN UNREACHABLE SUBSTRATE ASKS. The decide lane's own D1 catch falls to
|
|
51
|
+
# "no candidates -> ceo", and a bounded curl that never answers is read here the
|
|
52
|
+
# same way. Every failure direction in this file points at the human. A layer
|
|
53
|
+
# that acts when it cannot measure is worse than the ask it replaced.
|
|
54
|
+
#
|
|
55
|
+
# THE VETO IS NOT A CONFIDENCE NUMBER, AND CONFIDENCE CANNOT OUTRANK IT.
|
|
56
|
+
# Blast radius is a second axis. A vetoed fork never reaches the oracle at all —
|
|
57
|
+
# structurally unreachable, not reachable-and-outranked — so no amount of
|
|
58
|
+
# accumulated strength can ever license it. See _veto_for.
|
|
59
|
+
#
|
|
60
|
+
# USAGE
|
|
61
|
+
# do-decide.sh --leg <leg> --status <s> --detail <d> [--slug <s>] [--apply]
|
|
62
|
+
# one open leg -> a verdict line (+ act)
|
|
63
|
+
# do-decide.sh --settle --leg <leg> --outcome pass|open [--slug <s>]
|
|
64
|
+
# the closed loop: mark/warn the option
|
|
65
|
+
# do-decide.sh --table the decision table, as it is
|
|
66
|
+
# do-decide.sh --self-test fixtures + RED PROOFS
|
|
67
|
+
#
|
|
68
|
+
# OPTIONS
|
|
69
|
+
# --apply take the decision when the verdict is `highway`. Without it
|
|
70
|
+
# this script is a pure reporter — do-close.sh --dry-run and
|
|
71
|
+
# the self-test rely on that.
|
|
72
|
+
# --budget <secs> oracle + action wall clock (default: 12)
|
|
73
|
+
# --json one JSON object on stdout
|
|
74
|
+
#
|
|
75
|
+
# EXIT
|
|
76
|
+
# 0 a verdict was produced (taken OR recommended — both are success)
|
|
77
|
+
# 4 the fork is vetoed: it will never be automatic, and the row says why
|
|
78
|
+
# 5 no decision table entry for this leg+detail — the caller files as before
|
|
79
|
+
# 2 usage
|
|
80
|
+
#
|
|
81
|
+
# It never returns non-zero for "the substrate was down" or "confidence was low".
|
|
82
|
+
# Those are ordinary answers, and a closer that fails on them is a closer callers
|
|
83
|
+
# route around — do-close.sh's founding lesson, inherited whole.
|
|
84
|
+
set -uo pipefail
|
|
85
|
+
|
|
86
|
+
ROOT="$(cd "$(dirname "$0")/../.." && pwd)"
|
|
87
|
+
ONE_ENV_FILE="${ONE_ENV_FILE:-${DO_ENV_FILE:-one.ie/web/.env}}"
|
|
88
|
+
_MONOREPO_ENV_CANDIDATES="$ROOT/one.ie/web/.env $ROOT/one.ie/web/.dev.vars"
|
|
89
|
+
WORKSPACE="${CC_TASKS_WORKSPACE:-one}"
|
|
90
|
+
|
|
91
|
+
LEG=""; DSTATUS=""; DETAIL=""; SLUG=""; APPLY=0; BUDGET="${DECIDE_BUDGET:-12}"
|
|
92
|
+
JSON=0; SETTLE=0; OUTCOME=""; TABLE=0; SELFTEST=0
|
|
93
|
+
|
|
94
|
+
while [ $# -gt 0 ]; do
|
|
95
|
+
case "$1" in
|
|
96
|
+
--leg) LEG="${2:-}"; shift 2 ;;
|
|
97
|
+
--status) DSTATUS="${2:-}"; shift 2 ;;
|
|
98
|
+
--detail) DETAIL="${2:-}"; shift 2 ;;
|
|
99
|
+
--slug) SLUG="${2:-}"; shift 2 ;;
|
|
100
|
+
--outcome) OUTCOME="${2:-}"; shift 2 ;;
|
|
101
|
+
--budget) BUDGET="${2:-12}"; shift 2 ;;
|
|
102
|
+
--apply) APPLY=1; shift ;;
|
|
103
|
+
--settle) SETTLE=1; shift ;;
|
|
104
|
+
--table) TABLE=1; shift ;;
|
|
105
|
+
--json) JSON=1; shift ;;
|
|
106
|
+
--self-test) SELFTEST=1; shift ;;
|
|
107
|
+
-h|--help) sed -n '/^# USAGE/,/^# EXIT/p' "$0" | sed 's/^# \{0,1\}//'; exit 0 ;;
|
|
108
|
+
*) echo "do-decide: unknown arg $1" >&2; exit 2 ;;
|
|
109
|
+
esac
|
|
110
|
+
done
|
|
111
|
+
|
|
112
|
+
_env_key() {
|
|
113
|
+
local _f _v
|
|
114
|
+
for _f in "$ONE_ENV_FILE" "$ROOT/.env" $_MONOREPO_ENV_CANDIDATES; do
|
|
115
|
+
[ -f "$_f" ] || continue
|
|
116
|
+
_v=$(grep -E "^$1=" "$_f" 2>/dev/null | head -1 | sed 's/^[^=]*=//;s/^"//;s/"$//' || true)
|
|
117
|
+
[ -n "$_v" ] && { printf '%s' "$_v"; return 0; }
|
|
118
|
+
done
|
|
119
|
+
printf ''
|
|
120
|
+
}
|
|
121
|
+
_base() {
|
|
122
|
+
if [ -n "${ONE_API_URL:-}" ]; then printf '%s' "$ONE_API_URL"; return; fi
|
|
123
|
+
curl -s -o /dev/null --max-time 1.5 --connect-timeout 1 "http://localhost:4321/api/health" 2>/dev/null \
|
|
124
|
+
&& printf 'http://localhost:4321' || printf 'https://one.ie'
|
|
125
|
+
}
|
|
126
|
+
_jsonesc() { printf '%s' "${1:-}" | sed -e 's/\\/\\\\/g' -e 's/"/\\"/g' | tr '\n' ' '; }
|
|
127
|
+
|
|
128
|
+
# ═══ THE DECISION TABLE ═════════════════════════════════════════════════════
|
|
129
|
+
# Four entries, and the fourth is a veto. This is deliberately a TABLE and not an
|
|
130
|
+
# engine: it was enumerated from do-close.sh's actual `_emit` call sites, not
|
|
131
|
+
# imagined. A fork that is not in this table is not a decision — exit 5, and the
|
|
132
|
+
# caller files the row exactly as it did before. Adding a row is how this grows;
|
|
133
|
+
# generalising it is how it starts guessing.
|
|
134
|
+
#
|
|
135
|
+
# id | fires on | options (first = the declared prior)
|
|
136
|
+
# ---+--------------------------------+------------------------------------
|
|
137
|
+
# gate-mint gate unrun, no receipt mint · file
|
|
138
|
+
# derives-retry derives unrun (out of clock) retry · file
|
|
139
|
+
# promise-retry promise unrun (exit 3 / clock) retry · file
|
|
140
|
+
# writeback dims|feedback|task unrun at a door file [VETO]
|
|
141
|
+
# task-gate task unrun, gate not pass file [VETO]
|
|
142
|
+
_decision_for() { # <leg> <status> <detail> -> "<id> <opt1> <opt2>" or ""
|
|
143
|
+
local leg="$1" st="$2" d="$3"
|
|
144
|
+
[ "$st" = "unrun" ] || { printf ''; return; } # a `fail` is a verdict, not a fork
|
|
145
|
+
case "$leg" in
|
|
146
|
+
gate) case "$d" in *"no full-suite receipt"*) printf 'gate-mint mint file' ;; *) printf '' ;; esac ;;
|
|
147
|
+
derives) case "$d" in *"exceeded"*) printf 'derives-retry retry file' ;; *) printf '' ;; esac ;;
|
|
148
|
+
promise) case "$d" in
|
|
149
|
+
*"UNVERIFIABLE"*|*"exceeded"*) printf 'promise-retry retry file' ;;
|
|
150
|
+
*) printf '' ;; esac ;;
|
|
151
|
+
dims|feedback) printf 'writeback file' ;;
|
|
152
|
+
task) printf 'task-gate file' ;;
|
|
153
|
+
*) printf '' ;;
|
|
154
|
+
esac
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
# ═══ THE VETO ═══════════════════════════════════════════════════════════════
|
|
158
|
+
# Checked BEFORE the oracle is called, so a vetoed fork is structurally
|
|
159
|
+
# unreachable rather than reachable-but-outranked. Two standing vetoes, each with
|
|
160
|
+
# its measured reason, plus the blanket class.
|
|
161
|
+
_veto_for() { # <id> -> reason, or empty
|
|
162
|
+
case "$1" in
|
|
163
|
+
writeback)
|
|
164
|
+
# THE SELF-POISONING VETO, and it is the sharpest rule in this file.
|
|
165
|
+
# dims, feedback and task write THROUGH doors (mark-dims, loop:feedback,
|
|
166
|
+
# tasks:status). Their `unrun` is curl exit 7: the request timed out with
|
|
167
|
+
# the answer UNKNOWN — the write may well have landed. A retry that
|
|
168
|
+
# double-writes deposits strength twice on exactly the `claw_paths` rows
|
|
169
|
+
# this script reads back as confidence. An auto-retry here would inflate
|
|
170
|
+
# its own evidence, and the more it fired the more certain it would look.
|
|
171
|
+
# No confidence number may buy that. Ever.
|
|
172
|
+
printf 'an ambiguous WRITE cannot be retried — a double mark inflates the very weights this layer reads as confidence' ;;
|
|
173
|
+
task-gate)
|
|
174
|
+
# The repo's most expensive scar, named twice in do-close.sh's own header:
|
|
175
|
+
# cycles closed green at 0.92 with "tsc not measured, box saturated".
|
|
176
|
+
# The task<-gate edge is the thing that stopped it happening again.
|
|
177
|
+
printf 'the board write must never be decided around its gate — cycles once closed green at 0.92 with the suite unmeasured' ;;
|
|
178
|
+
*) printf '' ;;
|
|
179
|
+
esac
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
# The blanket class, independent of the table: an action string that ships,
|
|
183
|
+
# deploys, pushes, deletes, force-writes, spends, or touches the shared main tree
|
|
184
|
+
# is never taken by this script, whatever the table or the oracle says. Applied
|
|
185
|
+
# to the COMMAND about to run, so a table row edited to smuggle one in still
|
|
186
|
+
# cannot fire.
|
|
187
|
+
_action_forbidden() { # <command> -> reason, or empty
|
|
188
|
+
case "$1" in
|
|
189
|
+
*"release.sh"*|*"deploy.sh"*|*"./deploy"*|*"wrangler deploy"*|*" ship"*)
|
|
190
|
+
printf 'ships or deploys' ;;
|
|
191
|
+
*"git push"*|*"--force"*|*"-f "*|*"git reset --hard"*|*"git clean"*)
|
|
192
|
+
printf 'rewrites or discards history' ;;
|
|
193
|
+
*"rm -rf"*|*"DROP "*|*"undefine"*|*"secret put"*)
|
|
194
|
+
printf 'deletes or rotates' ;;
|
|
195
|
+
*) printf '' ;;
|
|
196
|
+
esac
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
# ═══ THE ACTIONS ════════════════════════════════════════════════════════════
|
|
200
|
+
# Every option is one line, and `file` is always the null action: it is what
|
|
201
|
+
# /close already did, so choosing it changes nothing and can break nothing.
|
|
202
|
+
_command_for() { # <id> <option> -> the command, or empty for the null action
|
|
203
|
+
local s="${SLUG:-<slug>}"
|
|
204
|
+
case "$1:$2" in
|
|
205
|
+
gate-mint:mint) printf 'cd %s/one.ie/web && FULL_VERIFY=1 bun run verify' "$ROOT" ;;
|
|
206
|
+
derives-retry:retry) printf 'bash %s/.claude/scripts/do-derives-check.sh %s' "$ROOT" "$s" ;;
|
|
207
|
+
promise-retry:retry) printf 'bash %s/.claude/scripts/do-promise-settle.sh %s' "$ROOT" "$s" ;;
|
|
208
|
+
*:file) printf '' ;;
|
|
209
|
+
*) printf '' ;;
|
|
210
|
+
esac
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
# What taking the option costs, so a recommendation carries its price and a
|
|
214
|
+
# reader can disagree with it on the evidence rather than on faith.
|
|
215
|
+
_cost_for() { # <id> <option>
|
|
216
|
+
case "$1:$2" in
|
|
217
|
+
gate-mint:mint) printf '~87s + one governor gate slot' ;;
|
|
218
|
+
derives-retry:retry) printf 'a bounded re-read, no gate slot' ;;
|
|
219
|
+
promise-retry:retry) printf 'the promise proof, re-run bounded' ;;
|
|
220
|
+
*:file) printf 'nothing — this is what /close already does' ;;
|
|
221
|
+
*) printf 'unknown' ;;
|
|
222
|
+
esac
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
# gate-mint is the one option with a machine precondition: minting takes a gate
|
|
226
|
+
# slot, and taking the last slot on a saturated box is how this repo once ran six
|
|
227
|
+
# concurrent tsc at load 57. Confidence says the choice is right; headroom says
|
|
228
|
+
# whether NOW is the moment. Both must hold.
|
|
229
|
+
_precondition_for() { # <id> <option> -> reason it cannot run now, or empty
|
|
230
|
+
[ "$1:$2" = "gate-mint:mint" ] || { printf ''; return; }
|
|
231
|
+
local hr=99
|
|
232
|
+
if [ -r "$ROOT/.claude/scripts/lib/govern.sh" ]; then
|
|
233
|
+
hr=$( . "$ROOT/.claude/scripts/lib/govern.sh" >/dev/null 2>&1
|
|
234
|
+
command -v gate_headroom >/dev/null 2>&1 && gate_headroom 2>/dev/null || echo 99 )
|
|
235
|
+
fi
|
|
236
|
+
case "$hr" in ''|*[!0-9]*) hr=99 ;; esac
|
|
237
|
+
# A broken sensor reads 99 and must never silently block — govern.sh's own rule.
|
|
238
|
+
[ "$hr" -lt 1 ] && printf 'no gate headroom (%s) — minting now would take the last slot on a saturated box' "$hr" || printf ''
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
# ═══ THE ORACLE ═════════════════════════════════════════════════════════════
|
|
242
|
+
# One bounded POST, a pure read. `workspace` must be nominated in the payload:
|
|
243
|
+
# world:route refuses with `forbidden: authentication required` when ctx.ownerSlug
|
|
244
|
+
# is unset, and a service key alone sets no slug (ask/[...receiver].ts:238 —
|
|
245
|
+
# a VERIFIED service caller may nominate one, nobody else may). Measured: without
|
|
246
|
+
# it, every verdict was `forbidden` and this layer would have asked forever.
|
|
247
|
+
_verdict() { # <id> -> "<reason> <receiver>"
|
|
248
|
+
local key resp cfg reason recv
|
|
249
|
+
key="$(_env_key GATEWAY_API_KEY)"
|
|
250
|
+
[ -n "$key" ] || { printf 'ceo -'; return; }
|
|
251
|
+
cfg="$(mktemp)"; chmod 600 "$cfg"
|
|
252
|
+
printf 'header = "Authorization: Bearer %s"\n' "$key" > "$cfg"
|
|
253
|
+
resp=$(curl -s --max-time "$BUDGET" --connect-timeout 2 -X POST \
|
|
254
|
+
"$(_base)/api/ask/world:route" -H 'Content-Type: application/json' --config "$cfg" \
|
|
255
|
+
-d "{\"data\":{\"workspace\":\"$WORKSPACE\",\"tags\":[\"decide:close:$1\"],\"decide\":true}}" 2>/dev/null)
|
|
256
|
+
rm -f "$cfg"
|
|
257
|
+
reason=$(printf '%s' "$resp" | sed -n 's/.*"reason":"\([a-z]*\)".*/\1/p')
|
|
258
|
+
recv=$(printf '%s' "$resp" | sed -n 's/.*"receiver":"\([^"]*\)".*/\1/p')
|
|
259
|
+
# No answer, a malformed answer, or an error body all land on `ceo`. Every
|
|
260
|
+
# failure direction in this file points at the human.
|
|
261
|
+
case "$reason" in highway|classified|ceo) ;; *) reason=ceo; recv="" ;; esac
|
|
262
|
+
printf '%s %s' "$reason" "${recv:--}"
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
# ═══ THE SETTLE — Rule 1, closed ════════════════════════════════════════════
|
|
266
|
+
# A decision taken is not a decision proven. The evidence this layer reads is
|
|
267
|
+
# written HERE, on the next close, from what actually happened to the leg:
|
|
268
|
+
# pass -> mark (the option came good; strength 1, five of them make a highway)
|
|
269
|
+
# open -> warn (it did not; one warn takes the authority straight back)
|
|
270
|
+
# Never from "the command exited 0" — that measures the command, not the choice.
|
|
271
|
+
_settle() { # <id> <option> <outcome>
|
|
272
|
+
local verb key edge cfg
|
|
273
|
+
case "$3" in pass) verb=mark ;; *) verb=warn ;; esac
|
|
274
|
+
key="$(_env_key GATEWAY_API_KEY)"; [ -n "$key" ] || return 1
|
|
275
|
+
edge=$(printf 'tag:one:decide:close:%s→%s' "$1" "$2" \
|
|
276
|
+
| sed 's/:/%3A/g; s/→/%E2%86%92/g')
|
|
277
|
+
cfg="$(mktemp)"; chmod 600 "$cfg"
|
|
278
|
+
printf 'header = "Authorization: Bearer %s"\n' "$key" > "$cfg"
|
|
279
|
+
# strength 1, ALWAYS — the sample floor depends on it (see the header).
|
|
280
|
+
curl -s -o /dev/null --max-time "$BUDGET" --connect-timeout 2 -X POST \
|
|
281
|
+
"$(_base)/api/$verb/$edge" -H 'Content-Type: application/json' \
|
|
282
|
+
--config "$cfg" -d '{"strength":1}' 2>/dev/null
|
|
283
|
+
local rc=$?; rm -f "$cfg"; return $rc
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
# ═══ --table ════════════════════════════════════════════════════════════════
|
|
287
|
+
if [ "$TABLE" -eq 1 ]; then
|
|
288
|
+
printf '%-14s %-26s %-18s %s\n' ID FIRES-ON OPTIONS VETO
|
|
289
|
+
for row in "gate-mint|gate unrun, no receipt|mint · file" \
|
|
290
|
+
"derives-retry|derives unrun (clock)|retry · file" \
|
|
291
|
+
"promise-retry|promise unrun (3/clock)|retry · file" \
|
|
292
|
+
"writeback|dims/feedback/task door|file" \
|
|
293
|
+
"task-gate|task unrun, gate not pass|file"; do
|
|
294
|
+
id="${row%%|*}"; rest="${row#*|}"; fires="${rest%%|*}"; opts="${rest#*|}"
|
|
295
|
+
printf '%-14s %-26s %-18s %s\n' "$id" "$fires" "$opts" "$(_veto_for "$id" | cut -c1-60)"
|
|
296
|
+
done
|
|
297
|
+
exit 0
|
|
298
|
+
fi
|
|
299
|
+
|
|
300
|
+
# ═══ --settle ═══════════════════════════════════════════════════════════════
|
|
301
|
+
if [ "$SETTLE" -eq 1 ]; then
|
|
302
|
+
[ -n "$LEG" ] && [ -n "$OUTCOME" ] || { echo "do-decide: --settle needs --leg and --outcome" >&2; exit 2; }
|
|
303
|
+
spec="$(_decision_for "$LEG" unrun "${DETAIL:-}")"
|
|
304
|
+
[ -n "$spec" ] || exit 5
|
|
305
|
+
id="${spec%% *}"; opt="${DSTATUS:-$(printf '%s' "$spec" | awk '{print $2}')}"
|
|
306
|
+
if _settle "$id" "$opt" "$OUTCOME"; then
|
|
307
|
+
echo "decide: settled $id→$opt as $OUTCOME ($([ "$OUTCOME" = pass ] && echo mark || echo warn))"
|
|
308
|
+
else
|
|
309
|
+
echo "decide: settle unreachable for $id→$opt — the path keeps its old weight"
|
|
310
|
+
fi
|
|
311
|
+
exit 0
|
|
312
|
+
fi
|
|
313
|
+
|
|
314
|
+
# ═══ --self-test ════════════════════════════════════════════════════════════
|
|
315
|
+
if [ "$SELFTEST" -eq 1 ]; then
|
|
316
|
+
fails=0
|
|
317
|
+
echo "── do-decide --self-test ──"
|
|
318
|
+
|
|
319
|
+
# 1. A fork with no table row is not a decision.
|
|
320
|
+
out=$(bash "$0" --leg dims --status fail --detail "refused" 2>&1); rc=$?
|
|
321
|
+
[ "$rc" -eq 5 ] && echo "ok: a leg with no table row exits 5 — the caller files as before" \
|
|
322
|
+
|| { echo "FAIL: expected exit 5 for an untabled fork (rc=$rc)"; fails=$((fails+1)); }
|
|
323
|
+
|
|
324
|
+
# 2. A vetoed fork exits 4 and NAMES why — before any oracle call.
|
|
325
|
+
out=$(bash "$0" --leg task --status unrun --detail "gate=unrun" 2>&1); rc=$?
|
|
326
|
+
if [ "$rc" -eq 4 ] && printf '%s' "$out" | grep -q '0.92'; then
|
|
327
|
+
echo "ok: the task←gate fork is vetoed (exit 4) and the row names the scar"
|
|
328
|
+
else echo "FAIL: task-gate veto did not fire (rc=$rc): $out"; fails=$((fails+1)); fi
|
|
329
|
+
|
|
330
|
+
# 3. The write-door veto fires with its self-poisoning reason.
|
|
331
|
+
out=$(bash "$0" --leg feedback --status unrun --detail "signal door did not answer" 2>&1); rc=$?
|
|
332
|
+
if [ "$rc" -eq 4 ] && printf '%s' "$out" | grep -qi 'double mark'; then
|
|
333
|
+
echo "ok: an ambiguous write door is vetoed, naming the self-poisoning reason"
|
|
334
|
+
else echo "FAIL: writeback veto did not fire (rc=$rc): $out"; fails=$((fails+1)); fi
|
|
335
|
+
|
|
336
|
+
# 4. RED PROOF for 2+3 — gut _veto_for and both must go green (i.e. stop vetoing).
|
|
337
|
+
gut="$(mktemp)"; sed 's/^_veto_for() { # <id> -> reason, or empty/_veto_for() { printf ""; return; } _veto_dead() {/' "$0" > "$gut"
|
|
338
|
+
rc=0; bash "$gut" --leg task --status unrun --detail "gate=unrun" >/dev/null 2>&1 || rc=$?
|
|
339
|
+
[ "$rc" -ne 4 ] && echo "ok: RED PROOF — a gutted _veto_for stops vetoing (checks 2-3 measure something)" \
|
|
340
|
+
|| { echo "FAIL: RED PROOF — veto still fired with _veto_for gutted"; fails=$((fails+1)); }
|
|
341
|
+
|
|
342
|
+
# 5. No oracle answer ⇒ ceo ⇒ RECOMMEND, never take. Point it at a dead door.
|
|
343
|
+
out=$(ONE_API_URL="http://127.0.0.1:1" DECIDE_BUDGET=2 bash "$0" --leg gate --status unrun \
|
|
344
|
+
--detail "no full-suite receipt — 0/2 lane(s)" --apply 2>&1); rc=$?
|
|
345
|
+
if [ "$rc" -eq 0 ] && printf '%s' "$out" | grep -q 'RECOMMEND' && ! printf '%s' "$out" | grep -q 'TAKEN'; then
|
|
346
|
+
echo "ok: an unreachable oracle reads ceo and RECOMMENDS — it never acts blind"
|
|
347
|
+
else echo "FAIL: dead oracle did not fall to recommend (rc=$rc): $out"; fails=$((fails+1)); fi
|
|
348
|
+
|
|
349
|
+
# 6. The blanket action veto outranks any verdict — a forbidden command cannot
|
|
350
|
+
# be taken even with `highway` forced. This is the check that proves
|
|
351
|
+
# confidence does not buy blast radius. The gut is an inserted early-return
|
|
352
|
+
# (a header rewrite mangles multi-line bodies — measured).
|
|
353
|
+
_gut() { # <file> <fn> <body> -> a temp copy with that function short-circuited
|
|
354
|
+
local f; f="$(mktemp)"
|
|
355
|
+
awk -v fn="$2" -v body="$3" '$0 ~ "^"fn"\\(\\) \\{" {print; print " "body; next} {print}' "$1" > "$f"
|
|
356
|
+
printf '%s' "$f"
|
|
357
|
+
}
|
|
358
|
+
gut2="$(_gut "$0" _verdict 'printf "highway mint"; return 0;')"
|
|
359
|
+
gut2b="$(_gut "$gut2" _command_for 'printf "bash .claude/scripts/release.sh ship"; return 0;')"
|
|
360
|
+
out=$(bash "$gut2b" --leg gate --status unrun --detail "no full-suite receipt" --apply 2>&1); rc=$?
|
|
361
|
+
if printf '%s' "$out" | grep -q 'ships or deploys' && ! printf '%s' "$out" | grep -q 'TAKEN'; then
|
|
362
|
+
echo "ok: a forbidden action is refused even on a forced highway verdict"
|
|
363
|
+
else echo "FAIL: forbidden action was not refused under highway (rc=$rc): $out"; fails=$((fails+1)); fi
|
|
364
|
+
|
|
365
|
+
# 7. RED PROOF for 6 — gut _action_forbidden and the same forced highway takes it.
|
|
366
|
+
gut3="$(_gut "$gut2b" _action_forbidden 'printf ""; return 0;')"
|
|
367
|
+
out=$(DECIDE_DRYCMD=1 bash "$gut3" --leg gate --status unrun --detail "no full-suite receipt" --apply 2>&1)
|
|
368
|
+
if printf '%s' "$out" | grep -q 'TAKEN'; then
|
|
369
|
+
echo "ok: RED PROOF — a gutted _action_forbidden lets it through (check 6 measures something)"
|
|
370
|
+
else echo "FAIL: RED PROOF — action still refused with the guard gutted: $out"; fails=$((fails+1)); fi
|
|
371
|
+
|
|
372
|
+
# 8. strength 1, always — the n>=5 sample floor depends on this one literal.
|
|
373
|
+
if grep -q "d '{\"strength\":1}'" "$0"; then
|
|
374
|
+
echo "ok: the settle writes strength 1 — HARDEN_STRENGTH stays an n>=5 sample floor"
|
|
375
|
+
else echo "FAIL: the settle no longer writes strength 1 — one event could become a highway"; fails=$((fails+1)); fi
|
|
376
|
+
|
|
377
|
+
# 9. Without --apply this script cannot act at all, whatever the verdict says.
|
|
378
|
+
gut4="$(_gut "$0" _verdict 'printf "highway mint"; return 0;')"
|
|
379
|
+
out=$(bash "$gut4" --leg gate --status unrun --detail "no full-suite receipt" 2>&1)
|
|
380
|
+
printf '%s' "$out" | grep -q 'TAKEN' \
|
|
381
|
+
&& { echo "FAIL: acted without --apply"; fails=$((fails+1)); } \
|
|
382
|
+
|| echo "ok: without --apply a highway verdict still only reports — dry-run is structural"
|
|
383
|
+
|
|
384
|
+
rm -f "$gut" "$gut2" "$gut2b" "$gut3" "$gut4"
|
|
385
|
+
echo "── $([ "$fails" -eq 0 ] && echo 'all checks pass' || echo "$fails FAILED") ──"
|
|
386
|
+
[ "$fails" -eq 0 ]; exit $?
|
|
387
|
+
fi
|
|
388
|
+
|
|
389
|
+
# ═══ one fork ═══════════════════════════════════════════════════════════════
|
|
390
|
+
[ -n "$LEG" ] || { echo "do-decide: --leg required" >&2; exit 2; }
|
|
391
|
+
SPEC="$(_decision_for "$LEG" "$DSTATUS" "$DETAIL")"
|
|
392
|
+
[ -n "$SPEC" ] || exit 5
|
|
393
|
+
ID="${SPEC%% *}"; OPTS="${SPEC#* }"
|
|
394
|
+
PREFER="$(printf '%s' "$OPTS" | awk '{print $1}')"
|
|
395
|
+
|
|
396
|
+
# The veto, before the oracle. A vetoed fork is reported with its options and its
|
|
397
|
+
# reason — the person still gets the ranking, they just also get told this one is
|
|
398
|
+
# theirs by rule, not by a number that happened to be low today.
|
|
399
|
+
VETO="$(_veto_for "$ID")"
|
|
400
|
+
if [ -n "$VETO" ]; then
|
|
401
|
+
if [ "$JSON" -eq 1 ]; then
|
|
402
|
+
printf '{"id":"%s","leg":"%s","verdict":"veto","reason":"%s","options":"%s","action":"none"}\n' \
|
|
403
|
+
"$ID" "$LEG" "$(_jsonesc "$VETO")" "$(_jsonesc "$OPTS")"
|
|
404
|
+
else
|
|
405
|
+
printf ' decide %-14s VETO %s\n' "$ID" "$VETO"
|
|
406
|
+
printf ' %-21s stays human by rule — no confidence buys it\n' ""
|
|
407
|
+
fi
|
|
408
|
+
exit 4
|
|
409
|
+
fi
|
|
410
|
+
|
|
411
|
+
REASON=""; RECV=""
|
|
412
|
+
read -r REASON RECV <<EOF
|
|
413
|
+
$(_verdict "$ID")
|
|
414
|
+
EOF
|
|
415
|
+
[ "$RECV" = "-" ] && RECV=""
|
|
416
|
+
|
|
417
|
+
# `highway` is the ONLY verdict that licenses acting, and the substrate must have
|
|
418
|
+
# picked an option this table actually knows. A highway pointing at an unknown
|
|
419
|
+
# target is stale evidence, not a mandate.
|
|
420
|
+
CHOICE="$PREFER"; TAKE=0
|
|
421
|
+
if [ "$REASON" = "highway" ] && [ -n "$RECV" ]; then
|
|
422
|
+
case " $OPTS " in *" $RECV "*) CHOICE="$RECV"; TAKE=1 ;; esac
|
|
423
|
+
fi
|
|
424
|
+
|
|
425
|
+
CMD="$(_command_for "$ID" "$CHOICE")"
|
|
426
|
+
FORBIDDEN="$(_action_forbidden "$CMD")"
|
|
427
|
+
PRECOND="$(_precondition_for "$ID" "$CHOICE")"
|
|
428
|
+
NOTE=""; RESULT=recommend
|
|
429
|
+
|
|
430
|
+
if [ "$TAKE" -eq 1 ] && [ -n "$FORBIDDEN" ]; then
|
|
431
|
+
TAKE=0; NOTE="refused: the action $FORBIDDEN — blast radius is not a confidence number"
|
|
432
|
+
elif [ "$TAKE" -eq 1 ] && [ -n "$PRECOND" ]; then
|
|
433
|
+
TAKE=0; NOTE="held: $PRECOND"
|
|
434
|
+
elif [ "$TAKE" -eq 1 ] && [ -z "$CMD" ]; then
|
|
435
|
+
# The null action (`file`) won the highway. Taking it means doing what /close
|
|
436
|
+
# already does — report it as chosen, run nothing.
|
|
437
|
+
NOTE="the null action — /close files the row, which is the proven choice here"
|
|
438
|
+
RESULT=taken
|
|
439
|
+
elif [ "$TAKE" -eq 1 ] && [ "$APPLY" -eq 0 ]; then
|
|
440
|
+
TAKE=0; NOTE="would take it — re-run with --apply (or without --dry-run)"
|
|
441
|
+
fi
|
|
442
|
+
|
|
443
|
+
if [ "$TAKE" -eq 1 ] && [ -n "$CMD" ] && [ "$APPLY" -eq 1 ]; then
|
|
444
|
+
if [ -n "${DECIDE_DRYCMD:-}" ]; then RESULT=taken; NOTE="(DECIDE_DRYCMD — command not run)"
|
|
445
|
+
else
|
|
446
|
+
rc=0; ( eval "$CMD" ) >/dev/null 2>&1 || rc=$?
|
|
447
|
+
RESULT=taken
|
|
448
|
+
NOTE="ran: exit $rc"
|
|
449
|
+
fi
|
|
450
|
+
fi
|
|
451
|
+
|
|
452
|
+
# The undo line is not a nicety. Auto-taking moves the human's veto from BEFORE
|
|
453
|
+
# the action to AFTER it, and that trade is only honest while the reversal is
|
|
454
|
+
# actually in their hand — so it ships with every taken decision, always.
|
|
455
|
+
UNDO="bash .claude/scripts/do-decide.sh --settle --leg $LEG --status $CHOICE --outcome open${SLUG:+ --slug $SLUG} # warn the path; the next close asks again"
|
|
456
|
+
|
|
457
|
+
if [ "$JSON" -eq 1 ]; then
|
|
458
|
+
printf '{"id":"%s","leg":"%s","verdict":"%s","confidence":"%s","choice":"%s","options":"%s","result":"%s","note":"%s","command":"%s","undo":"%s"}\n' \
|
|
459
|
+
"$ID" "$LEG" "$RESULT" "$REASON" "$CHOICE" "$(_jsonesc "$OPTS")" "$RESULT" \
|
|
460
|
+
"$(_jsonesc "$NOTE")" "$(_jsonesc "$CMD")" "$(_jsonesc "$UNDO")"
|
|
461
|
+
exit 0
|
|
462
|
+
fi
|
|
463
|
+
|
|
464
|
+
if [ "$RESULT" = "taken" ]; then
|
|
465
|
+
printf ' decide %-14s TAKEN %s (confidence: %s — the substrate has watched this choice come good)\n' "$ID" "$CHOICE" "$REASON"
|
|
466
|
+
[ -n "$NOTE" ] && printf ' %-21s %s\n' "" "$NOTE"
|
|
467
|
+
printf ' %-21s undo: %s\n' "" "$UNDO"
|
|
468
|
+
else
|
|
469
|
+
printf ' decide %-14s RECOMMEND %s (confidence: %s — not yet proven; a person decides)\n' "$ID" "$CHOICE" "$REASON"
|
|
470
|
+
for o in $OPTS; do
|
|
471
|
+
_m=" "; [ "$o" = "$CHOICE" ] && _m="→"
|
|
472
|
+
printf ' %-21s %s %-6s %s\n' "" "$_m" "$o" "$(_cost_for "$ID" "$o")"
|
|
473
|
+
done
|
|
474
|
+
[ -n "$NOTE" ] && printf ' %-21s %s\n' "" "$NOTE"
|
|
475
|
+
fi
|
|
476
|
+
exit 0
|
package/scripts/do-fleet.sh
CHANGED
|
@@ -33,7 +33,7 @@ WT_BASE="$ROOT/.do-worktrees"
|
|
|
33
33
|
|
|
34
34
|
# Worktree branches cut from trunk, never HEAD — a shared tree parked on a
|
|
35
35
|
# feature branch must not seed fleet plans with its commits. DO_BASE_REF overrides.
|
|
36
|
-
BASE_REF="${DO_BASE_REF:-
|
|
36
|
+
BASE_REF="${DO_BASE_REF:-dev}"
|
|
37
37
|
git -C "$ROOT" show-ref --verify --quiet "refs/heads/$BASE_REF" || BASE_REF=HEAD
|
|
38
38
|
|
|
39
39
|
GO=false
|
|
@@ -221,9 +221,15 @@ claim_task() { # claim_task <slug> → 0 ok to launch, 1 already claimed elsewh
|
|
|
221
221
|
[ -n "$secret" ] && break
|
|
222
222
|
done
|
|
223
223
|
[ -z "$secret" ] && return 0
|
|
224
|
+
# A mirrored plan (do-board.sh) hangs its cycle rows off the plan row, and the
|
|
225
|
+
# claim gate refuses a parent with open children — so lease the FIRST OPEN CYCLE's
|
|
226
|
+
# row when there is one (its own batch predecessors gate it), the plan row otherwise.
|
|
227
|
+
local addr tid
|
|
228
|
+
tid=$(bash "$ROOT/.claude/scripts/do-plan-json.sh" "$slug" 2>/dev/null | jq -r '.cycleRows[.openCycles[0]] // empty' 2>/dev/null || true)
|
|
229
|
+
if [ -n "$tid" ]; then addr="\"tid\":\"$tid\""; else addr="\"slug\":\"$slug\""; fi
|
|
224
230
|
resp=$(curl -sf -X POST "${DO_SIGNAL_URL:-https://one.ie}/api/ask/tasks:claim" \
|
|
225
231
|
-H "Content-Type: application/json" -H "Authorization: Bearer $secret" \
|
|
226
|
-
-d "{\"data\":{
|
|
232
|
+
-d "{\"data\":{$addr,\"workspace\":\"${CC_TASKS_WORKSPACE:-one}\"}}" 2>/dev/null || true)
|
|
227
233
|
case "$resp" in
|
|
228
234
|
*'"ok":true'*) return 0 ;; # lease held by us — launch
|
|
229
235
|
*'"error":"already-claimed"'*) echo " ~ $slug — claimed by another actor, skipping" >&2; return 1 ;;
|