@accidentally-awesome-labs/opencode-bestest 0.4.3
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/README.md +36 -0
- package/bin/init.ts +126 -0
- package/bin/opencode-bestest +3 -0
- package/opencode-assets/agents/plan-checker.md +27 -0
- package/opencode-assets/agents/researcher.md +20 -0
- package/opencode-assets/agents/reviewer.md +22 -0
- package/opencode-assets/commands/bestest-go.md +5 -0
- package/opencode-assets/commands/bestest-status.md +5 -0
- package/package.json +30 -0
- package/payload/VERSION +1 -0
- package/payload/agents/plan-checker.md +25 -0
- package/payload/agents/researcher.md +17 -0
- package/payload/agents/reviewer.md +21 -0
- package/payload/hooks/guard.sh +111 -0
- package/payload/hooks/lock-guard.sh +118 -0
- package/payload/hooks/session-start.sh +63 -0
- package/payload/hooks/syntax-check.sh +96 -0
- package/payload/scripts/trace.sh +98 -0
- package/payload/skills/bestest-go/SKILL.md +37 -0
- package/payload/skills/bestest-status/SKILL.md +16 -0
- package/payload/skills/build/SKILL.md +29 -0
- package/payload/skills/debug/SKILL.md +20 -0
- package/payload/skills/interrogate/SKILL.md +48 -0
- package/payload/skills/interrogate/references/challenge-tactics.md +21 -0
- package/payload/skills/interrogate/references/question-protocol.md +21 -0
- package/payload/skills/plan/SKILL.md +25 -0
- package/payload/skills/plan/references/assets.md +15 -0
- package/payload/skills/research/SKILL.md +23 -0
- package/payload/skills/ship/SKILL.md +28 -0
- package/payload/skills/using-bestest/SKILL.md +20 -0
- package/payload/skills/using-bestest/references/claude-code.md +16 -0
- package/payload/skills/using-bestest/references/codex.md +17 -0
- package/payload/skills/using-bestest/references/opencode.md +18 -0
- package/payload/templates/DEBUG.md +17 -0
- package/payload/templates/DECISIONS.md +11 -0
- package/payload/templates/RUNBOOK.md +24 -0
- package/payload/templates/SPEC.md +35 -0
- package/payload/templates/STATE.md +20 -0
- package/payload/templates/UAT.md +10 -0
- package/payload/templates/report.md +15 -0
- package/payload/templates/task-card.md +24 -0
- package/src/guards.ts +80 -0
- package/src/index.ts +34 -0
- package/src/resolve.ts +22 -0
- package/src/session.ts +57 -0
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# bestest: PostToolUse[Write|Edit|MultiEdit|apply_patch] syntax gate (SWE-agent lint pattern).
|
|
3
|
+
# Extension-dispatched syntax check; no-op when no checker is installed.
|
|
4
|
+
# Exit 2 feeds the error straight back to the model for an immediate fix.
|
|
5
|
+
# Claude edits carry .tool_input.file_path; Codex/OpenCode apply_patch carries
|
|
6
|
+
# the patch text in .tool_input.command — every touched file gets checked.
|
|
7
|
+
set -u
|
|
8
|
+
|
|
9
|
+
input="$(cat)"
|
|
10
|
+
root="${CLAUDE_PROJECT_DIR:-$(pwd)}"
|
|
11
|
+
|
|
12
|
+
get_file_path() {
|
|
13
|
+
if command -v jq >/dev/null 2>&1; then
|
|
14
|
+
printf '%s' "$input" | jq -r '.tool_input.file_path // empty' 2>/dev/null
|
|
15
|
+
elif command -v python3 >/dev/null 2>&1; then
|
|
16
|
+
printf '%s' "$input" | python3 -c 'import json,sys
|
|
17
|
+
try: print(json.load(sys.stdin).get("tool_input",{}).get("file_path",""))
|
|
18
|
+
except Exception: pass' 2>/dev/null
|
|
19
|
+
fi
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
get_command_text() {
|
|
23
|
+
if command -v jq >/dev/null 2>&1; then
|
|
24
|
+
printf '%s' "$input" | jq -r '.tool_input.command // empty' 2>/dev/null
|
|
25
|
+
elif command -v python3 >/dev/null 2>&1; then
|
|
26
|
+
printf '%s' "$input" | python3 -c 'import json,sys
|
|
27
|
+
try: print(json.load(sys.stdin).get("tool_input",{}).get("command",""))
|
|
28
|
+
except Exception: pass' 2>/dev/null
|
|
29
|
+
fi
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
patch_paths() {
|
|
33
|
+
cmd="$(get_command_text)"
|
|
34
|
+
case "$cmd" in
|
|
35
|
+
*'*** Begin Patch'*) ;;
|
|
36
|
+
*) return 0 ;;
|
|
37
|
+
esac
|
|
38
|
+
printf '%s\n' "$cmd" \
|
|
39
|
+
| sed -nE -e 's/^\*\*\* (Add|Update|Delete) File: //p' -e 's/^\*\*\* Move to: //p'
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
paths="$(get_file_path)"
|
|
43
|
+
[ -n "$paths" ] || paths="$(patch_paths)"
|
|
44
|
+
[ -n "$paths" ] || exit 0
|
|
45
|
+
|
|
46
|
+
fail() {
|
|
47
|
+
echo "bestest syntax-check: $fp failed — fix before moving on:" >&2
|
|
48
|
+
echo "$1" >&2
|
|
49
|
+
exit 2
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
check_one_file() {
|
|
53
|
+
fp="$1"
|
|
54
|
+
out=""
|
|
55
|
+
case "$fp" in
|
|
56
|
+
*.py)
|
|
57
|
+
command -v python3 >/dev/null 2>&1 || return 0
|
|
58
|
+
out="$(python3 -c 'import ast,sys
|
|
59
|
+
ast.parse(open(sys.argv[1]).read(), sys.argv[1])' "$fp" 2>&1)" || fail "$out" ;;
|
|
60
|
+
*.js|*.mjs|*.cjs)
|
|
61
|
+
command -v node >/dev/null 2>&1 || return 0
|
|
62
|
+
out="$(node --check "$fp" 2>&1)" || fail "$out" ;;
|
|
63
|
+
*.ts|*.tsx)
|
|
64
|
+
# Syntax-only (TS1xxx): single-file tsc without the project tsconfig would
|
|
65
|
+
# false-fail on jsx/paths/module settings (TS17004, TS2307, ...).
|
|
66
|
+
command -v tsc >/dev/null 2>&1 || return 0
|
|
67
|
+
out="$(tsc --noEmit --skipLibCheck --jsx preserve "$fp" 2>&1 | grep -F "$(basename "$fp")" | grep -E 'error TS1[0-9]{3}:')"
|
|
68
|
+
[ -n "$out" ] && fail "$out" ;;
|
|
69
|
+
*.sh|*.bash)
|
|
70
|
+
if command -v shellcheck >/dev/null 2>&1; then
|
|
71
|
+
out="$(shellcheck -S error "$fp" 2>&1)" || fail "$out"
|
|
72
|
+
else
|
|
73
|
+
out="$(bash -n "$fp" 2>&1)" || fail "$out"
|
|
74
|
+
fi ;;
|
|
75
|
+
*.json)
|
|
76
|
+
if command -v jq >/dev/null 2>&1; then
|
|
77
|
+
out="$(jq empty "$fp" 2>&1)" || fail "$out"
|
|
78
|
+
elif command -v python3 >/dev/null 2>&1; then
|
|
79
|
+
out="$(python3 -m json.tool "$fp" 2>&1 >/dev/null)" || fail "$out"
|
|
80
|
+
fi ;;
|
|
81
|
+
esac
|
|
82
|
+
return 0
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
while IFS= read -r fp; do
|
|
86
|
+
[ -n "$fp" ] || continue
|
|
87
|
+
# Patch headers are project-relative; anchor them to the project root.
|
|
88
|
+
case "$fp" in /*) : ;; *) fp="$root/$fp" ;; esac
|
|
89
|
+
# Deleted files (patch Delete headers) and unresolvable paths are skipped.
|
|
90
|
+
[ -f "$fp" ] || continue
|
|
91
|
+
check_one_file "$fp"
|
|
92
|
+
done <<EOF
|
|
93
|
+
$paths
|
|
94
|
+
EOF
|
|
95
|
+
|
|
96
|
+
exit 0
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# bestest trace: requirement-chain audit. Required gate evidence at P3 (--plan)
|
|
3
|
+
# and P5 (--all). Prints PASS or numbered failures; nonzero exit on failure.
|
|
4
|
+
#
|
|
5
|
+
# Chain audited: SPEC R-N.M -> card frontmatter -> commit trailer 'Bestest-Req:'
|
|
6
|
+
# -> report FRICTION -> UAT line -> DISCOVERED dispositions.
|
|
7
|
+
set -u
|
|
8
|
+
|
|
9
|
+
mode="${1:---plan}"
|
|
10
|
+
root="${CLAUDE_PROJECT_DIR:-$(pwd)}"
|
|
11
|
+
b="$root/.bestest"
|
|
12
|
+
fails=0
|
|
13
|
+
fail() { fails=$((fails+1)); printf 'FAIL %02d: %s\n' "$fails" "$1"; }
|
|
14
|
+
front() { awk '/^---$/{n++; next} n==1' "$1"; } # frontmatter body of a card
|
|
15
|
+
|
|
16
|
+
[ -f "$b/SPEC.md" ] || { echo "FAIL 01: no $b/SPEC.md — nothing to trace"; exit 1; }
|
|
17
|
+
|
|
18
|
+
rids="$(grep -oE 'R-[0-9]+\.[0-9]+' "$b/SPEC.md" | sort -u)"
|
|
19
|
+
[ -n "$rids" ] || fail "SPEC.md defines no R-N.M acceptance criteria"
|
|
20
|
+
|
|
21
|
+
cards="$(ls "$b"/plans/T-*.md 2>/dev/null || true)"
|
|
22
|
+
[ -n "$cards" ] || fail "no task cards in $b/plans/"
|
|
23
|
+
|
|
24
|
+
# --- plan-level checks -------------------------------------------------------
|
|
25
|
+
rid_re() { printf '(^|[^0-9.])%s([^0-9]|$)' "$(printf '%s' "$1" | sed 's/\./\\./g')"; } # R-1.1 must not match R-1.10
|
|
26
|
+
|
|
27
|
+
for r in $rids; do
|
|
28
|
+
covered=no
|
|
29
|
+
for c in $cards; do
|
|
30
|
+
front "$c" | grep -E '^requirements:' | grep -Eq "$(rid_re "$r")" && { covered=yes; break; }
|
|
31
|
+
done
|
|
32
|
+
[ "$covered" = yes ] || fail "$r has no covering task card"
|
|
33
|
+
done
|
|
34
|
+
|
|
35
|
+
for c in $cards; do
|
|
36
|
+
name="$(basename "$c")"
|
|
37
|
+
fm="$(front "$c")"
|
|
38
|
+
|
|
39
|
+
# cards may only cite R-IDs that exist in SPEC
|
|
40
|
+
for r in $(printf '%s' "$fm" | grep -E '^requirements:' | grep -oE 'R-[0-9]+\.[0-9]+' | sort -u); do
|
|
41
|
+
printf '%s\n' "$rids" | grep -qx "$r" || fail "$name cites $r which is not in SPEC.md"
|
|
42
|
+
done
|
|
43
|
+
|
|
44
|
+
# blocked_by targets must exist
|
|
45
|
+
for t in $(printf '%s' "$fm" | grep -E '^blocked_by:' | grep -oE 'T-[0-9]+'); do
|
|
46
|
+
[ -f "$b/plans/$t.md" ] || fail "$name blocked_by $t but $b/plans/$t.md does not exist"
|
|
47
|
+
done
|
|
48
|
+
|
|
49
|
+
# complexity: recompute floor from mechanical signals, compare to declared
|
|
50
|
+
nfiles="$(printf '%s' "$fm" | grep -E '^files:' | head -1 | tr ',' '\n' | grep -c '[^[:space:]]' || true)"
|
|
51
|
+
nverify="$(printf '%s\n' "$fm" | awk '/^verify:/{f=1;next} /^[a-zA-Z_]+:/{f=0} f&&/^[[:space:]]*-[[:space:]]/{c++} END{print c+0}')"
|
|
52
|
+
andflag=0
|
|
53
|
+
printf '%s' "$fm" | grep -E '^title:' | grep -Eq '[[:space:]][Aa]nd[[:space:]]' && andflag=1
|
|
54
|
+
declared="$(printf '%s' "$fm" | grep -E '^complexity:' | grep -oE '[0-9]+' | head -1)"
|
|
55
|
+
[ "$nfiles" -gt 0 ] || nfiles=1
|
|
56
|
+
floor=$(( 1 + 2 * (nfiles - 1) + 2 * nverify + 3 * andflag ))
|
|
57
|
+
[ -n "${declared:-}" ] || { fail "$name missing complexity: field"; declared=0; }
|
|
58
|
+
[ "$declared" -lt "$floor" ] && fail "$name understates complexity: declared $declared < mechanical floor $floor"
|
|
59
|
+
bigger=$(( declared > floor ? declared : floor ))
|
|
60
|
+
[ "$bigger" -ge 7 ] && fail "$name complexity $bigger >= 7 — split it (target <= 5)"
|
|
61
|
+
done
|
|
62
|
+
|
|
63
|
+
# --- full-chain checks (--all) -----------------------------------------------
|
|
64
|
+
if [ "$mode" = "--all" ]; then
|
|
65
|
+
for c in $cards; do
|
|
66
|
+
id="$(basename "$c" .md)"
|
|
67
|
+
front "$c" | grep -Eq '^status:[[:space:]]*done' || continue
|
|
68
|
+
rep="$b/reports/$id.md"
|
|
69
|
+
if [ ! -f "$rep" ]; then
|
|
70
|
+
fail "$id is done but $rep is missing"
|
|
71
|
+
elif ! awk '/^## FRICTION/{f=1;next} /^## /{f=0} f&&/^[[:space:]]*<!--/{next} f&&NF{c++} END{exit c?0:1}' "$rep"; then
|
|
72
|
+
fail "$id report has empty FRICTION section (write 'None' if truly none)"
|
|
73
|
+
fi
|
|
74
|
+
done
|
|
75
|
+
|
|
76
|
+
for r in $rids; do
|
|
77
|
+
git -C "$root" log -E --grep="Bestest-Req:.*$(rid_re "$r")" --oneline -1 2>/dev/null | grep -q . \
|
|
78
|
+
|| fail "$r has no commit with trailer 'Bestest-Req: $r'"
|
|
79
|
+
if [ -f "$b/UAT.md" ]; then
|
|
80
|
+
grep -Eq "$(rid_re "$r")" "$b/UAT.md" || fail "$r missing from UAT.md"
|
|
81
|
+
else
|
|
82
|
+
fail "no $b/UAT.md"
|
|
83
|
+
fi
|
|
84
|
+
done
|
|
85
|
+
|
|
86
|
+
if [ -f "$b/DISCOVERED.md" ]; then
|
|
87
|
+
while IFS= read -r line; do
|
|
88
|
+
printf '%s' "$line" | grep -q 'disposition:' \
|
|
89
|
+
|| fail "DISCOVERED entry lacks disposition: ${line%%|*}"
|
|
90
|
+
done < <(grep -E '^- ' "$b/DISCOVERED.md")
|
|
91
|
+
fi
|
|
92
|
+
fi
|
|
93
|
+
|
|
94
|
+
if [ "$fails" -eq 0 ]; then
|
|
95
|
+
echo "PASS: $(printf '%s\n' "$rids" | grep -c .) requirements, $(printf '%s\n' "$cards" | grep -c .) cards, chain clean ($mode)"
|
|
96
|
+
exit 0
|
|
97
|
+
fi
|
|
98
|
+
exit 1
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: bestest-go
|
|
3
|
+
description: Use when routing a bestest project to its lifecycle phase — bootstraps .bestest/ at P0 on first run.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# bestest-go — lifecycle router
|
|
7
|
+
|
|
8
|
+
1. Read `.bestest/STATE.md`. If missing: `mkdir -p .bestest/plans .bestest/reports .bestest/research`, copy `templates/STATE.md` from the plugin root into `.bestest/STATE.md`, set `phase: P0`, `milestone: v1` and `plugin: <plugin root>` — the absolute directory containing the plugin's `skills/`, `templates/`, `scripts/`; the invoking command passes it pre-rendered where the harness supports that, otherwise resolve per the harness map (using-bestest `references/<harness>.md`). Skills resolve `trace.sh` and templates through this line. Append `.bestest/.session-snapshot` to the project's `.gitignore`, commit.
|
|
9
|
+
**Brownfield check** — the repo already contains product code (real source or git history, not scaffolding)? Then before interrogating: (a) dispatch one read-only subagent to write `.bestest/CODEBASE.md`, ≤60 lines: layout, entry points, build/run/test commands, observed conventions, integration seams, deploy surface — every claim cited to a file path; (b) seed `.bestest/LOCKS` via explicit shell commands with one `glob` line per existing test directory — incumbent tests are immutable to implementers from day one; (c) interrogation treats CODEBASE.md as context and existing behavior as `[cited:path]` fact, not something to re-ask the user.
|
|
10
|
+
Then load the **interrogate** skill and begin Stage 0 with the user's idea (ask for it if none was given).
|
|
11
|
+
|
|
12
|
+
2. If `phase: done` (or the P5 ship gate is already logged and new work arrived): run **Milestone rollover** below.
|
|
13
|
+
|
|
14
|
+
3. Otherwise route on `phase:` — load the named skill and resume exactly at `stage:` / `card:`:
|
|
15
|
+
|
|
16
|
+
| phase | skill | exit gate (all evidence, no vibes) |
|
|
17
|
+
|---|---|---|
|
|
18
|
+
| P0 | interrogate (stages 0–2, then 4–5; stage 3 hands off to P1) | draft SPEC complete: Premise Verdict + EARS `R-N.M` criteria + non-empty out_of_scope + SPEC §8 doneness |
|
|
19
|
+
| P1 | research | every external claim `[cited:URL]`; stack decision-brief approved → **return to interrogate stage 4** |
|
|
20
|
+
| P2 | interrogate stage 6 (only) | rubric pass → Taste batch → Autonomy Contract → SPEC sha256 appended to LOCKS |
|
|
21
|
+
| P3 | plan | plan-checker PASS (≤3 loops) + `trace.sh --plan` clean + one-screen user approval |
|
|
22
|
+
| P4 | build | every card done: diff-scope clean, verify re-run, review closed |
|
|
23
|
+
| P5 | ship | UAT per R-ID + `trace.sh --all` clean + DISCOVERED dispositioned + user go/no-go |
|
|
24
|
+
|
|
25
|
+
4. On gate pass: update STATE.md (phase, next action, gate log line, and **re-derive Open interrupts from scratch** — an answered interrupt left standing misroutes the next session), commit `.bestest/`, announce the phase transition in one sentence, continue.
|
|
26
|
+
|
|
27
|
+
## Milestone rollover (P5 shipped → next milestone)
|
|
28
|
+
|
|
29
|
+
All via explicit shell gate steps (LOCKS/SPEC are hook-frozen against file edits):
|
|
30
|
+
1. `N` = STATE `milestone:` (default v1). `mkdir -p .bestest/milestones/N` and `git mv` SPEC.md, PLAN.md, UAT.md, RUNBOOK.md, plans/, reports/, research/ into it, plus a `cp` snapshot of the final STATE.md (its gate log is the milestone's ledger). DECISIONS.md, LESSONS.md, DISCOVERED.md stay live — history and debt carry forward.
|
|
31
|
+
2. Rewrite LOCKS dropping the SPEC `hash` line (the archived SPEC keeps its frozen copy); keep every test `glob` — incumbent tests stay immutable.
|
|
32
|
+
3. Fresh STATE.md from the template: `phase: P0`, `milestone: N+1`, same `plugin:` line. Commit `.bestest: roll over N -> N+1`.
|
|
33
|
+
4. Re-enter **interrogate** Stage 0 as brownfield: prior SPEC (`.bestest/milestones/N/SPEC.md`), the DISCOVERED backlog, and LESSONS are the opening context — the new idea is interrogated against what already ships, and unshipped R-IDs must be explicitly re-adopted or cut, never assumed.
|
|
34
|
+
|
|
35
|
+
Amending a frozen SPEC: new D-ID in DECISIONS.md → apply the edit via an explicit shell gate step → re-hash the `hash` line in LOCKS (the lock-guard block message points here).
|
|
36
|
+
|
|
37
|
+
Never skip a gate because the work "seems obvious" — gates are where the human front-loaded trust.
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: bestest-status
|
|
3
|
+
description: Use when reporting bestest project state — strictly read-only dashboard, never mutates anything.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# bestest-status — dashboard (STRICTLY READ-ONLY)
|
|
7
|
+
|
|
8
|
+
Report, compactly, from files only — no edits, no state changes, no "while I'm here" fixes:
|
|
9
|
+
|
|
10
|
+
1. `.bestest/STATE.md` — phase, stage, active card, next action, open interrupts.
|
|
11
|
+
2. Gate log — which gates passed, with dates.
|
|
12
|
+
3. Counts: task cards by status (todo/doing/done), DISCOVERED.md lines lacking `disposition:`, open risks in DECISIONS.md.
|
|
13
|
+
4. If P3+: run `"$PLUGIN"/scripts/trace.sh --plan` where `PLUGIN` = the `plugin:` line in STATE.md (read-only) and show PASS or its failure lines.
|
|
14
|
+
5. One line: "Next: <the next action verbatim from STATE.md>".
|
|
15
|
+
|
|
16
|
+
If `.bestest/` is missing, say so and point at the **bestest-go** skill.
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: build
|
|
3
|
+
description: Use when a bestest project enters P4 — orchestrate fresh subagents through task cards with mechanical gates, closed feedback loops, and risk-scaled review.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Build
|
|
7
|
+
|
|
8
|
+
You are the **orchestrator**: dispatch, gate, close loops. You do not write product code; builders do.
|
|
9
|
+
|
|
10
|
+
## Dispatch loop
|
|
11
|
+
1. **Pick:** lowest-numbered incomplete card whose `blocked_by:` are all done. Set `card:` + `stage:` in STATE.md, mark card `doing`, note `task-start=$(git rev-parse HEAD)`.
|
|
12
|
+
2. **Dispatch a fresh subagent** with: the card, LESSONS.md ("read first, append what you learn"), relevant D-IDs. File handoffs only — builders write code + `.bestest/reports/T-##.md`; they get no chat history.
|
|
13
|
+
3. **Builder contract** (put in the prompt): follow the card exactly; TDD (the failing test exists — make it pass, never edit it); commit with trailer `Bestest-Req: <R-IDs>`; on any underdetermined point return `BLOCKED: <specific question>` instead of improvising; report claim→evidence + FRICTION (or `None`) + Discovered.
|
|
14
|
+
4. **Gate mechanically** (never trust the report):
|
|
15
|
+
- Re-run every `verify:` command yourself; paste output.
|
|
16
|
+
- `git diff --name-only <task-start>..HEAD` ⊆ card `files:` — out-of-scope diffs get reverted or INTERRUPT; locked paths must show zero diff.
|
|
17
|
+
- Report FRICTION section present; Discovered lines actually appended to DISCOVERED.md.
|
|
18
|
+
5. **Close the loop:** FRICTION → patch the *remaining* cards now + append environment facts to LESSONS.md — before the next dispatch, not "later".
|
|
19
|
+
6. **Review** (risk-scaled): dispatch **reviewer** agent — card weight ≥4 → full adversarial pass; weight <4 → blockers-only. A finding closes only *fixed-and-reconfirmed by the reviewer*, or waived as a D-ID with a revisit trigger.
|
|
20
|
+
7. Mark done, update STATE.md, commit `.bestest/`, next card.
|
|
21
|
+
|
|
22
|
+
## Interrupt handling
|
|
23
|
+
- `BLOCKED:` from a builder → answer from SPEC/DECISIONS if derivable; else it's a real gap: INTERRUPT the user, record the answer as a D-ID, redispatch.
|
|
24
|
+
- **Loop tripwire:** same command failing 3× with the same error, or two states alternating 3× → stop the lane, record the signature in LESSONS, escalate to **debug** skill.
|
|
25
|
+
- 3 failed fix attempts on one card → debug skill; debug can't crack it → architecture escape: INTERRUPT with a one-paragraph problem statement + 2 options.
|
|
26
|
+
- Out-of-blast-radius discovery → one line in DISCOVERED.md: `- <summary> | discovered-from: T-## | blocks: <T-## or none>`. Never fix silently, never drop.
|
|
27
|
+
- LESSONS.md line format: `- [env|tool|codebase] <fact> (T-##)`.
|
|
28
|
+
|
|
29
|
+
Autonomy Contract (SPEC §9) governs everything above; GATED actions stop the line no matter what a card says.
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: debug
|
|
3
|
+
description: Use when a bestest build hits a defect that survives one obvious fix attempt, a loop tripwire fires, or a card fails review 3× — hypothesis-driven debugging with a repro-test iron law.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Debug
|
|
7
|
+
|
|
8
|
+
Open `.bestest/DEBUG-<slug>.md` (template: DEBUG.md). The file is the investigation; your memory is not.
|
|
9
|
+
|
|
10
|
+
## Iron law
|
|
11
|
+
**No fix until a failing reproduction test exists.** Smallest deterministic test that shows the defect — it becomes a permanent regression test (author it under a `may_edit_tests: true` micro-card). Can't reproduce it → you have an observation problem, not a bug fix; instrument first.
|
|
12
|
+
|
|
13
|
+
## Loop
|
|
14
|
+
1. Symptom: exact observed vs expected, error text verbatim.
|
|
15
|
+
2. List hypotheses — **every** plausible cause, cheapest-to-probe first. For each: the discriminating probe (a command, log, or breakpoint that splits the world in two).
|
|
16
|
+
3. Probe one hypothesis at a time. Killed → **Eliminated** (append-only, with evidence). Never re-litigate an eliminated hypothesis; never fix two hypotheses at once.
|
|
17
|
+
4. Confirmed → minimal fix → repro test passes → re-run the card's `verify:` + affected R-ID checks.
|
|
18
|
+
5. Record the root-cause pattern in LESSONS.md if any future card could hit it.
|
|
19
|
+
|
|
20
|
+
Three exhausted hypothesis rounds → architecture escape (see build skill). A debug that changes SPEC-visible behavior is an INTERRUPT, not a quiet patch.
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: interrogate
|
|
3
|
+
description: Use when starting a new bestest project or resuming P0/P2 — staged interrogation that challenges a raw idea until ambiguity, gaps, and pointless work are gone, ending in a frozen SPEC.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Interrogate
|
|
7
|
+
|
|
8
|
+
Resumable state machine; `stage:` lives in STATE.md. Question discipline: `references/question-protocol.md`. Challenge moves: `references/challenge-tactics.md`. Findings accumulate directly into a draft `.bestest/SPEC.md` (template: SPEC.md) and DECISIONS.md as you go — never hold them in memory.
|
|
9
|
+
|
|
10
|
+
## Stage 0 — Intake
|
|
11
|
+
Listen uninterrupted. Then play back 2–3 **materially different** interpretations of the idea ("A: a CLI for you; B: a service for your team; C: a library others embed") and have the user pick or correct. Record verbatim quotes as `[user]`.
|
|
12
|
+
**Brownfield:** if `.bestest/CODEBASE.md` or a prior milestone SPEC exists, open from them — each interpretation must say how it fits the existing system, and facts they establish are `[cited:path]`, never re-asked.
|
|
13
|
+
|
|
14
|
+
## Stage 1 — Premise
|
|
15
|
+
Six forcing questions, strictly one at a time, researching between answers so the next question is informed:
|
|
16
|
+
1. **Demand reality** — who concretely hits this problem, how often, what do they do today?
|
|
17
|
+
2. **Status quo** — why is doing nothing unacceptable?
|
|
18
|
+
3. **Desperate specificity** — describe the single worst recent incident of the problem.
|
|
19
|
+
4. **Narrowest wedge** — what is the smallest version that would still be used weekly?
|
|
20
|
+
5. **Observation** — how will we observe (not hope) that it worked?
|
|
21
|
+
6. **Future-fit** — what changes in 12 months that kills or grows this?
|
|
22
|
+
|
|
23
|
+
Between questions, search for existing tools that already solve it; present findings before asking the user to justify building. Exit: a written **Premise Verdict** the user confirms — or an honest recommendation to pivot or park.
|
|
24
|
+
|
|
25
|
+
## Stage 2 — Discovery
|
|
26
|
+
Adaptive, domain-specific gray areas across five buckets: users/actors · data & lifecycle · integration surface · failure/abuse · **Anti-Goals (mandatory, ≥3)**. Present options annotated with what research already found ("Postgres and SQLite both fit; SQLite unless you need concurrent writers — you said single user"). Batch related Taste questions; never ask what Stage-3 research can derive.
|
|
27
|
+
|
|
28
|
+
## Stage 3 — Research handoff
|
|
29
|
+
Zero user questions by default. Load the **research** skill: fan-out → primary sources → adversarial verification → cited stack table → SLOPCHECK on every proposed dependency. Output: SPEC §5 rows, all `[cited:URL]`.
|
|
30
|
+
|
|
31
|
+
## Stage 4 — Challenge
|
|
32
|
+
Now attack the accumulated idea (tactics reference): name tensions between stated goals; run the pre-mortem and contribute your own top-2 failure causes; challenge API/library assumptions against fetched docs, not memory; goal-trace every feature back to the Premise Verdict and propose purging orphans; offer an alternative for every weight≥6 decision.
|
|
33
|
+
|
|
34
|
+
## Stage 5 — Scope freeze
|
|
35
|
+
Every candidate requirement gets Include / Defer / Cut / Hold. `out_of_scope` must be non-empty with reasons; Deferred items go to the parking lot. Write acceptance criteria in **EARS grammar**, one sentence each, numbered `R-N.M`:
|
|
36
|
+
`WHEN <trigger> [WHILE <state>] THE SYSTEM SHALL <observable behavior>.`
|
|
37
|
+
If a criterion can't be phrased as observable behavior, it isn't a criterion — rework it.
|
|
38
|
+
Close the stage by writing **SPEC §8 — the doneness function**: the falsifiable test the P5 go/no-go will evaluate verbatim.
|
|
39
|
+
|
|
40
|
+
## Stage 6 — Spec & contract freeze (P2 gate)
|
|
41
|
+
1. **Rubric pass:** dispatch the plan-checker agent in spec mode. Findings come back typed `[Gap]` `[Ambiguity]` `[Conflict]` `[Assumption]` with R-ID cites. Freeze is blocked until every Gap/Conflict is fixed or explicitly accepted as a D-ID.
|
|
42
|
+
2. **Taste batch:** present all open judgment calls at once — "N calls I'll make unless you veto."
|
|
43
|
+
3. **Autonomy Contract:** walk the user through SPEC §9; get explicit agreement.
|
|
44
|
+
4. **Freeze:** on the user's explicit approval, run the gate step:
|
|
45
|
+
```bash
|
|
46
|
+
mkdir -p .bestest && h="$( (command -v sha256sum >/dev/null && sha256sum .bestest/SPEC.md || shasum -a 256 .bestest/SPEC.md) | cut -d' ' -f1)" && printf 'hash %s .bestest/SPEC.md\nglob <test-glob>\n' "$h" >> .bestest/LOCKS
|
|
47
|
+
```
|
|
48
|
+
Set `spec_hash:` in STATE.md, commit, advance to P3. This is the **last HIGH-touch moment** — everything after runs on the contract.
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# Challenge tactics (Stage 4)
|
|
2
|
+
|
|
3
|
+
Run all five; report what each found, even if "nothing".
|
|
4
|
+
|
|
5
|
+
## 1. Tension naming
|
|
6
|
+
Find pairs of stated goals that pull against each other ("offline-first" vs "always-fresh data"; "zero config" vs "multi-tenant"). Name the tension, state which side the current spec silently picked, make the user pick explicitly. D-ID the resolution.
|
|
7
|
+
|
|
8
|
+
## 2. Pre-mortem
|
|
9
|
+
"It's 6 months later and this project failed / is unused. Why?" Collect the user's causes, then add **your own top-2** — the ones the user is least likely to say (usually: 'the underlying need was occasional, not weekly' and 'integration friction beat the benefit'). Each cause → RISK entry with a tripwire, or a spec change now.
|
|
10
|
+
|
|
11
|
+
## 3. Doc-cited API challenge
|
|
12
|
+
Every external API/library the idea leans on: fetch the current docs (never trust memory — training data is stale) and verify the load-bearing assumption: rate limits, auth model, pricing, deprecations, platform requirements. Cite what you fetched. One mismatch here can invalidate the whole premise — that's an INTERRUPT, not a footnote.
|
|
13
|
+
|
|
14
|
+
## 4. Goal-tracing purge
|
|
15
|
+
Walk every feature/requirement back to the Premise Verdict. Anything that doesn't trace is a candidate purge — present the list: "these N items serve no stated goal; cut or justify." Justification creates a new stated goal (user confirms) — silence cuts it.
|
|
16
|
+
|
|
17
|
+
## 5. Alternatives for heavy decisions
|
|
18
|
+
Every weight≥6 decision gets one genuinely different alternative (not a strawman), with the strongest honest case for it in two sentences. If the user's choice survives the strongest opposing case, it's load-tested; if it flips, the challenge just paid for the whole interrogation.
|
|
19
|
+
|
|
20
|
+
## SLOPCHECK (dependency vetting, used by Stage 3)
|
|
21
|
+
For each proposed dependency: last release date · open-issue trend · maintainer bus-factor · install weight · license · does the stdlib/platform already do this? Reject any dep that fails two, unless a D-ID records why it's worth it.
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# Question protocol
|
|
2
|
+
|
|
3
|
+
**Prime Rule: never ask what's derivable.** If docs, code, research, or prior answers can answer it, derive and show your work instead. Asking a derivable question spends user trust and screen time for nothing.
|
|
4
|
+
|
|
5
|
+
## Classify every decision
|
|
6
|
+
- **Mechanical** — one defensible answer exists (lib version, file layout). Decide, record D-ID, move on. Never ask.
|
|
7
|
+
- **Taste** — several defensible answers; user preference is the tiebreaker (naming, UX tone, strictness). Batch these; present as "I'll do X unless you veto."
|
|
8
|
+
- **User-Challenge** — the user's stated position conflicts with evidence. Always surface, one at a time, evidence first.
|
|
9
|
+
|
|
10
|
+
## Weight before asking
|
|
11
|
+
`weight = irreversibility (1-3) × scope (1-3)`. Ask only weight ≥ 4. Below that: decide, D-ID, continue. Weight ≥ 6 additionally requires presenting one real alternative.
|
|
12
|
+
|
|
13
|
+
## Decision brief (the only question format)
|
|
14
|
+
> **Decision:** one line. **Context:** ≤3 lines, what research found. **Options:** A (recommended, why) / B (why not) [/ C]. **Default if no answer:** A.
|
|
15
|
+
|
|
16
|
+
One decision per message during Stages 1 and 4. No stacked questions.
|
|
17
|
+
|
|
18
|
+
## Budget & escapes
|
|
19
|
+
- ~25 asked decisions per project. At 20, warn; at 25, switch to **auto-pilot**: everything becomes Mechanical-with-D-ID except GATED items and User-Challenges.
|
|
20
|
+
- **Readiness meter** on every interrogation message: `readiness: 6/10 — premise firm, data lifecycle unknown, no anti-goals yet`. The user can say "freeze" at any level; record the gaps as RISK entries.
|
|
21
|
+
- **2-probe cap on vagueness:** if two rephrasings of the same question both get vague answers, stop probing — record a RISK ("R-x rests on assumed usage pattern [assumed]") and continue. Vague twice means the user doesn't know yet; the risk register, not the user, carries it from here.
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: plan
|
|
3
|
+
description: Use when a bestest project enters P3 — turn the frozen SPEC into zero-context task cards that survive the plan-checker and trace.sh.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Plan
|
|
7
|
+
|
|
8
|
+
Input: frozen SPEC. Output: `.bestest/PLAN.md` (ordered index + rationale) and `.bestest/plans/T-##.md` cards (template: task-card.md). Assets the build needs (data, fixtures, images, seeds): `references/assets.md`.
|
|
9
|
+
|
|
10
|
+
## Card discipline
|
|
11
|
+
- **Zero-context contract:** a fresh subagent with only the card + LESSONS.md must succeed. Exact paths, signatures, data shapes, D-ID pointers. No placeholders, no "as discussed".
|
|
12
|
+
- **Tracer bullet first:** T-01 is always the thinnest end-to-end slice through the real stack — it flushes environment lies before they infect ten cards.
|
|
13
|
+
- **TDD pairing:** tests are authored by a card with `may_edit_tests: true`; the implementer card that follows has `false` and makes them pass (the lock-guard hook enforces this physically).
|
|
14
|
+
- **Complexity formula**, computed honestly on every card: `1 + 2/extra file + 2/verify command + 3 if the title needs "and" + 2/new interface`. Over 6 → split before anyone reviews it.
|
|
15
|
+
- Every card: `requirements:` R-IDs (no orphan cards), `files:` blast radius, `verify:` commands a machine can re-run, `blocked_by:` for real order constraints only.
|
|
16
|
+
|
|
17
|
+
## Complexity Justification table (in PLAN.md)
|
|
18
|
+
Any design element beyond the simplest thing satisfying the R-IDs gets a row: `| Complexity | Why needed | Simpler alternative rejected because |`. No row → the plan-checker counts it as a blocker. This is where architecture astronautics goes to die.
|
|
19
|
+
|
|
20
|
+
## Checker loop (gate)
|
|
21
|
+
1. Dispatch **plan-checker** agent (card mode) with PLAN.md + cards + SPEC.
|
|
22
|
+
2. It recomputes complexity, hunts placeholders, orphan cards, uncovered R-IDs, missing assets, unjustified complexity. Verdict PASS or numbered blockers.
|
|
23
|
+
3. Fix and redispatch — **max 3 loops**; still failing → the SPEC is probably wrong: INTERRUPT the user with the specific contradiction.
|
|
24
|
+
4. Run `"$PLUGIN"/scripts/trace.sh --plan` where `PLUGIN` = the `plugin:` line in STATE.md — must print PASS (this is gate evidence, attach output).
|
|
25
|
+
5. Show the user one screen: task list, order, complexity totals, justification table. Approval → P4. (Card tampering by builders is caught mechanically: cards are never in a card's own `files:` list, so any card edit fails the diff-scope gate.)
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# Asset planning
|
|
2
|
+
|
|
3
|
+
Builds fail on missing *stuff* more often than missing code. During P3, walk SPEC §6 and make every asset a card or a card field — never an implicit hope.
|
|
4
|
+
|
|
5
|
+
## Checklist per asset
|
|
6
|
+
- **Data/fixtures:** source (generated? scraped? user-provided?), shape (schema written down), volume, refresh story. Generated data gets a generation card with a `verify:` that checks shape + count.
|
|
7
|
+
- **Images/media:** who produces them (model-generated placeholder vs user-supplied final), exact dimensions/format, where they live. Placeholder art is fine if a DISCOVERED line records the swap-before-ship.
|
|
8
|
+
- **Seeds/config/env:** every env var named in a card; secrets are GATED (user provides, never fabricated, never committed — verify `.gitignore` covers their file in the tracer card).
|
|
9
|
+
- **External accounts/keys:** API keys, OAuth apps, buckets — user-provided, requested at plan approval (not mid-build, where they stall a subagent).
|
|
10
|
+
- **Test doubles:** which externals get faked in tests, and one contract test per fake that pins the real shape it mimics.
|
|
11
|
+
|
|
12
|
+
## Rules
|
|
13
|
+
- An asset nobody is assigned to produce is a plan bug — the plan-checker flags it.
|
|
14
|
+
- Asset-producing cards run **before** their consumers (`blocked_by:`).
|
|
15
|
+
- If an asset needs the user (credentials, brand art, real data), collect it at the P3 approval screen — batch, once.
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: research
|
|
3
|
+
description: Use when a bestest project needs external facts — P1 stack derivation, doc-cited challenges, or any claim that must be [cited:URL] instead of remembered.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Research
|
|
7
|
+
|
|
8
|
+
Rule zero: **memory is a rumor.** Anything external — API shape, pricing, limit, version, benchmark — is `[assumed]` until a fetched URL says otherwise. `[assumed]` load-bearing claims block the P1 gate.
|
|
9
|
+
|
|
10
|
+
## Loop (per research question)
|
|
11
|
+
1. **Frame** — write `.bestest/research/RQ-<slug>.md`: the question, why it matters (which R-ID/decision it feeds), what answer shape is needed.
|
|
12
|
+
2. **Fan out** — dispatch researcher agents in parallel, one per RQ (or per candidate for comparisons). Each returns findings with URLs; they write their own RQ file (file handoff, not chat recall).
|
|
13
|
+
3. **Verify adversarially** — for each load-bearing claim, one attempt to refute it: a second independent source, or the primary source read closely (changelogs, pricing pages, GitHub issues beat blog posts). Claims that survive get `[cited:URL]`; claims that don't get flagged to the user or dropped.
|
|
14
|
+
4. **Synthesize** — decision-brief per open decision: options, recommendation, evidence rows. Feed SPEC §5 / DECISIONS.
|
|
15
|
+
|
|
16
|
+
## Stack derivation (P1)
|
|
17
|
+
Stack is an **output**, never an input. From SPEC constraints (platform, team skills `[user]`, data shape, scale honesty from the Premise) derive candidates → SLOPCHECK every dependency (see interrogate references) → produce the stack decision-brief table, every row cited. Present once, whole, for user approval — that's the single P1 gate.
|
|
18
|
+
|
|
19
|
+
## Citation hygiene
|
|
20
|
+
- Cite the page you actually fetched, not the search snippet.
|
|
21
|
+
- Version-sensitive claims name the version and date.
|
|
22
|
+
- Two sources disagree → say so in the brief; don't silently pick.
|
|
23
|
+
- A dead/paywalled source is not a citation.
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: ship
|
|
3
|
+
description: Use when a bestest project enters P5 — UAT against every acceptance criterion, full-chain audit, discovered-work disposition, production runbook, and the go/no-go.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Ship
|
|
7
|
+
|
|
8
|
+
Nothing new gets built here; P5 proves what exists and stages it for production.
|
|
9
|
+
|
|
10
|
+
## 1. UAT — one question per criterion
|
|
11
|
+
Create `.bestest/UAT.md` (template). For each `R-N.M` in SPEC §2: restate the EARS criterion as a single check the user can answer, attach the evidence pointer (command output, screenshot, URL), walk the user through them **one at a time**. Any fail → back to P4 with a card citing that R-ID; do not negotiate the criterion mid-UAT (that's a SPEC amendment: D-ID + re-hash).
|
|
12
|
+
|
|
13
|
+
## 2. Full-chain audit
|
|
14
|
+
`"$PLUGIN"/scripts/trace.sh --all` where `PLUGIN` = the `plugin:` line in STATE.md must print PASS — attach output as gate evidence. It enforces: every criterion covered, every done card reported with FRICTION, every R-ID committed with a `Bestest-Req:` trailer and present in UAT.
|
|
15
|
+
|
|
16
|
+
## 3. Disposition DISCOVERED.md — every line
|
|
17
|
+
Append `| disposition:` to each: `fix-now` (micro-card, run it) / `deferred to <where>` / `wontfix because <reason>`. trace.sh fails any bare line. This is where "never dropped" gets cashed.
|
|
18
|
+
|
|
19
|
+
## 4. LESSONS curation
|
|
20
|
+
Compress LESSONS.md: dedupe, drop task-local noise, keep durable environment/codebase facts. Offer the user the top items for promotion to the project memory file (per harness map) — their call, one batch.
|
|
21
|
+
|
|
22
|
+
## 5. Runbook
|
|
23
|
+
Fill `.bestest/RUNBOOK.md` (template) for the actual derived stack. The rollback section requires a **rehearsal transcript** — actually roll back once, paste it. Timeouts, observability floor, negative-path security smoke, restore drill, spend ceiling: each filled or `n/a + reason`.
|
|
24
|
+
|
|
25
|
+
## 6. Go/no-go
|
|
26
|
+
One screen: doneness function (SPEC §8) evaluated verbatim · UAT table · trace PASS · runbook gaps · open risks with tripwires. The user says go or no-go. **Deploy itself is GATED** — even after "go", the deploy command runs only with explicit user approval, per the Autonomy Contract.
|
|
27
|
+
|
|
28
|
+
On "go": log the gate, set `phase: done` in STATE.md, commit. The lifecycle is complete — the router's next run offers **milestone rollover** (archive to `.bestest/milestones/`, re-enter P0 brownfield).
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: using-bestest
|
|
3
|
+
description: Use when any bestest-managed project work happens — constitution for the bestest lifecycle, its state files, and its non-negotiable laws.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Using bestest
|
|
7
|
+
|
|
8
|
+
One lifecycle: **P0 interrogate → P1 research → P2 spec freeze → P3 plan → P4 build → P5 ship**, routed by the **bestest-go** skill, resumable from `.bestest/STATE.md` after any context clear or compaction (a hook re-injects it).
|
|
9
|
+
|
|
10
|
+
## Laws
|
|
11
|
+
|
|
12
|
+
1. **State lives in `.bestest/`, committed.** Memory is disposable; files are not. Update STATE.md at every gate and task boundary — it is what future-you wakes up to.
|
|
13
|
+
2. **Evidence before claims.** Every "done", "works", "faster" carries evidence: command output, diff, or `[cited:URL]`. Tag facts `[user]` / `[cited:URL]` / `[assumed]`.
|
|
14
|
+
3. **Never ask what's derivable.** Research first; ask only weight≥4 decisions (weight = irreversibility × scope).
|
|
15
|
+
4. **The Autonomy Contract (SPEC §9) governs.** PROCEED / INTERRUPT / GATED — when in doubt, INTERRUPT beats improvising.
|
|
16
|
+
5. **Locks are physical — and root-scoped.** Frozen SPEC and test files are hook-enforced, but hooks see only the session's project root: run bestest sessions from the target repo's root, or locks, guards, state injection, and drift tracking silently don't apply. Don't fight the guard; follow the amendment path it names.
|
|
17
|
+
6. **Discovered ≠ do.** Out-of-blast-radius work goes to DISCOVERED.md — never fixed silently, never dropped.
|
|
18
|
+
7. **Compactness is the product.** Budgets in README are law; exceeding them is a bug.
|
|
19
|
+
|
|
20
|
+
Use your harness's natives — planning mode, todo tracking, subagents, structured questions, worktrees; bestest adds no substitutes. Its names for them, plugin-root resolution, and guarded tools: `references/<harness>.md` (claude-code, codex, opencode).
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
# Harness map — Claude Code
|
|
2
|
+
|
|
3
|
+
| Concept | Native here |
|
|
4
|
+
|---|---|
|
|
5
|
+
| Router | `/bestest:go`, `/bestest:status` (plugin command stubs → bestest-go/bestest-status skills) |
|
|
6
|
+
| Plugin root | `${CLAUDE_PLUGIN_ROOT}`, pre-rendered inside the command stubs; bootstrap records it as the `plugin:` line in STATE.md |
|
|
7
|
+
| Planning mode | plan mode — read-only exploration before mutating anything |
|
|
8
|
+
| Todo tracking | TodoWrite — one entry per gate step or card |
|
|
9
|
+
| Structured user questions | AskUserQuestion — batch weight≥4 decisions into one call |
|
|
10
|
+
| Subagent dispatch | Task tool; plan-checker / researcher / reviewer ship as plugin agents; parallel dispatch supported |
|
|
11
|
+
| Isolation | git worktrees |
|
|
12
|
+
| Compaction survival | SessionStart hook (matcher startup\|resume\|clear\|compact) re-injects STATE.md lines 1–60 + LOCKS + drift notice |
|
|
13
|
+
| Memory file (LESSONS promotion) | CLAUDE.md |
|
|
14
|
+
| Guarded tools | Bash → guard.sh; Write/Edit/MultiEdit → lock-guard.sh, syntax-check.sh |
|
|
15
|
+
|
|
16
|
+
Everything above is wiring, not behavior: the laws in using-bestest are identical on every harness.
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
# Harness map — Codex CLI
|
|
2
|
+
|
|
3
|
+
| Concept | Native here |
|
|
4
|
+
|---|---|
|
|
5
|
+
| Router | `$bestest-go` / `$bestest-status` skill mentions (or implicit trigger by description) |
|
|
6
|
+
| Plugin root | newest dir from `ls -d ~/.codex/plugins/cache/*/bestest/*` — bootstrap records it as the `plugin:` line in STATE.md (hooks also get `${CLAUDE_PLUGIN_ROOT}` env) |
|
|
7
|
+
| Planning mode | `/plan` |
|
|
8
|
+
| Todo tracking | built-in plan/update_plan facility |
|
|
9
|
+
| Structured user questions | plain chat — one decision per message, options lettered |
|
|
10
|
+
| Subagent dispatch | prose-directed dispatch works once roles are registered; **bootstrap extra (gated shell step): copy `adapters/codex/agents/*.toml` from the plugin root into the project's `.codex/agents/`** — plugin-bundled agents don't auto-register; depth 1 |
|
|
11
|
+
| Isolation | separate checkout (no native worktree command) |
|
|
12
|
+
| Compaction survival | SessionStart + PostCompact hooks re-inject STATE.md lines 1–60 + LOCKS + drift notice |
|
|
13
|
+
| Memory file (LESSONS promotion) | AGENTS.md (32 KiB read cap) |
|
|
14
|
+
| Guarded tools | shell → guard.sh; apply_patch (file edits) → lock-guard.sh, syntax-check.sh |
|
|
15
|
+
| Hook trust | hooks need a one-time trust review at install; any script update re-flags them — re-trust or they silently stop enforcing |
|
|
16
|
+
|
|
17
|
+
Everything above is wiring, not behavior: the laws in using-bestest are identical on every harness.
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
# Harness map — OpenCode
|
|
2
|
+
|
|
3
|
+
| Concept | Native here |
|
|
4
|
+
|---|---|
|
|
5
|
+
| Router | `/bestest-go`, `/bestest-status` commands (installed stubs → skills) |
|
|
6
|
+
| Skill names | installed with a `bestest-` prefix (`bestest-interrogate`, `bestest-plan`, …) — prose saying "the interrogate skill" means `bestest-interrogate` |
|
|
7
|
+
| Plugin root | `.opencode/bestest` (runtime payload the installer copied); recorded as the `plugin:` line in STATE.md at bootstrap |
|
|
8
|
+
| Planning mode | Plan agent (Tab-cycled primary) |
|
|
9
|
+
| Todo tracking | todowrite tool |
|
|
10
|
+
| Structured user questions | question tool — batch weight≥4 decisions |
|
|
11
|
+
| Subagent dispatch | task tool with the installed plan-checker / researcher / reviewer agents (`@mention` or prose-directed) |
|
|
12
|
+
| Isolation | git worktrees via your own shell steps |
|
|
13
|
+
| Compaction survival | `opencode.json` instructions loads `.bestest/.context.md` (plugin-maintained digest: STATE.md 1–60 + LOCKS + active card + DRIFT); compaction re-inject rides the plugin |
|
|
14
|
+
| Memory file (LESSONS promotion) | AGENTS.md |
|
|
15
|
+
| Guarded tools | bash → guard.sh; write/edit/apply_patch → lock-guard.sh, syntax-check.sh — via the `@accidentally-awesome-labs/opencode-bestest` npm plugin (exit 2 → blocked) |
|
|
16
|
+
| Degraded mode | without the npm plugin there are NO guards, no auto-injection, no drift detection — commands still resume by reading `.bestest/STATE.md` |
|
|
17
|
+
|
|
18
|
+
Everything above is wiring, not behavior: the laws in using-bestest are identical on every harness.
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
# DEBUG — <symptom slug>
|
|
2
|
+
<!-- One file per investigation: .bestest/DEBUG-<slug>.md. Survives /clear. -->
|
|
3
|
+
|
|
4
|
+
## Symptom
|
|
5
|
+
<!-- exact observed behavior + exact expected behavior; error text verbatim -->
|
|
6
|
+
|
|
7
|
+
## Reproduction test
|
|
8
|
+
<!-- IRON LAW: no fix until a failing repro test exists. Path + command + failing output. -->
|
|
9
|
+
|
|
10
|
+
## Hypotheses
|
|
11
|
+
<!-- | H# | hypothesis | cheapest discriminating probe | status: open/confirmed/eliminated | -->
|
|
12
|
+
|
|
13
|
+
## Eliminated (append-only)
|
|
14
|
+
<!-- H# + the evidence that killed it — never retry an eliminated hypothesis -->
|
|
15
|
+
|
|
16
|
+
## Fix + verification
|
|
17
|
+
<!-- diff summary; repro test now passing (output); which R-IDs re-verified -->
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
# DECISIONS — append-only
|
|
2
|
+
<!-- Never rewrite history; supersede with a new D-ID that references the old. -->
|
|
3
|
+
|
|
4
|
+
## Decisions
|
|
5
|
+
<!-- D-001 | class: Mechanical/Taste/User-Challenge | weight: N | decision | rationale | evidence: [user]/[cited:URL]/[assumed] -->
|
|
6
|
+
|
|
7
|
+
## Risk register
|
|
8
|
+
<!-- RISK-001 | description | likelihood | blast radius | tripwire that reopens it -->
|
|
9
|
+
|
|
10
|
+
## Review waivers
|
|
11
|
+
<!-- D-0NN | class: Waiver | finding waived | why acceptable | revisit trigger (date or event) — waivers are decisions, same D-ID sequence -->
|