Files
command-center/agent/managed-skills/dankvoice-bundle-swap-red-proof/SKILL.md
T

3.8 KiB

name, description
name description
dankvoice-bundle-swap-red-proof Prove a dankvoice behavior test is red-before/green-after by pointing DV_EXT at the previously committed dist bundle, with a pinned scratch fixture dir.

Use when a new black-box tests/behavior.bats assertion in dankvoice must be shown to be red-capable (fails on the pre-change code) without git stash/worktree juggling, or when the old bundle must be compared to the new one.

Why

The bats suite drives dist/index.js only (nothing imports src/), and the bundle is self-contained. So the previous commit's behavior is one git show away: write it to a file, point DV_EXT at it, run the same driver, and read the same PLAYS n / CALL / NOTIFY lines the test asserts.

Procedure

  1. Build the new bundle and export the old one:
    cd ~/Projects/<dankvoice-checkout>
    bun run build >/dev/null 2>&1
    git show HEAD:dist/index.js > /tmp/old-dist.js
    
  2. Stand up the fixtures in a pinned scratch dir — never $(ls -dt /tmp/tmp.* | head -1): other live sessions on the box create tmp.* dirs continuously, and a glob picks theirs, which is how a red-proof silently becomes "Module not found" and then a false PLAYS 0.
    W=/tmp/dv-redproof; rm -rf "$W"; mkdir -p "$W/bin"
    
  3. Copy the real player stub, not a simplification. The driver counts plays from the stub log; a stub that only sleeps records nothing and reports PLAYS 0 for every build, red and green alike. Mirror setup() in tests/behavior.bats:
    cat > "$W/player.sh" <<'SH'
    #!/usr/bin/env bash
    printf '%s\n' "$*" >> "$DV_STUB_LOG"
    for arg in "$@"; do case "$arg" in *.wav) cp "$arg" "$DV_COPY" ;; esac; done
    sleep "${DV_HOLD:-0.1}"
    SH
    chmod +x "$W/player.sh"
    ln -s "$W/player.sh" "$W/bin/pw-play"          # PATH fallback player
    printf '#!/usr/bin/env bash\nprintf "116\\talsa_output.usb-KT.0\\taudio/sink\\t*\\n"\n' > "$W/bin/wpctl"
    chmod +x "$W/bin/wpctl"
    sed -n '86,408p' tests/behavior.bats > "$W/driver.ts"   # the inline heredoc driver
    
    (Re-check those line bounds against the current file; the driver lives inside setup().)
  4. Export the env the driver expects and run old vs new against the SAME scenario:
    export DV_STUB="$W/player.sh" DV_STUB_LOG="$W/player.log" DV_COPY="$W/played.wav" \
           DV_OMPCONFIG=/dev/null DANKVOICE_CONFIG="$W/settings.json" DV_MODELS="$W/models.yml" DV_WPCTL=x
    for ext in /tmp/old-dist.js "$PWD/dist/index.js"; do
      rm -f "$W/player.log"
      DV_EXT="$ext" DV_PLAYER_BIN="$W/no-such-player" bun "$W/driver.ts" speak | grep -E '^PLAYS|^NOTIFY'
    done
    
    The driver sets its own fixture server URL and prepends dirname "$DV_STUB")/bin to PATH (see its DANKVOICE_* block), so the discovered-player fallback has somewhere real to land.
  5. Add a control: same scenario with a valid player path. Old-vs-new differences that the control also shows are harness bugs, not behavior changes.

Reading the result

  • old PLAYS 0 + new PLAYS 1 + control PLAYS 1 → the assertion is red-capable and the fix is real.
  • identical results old vs new → the harness is lying (stub too thin, wrong scratch dir, or the scenario never reaches the changed path). Fix the harness before believing any green.
  • File-mode assertions: pre-seed the file with the old mode (printf … > file; chmod 644 file) — a fresh write with mode: in writeFileSync only applies at creation, so a fresh file can look green while the old code is equally green.

Gotchas

  • Never poll the bats suite while doing this; setup() runs bun run build, so a concurrent src/ edit gets compiled into someone else's run (see dankvoice-bats-serialization).
  • bun run build does not typecheck; a stale identifier reference survives bundling and only fails at runtime — the suite, not the build, is the gate.