deepflow 0.1.54 → 0.1.56
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/bin/deepflow-auto.sh +67 -22
- package/package.json +1 -1
package/bin/deepflow-auto.sh
CHANGED
|
@@ -28,11 +28,30 @@ INTERRUPTED=false
|
|
|
28
28
|
# restarted with --resume to get a fresh context window.
|
|
29
29
|
CONTEXT_THRESHOLD_PCT=50
|
|
30
30
|
|
|
31
|
-
#
|
|
32
|
-
#
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
31
|
+
# Per-spec status/winner tracking (bash 3.2 compatible, no associative arrays)
|
|
32
|
+
# Uses a temp directory with one file per key.
|
|
33
|
+
_SPEC_MAP_DIR=""
|
|
34
|
+
_spec_map_init() {
|
|
35
|
+
if [[ -z "$_SPEC_MAP_DIR" ]]; then
|
|
36
|
+
_SPEC_MAP_DIR="$(mktemp -d "${TMPDIR:-/tmp}/deepflow-spec-map.XXXXXX")"
|
|
37
|
+
fi
|
|
38
|
+
}
|
|
39
|
+
_spec_set() { # usage: _spec_set STATUS myspec converged
|
|
40
|
+
_spec_map_init
|
|
41
|
+
printf '%s' "$3" > "${_SPEC_MAP_DIR}/${1}__${2}"
|
|
42
|
+
}
|
|
43
|
+
_spec_get() { # usage: _spec_get STATUS myspec [default]
|
|
44
|
+
_spec_map_init
|
|
45
|
+
local f="${_SPEC_MAP_DIR}/${1}__${2}"
|
|
46
|
+
if [[ -f "$f" ]]; then cat "$f"; else printf '%s' "${3:-}"; fi
|
|
47
|
+
}
|
|
48
|
+
_spec_isset() { # usage: _spec_isset STATUS myspec
|
|
49
|
+
_spec_map_init
|
|
50
|
+
[[ -f "${_SPEC_MAP_DIR}/${1}__${2}" ]]
|
|
51
|
+
}
|
|
52
|
+
_spec_map_cleanup() {
|
|
53
|
+
[[ -n "$_SPEC_MAP_DIR" && -d "$_SPEC_MAP_DIR" ]] && rm -rf "$_SPEC_MAP_DIR"
|
|
54
|
+
}
|
|
36
55
|
|
|
37
56
|
# ---------------------------------------------------------------------------
|
|
38
57
|
# Logging
|
|
@@ -436,6 +455,7 @@ run_single_spike() {
|
|
|
436
455
|
local slug="$2"
|
|
437
456
|
local hypothesis="$3"
|
|
438
457
|
local method="$4"
|
|
458
|
+
local spec_file="$5"
|
|
439
459
|
|
|
440
460
|
local worktree_path="${PROJECT_ROOT}/.deepflow/worktrees/${spec_name}-${slug}"
|
|
441
461
|
local branch_name="df/${spec_name}-${slug}"
|
|
@@ -455,6 +475,12 @@ run_single_spike() {
|
|
|
455
475
|
}
|
|
456
476
|
fi
|
|
457
477
|
|
|
478
|
+
# Extract acceptance criteria from spec (the human's judgment proxy)
|
|
479
|
+
local acceptance_criteria=""
|
|
480
|
+
if [[ -f "$spec_file" ]]; then
|
|
481
|
+
acceptance_criteria="$(sed -n '/^## Acceptance Criteria/,/^## /{ /^## Acceptance Criteria/d; /^## /d; p; }' "$spec_file")"
|
|
482
|
+
fi
|
|
483
|
+
|
|
458
484
|
# Build spike prompt
|
|
459
485
|
local spike_prompt
|
|
460
486
|
spike_prompt="You are running a spike experiment to validate a hypothesis for spec '${spec_name}'.
|
|
@@ -465,13 +491,19 @@ Hypothesis: ${hypothesis}
|
|
|
465
491
|
Method: ${method}
|
|
466
492
|
--- END HYPOTHESIS ---
|
|
467
493
|
|
|
494
|
+
--- ACCEPTANCE CRITERIA (from spec — the human's judgment proxy) ---
|
|
495
|
+
${acceptance_criteria}
|
|
496
|
+
--- END ACCEPTANCE CRITERIA ---
|
|
497
|
+
|
|
468
498
|
Your tasks:
|
|
469
499
|
1. Validate this hypothesis by implementing the minimum necessary to prove or disprove it.
|
|
500
|
+
The spike must demonstrate that the approach can satisfy the acceptance criteria above.
|
|
470
501
|
2. Write an experiment file at: .deepflow/experiments/${spec_name}--${slug}--active.md
|
|
471
502
|
The experiment file should contain:
|
|
472
503
|
- ## Hypothesis: restate the hypothesis
|
|
473
504
|
- ## Method: what you did to validate
|
|
474
505
|
- ## Results: what you observed
|
|
506
|
+
- ## Criteria Check: for each acceptance criterion, can this approach satisfy it? (yes/no/unclear)
|
|
475
507
|
- ## Conclusion: PASSED or FAILED with reasoning
|
|
476
508
|
3. Write a result YAML file at: .deepflow/results/spike-${slug}.yaml
|
|
477
509
|
The YAML must contain:
|
|
@@ -573,7 +605,7 @@ run_spikes() {
|
|
|
573
605
|
auto_log "Spawning spike for ${slug} (hypothesis ${i}/${count})"
|
|
574
606
|
echo "Spawning spike: ${slug}"
|
|
575
607
|
|
|
576
|
-
run_single_spike "$spec_name" "$slug" "$hypothesis" "$method" &
|
|
608
|
+
run_single_spike "$spec_name" "$slug" "$hypothesis" "$method" "$spec_file" &
|
|
577
609
|
pids+=($!)
|
|
578
610
|
done
|
|
579
611
|
|
|
@@ -875,6 +907,13 @@ $(cat "$experiment_file")
|
|
|
875
907
|
# -----------------------------------------------------------------------
|
|
876
908
|
# 2. Build selection prompt
|
|
877
909
|
# -----------------------------------------------------------------------
|
|
910
|
+
|
|
911
|
+
# Extract acceptance criteria from spec (the human's judgment proxy)
|
|
912
|
+
local acceptance_criteria=""
|
|
913
|
+
if [[ -f "$spec_file" ]]; then
|
|
914
|
+
acceptance_criteria="$(sed -n '/^## Acceptance Criteria/,/^## /{ /^## Acceptance Criteria/d; /^## /d; p; }' "$spec_file")"
|
|
915
|
+
fi
|
|
916
|
+
|
|
878
917
|
local selection_prompt
|
|
879
918
|
selection_prompt="You are an adversarial quality judge in an autonomous development workflow.
|
|
880
919
|
Your job is to compare implementation approaches for spec '${spec_name}' and select the best one — or reject all if quality is insufficient.
|
|
@@ -883,6 +922,11 @@ IMPORTANT:
|
|
|
883
922
|
- This selection phase ALWAYS runs, even with only 1 approach. With a single approach you act as a quality gate.
|
|
884
923
|
- You CAN and SHOULD reject all approaches if the quality is insufficient. Do not rubber-stamp poor work.
|
|
885
924
|
- Base your judgment ONLY on the artifacts provided below. Do NOT read code files.
|
|
925
|
+
- Judge each approach against the ACCEPTANCE CRITERIA below — these represent the human's intent.
|
|
926
|
+
|
|
927
|
+
--- ACCEPTANCE CRITERIA (from spec) ---
|
|
928
|
+
${acceptance_criteria}
|
|
929
|
+
--- END ACCEPTANCE CRITERIA ---
|
|
886
930
|
|
|
887
931
|
There are ${#approach_slugs[@]} approach(es) to evaluate:
|
|
888
932
|
|
|
@@ -1025,18 +1069,18 @@ generate_report() {
|
|
|
1025
1069
|
all_spec_names+=("$sname")
|
|
1026
1070
|
|
|
1027
1071
|
# If status was not set by the main loop, determine it now
|
|
1028
|
-
if
|
|
1072
|
+
if ! _spec_isset STATUS "$sname"; then
|
|
1029
1073
|
# Check if winner file exists
|
|
1030
1074
|
if [[ -f "${PROJECT_ROOT}/.deepflow/selection/${sname}-winner.json" ]]; then
|
|
1031
|
-
|
|
1075
|
+
_spec_set STATUS "$sname" "converged"
|
|
1032
1076
|
# Extract winner slug
|
|
1033
1077
|
local w_slug
|
|
1034
1078
|
w_slug="$(grep -o '"winner"[[:space:]]*:[[:space:]]*"[^"]*"' "${PROJECT_ROOT}/.deepflow/selection/${sname}-winner.json" | sed 's/.*"winner"[[:space:]]*:[[:space:]]*"\([^"]*\)".*/\1/')" || w_slug=""
|
|
1035
|
-
|
|
1079
|
+
_spec_set WINNER "$sname" "$w_slug"
|
|
1036
1080
|
elif [[ "$INTERRUPTED" == "true" ]]; then
|
|
1037
|
-
|
|
1081
|
+
_spec_set STATUS "$sname" "in-progress"
|
|
1038
1082
|
else
|
|
1039
|
-
|
|
1083
|
+
_spec_set STATUS "$sname" "halted"
|
|
1040
1084
|
fi
|
|
1041
1085
|
fi
|
|
1042
1086
|
done
|
|
@@ -1045,15 +1089,15 @@ generate_report() {
|
|
|
1045
1089
|
# If interrupted, override any unfinished specs
|
|
1046
1090
|
if [[ "$INTERRUPTED" == "true" ]]; then
|
|
1047
1091
|
for sname in "${all_spec_names[@]}"; do
|
|
1048
|
-
if [[ "$
|
|
1049
|
-
|
|
1092
|
+
if [[ "$(_spec_get STATUS "$sname")" != "converged" ]]; then
|
|
1093
|
+
_spec_set STATUS "$sname" "in-progress"
|
|
1050
1094
|
fi
|
|
1051
1095
|
done
|
|
1052
1096
|
overall_status="in-progress"
|
|
1053
1097
|
else
|
|
1054
1098
|
# Determine overall status from per-spec statuses
|
|
1055
1099
|
for sname in "${all_spec_names[@]}"; do
|
|
1056
|
-
local s="$
|
|
1100
|
+
local s="$(_spec_get STATUS "$sname")"
|
|
1057
1101
|
if [[ "$s" == "halted" ]]; then
|
|
1058
1102
|
overall_status="halted"
|
|
1059
1103
|
elif [[ "$s" == "in-progress" ]]; then
|
|
@@ -1075,7 +1119,7 @@ generate_report() {
|
|
|
1075
1119
|
# Winner info (if converged)
|
|
1076
1120
|
if [[ "$overall_status" == "converged" ]]; then
|
|
1077
1121
|
for sname in "${all_spec_names[@]}"; do
|
|
1078
|
-
local w="$
|
|
1122
|
+
local w="$(_spec_get WINNER "$sname")"
|
|
1079
1123
|
if [[ -n "$w" ]]; then
|
|
1080
1124
|
local summary=""
|
|
1081
1125
|
local winner_file="${PROJECT_ROOT}/.deepflow/selection/${sname}-winner.json"
|
|
@@ -1092,8 +1136,8 @@ generate_report() {
|
|
|
1092
1136
|
echo "| Spec | Status | Winner |"
|
|
1093
1137
|
echo "|------|--------|--------|"
|
|
1094
1138
|
for sname in "${all_spec_names[@]}"; do
|
|
1095
|
-
local s="$
|
|
1096
|
-
local w="$
|
|
1139
|
+
local s="$(_spec_get STATUS "$sname" "unknown")"
|
|
1140
|
+
local w="$(_spec_get WINNER "$sname" "-")"
|
|
1097
1141
|
echo "| ${sname} | ${s} | ${w} |"
|
|
1098
1142
|
done
|
|
1099
1143
|
echo ""
|
|
@@ -1104,7 +1148,7 @@ generate_report() {
|
|
|
1104
1148
|
|
|
1105
1149
|
local has_changes=false
|
|
1106
1150
|
for sname in "${all_spec_names[@]}"; do
|
|
1107
|
-
local w="$
|
|
1151
|
+
local w="$(_spec_get WINNER "$sname")"
|
|
1108
1152
|
if [[ -n "$w" ]]; then
|
|
1109
1153
|
has_changes=true
|
|
1110
1154
|
local branch_name="df/${sname}-${w}"
|
|
@@ -1171,10 +1215,10 @@ run_spec_cycle() {
|
|
|
1171
1215
|
auto_log "Selection accepted for ${spec_file} at cycle ${cycle}"
|
|
1172
1216
|
echo "Selection accepted for $(basename "$spec_file") at cycle ${cycle}"
|
|
1173
1217
|
# Track convergence
|
|
1174
|
-
|
|
1218
|
+
_spec_set STATUS "$spec_name" "converged"
|
|
1175
1219
|
local w_slug
|
|
1176
1220
|
w_slug="$(grep -o '"winner"[[:space:]]*:[[:space:]]*"[^"]*"' "${PROJECT_ROOT}/.deepflow/selection/${spec_name}-winner.json" | sed 's/.*"winner"[[:space:]]*:[[:space:]]*"\([^"]*\)".*/\1/')" || w_slug=""
|
|
1177
|
-
|
|
1221
|
+
_spec_set WINNER "$spec_name" "$w_slug"
|
|
1178
1222
|
break
|
|
1179
1223
|
fi
|
|
1180
1224
|
|
|
@@ -1183,8 +1227,8 @@ run_spec_cycle() {
|
|
|
1183
1227
|
done
|
|
1184
1228
|
|
|
1185
1229
|
# If we exited the loop without converging, mark as halted
|
|
1186
|
-
if [[ "$
|
|
1187
|
-
|
|
1230
|
+
if [[ "$(_spec_get STATUS "$spec_name")" != "converged" ]]; then
|
|
1231
|
+
_spec_set STATUS "$spec_name" "halted"
|
|
1188
1232
|
fi
|
|
1189
1233
|
}
|
|
1190
1234
|
|
|
@@ -1257,6 +1301,7 @@ handle_signal() {
|
|
|
1257
1301
|
}
|
|
1258
1302
|
|
|
1259
1303
|
trap handle_signal SIGINT SIGTERM
|
|
1304
|
+
trap _spec_map_cleanup EXIT
|
|
1260
1305
|
|
|
1261
1306
|
# Safety assertions: this script must never modify spec files or push to remotes.
|
|
1262
1307
|
# These constraints are enforced by design — no write/push commands exist in this script.
|