Root causes found by reproducing a clean install from keigit:
1. PROFILE_PRIMS resolved only inside check_prereqs → unbound for
--no-execute (plan showed 0 prims for every profile) and silently
empty for --skip-prereqs. Now resolved unconditionally in install.sh
before any reader (SSoT).
2. Every profile (even minimal, advertised "no Rust compile") fell back
to a 5-15 min `cargo build --workspace` because no prebuilt release
binaries exist. Auto-set KEI_SKIP_RUST for profiles with no rust
primitives → minimal installs in ~18s (assembler only). cargo stays a
hard prereq because the agent assembler always compiles.
3. The assembler aborted the WHOLE install on any single bad manifest
(set -e). generate_agents is now tolerant: bad manifests print FAIL
but hooks/skills/settings still land. Commit-time validate stays strict.
4. Data bugs that broke the assembler:
- duplicate [taxonomy] table in _roles/{auditor,merger}.toml
- fal-ai-runner handoff → keimd-expert (not shipped in kit)
- infra-implementer-cicd forbidden_domain literal `${{ secrets.NAME }}`
collided with assembler ${{ }} placeholder detection
5. Metadata: KeiSei84 (nonexistent GitHub org) → KeiSeiLab/KeiSeiKit-1.0
across plugin manifests, bootstrap, README, docs, Cargo/npm metadata.
.claude-plugin/{plugin,marketplace}.json 0.16.0 → 0.38.0. SECURITY.md
supported version 0.14.x → 0.38.x.
feat: ship KeiSei tamagotchi statusline into the kit
- scripts/keisei-pet{,-update}.sh (portable, state under ~/.claude/pet/)
- install copies them to ~/.claude/scripts/
- settings-snippet adds statusLine (set-if-absent, never clobbers an
existing one) + 4 pet-update hooks (prompt/rust_write/github_block/sleep)
Verified: clean minimal install RC=0, zero FAIL, 38 agents + 52 hooks +
68 skills, settings valid, statusLine wired, pet renders, idempotent re-run.
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
133 lines
5.2 KiB
Bash
133 lines
5.2 KiB
Bash
# shellcheck shell=bash
|
|
# lib-rust-prebuild.sh — fresh-install Rust binary acquisition (v0.18+).
|
|
#
|
|
# Purpose: when install.sh runs in a fresh-clone tree, $KIT_DIR/_primitives/
|
|
# _rust/target/release/ is empty (target/ is gitignored). Without binaries,
|
|
# copy_prebuilt_substrate_binaries() in lib-substrate.sh skips silently and
|
|
# end users get no kei-fork / kei-ledger / kei-cortex / etc.
|
|
#
|
|
# Two acquisition paths:
|
|
#
|
|
# Path A — download from latest github release (fast, no Rust required):
|
|
# 1. Detect platform via uname → Rust target triple.
|
|
# 2. Fetch keisei-${TARGET}.tar.gz from
|
|
# https://github.com/KeiSeiLab/KeiSeiKit-1.0/releases/latest/download/
|
|
# 3. Verify sha256.
|
|
# 4. Extract into target/release/.
|
|
#
|
|
# Path B — cargo build --release --workspace fallback (slow, requires Rust):
|
|
# 1. Check `cargo` on PATH.
|
|
# 2. cd $KIT_DIR/_primitives/_rust && cargo build --release --workspace.
|
|
# 3. Slow first install (~5-15 min); subsequent installs are no-op.
|
|
#
|
|
# Path A tried first. On 404 / network fail / sha mismatch → Path B.
|
|
# On both failures → say + return non-zero (caller decides whether to abort).
|
|
#
|
|
# Requires: say from lib-log.sh.
|
|
# Reads globals: $KIT_DIR.
|
|
|
|
# Detect Rust target triple for current host.
|
|
# Echo target triple. Echo nothing on unsupported platform.
|
|
detect_rust_target() {
|
|
local arch os
|
|
arch="$(uname -m)"
|
|
os="$(uname -s)"
|
|
case "$arch" in
|
|
x86_64|amd64) arch="x86_64" ;;
|
|
arm64|aarch64) arch="aarch64" ;;
|
|
*) say " unsupported arch: $arch" >&2; return 1 ;;
|
|
esac
|
|
case "$os" in
|
|
Darwin) echo "${arch}-apple-darwin" ;;
|
|
Linux) echo "${arch}-unknown-linux-gnu" ;;
|
|
*) say " unsupported os: $os" >&2; return 1 ;;
|
|
esac
|
|
}
|
|
|
|
# True iff at least 5 of the kit's substrate-core binaries are pre-built
|
|
# in $KIT_DIR/_primitives/_rust/target/release/. Five is a quorum threshold;
|
|
# a partial build (e.g. user ran `cargo build -p kei-fork` once) is treated
|
|
# as "not pre-built" and we attempt full acquisition.
|
|
has_prebuilt_substrate_binaries() {
|
|
local src="$KIT_DIR/_primitives/_rust/target/release"
|
|
[ -d "$src" ] || return 1
|
|
local count
|
|
count=$(ls -1 "$src" 2>/dev/null | grep -cE '^kei-(fork|ledger|spawn|memory|router|cortex|capability|pet|shared|store|task|search-core|migrate)$' || true)
|
|
[ "${count:-0}" -ge 5 ]
|
|
}
|
|
|
|
# Path A: download release tarball from github.
|
|
# Returns 0 on success (binaries extracted), 1 on any failure (caller falls back).
|
|
download_release_tarball() {
|
|
local target="$1"
|
|
[ -n "$target" ] || return 1
|
|
local tarball="keisei-${target}.tar.gz"
|
|
local url="https://github.com/KeiSeiLab/KeiSeiKit-1.0/releases/latest/download/${tarball}"
|
|
local tmp
|
|
tmp="$(mktemp -d -t keisei-prebuild-XXXX 2>/dev/null)" || return 1
|
|
command -v curl >/dev/null 2>&1 || { rm -rf "$tmp"; return 1; }
|
|
say " downloading prebuilt ${tarball}…"
|
|
if ! curl -fL --max-time 120 -o "$tmp/$tarball" "$url" 2>/dev/null; then
|
|
say " ${tarball} not available (HTTP fail) — falling back to cargo build"
|
|
rm -rf "$tmp"
|
|
return 1
|
|
fi
|
|
if curl -fL --max-time 30 -o "$tmp/${tarball}.sha256" "${url}.sha256" 2>/dev/null; then
|
|
(cd "$tmp" && shasum -a 256 -c "${tarball}.sha256" >/dev/null 2>&1) \
|
|
|| { say " sha256 mismatch on ${tarball} — refusing to install"; rm -rf "$tmp"; return 1; }
|
|
else
|
|
say " ERROR: no sha256 sidecar found at ${url}.sha256"
|
|
say " Refusing to install unverified tarball (RULE 0.1 supply-chain hardening)."
|
|
say " Override with KEI_ALLOW_UNVERIFIED_TARBALL=1 (visible per-call)."
|
|
if [ "${KEI_ALLOW_UNVERIFIED_TARBALL:-0}" = "1" ]; then
|
|
say " KEI_ALLOW_UNVERIFIED_TARBALL=1 set — proceeding without verification (DANGEROUS)."
|
|
else
|
|
rm -rf "$tmp"
|
|
return 1
|
|
fi
|
|
fi
|
|
local dst="$KIT_DIR/_primitives/_rust/target/release"
|
|
mkdir -p "$dst" || { rm -rf "$tmp"; return 1; }
|
|
if ! tar -xzf "$tmp/$tarball" -C "$dst" 2>/dev/null; then
|
|
say " failed to extract ${tarball}"
|
|
rm -rf "$tmp"
|
|
return 1
|
|
fi
|
|
rm -rf "$tmp"
|
|
say " prebuilt binaries installed (Path A) ✓"
|
|
return 0
|
|
}
|
|
|
|
# Path B: cargo build --release --workspace fallback.
|
|
cargo_build_workspace_fallback() {
|
|
command -v cargo >/dev/null 2>&1 \
|
|
|| { say " cargo not on PATH — install Rust: https://rustup.rs/ (or set KEI_SKIP_RUST=1)"; return 1; }
|
|
local crates_dir="$KIT_DIR/_primitives/_rust"
|
|
[ -f "$crates_dir/Cargo.toml" ] || { say " $crates_dir/Cargo.toml missing"; return 1; }
|
|
say " cargo build --release --workspace (slow first time, ~5-15 min)"
|
|
(cd "$crates_dir" && cargo build --release --workspace 2>&1 | tail -3) || {
|
|
say " cargo build failed — see output above"
|
|
return 1
|
|
}
|
|
say " binaries built from source (Path B) ✓"
|
|
return 0
|
|
}
|
|
|
|
# Main entry — call from install.sh BEFORE copy_prebuilt_substrate_binaries.
|
|
# Idempotent: returns 0 immediately if binaries already present.
|
|
ensure_rust_binaries() {
|
|
if has_prebuilt_substrate_binaries; then
|
|
return 0
|
|
fi
|
|
if [ "${KEI_SKIP_RUST:-0}" = "1" ]; then
|
|
say " KEI_SKIP_RUST=1 — skipping Rust binary acquisition"
|
|
return 0
|
|
fi
|
|
say "no prebuilt Rust binaries found — acquiring…"
|
|
local target
|
|
target="$(detect_rust_target)" || target=""
|
|
if [ -n "$target" ] && download_release_tarball "$target"; then
|
|
return 0
|
|
fi
|
|
cargo_build_workspace_fallback
|
|
}
|