fix: address v0.5.0 review findings
- Add --to/--test-cmd mutual exclusivity guard in rollback script - Convert all jq string interpolation to --arg (cmd_extract, cmd_inject, cmd_forget) - Fix CRITICAL/WARNING grep to match table rows only (not prose) - Add thorough+cycle-1 guard to fast-path bash snippet in check-phase - Clarify prev_run_id selection comment (tail -1 = most recent non-current)
This commit is contained in:
@@ -141,14 +141,14 @@ cmd_extract() {
|
|||||||
if [[ "$overlap" -ge 50 ]]; then
|
if [[ "$overlap" -ge 50 ]]; then
|
||||||
# Match found — update existing lesson
|
# Match found — update existing lesson
|
||||||
local tmp_file="${LESSONS_FILE}.tmp"
|
local tmp_file="${LESSONS_FILE}.tmp"
|
||||||
jq -c "
|
jq -c --arg lid "$lesson_id" --arg ts "$(now_ts)" --arg rid "$run_id" '
|
||||||
if .id == \"$lesson_id\" then
|
if .id == $lid then
|
||||||
.frequency += 1 |
|
.frequency += 1 |
|
||||||
.ts = \"$(now_ts)\" |
|
.ts = $ts |
|
||||||
.last_seen_run = \"$run_id\" |
|
.last_seen_run = $rid |
|
||||||
.runs_since_last_seen = 0
|
.runs_since_last_seen = 0
|
||||||
else . end
|
else . end
|
||||||
" "$LESSONS_FILE" > "$tmp_file"
|
' "$LESSONS_FILE" > "$tmp_file"
|
||||||
mv "$tmp_file" "$LESSONS_FILE"
|
mv "$tmp_file" "$LESSONS_FILE"
|
||||||
matched=true
|
matched=true
|
||||||
updated=$((updated + 1))
|
updated=$((updated + 1))
|
||||||
@@ -224,25 +224,25 @@ cmd_inject() {
|
|||||||
# - Filter by domain (match or "general") and archetype (if provided)
|
# - Filter by domain (match or "general") and archetype (if provided)
|
||||||
# - Sort by frequency desc, cap at 10
|
# - Sort by frequency desc, cap at 10
|
||||||
local lessons
|
local lessons
|
||||||
lessons=$(jq -c "
|
lessons=$(jq -c --arg domain "$domain" --arg archetype "$archetype" '
|
||||||
select(
|
select(
|
||||||
(.type == \"preference\") or
|
(.type == "preference") or
|
||||||
(.frequency >= 5) or
|
(.frequency >= 5) or
|
||||||
(
|
(
|
||||||
(.frequency >= 2) and
|
(.frequency >= 2) and
|
||||||
(
|
(
|
||||||
(\"$domain\" == \"\") or
|
($domain == "") or
|
||||||
(.domain == \"$domain\") or
|
(.domain == $domain) or
|
||||||
(.domain == \"general\")
|
(.domain == "general")
|
||||||
) and
|
) and
|
||||||
(
|
(
|
||||||
(\"$archetype\" == \"\") or
|
($archetype == "") or
|
||||||
(.archetype == null) or
|
(.archetype == null) or
|
||||||
(.archetype == \"$archetype\")
|
(.archetype == $archetype)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
" "$LESSONS_FILE" 2>/dev/null | jq -sc 'sort_by(-.frequency) | .[:10][]' 2>/dev/null || true)
|
' "$LESSONS_FILE" 2>/dev/null | jq -sc 'sort_by(-.frequency) | .[:10][]' 2>/dev/null || true)
|
||||||
|
|
||||||
if [[ -z "$lessons" ]]; then
|
if [[ -z "$lessons" ]]; then
|
||||||
return 0
|
return 0
|
||||||
@@ -382,7 +382,9 @@ cmd_regression_check() {
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
local prev_run_id
|
local prev_run_id
|
||||||
|
# Get the most recent run that is not the current one (index is append-newest-last)
|
||||||
prev_run_id=$(jq -r --arg rid "$run_id" 'select(.run_id != $rid) | .run_id' "$INDEX_FILE" 2>/dev/null | tail -1)
|
prev_run_id=$(jq -r --arg rid "$run_id" 'select(.run_id != $rid) | .run_id' "$INDEX_FILE" 2>/dev/null | tail -1)
|
||||||
|
# Note: tail -1 gives the last non-current entry, which is the most recent previous run
|
||||||
|
|
||||||
if [[ -z "$prev_run_id" ]]; then
|
if [[ -z "$prev_run_id" ]]; then
|
||||||
echo "[archeflow-memory] No previous run found — skipping regression check." >&2
|
echo "[archeflow-memory] No previous run found — skipping regression check." >&2
|
||||||
@@ -555,17 +557,17 @@ cmd_forget() {
|
|||||||
ensure_dir
|
ensure_dir
|
||||||
|
|
||||||
# Check if the lesson exists
|
# Check if the lesson exists
|
||||||
if ! jq -e "select(.id == \"$target_id\")" "$LESSONS_FILE" > /dev/null 2>&1; then
|
if ! jq -e --arg tid "$target_id" 'select(.id == $tid)' "$LESSONS_FILE" > /dev/null 2>&1; then
|
||||||
echo "Error: lesson $target_id not found." >&2
|
echo "Error: lesson $target_id not found." >&2
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Archive the lesson
|
# Archive the lesson
|
||||||
jq -c "select(.id == \"$target_id\")" "$LESSONS_FILE" >> "$ARCHIVE_FILE"
|
jq -c --arg tid "$target_id" 'select(.id == $tid)' "$LESSONS_FILE" >> "$ARCHIVE_FILE"
|
||||||
|
|
||||||
# Remove from lessons
|
# Remove from lessons
|
||||||
local tmp_file="${LESSONS_FILE}.tmp"
|
local tmp_file="${LESSONS_FILE}.tmp"
|
||||||
jq -c "select(.id != \"$target_id\")" "$LESSONS_FILE" > "$tmp_file"
|
jq -c --arg tid "$target_id" 'select(.id != $tid)' "$LESSONS_FILE" > "$tmp_file"
|
||||||
mv "$tmp_file" "$LESSONS_FILE"
|
mv "$tmp_file" "$LESSONS_FILE"
|
||||||
|
|
||||||
echo "[archeflow-memory] Forgot lesson $target_id (moved to archive)" >&2
|
echo "[archeflow-memory] Forgot lesson $target_id (moved to archive)" >&2
|
||||||
|
|||||||
@@ -29,6 +29,12 @@ while [[ $# -gt 0 ]]; do
|
|||||||
esac
|
esac
|
||||||
done
|
done
|
||||||
|
|
||||||
|
# Mutual exclusivity check
|
||||||
|
if [[ -n "$TARGET_PHASE" && -n "$TEST_CMD" ]]; then
|
||||||
|
echo "ERROR: --to and --test-cmd are mutually exclusive." >&2
|
||||||
|
exit 2
|
||||||
|
fi
|
||||||
|
|
||||||
# --- Phase rollback mode ---
|
# --- Phase rollback mode ---
|
||||||
if [[ -n "$TARGET_PHASE" ]]; then
|
if [[ -n "$TARGET_PHASE" ]]; then
|
||||||
# Validate phase name
|
# Validate phase name
|
||||||
|
|||||||
@@ -109,18 +109,19 @@ Save output to `.archeflow/artifacts/${RUN_ID}/check-guardian.md`.
|
|||||||
After Guardian completes, parse its output before spawning other reviewers:
|
After Guardian completes, parse its output before spawning other reviewers:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
CRITICAL_COUNT=$(grep -ci "CRITICAL" ".archeflow/artifacts/${RUN_ID}/check-guardian.md" || echo 0)
|
CRITICAL_COUNT=$(grep -c "| CRITICAL |" ".archeflow/artifacts/${RUN_ID}/check-guardian.md" || echo 0)
|
||||||
WARNING_COUNT=$(grep -ci "WARNING" ".archeflow/artifacts/${RUN_ID}/check-guardian.md" || echo 0)
|
WARNING_COUNT=$(grep -c "| WARNING |" ".archeflow/artifacts/${RUN_ID}/check-guardian.md" || echo 0)
|
||||||
|
|
||||||
if [[ "$CRITICAL_COUNT" -eq 0 && "$WARNING_COUNT" -eq 0 && "$ESCALATED" != "true" ]]; then
|
# A2 fast-path: skip remaining reviewers if Guardian is clean
|
||||||
# A2 fast-path: skip remaining reviewers
|
# Exception: first cycle of thorough workflows always spawns all reviewers
|
||||||
|
if [[ "$CRITICAL_COUNT" -eq 0 && "$WARNING_COUNT" -eq 0 \
|
||||||
|
&& "$ESCALATED" != "true" \
|
||||||
|
&& ! ("$WORKFLOW" == "thorough" && "$CYCLE" -eq 1) ]]; then
|
||||||
echo "Guardian fast-path: 0 CRITICAL, 0 WARNING — skipping remaining reviewers."
|
echo "Guardian fast-path: 0 CRITICAL, 0 WARNING — skipping remaining reviewers."
|
||||||
# Proceed directly to Act phase
|
# Proceed directly to Act phase
|
||||||
fi
|
fi
|
||||||
```
|
```
|
||||||
|
|
||||||
**Exception:** First cycle of `thorough` workflows always spawns all reviewers, even if Guardian is clean.
|
|
||||||
|
|
||||||
### Step 3: Parallel Reviewer Spawning
|
### Step 3: Parallel Reviewer Spawning
|
||||||
|
|
||||||
If A2 does not trigger, spawn remaining reviewers in parallel based on workflow:
|
If A2 does not trigger, spawn remaining reviewers in parallel based on workflow:
|
||||||
|
|||||||
Reference in New Issue
Block a user