C: bulk playbook record — operational rating wiring

POST /v1/matrix/playbooks/bulk accepts an array of playbook entries
and records each independently — failures per-entry don't abort the
batch. Designed for two operational use cases:

  1. Backfilling historical placement data into the playbook
     substrate (the Rust system has 4,701 fill operations recorded
     with embeddings; that data deserves to feed the Go learning
     loop without a 4,701-call procedural script).
  2. Batched click-tracking from a session's worth of coordinator
     interactions, posted once at idle rather than per-click.

Per-entry response shape: {index, playbook_id} on success or
{index, error} on failure. Caller can inspect failures without
diffing.

Smoke (scripts/playbook_smoke.sh, new assertion #4):
  Bulk POST 3 entries: 2 valid (alpha→widget-a, bravo→widget-b) +
  1 invalid (empty query_text). Verifies recorded=2, failed=1,
  the 2 valid ones get playbook_ids back, and the invalid one
  surfaces its validation error in-line.

Single-record /matrix/playbooks/record from 06e7152 still works
unchanged; bulk is additive. The corpus field can be set per-
entry or once at the batch level (entry-level wins on collision).

Per the small-model autonomous pipeline framing: this is the
"the playbook gets denser with each iteration" mechanism. Click
tracking → bulk POST → playbook entries → future similar queries
get those answers boosted via the existing /matrix/search
use_playbook path. The learning loop now has both inflows wired
(single + bulk) — what remains is the demo UI shim that calls
/feedback on result interaction (deferred — no Go demo UI yet).

15-smoke regression all green.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
root
2026-04-29 20:10:13 -05:00
co-authored by Claude Opus 4.7
parent b199093d1f
commit 6392772f41
2 changed files with 90 additions and 1 deletions
+23
View File
@@ -166,6 +166,29 @@ else
echo " ✗ ratio out of band: $RATIO"; FAILED=1
fi
# ── 4. /matrix/playbooks/bulk — component C (operational rating wiring)
echo "[playbook-smoke] bulk record 3 entries:"
BULK_RESP="$(curl -sS -X POST http://127.0.0.1:3110/v1/matrix/playbooks/bulk \
-H 'Content-Type: application/json' \
-d "$(jq -n '{
entries: [
{query_text: "alpha test query", answer_id: "widget-a", answer_corpus: "widgets", score: 0.9},
{query_text: "bravo test query", answer_id: "widget-b", answer_corpus: "widgets", score: 0.8},
{query_text: "", answer_id: "x", answer_corpus: "widgets", score: 0.5}
]
}')")"
RECORDED="$(echo "$BULK_RESP" | jq -r '.recorded')"
FAIL="$(echo "$BULK_RESP" | jq -r '.failed')"
GOT_PB_A="$(echo "$BULK_RESP" | jq -r '.results[0].playbook_id // empty')"
ERR_BAD="$(echo "$BULK_RESP" | jq -r '.results[2].error // empty')"
if [ "$RECORDED" = "2" ] && [ "$FAIL" = "1" ] && [ -n "$GOT_PB_A" ] && [ -n "$ERR_BAD" ]; then
echo " ✓ 2 recorded, 1 failed (empty query_text caught), per-entry IDs/errors returned"
else
echo " ✗ recorded=$RECORDED failed=$FAIL pb_a=$GOT_PB_A err=$ERR_BAD"
echo " full: $BULK_RESP"
FAILED=1
fi
if [ "$FAILED" -eq 0 ]; then
echo "[playbook-smoke] Playbook acceptance gate: PASSED"
exit 0