forked from heavy-duty/box
feat: emit drill record drafts
This commit is contained in:
parent
54e82e82cc
commit
30e47836ba
5 changed files with 173 additions and 3 deletions
|
|
@ -15,6 +15,7 @@ which records not just what changed but what each drill run proved.
|
|||
|
||||
### Added
|
||||
|
||||
- The hardware drill can emit an uncoloured release-record draft with a shared run ID (#152)
|
||||
- `kimi-box` template — the Moonshot Kimi CLI agent seed (#158; rig#109's tenant)
|
||||
|
||||
## 0.9.0 — 2026-07-21
|
||||
|
|
|
|||
|
|
@ -10,6 +10,8 @@
|
|||
# bash drill/drill.sh --yes # no prompt (CI, or you've read it)
|
||||
# bash drill/drill.sh --ref main # drill a different branch of the repo
|
||||
# bash drill/drill.sh --keep-boxes # leave the boxes up to poke at
|
||||
# --emit-record <path> write an editable Markdown record draft
|
||||
# --run-id <id> share one ID across the family drills
|
||||
#
|
||||
# Four phases:
|
||||
# A. Incus semantics — the assumptions box is built on, probed directly.
|
||||
|
|
@ -36,6 +38,17 @@ REPO="${BOX_REPO:-heavy-duty/box}"
|
|||
REF="${BOX_REF:-main}"
|
||||
YES=0; KEEP=0
|
||||
SELF="$(readlink -f "$0")"
|
||||
EMIT_RECORD="${DRILL_EMIT_RECORD:-}"
|
||||
RUN_ID="${DRILL_RUN_ID:-}"
|
||||
DRILL_STARTED_EPOCH="${DRILL_STARTED_EPOCH:-$(date +%s)}"
|
||||
DRILL_DATE="${DRILL_DATE:-$(date -u +%F)}"
|
||||
if [ -z "${DRILL_INVOCATION:-}" ]; then
|
||||
printf -v DRILL_INVOCATION 'bash %q' "$0"
|
||||
printf -v _drill_args ' %q' "$@"
|
||||
DRILL_INVOCATION+="$_drill_args"
|
||||
fi
|
||||
# shellcheck source=drill/record.sh
|
||||
. "$(dirname "$SELF")/record.sh"
|
||||
|
||||
while [ $# -gt 0 ]; do
|
||||
case "$1" in
|
||||
|
|
@ -43,11 +56,19 @@ while [ $# -gt 0 ]; do
|
|||
--keep-boxes) KEEP=1; shift ;;
|
||||
--repo) REPO="$2"; shift 2 ;;
|
||||
--ref) REF="$2"; shift 2 ;;
|
||||
--emit-record)
|
||||
[ "$#" -ge 2 ] || { echo "drill: --emit-record needs a value" >&2; exit 2; }
|
||||
EMIT_RECORD="$2"; shift 2 ;;
|
||||
--run-id)
|
||||
[ "$#" -ge 2 ] || { echo "drill: --run-id needs a value" >&2; exit 2; }
|
||||
RUN_ID="$2"; shift 2 ;;
|
||||
--in-group) shift; break ;; # internal: see below
|
||||
-h|--help) sed -n '2,18p' "$0" | sed 's/^# \{0,1\}//'; exit 0 ;;
|
||||
-h|--help) sed -n '2,20p' "$0" | sed 's/^# \{0,1\}//'; exit 0 ;;
|
||||
*) echo "drill: unknown option: $1" >&2; exit 2 ;;
|
||||
esac
|
||||
done
|
||||
export DRILL_EMIT_RECORD="$EMIT_RECORD" DRILL_RUN_ID="$RUN_ID"
|
||||
export DRILL_STARTED_EPOCH DRILL_DATE DRILL_INVOCATION
|
||||
|
||||
pass=0; fail=0; findings=(); audit=()
|
||||
ok() { printf ' \033[32mPASS\033[0m %s\n' "$*"; pass=$((pass + 1)); }
|
||||
|
|
@ -280,11 +301,25 @@ EOF
|
|||
# credentials are untouched, so we still have to enter the group ourselves —
|
||||
# once, for the remainder of the drill.
|
||||
inf "re-entering inside the incus-admin group…"
|
||||
exec sg incus-admin -c "IN_GROUP=1 DRILL_OWNS_SETUP='$OWNS' BOX_REPO='$REPO' BOX_REF='$REF' KEEP=$KEEP bash '$SELF' --in-group"
|
||||
printf -v reexec '%q ' env IN_GROUP=1 "DRILL_OWNS_SETUP=$OWNS" \
|
||||
"BOX_REPO=$REPO" "BOX_REF=$REF" "KEEP=$KEEP" \
|
||||
"DRILL_EMIT_RECORD=$EMIT_RECORD" "DRILL_RUN_ID=$RUN_ID" \
|
||||
"DRILL_STARTED_EPOCH=$DRILL_STARTED_EPOCH" "DRILL_DATE=$DRILL_DATE" \
|
||||
"DRILL_INVOCATION=$DRILL_INVOCATION" bash "$SELF" --in-group
|
||||
exec sg incus-admin -c "$reexec"
|
||||
fi
|
||||
|
||||
export PATH="$HOME/.local/bin:$PATH"
|
||||
KEEP="${KEEP:-0}"
|
||||
record_version='<not recorded>'; record_box_sha='<unresolved>'
|
||||
record_rig_repo='<not recorded>'; record_rig_ref='<not recorded>'; record_rig_sha='<unresolved>'
|
||||
if [ -n "$EMIT_RECORD" ]; then
|
||||
record_version="$(cat "$HOME/.local/share/box/current/VERSION" 2>/dev/null || echo unknown)"
|
||||
[ -n "$RUN_ID" ] || RUN_ID="$(drill_default_run_id "$record_version" "$DRILL_DATE")"
|
||||
if ! record_box_sha="$(drill_resolve_ref_sha "$REPO" "$REF")"; then
|
||||
no "could not resolve exact box SHA for $REPO@$REF — the record cannot pin what ran"
|
||||
fi
|
||||
fi
|
||||
|
||||
# PROVE THE INSTALLER'S CONTRACT (#64) — first, before the clean or anything
|
||||
# else on this host mutates the stack, and before the drill runs setup-host
|
||||
|
|
@ -590,6 +625,15 @@ printf '\n minting a claude-box box (cold, ~10 min)…\n'
|
|||
t0=$SECONDS
|
||||
if mint_box /tmp/mint-drill.log --name drill --template claude-box; then
|
||||
ok "box new --name drill --template claude-box ($((SECONDS - t0))s)"
|
||||
if [ -n "$EMIT_RECORD" ]; then
|
||||
record_rig_repo="$(incus config get drill user.box.rig.repo 2>/dev/null)"
|
||||
record_rig_ref="$(incus config get drill user.box.rig.ref 2>/dev/null)"
|
||||
if [ -z "$record_rig_repo" ] || [ -z "$record_rig_ref" ]; then
|
||||
no "minted box did not record the rig repo/ref — the record cannot pin what converged it"
|
||||
elif ! record_rig_sha="$(drill_resolve_ref_sha "$record_rig_repo" "$record_rig_ref")"; then
|
||||
no "could not resolve exact rig SHA for $record_rig_repo@$record_rig_ref"
|
||||
fi
|
||||
fi
|
||||
else
|
||||
no "box new FAILED — tail: $(tail -3 /tmp/mint-drill.log | tr '\n' ' ')"
|
||||
timeout -k 5 60 incus delete -f drill >/dev/null 2>&1
|
||||
|
|
@ -978,6 +1022,22 @@ else
|
|||
|| no "a drill box survived teardown: $(printf '%s' "$leftover" | awk '{print $1}' | tr '\n' ' ')"
|
||||
fi
|
||||
|
||||
if [ -n "$EMIT_RECORD" ]; then
|
||||
# Standard host metadata, optional by design.
|
||||
# shellcheck disable=SC1091
|
||||
record_os="$(. /etc/os-release 2>/dev/null; printf '%s' "${PRETTY_NAME:-unknown OS}")"
|
||||
record_host="$(hostname) / $record_os, $(uname -srmo), Incus $(incus --version 2>/dev/null || echo unknown)"
|
||||
record_elapsed=$(($(date +%s) - DRILL_STARTED_EPOCH))
|
||||
if drill_write_record "$EMIT_RECORD" "$record_version" "$RUN_ID" "$record_host" \
|
||||
"$DRILL_DATE" "$REPO" "$REF" "$record_box_sha" \
|
||||
"$record_rig_repo" "$record_rig_ref" "$record_rig_sha" \
|
||||
"$DRILL_INVOCATION" "$pass" "$fail" "$record_elapsed" findings; then
|
||||
inf "wrote editable release-record draft: $EMIT_RECORD"
|
||||
else
|
||||
no "could not emit the release-record draft at $EMIT_RECORD"
|
||||
fi
|
||||
fi
|
||||
|
||||
phase "Summary"
|
||||
printf ' %s passed, %s failed\n' "$pass" "$fail"
|
||||
if [ "${#findings[@]}" -gt 0 ]; then
|
||||
|
|
|
|||
77
drill/record.sh
Normal file
77
drill/record.sh
Normal file
|
|
@ -0,0 +1,77 @@
|
|||
#!/usr/bin/env bash
|
||||
# Pure helpers for drill/drill.sh's generated release-record draft (#152).
|
||||
|
||||
drill_default_run_id() {
|
||||
local version="$1" run_date="$2"
|
||||
printf 'drill-%s-%s-01\n' "$version" "${run_date//-/}"
|
||||
}
|
||||
|
||||
drill_resolve_ref_sha() {
|
||||
local repo="$1" ref="$2" remote refs sha
|
||||
case "$ref" in
|
||||
[0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f])
|
||||
printf '%s\n' "$ref"
|
||||
return
|
||||
;;
|
||||
esac
|
||||
case "$repo" in
|
||||
/*|./*|../*|http://*|https://*|git@*) remote="$repo" ;;
|
||||
*) remote="https://github.com/$repo.git" ;;
|
||||
esac
|
||||
refs="$(git ls-remote "$remote" \
|
||||
"refs/heads/$ref" "refs/tags/$ref" "refs/tags/$ref^{}" 2>/dev/null)" || return 1
|
||||
sha="$(printf '%s\n' "$refs" | awk -v ref="$ref" '
|
||||
$2 == "refs/tags/" ref "^{}" { peeled=$1 }
|
||||
$2 == "refs/heads/" ref { head=$1 }
|
||||
$2 == "refs/tags/" ref { tag=$1 }
|
||||
END { if (peeled) print peeled; else if (head) print head; else if (tag) print tag }
|
||||
')"
|
||||
[ -n "$sha" ] || return 1
|
||||
printf '%s\n' "$sha"
|
||||
}
|
||||
|
||||
drill_write_record() {
|
||||
local path="$1" version="$2" run_id="$3" host="$4" run_date="$5"
|
||||
local box_repo="$6" box_ref="$7" box_sha="$8" rig_repo="$9"
|
||||
shift 9
|
||||
local rig_ref="$1" rig_sha="$2" invocation="$3" passed="$4" failed="$5"
|
||||
local elapsed="$6" findings_name="$7" tmp finding plain total minutes
|
||||
local -n record_findings="$findings_name"
|
||||
|
||||
if [ -e "$path" ]; then
|
||||
echo "drill: record path already exists; refusing to overwrite evidence: $path" >&2
|
||||
return 1
|
||||
fi
|
||||
[ -d "$(dirname "$path")" ] || {
|
||||
echo "drill: record directory does not exist: $(dirname "$path")" >&2
|
||||
return 1
|
||||
}
|
||||
|
||||
total=$((passed + failed))
|
||||
minutes=$((elapsed / 60))
|
||||
tmp="$(mktemp "$path.tmp.XXXXXX")" || return 1
|
||||
{
|
||||
printf '# Release drill — %s\n\n' "$version"
|
||||
printf '> Generated draft: verify the facts and add operator judgement before commit.\n\n'
|
||||
printf -- "- **Run ID:** \`%s\`\n" "$run_id"
|
||||
printf -- '- **Host:** %s\n' "$host"
|
||||
printf -- '- **Date:** %s\n' "$run_date"
|
||||
printf -- '- **Candidate refs:**\n'
|
||||
printf " - box \`%s\` @ \`%s\` (\`%s\`)\n" "$box_ref" "$box_sha" "$box_repo"
|
||||
printf " - rig \`%s\` @ \`%s\` (\`%s\`)\n" "$rig_ref" "$rig_sha" "$rig_repo"
|
||||
printf '\n## What ran\n\n'
|
||||
printf "\`%s\` — phases A, B, C, E, D, M.\n" "$invocation"
|
||||
printf '\n## Result\n\n'
|
||||
printf '**%s/%s passed, %s failed.** %s minutes wall clock.\n\n' \
|
||||
"$passed" "$total" "$failed" "$minutes"
|
||||
if [ "${#record_findings[@]}" -eq 0 ]; then
|
||||
printf -- '- No failures or notes recorded by the harness.\n'
|
||||
else
|
||||
for finding in "${record_findings[@]}"; do
|
||||
plain="$(printf '%s' "$finding" | sed $'s/\033\\[[0-9;]*m//g')"
|
||||
printf -- '- %s\n' "$plain"
|
||||
done
|
||||
fi
|
||||
} > "$tmp" || { rm -f "$tmp"; return 1; }
|
||||
mv "$tmp" "$path"
|
||||
}
|
||||
|
|
@ -47,6 +47,27 @@ is a good record. So is a maintainer's written waiver explaining why this
|
|||
release shipped without a full drill. What the gate refuses is silence — #95,
|
||||
#114 and #148 all shipped unproven because a skip left no trace.
|
||||
|
||||
## Generate the factual draft
|
||||
|
||||
The harness can write the facts it already knows directly into a new record:
|
||||
|
||||
```sh
|
||||
bash drill/drill.sh --ref release/0.9.1 \
|
||||
--run-id drill-0.9.1-20260818-01 \
|
||||
--emit-record drills/0.9.1.md
|
||||
```
|
||||
|
||||
`--run-id` wins over `DRILL_RUN_ID`; if neither is set, the harness generates
|
||||
`drill-<version>-<UTC date>-01`. Supply the same ID explicitly to each family
|
||||
drill so their records reconcile. The emitter refuses to overwrite an existing
|
||||
file, and its Markdown contains no terminal colour escapes.
|
||||
|
||||
The generated file is a **draft, not finished release evidence**. It records
|
||||
the host, invocation, elapsed time, findings, and the exact box and rig refs and
|
||||
SHAs the run selected. Before committing it, verify those facts and add the
|
||||
operator judgement that a script cannot make: hardware detail, the meaning of
|
||||
any failures or skips, and whether they block release.
|
||||
|
||||
## Worked example
|
||||
|
||||
The version below is a **placeholder that can never be a real release**.
|
||||
|
|
|
|||
13
test/cli.sh
13
test/cli.sh
|
|
@ -3119,22 +3119,33 @@ drill_record_fixture() {
|
|||
|
||||
check "drill record: renderer writes a Markdown draft" 0 "" drill_record_fixture
|
||||
check "drill record: names the release version" 0 "# Release drill — 0.9.1" cat "$DRILL_RECORD"
|
||||
# Backticks are literal Markdown delimiters.
|
||||
# shellcheck disable=SC2016
|
||||
check "drill record: carries the shared run ID" 0 '**Run ID:** `drill-0.9.1-20260818-01`' cat "$DRILL_RECORD"
|
||||
# shellcheck disable=SC2016
|
||||
check "drill record: pins the box ref and full SHA" 0 'box `release/0.9.1` @ `0123456789abcdef0123456789abcdef01234567`' cat "$DRILL_RECORD"
|
||||
# shellcheck disable=SC2016
|
||||
check "drill record: pins the rig ref and full SHA" 0 'rig `release/0.4.0` @ `89abcdef0123456789abcdef0123456789abcdef`' cat "$DRILL_RECORD"
|
||||
# shellcheck disable=SC2016
|
||||
check "drill record: records the invocation" 0 '`bash drill/drill.sh --ref release/0.9.1 --run-id drill-0.9.1-20260818-01`' cat "$DRILL_RECORD"
|
||||
check "drill record: renders pass/fail counts and wall clock" 0 '**84/85 passed, 1 failed.** 41 minutes wall clock.' cat "$DRILL_RECORD"
|
||||
check "drill record: carries plain findings" 0 '- FAIL: sibling isolation regressed' cat "$DRILL_RECORD"
|
||||
check "drill record: strips terminal colour" 1 $'\033' grep -q $'\033' "$DRILL_RECORD"
|
||||
check "drill record: strips terminal colour" 1 "" grep -q $'\033' "$DRILL_RECORD"
|
||||
|
||||
printf 'operator evidence\n' > "$DRILL_RECORD_DIR/existing.md"
|
||||
# Expansion belongs to the bash -c fixture.
|
||||
# shellcheck disable=SC2016
|
||||
check "drill record: refuses to overwrite evidence" 1 "already exists" \
|
||||
bash -c '. "$1/drill/record.sh"; findings=(); drill_write_record "$2" v id host date repo ref sha rig rref rsha invocation 0 0 0 findings' \
|
||||
_ "$ROOT" "$DRILL_RECORD_DIR/existing.md"
|
||||
check "drill record: an overwrite refusal preserves the file" 0 "operator evidence" cat "$DRILL_RECORD_DIR/existing.md"
|
||||
|
||||
# shellcheck disable=SC2016
|
||||
check "drill record: default run ID joins version and UTC date" 0 "drill-0.9.1-20260818-01" \
|
||||
bash -c '. "$1/drill/record.sh"; drill_default_run_id 0.9.1 2026-08-18' _ "$ROOT"
|
||||
# shellcheck disable=SC2016
|
||||
check "drill record: an already exact ref stays exact" 0 "0123456789abcdef0123456789abcdef01234567" \
|
||||
bash -c '. "$1/drill/record.sh"; drill_resolve_ref_sha repo 0123456789abcdef0123456789abcdef01234567' _ "$ROOT"
|
||||
check "drill: help names --emit-record" 0 "--emit-record <path>" bash "$ROOT/drill/drill.sh" --help
|
||||
check "drill: help names --run-id" 0 "--run-id <id>" bash "$ROOT/drill/drill.sh" --help
|
||||
check "drill: --emit-record needs a value before any mutation" 2 "--emit-record needs a value" \
|
||||
|
|
|
|||
Loading…
Reference in a new issue