Skip to content

Commit cb06659

Browse files
Merge remote-tracking branch 'origin/main' into worktree-20260325-181052
2 parents 4b938ad + c8afbd5 commit cb06659

File tree

4 files changed

+132
-5
lines changed

4 files changed

+132
-5
lines changed

plugins/dso/scripts/sprint-list-epics.sh

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -108,11 +108,13 @@ print(json.dumps({'index': idx, 'child_counts': dict(child_counts)}))
108108
" 2>/dev/null || echo '{"index":{},"child_counts":{}}'
109109
}
110110

111-
# Count non-hidden subdirectories in tracker to detect "has entries but reducer failed"
111+
# Check for non-hidden subdirectories in tracker to detect "has entries but reducer failed".
112+
# Uses find -L to follow symlinks — in worktrees, .tickets-tracker is a symlink to the
113+
# main repo's tracker dir, and find without -L returns 0 entries through symlinks on macOS.
112114
_tracker_has_entries() {
113-
local count
114-
count=$(find "$TRACKER_DIR" -mindepth 1 -maxdepth 1 -type d ! -name '.*' 2>/dev/null | head -1)
115-
[ -n "$count" ]
115+
local first_entry
116+
first_entry=$(find -L "$TRACKER_DIR" -mindepth 1 -maxdepth 1 -type d ! -name '.*' 2>/dev/null | head -1)
117+
[ -n "$first_entry" ]
116118
}
117119

118120
# Build index with retry on transient failure

plugins/dso/scripts/validate-review-output.sh

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ set -euo pipefail
1818
#
1919
# Caller IDs and their schema hashes (--caller for review-protocol):
2020
# roadmap f4e5f5a355e4c145
21+
# brainstorm f4e5f5a355e4c145
2122
# design-wireframe bd60a68f8060f939
2223
# implementation-plan ae8bfc7bd9a0d7e3
2324
# retro 8a1a3dd74e54f101
@@ -52,6 +53,7 @@ HASH_PLAN_REVIEW="9dba6875b85b7bc3"
5253

5354
# --- Per-caller schema hashes (for --caller with review-protocol) ---
5455
HASH_CALLER_ROADMAP="f4e5f5a355e4c145"
56+
HASH_CALLER_BRAINSTORM="f4e5f5a355e4c145"
5557
HASH_CALLER_DESIGN_WIREFRAME="bd60a68f8060f939"
5658
HASH_CALLER_IMPLEMENTATION_PLAN="ae8bfc7bd9a0d7e3"
5759
HASH_CALLER_RETRO="8a1a3dd74e54f101"
@@ -84,6 +86,7 @@ Prompt IDs:
8486
8587
Caller IDs (use with: review-protocol <file> --caller <id>):
8688
roadmap ${HASH_CALLER_ROADMAP}
89+
brainstorm ${HASH_CALLER_BRAINSTORM}
8790
design-wireframe ${HASH_CALLER_DESIGN_WIREFRAME}
8891
implementation-plan ${HASH_CALLER_IMPLEMENTATION_PLAN}
8992
retro ${HASH_CALLER_RETRO}
@@ -107,6 +110,7 @@ fi
107110

108111
if [[ "$1" == "--list-callers" ]]; then
109112
echo "roadmap ${HASH_CALLER_ROADMAP}"
113+
echo "brainstorm ${HASH_CALLER_BRAINSTORM}"
110114
echo "design-wireframe ${HASH_CALLER_DESIGN_WIREFRAME}"
111115
echo "implementation-plan ${HASH_CALLER_IMPLEMENTATION_PLAN}"
112116
echo "retro ${HASH_CALLER_RETRO}"
@@ -164,7 +168,7 @@ fi
164168
# Validate known caller IDs
165169
if [[ -n "$CALLER_ID" ]]; then
166170
case "$CALLER_ID" in
167-
roadmap|design-wireframe|implementation-plan|retro|design-review|dev-onboarding|preplanning) ;;
171+
roadmap|brainstorm|design-wireframe|implementation-plan|retro|design-review|dev-onboarding|preplanning) ;;
168172
*)
169173
echo "ERROR: unknown caller-id: '$CALLER_ID'" >&2
170174
echo "Run '$SCRIPT_NAME --list-callers' to see valid caller IDs." >&2
@@ -444,6 +448,26 @@ CALLER_SCHEMAS = {
444448
},
445449
],
446450
},
451+
"brainstorm": {
452+
"schema_hash": "f4e5f5a355e4c145",
453+
"perspectives": [
454+
{
455+
"perspective": "Agent Clarity",
456+
"required_dimensions": ["self_contained", "success_measurable"],
457+
"required_finding_fields": [],
458+
},
459+
{
460+
"perspective": "Scope",
461+
"required_dimensions": ["right_sized", "no_overlap", "dependency_aware"],
462+
"required_finding_fields": [],
463+
},
464+
{
465+
"perspective": "Value",
466+
"required_dimensions": ["user_impact", "validation_signal"],
467+
"required_finding_fields": [],
468+
},
469+
],
470+
},
447471
"design-wireframe": {
448472
"schema_hash": "bd60a68f8060f939",
449473
"perspectives": [
@@ -871,6 +895,7 @@ case "$PROMPT_ID" in
871895
if [[ "$FAILED" -eq 0 && -n "$CALLER_ID" ]]; then
872896
case "$CALLER_ID" in
873897
roadmap) CALLER_HASH="$HASH_CALLER_ROADMAP" ;;
898+
brainstorm) CALLER_HASH="$HASH_CALLER_BRAINSTORM" ;;
874899
design-wireframe) CALLER_HASH="$HASH_CALLER_DESIGN_WIREFRAME" ;;
875900
implementation-plan) CALLER_HASH="$HASH_CALLER_IMPLEMENTATION_PLAN" ;;
876901
retro) CALLER_HASH="$HASH_CALLER_RETRO" ;;

tests/hooks/test-validate-review-output.sh

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -724,4 +724,61 @@ assert_ne \
724724
"0" \
725725
"$OLD_DIM_EXIT"
726726

727+
# ============================================================
728+
# 14. brainstorm caller: accepted with same schema as roadmap
729+
# ============================================================
730+
731+
# brainstorm uses the same perspectives as roadmap (Agent Clarity, Scope, Value)
732+
VALID_RP_BRAINSTORM=$(write_fixture "rp-brainstorm-valid.json" '{
733+
"subject": "Brainstorm epic review",
734+
"reviews": [
735+
{
736+
"perspective": "Agent Clarity",
737+
"status": "reviewed",
738+
"dimensions": {
739+
"self_contained": 4,
740+
"success_measurable": 4
741+
},
742+
"findings": []
743+
},
744+
{
745+
"perspective": "Scope",
746+
"status": "reviewed",
747+
"dimensions": {
748+
"right_sized": 4,
749+
"no_overlap": 4,
750+
"dependency_aware": 4
751+
},
752+
"findings": []
753+
},
754+
{
755+
"perspective": "Value",
756+
"status": "reviewed",
757+
"dimensions": {
758+
"user_impact": 4,
759+
"validation_signal": 4
760+
},
761+
"findings": []
762+
}
763+
],
764+
"conflicts": []
765+
}')
766+
767+
VALID_RP_BRAINSTORM_EXIT=$(run_script review-protocol "$VALID_RP_BRAINSTORM" --caller brainstorm)
768+
assert_eq \
769+
"test_review_protocol_caller_brainstorm_valid_passes: valid brainstorm caller schema exits 0" \
770+
"0" \
771+
"$VALID_RP_BRAINSTORM_EXIT"
772+
773+
VALID_RP_BRAINSTORM_OUTPUT=$(run_script_output review-protocol "$VALID_RP_BRAINSTORM" --caller brainstorm)
774+
assert_contains \
775+
"test_review_protocol_caller_brainstorm_schema_valid_yes: brainstorm caller output contains SCHEMA_VALID: yes" \
776+
"SCHEMA_VALID: yes" \
777+
"$VALID_RP_BRAINSTORM_OUTPUT"
778+
779+
assert_contains \
780+
"test_review_protocol_caller_brainstorm_output_includes_caller: output includes caller=brainstorm" \
781+
"caller=brainstorm" \
782+
"$VALID_RP_BRAINSTORM_OUTPUT"
783+
727784
print_summary

tests/scripts/test-sprint-list-epics.sh

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -530,6 +530,49 @@ else
530530
(( FAIL++ ))
531531
fi
532532

533+
# ── Test 27: Retry works when tracker dir is a symlink (worktree scenario) ─────
534+
echo "Test 27: test_retry_through_symlink — retry detects entries through symlink"
535+
test_retry_through_symlink() {
536+
local TDIR27 ACTUAL27 SYMLINK27
537+
TDIR27=$(mktemp -d)
538+
ACTUAL27="$TDIR27/actual-tracker"
539+
SYMLINK27="$TDIR27/symlinked-tracker"
540+
mkdir -p "$ACTUAL27"
541+
542+
# Create a valid v3 epic in the actual directory
543+
make_v3_ticket "$ACTUAL27" "epic-symlink" "epic" "open" "1" "" "Symlink Epic"
544+
545+
# Create a symlink pointing to the actual directory (mimics worktree .tickets-tracker)
546+
ln -s "$ACTUAL27" "$SYMLINK27"
547+
548+
# Make the epic dir temporarily unreadable (simulates transient failure).
549+
# The retry mechanism must detect entries THROUGH the symlink.
550+
chmod 000 "$ACTUAL27/epic-symlink"
551+
552+
# Restore permissions before first retry fires
553+
(sleep 0.1 && chmod 755 "$ACTUAL27/epic-symlink") &
554+
local restore_pid=$!
555+
556+
local out27 exit27=0
557+
out27=$(TICKETS_TRACKER_DIR="$SYMLINK27" SPRINT_MAX_RETRIES=3 SPRINT_RETRY_WAIT=0.8 \
558+
bash "$SCRIPT" 2>/dev/null) || exit27=$?
559+
560+
wait "$restore_pid" 2>/dev/null || true
561+
chmod -R 755 "$ACTUAL27" 2>/dev/null || true
562+
rm -rf "$TDIR27"
563+
564+
# The script should have retried (via symlink) and found the epic
565+
[ "$exit27" -eq 0 ] || return 1
566+
echo "$out27" | grep -q "epic-symlink" || return 1
567+
}
568+
if test_retry_through_symlink; then
569+
echo " PASS: retry works through symlinked tracker dir"
570+
(( PASS++ ))
571+
else
572+
echo " FAIL: retry did not work through symlinked tracker dir" >&2
573+
(( FAIL++ ))
574+
fi
575+
533576
echo ""
534577
echo "Results: $PASS passed, $FAIL failed"
535578
[ "$FAIL" -eq 0 ]

0 commit comments

Comments
 (0)