Add onboarding doc-test harness
Disposable rig that runs the global onboarding-tester agent against the developer SDK-integration journey: boots a fresh keysat fixture, mints a merchant-onboard scoped key, serves keysat-docs as the published corpus, scaffolds a pristine Next.js/TS proof-of-work, and has the agent gate it docs-only. Stage 1 (no payments) reached completed-clean over three runs; see onboarding-harness/STAGE1-RESULT.md. Stage 2 (regtest buyer-pays) is gated on the agent-payment-connect scope work.
This commit is contained in:
Executable
+57
@@ -0,0 +1,57 @@
|
||||
#!/usr/bin/env bash
|
||||
# Shared config + helpers for the Keysat onboarding harness.
|
||||
# Sourced by the stage scripts; not run directly.
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
HARNESS_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
# onboarding-harness/ -> licensing-service-startos/ -> workspace root
|
||||
WORKSPACE="$(cd "$HARNESS_DIR/../.." && pwd)"
|
||||
DAEMON_DIR="$WORKSPACE/licensing-service-startos/licensing-service"
|
||||
DAEMON_BIN="$DAEMON_DIR/target/release/keysat"
|
||||
DOCS_DIR="$WORKSPACE/keysat-docs"
|
||||
TEMPLATE_DIR="$HARNESS_DIR/sandbox-template"
|
||||
|
||||
# Per-run scratch lives under runs/ (gitignored). The agent's sandbox copy
|
||||
# lives under /tmp/onboarding-tester/ per the onboarding-tester guide.
|
||||
RUNS_DIR="$HARNESS_DIR/runs"
|
||||
SANDBOX_BASE="/tmp/onboarding-tester"
|
||||
|
||||
# The active run's state file is pointed to by runs/current.
|
||||
CURRENT_LINK="$RUNS_DIR/current"
|
||||
|
||||
log() { printf '\033[1;34m[harness]\033[0m %s\n' "$*" >&2; }
|
||||
ok() { printf '\033[1;32m[ ok ]\033[0m %s\n' "$*" >&2; }
|
||||
warn() { printf '\033[1;33m[warn]\033[0m %s\n' "$*" >&2; }
|
||||
die() { printf '\033[1;31m[fail]\033[0m %s\n' "$*" >&2; exit 1; }
|
||||
|
||||
# state_set KEY VALUE — append/update a KEY=VALUE line in the run state file.
|
||||
# Not concurrency-safe (uses a fixed temp suffix); the stages call it serially.
|
||||
state_set() {
|
||||
local f="$1" k="$2" v="$3"
|
||||
touch "$f"
|
||||
# strip any existing line for this key, then append
|
||||
grep -v "^${k}=" "$f" > "$f.tmp" 2>/dev/null || true
|
||||
mv "$f.tmp" "$f"
|
||||
printf '%s=%s\n' "$k" "$v" >> "$f"
|
||||
}
|
||||
|
||||
# state_get FILE KEY
|
||||
state_get() { grep "^${2}=" "$1" | head -1 | cut -d= -f2-; }
|
||||
|
||||
# free_port — echo an unused TCP port on 127.0.0.1.
|
||||
free_port() {
|
||||
node -e 'const s=require("net").createServer();s.listen(0,"127.0.0.1",()=>{console.log(s.address().port);s.close();});'
|
||||
}
|
||||
|
||||
# wait_http URL TRIES — poll until URL returns 2xx/3xx, or die.
|
||||
wait_http() {
|
||||
local url="$1" tries="${2:-50}" i
|
||||
for i in $(seq 1 "$tries"); do
|
||||
if curl -fsS -o /dev/null "$url" 2>/dev/null; then return 0; fi
|
||||
sleep 0.2
|
||||
done
|
||||
return 1
|
||||
}
|
||||
|
||||
require() { command -v "$1" >/dev/null 2>&1 || die "missing required tool: $1"; }
|
||||
Reference in New Issue
Block a user