scrum: wrapper resilience + Python tz deprecation fix

Two small fixes after testing the tool end-to-end:

1. scrum_review.sh's tally-aggregation step occasionally exits non-zero
   even when the per-reviewer markdown verdicts are all written
   correctly. Wrapper was bailing on that exit code and dropping the
   KB write. Now the wrapper:
   - Treats scrum_review.sh's exit code as advisory
   - If a tally markdown exists, uses it
   - If only per-reviewer markdowns exist, auto-rebuilds a minimal
     tally listing them (so KB row still gets written)
   - Only bails if NO per-reviewer verdicts at all

2. Python `datetime.utcnow()` deprecated. Switched to
   `datetime.now(datetime.UTC).isoformat().replace("+00:00", "Z")`
   for the same Z-suffix shape callers expect.

Verified: ./scrum --since=HEAD~1 now writes KB row even when
scrum_review.sh's tally step has issues. KB rows: 2 (and growing).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
root 2026-05-03 02:44:45 -05:00
parent dbcd05c5c5
commit 991db7be1a

34
scrum
View File

@ -87,18 +87,32 @@ export LH_GATEWAY="${LH_GATEWAY:-http://127.0.0.1:4110}"
# works correctly (lands in golangLAKEHOUSE root, where reports/ lives). # works correctly (lands in golangLAKEHOUSE root, where reports/ lives).
SCRUM_DIR=$(dirname "$SCRUM_REVIEW") SCRUM_DIR=$(dirname "$SCRUM_REVIEW")
SCRUM_REPO=$(dirname "$SCRUM_DIR") SCRUM_REPO=$(dirname "$SCRUM_DIR")
( cd "$SCRUM_REPO" && bash "$SCRUM_REVIEW" "$DIFF_FILE" "$LABEL" ) || { # Run the underlying review. We treat ANY tally-file produced as a usable
echo "[scrum] reviewers failed — bailing" # result, even if scrum_review.sh exits non-zero on its own aggregation
rm -f "$DIFF_FILE" # step (its tally-counting can mis-fire while the verdicts themselves are
exit 1 # fine — the per-reviewer markdown files are what matter).
} ( cd "$SCRUM_REPO" && bash "$SCRUM_REVIEW" "$DIFF_FILE" "$LABEL" ) || true
# Locate the tally file the review just wrote
TALLY="$SCRUM_REPO/reports/scrum/_evidence/$(date +%Y-%m-%d)/verdicts/${LABEL}_tally.md" TALLY="$SCRUM_REPO/reports/scrum/_evidence/$(date +%Y-%m-%d)/verdicts/${LABEL}_tally.md"
if [ ! -f "$TALLY" ]; then if [ ! -f "$TALLY" ]; then
echo "[scrum] no tally found at $TALLY (review may have failed silently)" # Build a minimal tally from the per-reviewer files if scrum_review.sh
rm -f "$DIFF_FILE" # didn't produce one. Lets findings still flow to the KB.
exit 1 VERDICTS_DIR="$SCRUM_REPO/reports/scrum/_evidence/$(date +%Y-%m-%d)/verdicts"
if ls "$VERDICTS_DIR/${LABEL}_"*.md >/dev/null 2>&1; then
{
echo "# Convergence tally — $LABEL (auto-rebuilt by ./scrum wrapper)"
echo
echo "scrum_review.sh did not emit a tally; per-reviewer verdicts:"
echo
for f in "$VERDICTS_DIR/${LABEL}_"*.md; do
echo "- $(basename "$f")"
done
} > "$TALLY"
else
echo "[scrum] no per-reviewer verdicts produced — bailing"
rm -f "$DIFF_FILE"
exit 1
fi
fi fi
# Push to KB — one JSONL row per scrum run, queryable via DuckDB or jq # Push to KB — one JSONL row per scrum run, queryable via DuckDB or jq
@ -121,7 +135,7 @@ from pathlib import Path
tally = Path("$TALLY").read_text() tally = Path("$TALLY").read_text()
row = { row = {
"schema": "scrum_finding.v1", "schema": "scrum_finding.v1",
"ts": datetime.datetime.utcnow().isoformat() + "Z", "ts": datetime.datetime.now(datetime.UTC).isoformat().replace("+00:00", "Z"),
"label": "$LABEL", "label": "$LABEL",
"diff_mode": "$DIFF_MODE", "diff_mode": "$DIFF_MODE",
"diff_bytes": $DIFF_SIZE, "diff_bytes": $DIFF_SIZE,