@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,396 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# factory-walk.sh — the factory's deterministic check of ONE piece of work.
|
|
3
|
+
#
|
|
4
|
+
# manifest: needs-env
|
|
5
|
+
# Names one.ie/web (the previewed app) and reads that app's gitignored .env
|
|
6
|
+
# through the scripts it composes. Every stage degrades to `unrun`, never to a
|
|
7
|
+
# pass, when the environment cannot answer.
|
|
8
|
+
#
|
|
9
|
+
# WHAT IT IS. One command whose exit code is the verdict on a task: it walks the
|
|
10
|
+
# work across the lifecycle stages text/factory-do.md § THE WHOLE PATH names —
|
|
11
|
+
# size · isolate · gate · prove · human · substrate — and writes one receipt. It
|
|
12
|
+
# builds NO new gate. Every stage is an existing script, chosen by the tier and
|
|
13
|
+
# the surface, run through the governor and the memo:
|
|
14
|
+
#
|
|
15
|
+
# size do-tier.sh how big is the change; UNSIZED is a FAIL,
|
|
16
|
+
# because absence of recon must never read
|
|
17
|
+
# as simplicity
|
|
18
|
+
# isolate worktree-preview.sh a UI task's tree is a real worktree with
|
|
19
|
+
# local .vite/.astro caches (n/a on main)
|
|
20
|
+
# gate verify-fast.sh the tier's lane, per folder do-folder.sh
|
|
21
|
+
# maps — fast for PATCH/FIX/FEATURE, FULL
|
|
22
|
+
# for SCHEMA or schema/sdk/auth paths; via
|
|
23
|
+
# gate-run.sh (slot), tsc-cached.sh and
|
|
24
|
+
# test-cached.sh (memo). Exit 144 = UNRUN.
|
|
25
|
+
# prove do-prove.sh UI: every route, landing rule, against the
|
|
26
|
+
# do-walk.sh --agents task's preview URL. Otherwise the slug's
|
|
27
|
+
# agents walk (text/<slug>-agents.md).
|
|
28
|
+
# human the link block UI only: the preview URL, one stop per
|
|
29
|
+
# route or per text/<slug>-humans.md stop,
|
|
30
|
+
# and the instruction that records the
|
|
31
|
+
# verdict. `--humans` on a tty asks y/n.
|
|
32
|
+
# Until a person answers, PENDING — which
|
|
33
|
+
# is unrun, which is not a pass.
|
|
34
|
+
# substrate factory-check.sh SCHEMA tier only: the ladder is live.
|
|
35
|
+
#
|
|
36
|
+
# THE HONESTY LAW, inherited from do-w4-gates.sh: every stage has FOUR states
|
|
37
|
+
# pass : ran, green fail : ran, red
|
|
38
|
+
# unrun : could not run n/a : does not apply, by rule
|
|
39
|
+
# and the verdict is `pass` only with ZERO fails AND ZERO unruns. A missing row
|
|
40
|
+
# is treated as unrun and named — an absent row is the fail-open trap in data
|
|
41
|
+
# form. Exit 0 = pass · 1 = a stage failed · 3 = nothing failed but something
|
|
42
|
+
# was not proven (unrun / pending human).
|
|
43
|
+
#
|
|
44
|
+
# THE LANE IS PART OF THE RECEIPT. A fast pass is never reported as a full pass:
|
|
45
|
+
# the receipt and the last line carry `lane:<fast|full|test|none>` beside
|
|
46
|
+
# `verdict:<ok|red|unrun>`, which is exactly the pair the executor writes onto
|
|
47
|
+
# the task with tasks:tag (§ Tests, T4).
|
|
48
|
+
#
|
|
49
|
+
# Usage:
|
|
50
|
+
# factory-walk.sh <slug> [--files <path>...] [--route </path>]...
|
|
51
|
+
# [--preview <url>] [--no-gate] [--humans] [--json <file>]
|
|
52
|
+
# factory-walk.sh --self-test
|
|
53
|
+
#
|
|
54
|
+
# <slug> names text/<slug>-agents.md / -humans.md when they exist, and
|
|
55
|
+
# the receipt. Any word; a task id is fine.
|
|
56
|
+
# --files the changed paths (default: git diff HEAD + untracked, from
|
|
57
|
+
# the repo this script lives in — a worktree checks itself)
|
|
58
|
+
# --route a route to prove; repeatable. Derived from changed
|
|
59
|
+
# src/pages/**.astro when omitted (dynamic [param] routes are
|
|
60
|
+
# skipped and named — pass them explicitly)
|
|
61
|
+
# --preview the task's private server, from worktree-preview.sh up
|
|
62
|
+
# (default http://localhost:4321 — the human's server)
|
|
63
|
+
# --no-gate record the gate as UNRUN instead of running it (a read of the
|
|
64
|
+
# other stages; never a pass)
|
|
65
|
+
# --humans on a tty, ask y/n per stop and record the human verdict
|
|
66
|
+
# --json where the receipt goes (default $TMPDIR/one-factory-walk/<slug>.json)
|
|
67
|
+
#
|
|
68
|
+
# Env, self-test only (the TSC_CACHE_CMD idiom): FACTORY_WALK_TIER_CMD,
|
|
69
|
+
# FACTORY_WALK_GATE_CMD, FACTORY_WALK_PROVE_CMD, FACTORY_WALK_SUBSTRATE_CMD
|
|
70
|
+
# substitute the stage's command so every state can be driven deterministically,
|
|
71
|
+
# and FACTORY_WALK_DROP_ROW=<stage> drops a row to prove the missing-row trap
|
|
72
|
+
# bites. None of them is read outside --self-test.
|
|
73
|
+
set -uo pipefail
|
|
74
|
+
|
|
75
|
+
ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
|
|
76
|
+
S="$ROOT/.claude/scripts"
|
|
77
|
+
cd "$ROOT" || exit 2
|
|
78
|
+
|
|
79
|
+
# ---------------------------------------------------------------------------
|
|
80
|
+
# self-test — every state driven, and the two red proofs that matter
|
|
81
|
+
# ---------------------------------------------------------------------------
|
|
82
|
+
if [ "${1:-}" = "--self-test" ]; then
|
|
83
|
+
fails=0; T="$(mktemp -d)"
|
|
84
|
+
ok() { printf ' ok %s\n' "$*"; }
|
|
85
|
+
bad() { printf ' FAIL %s\n' "$*"; fails=$((fails+1)); }
|
|
86
|
+
# stubs: a tier, a gate, a prove, a substrate check — each a tiny script
|
|
87
|
+
printf '#!/bin/bash\necho "{\\"tier\\":\\"%s\\"}"; exit %s\n' FIX 0 > "$T/tier-fix"; chmod +x "$T/tier-fix"
|
|
88
|
+
printf '#!/bin/bash\necho "{\\"tier\\":\\"%s\\"}"; exit %s\n' SCHEMA 0 > "$T/tier-schema"; chmod +x "$T/tier-schema"
|
|
89
|
+
printf '#!/bin/bash\necho "{\\"tier\\":\\"%s\\"}"; exit %s\n' UNSIZED 3 > "$T/tier-unsized"; chmod +x "$T/tier-unsized"
|
|
90
|
+
for rc in 0 1 3 144; do printf '#!/bin/bash\nexit %s\n' "$rc" > "$T/rc$rc"; chmod +x "$T/rc$rc"; done
|
|
91
|
+
printf '#!/bin/bash\necho "PROVE: skipped (no reachable environment)"; exit 0\n' > "$T/prove-skipped"; chmod +x "$T/prove-skipped"
|
|
92
|
+
printf '#!/bin/bash\necho "PROVE: pass (1 route(s) proven)"; exit 0\n' > "$T/prove-pass"; chmod +x "$T/prove-pass"
|
|
93
|
+
run() { # run <expected-exit> <label> <env...> -- <args...>
|
|
94
|
+
local want="$1" label="$2"; shift 2
|
|
95
|
+
local envs=(); while [ "$1" != "--" ]; do envs+=("$1"); shift; done; shift
|
|
96
|
+
local out rc
|
|
97
|
+
out="$(env "${envs[@]+"${envs[@]}"}" FACTORY_WALK_SELFTEST=1 bash "$0" "$@" --json "$T/r.json" 2>&1)"; rc=$?
|
|
98
|
+
if [ "$rc" = "$want" ]; then ok "$label (exit $rc)"; else bad "$label — expected exit $want, got $rc"; printf '%s\n' "$out" | tail -8 | sed 's/^/ /'; fi
|
|
99
|
+
LAST_OUT="$out"
|
|
100
|
+
}
|
|
101
|
+
COMMON=(FACTORY_WALK_SUBSTRATE_CMD="$T/rc0" FACTORY_WALK_PROVE_CMD="$T/rc0")
|
|
102
|
+
|
|
103
|
+
echo "== green: a FIX with every stage answering"
|
|
104
|
+
run 0 "non-UI FIX, gate green, walk green" FACTORY_WALK_TIER_CMD="$T/tier-fix" FACTORY_WALK_GATE_CMD="$T/rc0" "${COMMON[@]}" -- selftest --files one.ie/web/src/lib/x.ts
|
|
105
|
+
jq -e '.verdict=="ok" and .lane=="fast" and .tier=="FIX"' "$T/r.json" >/dev/null && ok "receipt carries verdict:ok lane:fast tier:FIX" || bad "receipt wrong: $(cat "$T/r.json")"
|
|
106
|
+
|
|
107
|
+
echo "== RED PROOFS: the walk must be able to lose"
|
|
108
|
+
run 1 "gate exits 1 → verdict red, exit 1" FACTORY_WALK_TIER_CMD="$T/tier-fix" FACTORY_WALK_GATE_CMD="$T/rc1" "${COMMON[@]}" -- selftest --files one.ie/web/src/lib/x.ts
|
|
109
|
+
jq -e '.verdict=="red"' "$T/r.json" >/dev/null && ok "receipt says red" || bad "receipt did not say red"
|
|
110
|
+
run 3 "gate exits 144 (unrun) → NOT a pass, exit 3" FACTORY_WALK_TIER_CMD="$T/tier-fix" FACTORY_WALK_GATE_CMD="$T/rc144" "${COMMON[@]}" -- selftest --files one.ie/web/src/lib/x.ts
|
|
111
|
+
jq -e '.stages[]|select(.stage=="gate")|.status=="unrun"' "$T/r.json" >/dev/null && ok "144 is recorded as unrun" || bad "144 not recorded as unrun"
|
|
112
|
+
run 1 "no paths → UNSIZED → FAIL (absence of recon is not simplicity)" FACTORY_WALK_TIER_CMD="$T/tier-unsized" FACTORY_WALK_GATE_CMD="$T/rc0" "${COMMON[@]}" -- selftest --files one.ie/web/src/lib/x.ts
|
|
113
|
+
run 3 "--no-gate → gate unrun → exit 3, never 0" FACTORY_WALK_TIER_CMD="$T/tier-fix" FACTORY_WALK_GATE_CMD="$T/rc0" "${COMMON[@]}" -- selftest --files one.ie/web/src/lib/x.ts --no-gate
|
|
114
|
+
run 3 "a dropped stage row reads as unrun, never as pass" FACTORY_WALK_TIER_CMD="$T/tier-fix" FACTORY_WALK_GATE_CMD="$T/rc0" FACTORY_WALK_DROP_ROW=gate "${COMMON[@]}" -- selftest --files one.ie/web/src/lib/x.ts
|
|
115
|
+
case "$LAST_OUT" in *"no row for gate"*) ok "the missing row is NAMED" ;; *) bad "missing row not named" ;; esac
|
|
116
|
+
|
|
117
|
+
echo "== UI: the human gets a link and the walk is PENDING until they answer"
|
|
118
|
+
run 3 "UI change, prove skipped, no human yet → exit 3" FACTORY_WALK_TIER_CMD="$T/tier-fix" FACTORY_WALK_GATE_CMD="$T/rc0" FACTORY_WALK_PROVE_CMD="$T/prove-skipped" FACTORY_WALK_SUBSTRATE_CMD="$T/rc0" -- selftest --files one.ie/web/src/pages/factory.astro --preview http://localhost:4399
|
|
119
|
+
case "$LAST_OUT" in *"HUMAN WALK"*"http://localhost:4399/factory"*"factory-walk.sh selftest --humans"*) ok "link block: URL, route, and the record-the-verdict instruction" ;; *) bad "link block missing pieces"; printf '%s\n' "$LAST_OUT" | grep -n 'HUMAN\|http' | head -5 ;; esac
|
|
120
|
+
jq -e '.stages[]|select(.stage=="prove")|.status=="unrun"' "$T/r.json" >/dev/null && ok "a skipped prove is unrun (do-prove exits 0 on skip — the walk reads the line, not the code)" || bad "skipped prove misread"
|
|
121
|
+
run 3 "UI, prove PASS, human pending → still exit 3 (a person has not looked)" FACTORY_WALK_TIER_CMD="$T/tier-fix" FACTORY_WALK_GATE_CMD="$T/rc0" FACTORY_WALK_PROVE_CMD="$T/prove-pass" FACTORY_WALK_SUBSTRATE_CMD="$T/rc0" -- selftest --files one.ie/web/src/pages/factory.astro --preview http://localhost:4399
|
|
122
|
+
jq -e '.stages[]|select(.stage=="human")|.status=="unrun" and (.detail|test("PENDING"))' "$T/r.json" >/dev/null && ok "human stage is PENDING, counted as unrun" || bad "human stage not pending"
|
|
123
|
+
run 3 "a dynamic [param] page with no --route is unrun and named" FACTORY_WALK_TIER_CMD="$T/tier-fix" FACTORY_WALK_GATE_CMD="$T/rc0" FACTORY_WALK_PROVE_CMD="$T/prove-pass" FACTORY_WALK_SUBSTRATE_CMD="$T/rc0" -- selftest --files 'one.ie/web/src/pages/u/[slug]/tasks.astro'
|
|
124
|
+
case "$LAST_OUT" in *"pass --route"*) ok "the fix is named in the output" ;; *) bad "dynamic route not named" ;; esac
|
|
125
|
+
|
|
126
|
+
echo "== SCHEMA: the substrate check joins, and a 3 is cannot-run"
|
|
127
|
+
run 3 "schema tier, substrate exits 3 → unrun" FACTORY_WALK_TIER_CMD="$T/tier-schema" FACTORY_WALK_GATE_CMD="$T/rc0" FACTORY_WALK_PROVE_CMD="$T/rc0" FACTORY_WALK_SUBSTRATE_CMD="$T/rc3" -- selftest --files schema/one.tql
|
|
128
|
+
jq -e '.lane=="full"' "$T/r.json" >/dev/null && ok "SCHEMA takes the FULL lane" || bad "SCHEMA did not take the full lane: $(jq -r .lane "$T/r.json")"
|
|
129
|
+
run 1 "schema tier, substrate exits 1 → red" FACTORY_WALK_TIER_CMD="$T/tier-schema" FACTORY_WALK_GATE_CMD="$T/rc0" FACTORY_WALK_PROVE_CMD="$T/rc0" FACTORY_WALK_SUBSTRATE_CMD="$T/rc1" -- selftest --files schema/one.tql
|
|
130
|
+
|
|
131
|
+
echo "== doc-only: no gate by rule (n/a), and n/a is not unrun"
|
|
132
|
+
run 0 "a text/ change: gate n/a, prove via walk stub, pass" FACTORY_WALK_TIER_CMD="$T/tier-fix" FACTORY_WALK_GATE_CMD="$T/rc1" "${COMMON[@]}" -- selftest --files text/factory-do.md
|
|
133
|
+
jq -e '.stages[]|select(.stage=="gate")|.status=="n/a"' "$T/r.json" >/dev/null && ok "doc-only gate is n/a (the red stub was never run)" || bad "doc-only gate not n/a"
|
|
134
|
+
|
|
135
|
+
rm -rf "$T"
|
|
136
|
+
[ "$fails" -eq 0 ] && { echo "factory-walk: self-test PASS"; exit 0; }
|
|
137
|
+
echo "factory-walk: self-test FAILED ($fails)"; exit 1
|
|
138
|
+
fi
|
|
139
|
+
|
|
140
|
+
# ---------------------------------------------------------------------------
|
|
141
|
+
# args
|
|
142
|
+
# ---------------------------------------------------------------------------
|
|
143
|
+
slug=""; files=(); routes=(); preview="${FACTORY_WALK_PREVIEW:-http://localhost:4321}"
|
|
144
|
+
no_gate=0; humans=0; json_out=""
|
|
145
|
+
while [ "$#" -gt 0 ]; do
|
|
146
|
+
case "$1" in
|
|
147
|
+
--files) shift; while [ "$#" -gt 0 ] && [ "${1#--}" = "$1" ]; do files+=("$1"); shift; done ;;
|
|
148
|
+
--route) routes+=("$2"); shift 2 ;;
|
|
149
|
+
--preview) preview="${2%/}"; shift 2 ;;
|
|
150
|
+
--no-gate) no_gate=1; shift ;;
|
|
151
|
+
--humans) humans=1; shift ;;
|
|
152
|
+
--json) json_out="$2"; shift 2 ;;
|
|
153
|
+
--*) echo "factory-walk: unknown flag $1" >&2; exit 2 ;;
|
|
154
|
+
*) [ -z "$slug" ] && slug="$1" || { echo "factory-walk: one slug only" >&2; exit 2; }; shift ;;
|
|
155
|
+
esac
|
|
156
|
+
done
|
|
157
|
+
[ -n "$slug" ] || { sed -n '2,3p;42,60p' "$0" >&2; exit 2; }
|
|
158
|
+
[ -n "$json_out" ] || { mkdir -p "${TMPDIR:-/tmp}/one-factory-walk"; json_out="${TMPDIR:-/tmp}/one-factory-walk/$slug.json"; }
|
|
159
|
+
selftest="${FACTORY_WALK_SELFTEST:-0}"
|
|
160
|
+
|
|
161
|
+
if [ "${#files[@]}" -eq 0 ]; then
|
|
162
|
+
while IFS= read -r f; do [ -n "$f" ] && files+=("$f"); done < <(
|
|
163
|
+
{ git diff --name-only HEAD 2>/dev/null; git ls-files --others --exclude-standard 2>/dev/null; } | sort -u)
|
|
164
|
+
fi
|
|
165
|
+
|
|
166
|
+
# ---------------------------------------------------------------------------
|
|
167
|
+
# receipt rows — jq lines, exactly the do-w4-gates.sh shape
|
|
168
|
+
# ---------------------------------------------------------------------------
|
|
169
|
+
ROWS="$(mktemp)"; trap 'rm -f "$ROWS"' EXIT
|
|
170
|
+
_add() { # stage status detail
|
|
171
|
+
[ "$selftest" = "1" ] && [ "${FACTORY_WALK_DROP_ROW:-}" = "$1" ] && return 0
|
|
172
|
+
jq -n --arg s "$1" --arg st "$2" --arg d "$3" '{stage:$s,status:$st,detail:$d}' >> "$ROWS"
|
|
173
|
+
printf ' %-9s %-6s %s\n' "$1" "$2" "$3"
|
|
174
|
+
}
|
|
175
|
+
_cmd() { # _cmd <ENV_NAME> <default...> — self-test substitution only
|
|
176
|
+
local v="$1"; shift
|
|
177
|
+
if [ "$selftest" = "1" ] && [ -n "${!v:-}" ]; then printf '%s' "${!v}"; else printf '%s' "$*"; fi
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
echo "FACTORY-WALK: $slug · ${#files[@]} file(s) · preview $preview"
|
|
181
|
+
|
|
182
|
+
# ---------------------------------------------------------------------------
|
|
183
|
+
# 1. size — the fork everything else hangs off
|
|
184
|
+
# ---------------------------------------------------------------------------
|
|
185
|
+
tier="UNKNOWN"
|
|
186
|
+
_tier_cmd="$(_cmd FACTORY_WALK_TIER_CMD bash "$S/do-tier.sh")"
|
|
187
|
+
_tier_out="$(printf '%s\n' "${files[@]}" | $_tier_cmd 2>/dev/null)"; _tier_rc=$?
|
|
188
|
+
tier="$(printf '%s' "$_tier_out" | jq -r '.tier // "UNKNOWN"' 2>/dev/null || echo UNKNOWN)"
|
|
189
|
+
if [ "$_tier_rc" -eq 3 ] || [ "$tier" = "UNSIZED" ]; then
|
|
190
|
+
_add size fail "UNSIZED — no paths to size; absence of recon must never read as simplicity (do-tier.sh exit 3)"
|
|
191
|
+
elif [ "$_tier_rc" -ne 0 ] || [ "$tier" = "UNKNOWN" ]; then
|
|
192
|
+
_add size unrun "do-tier.sh could not answer (exit $_tier_rc)"
|
|
193
|
+
else
|
|
194
|
+
_add size pass "tier=$tier"
|
|
195
|
+
fi
|
|
196
|
+
|
|
197
|
+
# surface — from the paths, by rule
|
|
198
|
+
ui=0; substrate=0; full=0; doc_only=1; pages=()
|
|
199
|
+
for f in "${files[@]}"; do
|
|
200
|
+
case "$f" in
|
|
201
|
+
one.ie/web/src/pages/*|one.ie/web/src/components/*|one.ie/web/src/layouts/*|*.astro) ui=1 ;;
|
|
202
|
+
esac
|
|
203
|
+
case "$f" in schema/*|*.tql) substrate=1 ;; esac
|
|
204
|
+
case "$f" in schema/*|packages/sdk/*|*auth*|*authority*|*roles*) full=1 ;; esac
|
|
205
|
+
case "$f" in *.md|.claude/*|text/*|docs/*) ;; *) doc_only=0 ;; esac
|
|
206
|
+
case "$f" in one.ie/web/src/pages/*.astro) pages+=("$f") ;; esac
|
|
207
|
+
done
|
|
208
|
+
[ "$tier" = "SCHEMA" ] && full=1
|
|
209
|
+
# derive routes from the changed pages
|
|
210
|
+
for pg in "${pages[@]+"${pages[@]}"}"; do
|
|
211
|
+
r="${pg#one.ie/web/src/pages}"; r="${r%.astro}"; r="${r%/index}"; [ -z "$r" ] && r="/"
|
|
212
|
+
case "$r" in *\[*) echo " route note $pg is dynamic — pass --route <concrete path> to prove it"; dyn=1; continue ;; esac
|
|
213
|
+
routes+=("$r")
|
|
214
|
+
done
|
|
215
|
+
dyn="${dyn:-0}"
|
|
216
|
+
|
|
217
|
+
# ---------------------------------------------------------------------------
|
|
218
|
+
# 2. isolate — a UI task lives in a worktree with local caches
|
|
219
|
+
# ---------------------------------------------------------------------------
|
|
220
|
+
if [ "$ui" -eq 1 ] && [ "$selftest" != "1" ]; then
|
|
221
|
+
_common="$(git rev-parse --path-format=absolute --git-common-dir 2>/dev/null || true)"
|
|
222
|
+
if [ -n "$_common" ] && [ "$(dirname "$_common")" != "$ROOT" ]; then
|
|
223
|
+
if bash "$S/worktree-preview.sh" check --dir "$ROOT/one.ie/web" >/dev/null 2>&1; then
|
|
224
|
+
_add isolate pass "linked worktree, per-entry node_modules, local .vite/.astro"
|
|
225
|
+
else
|
|
226
|
+
_add isolate fail "worktree-preview.sh check RED — see \`worktree-preview.sh check --dir $ROOT/one.ie/web\`"
|
|
227
|
+
fi
|
|
228
|
+
else
|
|
229
|
+
_add isolate n/a "main checkout — the human's tree; a task's build goes in a worktree (§ Concurrency)"
|
|
230
|
+
fi
|
|
231
|
+
elif [ "$ui" -eq 1 ]; then
|
|
232
|
+
_add isolate n/a "self-test"
|
|
233
|
+
else
|
|
234
|
+
_add isolate n/a "not a UI change"
|
|
235
|
+
fi
|
|
236
|
+
|
|
237
|
+
# ---------------------------------------------------------------------------
|
|
238
|
+
# 3. gate — the tier's lane, per folder, through the governor and the memo
|
|
239
|
+
# ---------------------------------------------------------------------------
|
|
240
|
+
lane="none"
|
|
241
|
+
if [ "$doc_only" -eq 1 ]; then
|
|
242
|
+
_add gate n/a "doc-only change — no gate by rule (do-folder.sh)"
|
|
243
|
+
elif [ "$no_gate" -eq 1 ]; then
|
|
244
|
+
_add gate unrun "--no-gate: the lane was not run (a read, never a pass)"
|
|
245
|
+
lane="$([ "$full" -eq 1 ] && echo full || echo fast)"
|
|
246
|
+
else
|
|
247
|
+
lane="$([ "$full" -eq 1 ] && echo full || echo fast)"
|
|
248
|
+
_gate_cmd="$(_cmd FACTORY_WALK_GATE_CMD "")"
|
|
249
|
+
if [ -n "$_gate_cmd" ]; then
|
|
250
|
+
$_gate_cmd "$lane" >/dev/null 2>&1; _g=$?
|
|
251
|
+
case "$_g" in
|
|
252
|
+
0) _add gate pass "lane=$lane (stub)" ;;
|
|
253
|
+
144) _add gate unrun "lane=$lane exit 144 — the gate could not run (queued out / killed); not red, not green" ;;
|
|
254
|
+
*) _add gate fail "lane=$lane exit $_g" ;;
|
|
255
|
+
esac
|
|
256
|
+
else
|
|
257
|
+
_gfail=0; _gunrun=0; _gran=0
|
|
258
|
+
while IFS= read -r row; do
|
|
259
|
+
folder="$(printf '%s' "$row" | jq -r '.folder // empty')"; [ -n "$folder" ] || continue
|
|
260
|
+
[ -d "$ROOT/$folder" ] || { _add gate unrun "$folder: not on disk"; _gunrun=1; continue; }
|
|
261
|
+
_log="$(mktemp)"
|
|
262
|
+
if jq -e '.scripts["verify:fast"]' "$ROOT/$folder/package.json" >/dev/null 2>&1; then
|
|
263
|
+
( cd "$ROOT/$folder" && FULL_VERIFY="$( [ "$lane" = full ] && echo 1 || echo 0 )" bun run verify:fast ) > "$_log" 2>&1; _g=$?
|
|
264
|
+
_lane_ran="$lane"
|
|
265
|
+
elif jq -e '.scripts.test' "$ROOT/$folder/package.json" >/dev/null 2>&1; then
|
|
266
|
+
( cd "$ROOT/$folder" && bun run test ) > "$_log" 2>&1; _g=$?
|
|
267
|
+
_lane_ran="test"; lane="test"
|
|
268
|
+
else
|
|
269
|
+
_add gate unrun "$folder: no verify:fast or test script"; _gunrun=1; rm -f "$_log"; continue
|
|
270
|
+
fi
|
|
271
|
+
_gran=1
|
|
272
|
+
case "$_g" in
|
|
273
|
+
0) _add gate pass "$folder lane=$_lane_ran — $(grep -o 'PASS ([^)]*)\|cache HIT[^—]*\|typecheck: 0 errors' "$_log" | tail -1)" ;;
|
|
274
|
+
144) _add gate unrun "$folder lane=$_lane_ran exit 144 — could not run (queued out or killed); log $_log"; _gunrun=1 ;;
|
|
275
|
+
*) _add gate fail "$folder lane=$_lane_ran exit $_g — $(grep -m1 'FAILED\|FAIL\|error' "$_log" | cut -c1-120); log $_log" ; _gfail=1 ;;
|
|
276
|
+
esac
|
|
277
|
+
[ "$_g" -eq 0 ] && rm -f "$_log"
|
|
278
|
+
done < <(printf '%s\n' "${files[@]}" | bash "$S/do-folder.sh" 2>/dev/null | jq -c 'select(.folder != null)')
|
|
279
|
+
[ "$_gran" -eq 0 ] && [ "$_gfail" -eq 0 ] && [ "$_gunrun" -eq 0 ] && _add gate unrun "no folder mapped — do-folder.sh answered nothing for these paths"
|
|
280
|
+
fi
|
|
281
|
+
fi
|
|
282
|
+
|
|
283
|
+
# ---------------------------------------------------------------------------
|
|
284
|
+
# 4. prove — routes with the landing rule, or the slug's agents walk
|
|
285
|
+
# ---------------------------------------------------------------------------
|
|
286
|
+
if [ "$ui" -eq 1 ]; then
|
|
287
|
+
if [ "${#routes[@]}" -eq 0 ]; then
|
|
288
|
+
_add prove unrun "UI change with no provable route$([ "$dyn" = 1 ] && echo ' (dynamic page)') — pass --route </path>"
|
|
289
|
+
else
|
|
290
|
+
_prove_cmd="$(_cmd FACTORY_WALK_PROVE_CMD bash "$S/do-prove.sh")"
|
|
291
|
+
_rargs=(); for r in "${routes[@]}"; do _rargs+=(--route "$r"); done
|
|
292
|
+
_pout="$(PROVE_BASE_URL="$preview" $_prove_cmd "${_rargs[@]}" 2>&1)"; _p=$?
|
|
293
|
+
case "$_pout" in
|
|
294
|
+
*"PROVE: skipped"*|*"PROVE: no changes"*) _add prove unrun "do-prove.sh skipped — no reachable environment at $preview (exit 0 there is NOT a pass)" ;;
|
|
295
|
+
*) if [ "$_p" -eq 0 ]; then _add prove pass "${#routes[@]} route(s) at $preview, landing rule held"
|
|
296
|
+
else _add prove fail "$(printf '%s\n' "$_pout" | grep -m1 'PROVE: FAIL' | cut -c1-140)"; fi ;;
|
|
297
|
+
esac
|
|
298
|
+
fi
|
|
299
|
+
else
|
|
300
|
+
_prove_cmd="$(_cmd FACTORY_WALK_PROVE_CMD "")"
|
|
301
|
+
if [ -n "$_prove_cmd" ]; then
|
|
302
|
+
$_prove_cmd >/dev/null 2>&1; _p=$?
|
|
303
|
+
case "$_p" in 0) _add prove pass "agents walk (stub)";; 3) _add prove unrun "walk could not run (stub 3)";; *) _add prove fail "walk failed (stub $_p)";; esac
|
|
304
|
+
elif [ -f "$ROOT/text/$slug-agents.md" ]; then
|
|
305
|
+
_wout="$(WALK_BASE_URL="$preview" bash "$S/do-walk.sh" "$slug" --agents --strict 2>&1)"; _p=$?
|
|
306
|
+
case "$_p" in
|
|
307
|
+
0) _add prove pass "$(printf '%s\n' "$_wout" | grep -m1 '^WALK: pass')" ;;
|
|
308
|
+
3) _add prove unrun "$(printf '%s\n' "$_wout" | grep -m1 'could not be run' | cut -c1-140)" ;;
|
|
309
|
+
*) _add prove fail "$(printf '%s\n' "$_wout" | grep -m1 '^WALK: FAIL' | cut -c1-140)" ;;
|
|
310
|
+
esac
|
|
311
|
+
else
|
|
312
|
+
_add prove unrun "no text/$slug-agents.md — write the walk (one stop per deliverable, expect_cmd = the accept:)"
|
|
313
|
+
fi
|
|
314
|
+
fi
|
|
315
|
+
|
|
316
|
+
# ---------------------------------------------------------------------------
|
|
317
|
+
# 5. human — UI only: the link, the stops, and how the verdict lands
|
|
318
|
+
# ---------------------------------------------------------------------------
|
|
319
|
+
if [ "$ui" -eq 1 ]; then
|
|
320
|
+
hdoc="$ROOT/text/$slug-humans.md"
|
|
321
|
+
echo
|
|
322
|
+
echo "── HUMAN WALK — $slug ──────────────────────────────────────────────"
|
|
323
|
+
echo " open: $preview${routes[0]:-/}"
|
|
324
|
+
if [ -f "$hdoc" ]; then
|
|
325
|
+
WALK_BASE_URL="$preview" bash "$S/do-walk.sh" "$slug" --humans --list 2>/dev/null | sed -n '2,$p' | sed 's/^/ /'
|
|
326
|
+
else
|
|
327
|
+
i=0
|
|
328
|
+
for r in "${routes[@]+"${routes[@]}"}"; do
|
|
329
|
+
i=$((i+1)); echo " $i. $preview$r"
|
|
330
|
+
echo " · the page you land on IS $r (a bounce to /signin proves nothing — sign in first)"
|
|
331
|
+
echo " · the change this task describes is visible and behaves; no console errors (⌥⌘I)"
|
|
332
|
+
done
|
|
333
|
+
[ "$i" -eq 0 ] && echo " (no route derived — open the preview and the page this task changed)"
|
|
334
|
+
echo " No text/$slug-humans.md yet — one \`\`\`walk block per stop makes this list yours."
|
|
335
|
+
fi
|
|
336
|
+
echo " record: bash .claude/scripts/factory-walk.sh $slug --humans # asks y/n per stop on a tty"
|
|
337
|
+
echo " or: signal(\"tasks:tag\", { tid, tags: [\"verdict:ok\"] }) # or verdict:red — lands on the task"
|
|
338
|
+
echo "────────────────────────────────────────────────────────────────────"
|
|
339
|
+
echo
|
|
340
|
+
if [ "$humans" -eq 1 ] && [ -t 0 ] && [ -f "$hdoc" ]; then
|
|
341
|
+
if WALK_BASE_URL="$preview" bash "$S/do-walk.sh" "$slug" --humans; then _add human pass "a person walked every stop and said ok"
|
|
342
|
+
else _add human fail "a person rejected a stop"; fi
|
|
343
|
+
elif [ "$humans" -eq 1 ] && [ -t 0 ]; then
|
|
344
|
+
printf ' verified in the browser? [y/n] '; read -r v || v=n
|
|
345
|
+
case "$v" in y|Y|yes) _add human pass "a person looked and said ok" ;; *) _add human fail "a person looked and said red" ;; esac
|
|
346
|
+
else
|
|
347
|
+
_add human unrun "PENDING — a person has not looked; the link block above is the instruction"
|
|
348
|
+
fi
|
|
349
|
+
else
|
|
350
|
+
_add human n/a "not a UI change"
|
|
351
|
+
fi
|
|
352
|
+
|
|
353
|
+
# ---------------------------------------------------------------------------
|
|
354
|
+
# 6. substrate — SCHEMA tier: the ladder is live, and a 3 is cannot-run
|
|
355
|
+
# ---------------------------------------------------------------------------
|
|
356
|
+
if [ "$substrate" -eq 1 ] || [ "$tier" = "SCHEMA" ]; then
|
|
357
|
+
_sub_cmd="$(_cmd FACTORY_WALK_SUBSTRATE_CMD bash "$S/factory-check.sh" schema-live)"
|
|
358
|
+
$_sub_cmd >/dev/null 2>&1; _s=$?
|
|
359
|
+
case "$_s" in
|
|
360
|
+
0) _add substrate pass "factory-check.sh schema-live" ;;
|
|
361
|
+
3) _add substrate unrun "factory-check.sh could not reach the substrate (3) — nothing proven either way" ;;
|
|
362
|
+
*) _add substrate fail "factory-check.sh schema-live RED (exit $_s)" ;;
|
|
363
|
+
esac
|
|
364
|
+
else
|
|
365
|
+
_add substrate n/a "not a schema change"
|
|
366
|
+
fi
|
|
367
|
+
|
|
368
|
+
# ---------------------------------------------------------------------------
|
|
369
|
+
# verdict — zero fails AND zero unruns, over exactly the six rows
|
|
370
|
+
# ---------------------------------------------------------------------------
|
|
371
|
+
fails=$(jq -s '[.[]|select(.status=="fail")]|length' "$ROWS")
|
|
372
|
+
unruns=$(jq -s '[.[]|select(.status=="unrun")]|length' "$ROWS")
|
|
373
|
+
missing=0
|
|
374
|
+
for st in size isolate gate prove human substrate; do
|
|
375
|
+
if [ "$(jq -r --arg s "$st" 'select(.stage==$s)|.stage' "$ROWS" 2>/dev/null | head -1)" != "$st" ]; then
|
|
376
|
+
echo " $st unrun no row for $st — an absent row is the fail-open trap in data form"
|
|
377
|
+
missing=$((missing+1))
|
|
378
|
+
fi
|
|
379
|
+
done
|
|
380
|
+
unruns=$((unruns + missing))
|
|
381
|
+
if [ "$fails" -gt 0 ]; then verdict=red; rc=1
|
|
382
|
+
elif [ "$unruns" -gt 0 ]; then verdict=unrun; rc=3
|
|
383
|
+
else verdict=ok; rc=0; fi
|
|
384
|
+
|
|
385
|
+
jq -n --arg slug "$slug" --arg tier "$tier" --arg lane "$lane" --arg verdict "$verdict" \
|
|
386
|
+
--arg preview "$preview" --arg ts "$(date -u +%Y-%m-%dT%H:%M:%SZ)" \
|
|
387
|
+
--argjson ui "$ui" --argjson fails "$fails" --argjson unruns "$unruns" \
|
|
388
|
+
--slurpfile rows "$ROWS" \
|
|
389
|
+
'{slug:$slug, ts:$ts, tier:$tier, lane:$lane, verdict:$verdict, ui:($ui==1), preview:$preview,
|
|
390
|
+
fails:$fails, unruns:$unruns, stages:$rows}' > "$json_out" 2>/dev/null \
|
|
391
|
+
|| jq -n --arg slug "$slug" --arg verdict "$verdict" --arg lane "$lane" --arg tier "$tier" '{slug:$slug,verdict:$verdict,lane:$lane,tier:$tier,stages:[]}' > "$json_out"
|
|
392
|
+
|
|
393
|
+
echo
|
|
394
|
+
echo "FACTORY-WALK: $verdict — $fails failed · $unruns not proven · tier $tier · receipt $json_out"
|
|
395
|
+
echo "tasks:tag lane:$lane verdict:$verdict # what the executor writes on the task (T4)"
|
|
396
|
+
exit "$rc"
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# factory-width.sh — how many factory tasks this box may build AT ONCE, measured.
|
|
3
|
+
#
|
|
4
|
+
# manifest: portable
|
|
5
|
+
#
|
|
6
|
+
# The Workflow runtime caps a script's concurrency at min(16, cpus-2) — CORES,
|
|
7
|
+
# which were never the binding constraint here (10 cores authorised 8 worktrees
|
|
8
|
+
# on a 24 GB box; 8 cycles is ~16 GB of gates). Two things bind first, and this
|
|
9
|
+
# prints the smaller so the launcher passes it as args.width:
|
|
10
|
+
#
|
|
11
|
+
# memory gate_headroom — MB actually free (vm_stat: free + purgeable + cold
|
|
12
|
+
# cache, never memory_pressure's inflated figure) ÷ the measured price
|
|
13
|
+
# of one cycle. 99 means "the sensor is unreadable — do not constrain".
|
|
14
|
+
# ports the preview range minus what a neighbour already holds. One
|
|
15
|
+
# server per UI task; 4321 is the human's and is never counted.
|
|
16
|
+
#
|
|
17
|
+
# Prints ONE JSON line: {"width":N,"memory":N,"ports":N,"price_mb":N}. Never 0 —
|
|
18
|
+
# work slows, it never stops (the governor's own floor). Exit 0 always; a reader
|
|
19
|
+
# that cannot get a number gets 1, printed, not a crash.
|
|
20
|
+
#
|
|
21
|
+
# bash .claude/scripts/factory-width.sh # {"width":1,...}
|
|
22
|
+
# bash .claude/scripts/factory-width.sh --explain # the same, with the why
|
|
23
|
+
set -uo pipefail
|
|
24
|
+
ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
|
|
25
|
+
LIB="$ROOT/.claude/scripts/lib/govern.sh"
|
|
26
|
+
PORT_MIN="${PREVIEW_PORT_MIN:-4322}"; PORT_MAX="${PREVIEW_PORT_MAX:-4329}"
|
|
27
|
+
|
|
28
|
+
mem=99; price=0
|
|
29
|
+
if [ -f "$LIB" ]; then
|
|
30
|
+
# shellcheck source=lib/govern.sh
|
|
31
|
+
. "$LIB"
|
|
32
|
+
mem="$(gate_headroom 2>/dev/null || echo 99)"
|
|
33
|
+
price="$(gate_price_mb 2>/dev/null || echo 0)"
|
|
34
|
+
fi
|
|
35
|
+
case "$mem" in ''|*[!0-9]*) mem=99 ;; esac
|
|
36
|
+
|
|
37
|
+
ports=0
|
|
38
|
+
if command -v lsof >/dev/null 2>&1; then
|
|
39
|
+
for ((p = PORT_MIN; p <= PORT_MAX; p++)); do
|
|
40
|
+
lsof -nP -iTCP:"$p" -sTCP:LISTEN >/dev/null 2>&1 || ports=$((ports + 1))
|
|
41
|
+
done
|
|
42
|
+
else
|
|
43
|
+
ports=$((PORT_MAX - PORT_MIN + 1)) # no lsof: cannot see neighbours; the range is the cap
|
|
44
|
+
fi
|
|
45
|
+
[ "$ports" -lt 1 ] && ports=1
|
|
46
|
+
|
|
47
|
+
width="$mem"; [ "$ports" -lt "$width" ] && width="$ports"
|
|
48
|
+
[ "$width" -lt 1 ] && width=1
|
|
49
|
+
# 99 is "unconstrained by memory"; the ports then bind, and they always exist.
|
|
50
|
+
[ "$width" -gt 16 ] && width=16
|
|
51
|
+
|
|
52
|
+
printf '{"width":%s,"memory":%s,"ports":%s,"price_mb":%s}\n' "$width" "$mem" "$ports" "$price"
|
|
53
|
+
if [ "${1:-}" = "--explain" ]; then
|
|
54
|
+
echo "width $width = min(memory funds $mem cycle(s) at ${price} MB, $ports free preview port(s) in $PORT_MIN-$PORT_MAX)" >&2
|
|
55
|
+
[ "$mem" = 99 ] && echo "memory sensor unreadable (99) — not constraining; ports bind" >&2
|
|
56
|
+
fi
|
|
57
|
+
exit 0
|
package/scripts/fade-toxic.sh
CHANGED
|
@@ -4,7 +4,8 @@
|
|
|
4
4
|
# Runs every hour via ie.one.fade-toxic.plist:
|
|
5
5
|
# 1. --sync-closes reconcile close-derived weight from learnings.md (idempotent)
|
|
6
6
|
# 2. --fade --rate decay LIVE weight (strength cools, resistance heals 2× faster)
|
|
7
|
-
# 3. regenerate todo.md (
|
|
7
|
+
# 3. regenerate todo.md (this loop is its ONLY writer since 2026-09-05 — the
|
|
8
|
+
# per-edit/Stop/SessionStart hook that also wrote it cost 5.7s a fire)
|
|
8
9
|
# 4. append a one-line toxic report to the log
|
|
9
10
|
#
|
|
10
11
|
# NON-DESTRUCTIVE by contract: fades + reports only. It NEVER deletes a todo, edits a plan,
|
|
@@ -31,7 +32,7 @@ TS=$(date '+%Y-%m-%d %H:%M')
|
|
|
31
32
|
python3 "$RANK" --sync-closes >/dev/null 2>&1 || true
|
|
32
33
|
FADED_LINE=$(python3 "$RANK" --fade --rate "$FADE_RATE" 2>/dev/null | head -1 || true)
|
|
33
34
|
|
|
34
|
-
# 3 — regenerate todo.md
|
|
35
|
+
# 3 — regenerate todo.md. `do-rank.py` is live for anything that needs it fresher than hourly.
|
|
35
36
|
QUEUE_OUT=$(python3 "$RANK" 2>/dev/null || true)
|
|
36
37
|
if [ -n "$QUEUE_OUT" ]; then
|
|
37
38
|
{
|
|
@@ -41,7 +42,7 @@ if [ -n "$QUEUE_OUT" ]; then
|
|
|
41
42
|
echo "$QUEUE_OUT"
|
|
42
43
|
echo '```'
|
|
43
44
|
echo
|
|
44
|
-
echo "> Auto-generated by do-rank.py (hourly fade-toxic loop
|
|
45
|
+
echo "> Auto-generated by do-rank.py (hourly fade-toxic loop). Fresher: python3 .claude/scripts/do-rank.py"
|
|
45
46
|
echo "> Run \`do-rank.py --toxic\` for the demoted list, \`--frontier\` for what's next."
|
|
46
47
|
} > "$ROOT/todo.md"
|
|
47
48
|
fi
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
You are the hand. Build task task:01a07591e5c350a306c93933: "In pages/components add a button > add this component to a page — it shows a list of pages in the workspace, you select the page to add the component, then edit the page or continue adding components".
|
|
2
|
+
Notes from the board:
|
|
3
|
+
SPEC (the title is the whole spec; the row's notes were empty — this brief was assembled by the launching session from a real read of the tree on 2026-09-06, every file:line verified).
|
|
4
|
+
|
|
5
|
+
WHAT TO BUILD
|
|
6
|
+
On /components (the Component Library gallery, ComponentBrowser.tsx), give every block an 'Add to page' affordance. Clicking it opens a picker listing the workspace's pages; choosing one appends that block to that page; after the write, offer two exits — 'Edit page' (link to the page editor) and 'Continue adding components' (dismiss the picker, stay in the gallery).
|
|
7
|
+
|
|
8
|
+
BOTH RECEIVERS ALREADY EXIST — DO NOT WRITE A NEW ONE, DO NOT ADD AN API ROUTE.
|
|
9
|
+
- pages:list — one.ie/web/src/lib/resolvers/pages.ts:670. Request { slug }. Returns { pages: [{ slug, title, status, updated_at }] } ordered by updated_at DESC. This is the picker's list. Returns { pages: [] } on any auth denial.
|
|
10
|
+
- pages:add-block — one.ie/web/src/lib/resolvers/pages.ts:630. Request { slug, page, section: { component, props }, atIndex? }. atIndex omitted = append to end, which is what this feature wants. It already runs normalizeBlockProps(BLOCK_SCHEMA, ...) server-side, so send the block's defaultProps verbatim — do NOT normalize on the client.
|
|
11
|
+
|
|
12
|
+
EXACT CALL-SITE PRECEDENT — copy this shape:
|
|
13
|
+
one.ie/web/src/components/chat/BlockFrame.tsx:112-125. It is the same feature one surface over ('Add to page' from chat). Note its gate: `const canAddToPage = addToPage && !!slug && !!page`, its pending/added state machine, and `emitClick('ui:chat:add-to-page', { component })` before the call. Use `ask` from '@/lib/in/ask'. Emit a sibling signal name, e.g. 'ui:component-browser:add-to-page'.
|
|
14
|
+
|
|
15
|
+
THE ONE DESIGN DECISION, ALREADY SETTLED — DO NOT RE-OPEN IT.
|
|
16
|
+
/components is a genuinely PUBLIC route. pages/components.astro mounts <ComponentBrowser client:only="react" /> with a plain Layout and passes NO props, and ComponentBrowser takes none. It is NOT one of the slugless console pages: those (see pages/tasks.astro) call resolveRoom() and rewrite to /u/[slug]/..., and components.astro does neither. There is also no workspace-scoped mount — ComponentBrowser appears only in pages/components.astro and is referenced by components/puck/BlockFinder.tsx.
|
|
17
|
+
|
|
18
|
+
So: derive the workspace slug SERVER-SIDE in pages/components.astro (from Astro.locals.workspaceContext?.workspace ?? Astro.locals.slug — verify which is right against how another workspace-aware page reads it) and pass it down as an optional `slug` prop to ComponentBrowser. When there is no session there is no slug, and the 'Add to page' button MUST NOT RENDER — same gate shape as BlockFrame's canAddToPage. An anonymous visitor keeps exactly today's public gallery, unchanged. Do NOT invent a client-side workspace read, do NOT add a new route, do NOT make /components members-only.
|
|
19
|
+
|
|
20
|
+
WHERE THE BUTTON GOES
|
|
21
|
+
ComponentBrowser.tsx has two surfaces for a block: the grid card (article, ~line 250) and PreviewModal (~line 143). Put the affordance in the PreviewModal footer at minimum — the modal is the block's detail view and already has a footer row. A card-level quick-add is welcome but must not swallow the card's existing onClick (which opens the preview).
|
|
22
|
+
|
|
23
|
+
DONE LOOKS LIKE
|
|
24
|
+
1. Signed in, /components → open any block → 'Add to page' → picker lists this workspace's real pages → pick one → success state → 'Edit page' and 'Continue adding components' both present and both work.
|
|
25
|
+
2. The block actually lands: re-open that page in the editor and the block is there, rendered, at the end.
|
|
26
|
+
3. Signed out, /components renders exactly as before with no 'Add to page' button anywhere.
|
|
27
|
+
4. `cd one.ie/web && bun run verify:fast` green. Add a unit test for the picker gate (no slug ⇒ no button).
|
|
28
|
+
|
|
29
|
+
CONSTRAINTS
|
|
30
|
+
- 6-token palette only (hook:design-check blocks otherwise) — follow the existing var(--color-border) / text-font / bg-foreground idiom in this very file.
|
|
31
|
+
- Do not regress the IntersectionObserver lazy-mount or the PreviewErrorBoundary; the gallery renders ~376 blocks.
|
|
32
|
+
- Edit in a worktree, never on shared main.
|
|
33
|
+
|
|
34
|
+
RULES, each one a recorded outage (text/factory-do.md § Concurrency):
|
|
35
|
+
1. Work in YOUR OWN worktree, never the shared main tree. Slug: task-task:01a07591e5c350a306c93933.
|
|
36
|
+
UI task — run: bash .claude/scripts/worktree-preview.sh up task-task:01a07591e5c350a306c93933 --route /components
|
|
37
|
+
It cuts the worktree from main, links node_modules CONTENTS (never the dir), copies .env, allocates a port (never sweeps), and hands you a URL only after 3 consecutive 200s. Use the path and URL it prints.
|
|
38
|
+
2. NEVER `bun install` inside the worktree. NEVER symlink node_modules itself.
|
|
39
|
+
3. Make the change the task describes — minimal, in the worktree. Write or extend the test that names the concrete failure this change prevents (input → wrong result). No test that guards a shape.
|
|
40
|
+
4. Run only YOUR test file(s) in the worktree: cd <wt>/one.ie/web && bunx vitest related --run <files> — through bash ../../.claude/scripts/gate-run.sh doer -- … . Do NOT run the suite; factory-walk.sh runs the tier's lane after you.
|
|
41
|
+
5. Commit in the worktree by EXPLICIT PATH (git add <file>...), message: "task(task:01a07591e5c350a306c93933): <what was measured>". Never git add -A.
|
|
42
|
+
6. Report files from `git status --porcelain` / `git show --stat` in the worktree, never from memory.
|
|
43
|
+
7. THE BRAIN AND THE EDGE (root CLAUDE.md, LOCKED): if the change adds or touches a receiver, it reads KV / BrainDO JSON — never typedbQuery — and writes to the brain fire-and-forget or via sync/. resolvers/factory.ts is the one exception. Prove the door: bash .claude/scripts/signal-watch.sh --local (with your preview as SIGNAL_WATCH_LOCAL) — a door over budget or reaching for the brain is red, and red closes nothing.
|
|
44
|
+
If the task cannot be done as written, do the part that can, say exactly what you left out and why, and return committed:false rather than inventing scope.
|