@ai-dev-methodologies/rlp-desk 0.2.2 → 0.2.3

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ai-dev-methodologies/rlp-desk",
3
- "version": "0.2.2",
3
+ "version": "0.2.3",
4
4
  "description": "Fresh-context iterative loops for Claude Code — autonomous task completion with independent verification",
5
5
  "scripts": {
6
6
  "postinstall": "node scripts/postinstall.js",
@@ -1411,7 +1411,56 @@ run_consensus_verification() {
1411
1411
  # Consensus disagreement
1412
1412
  log_debug "[EXEC] iter=$iter phase=consensus_disagreement round=$CONSENSUS_ROUND claude=$CLAUDE_VERDICT codex=$CODEX_VERDICT action=fix_contract"
1413
1413
 
1414
- # Either fails build combined fix contract
1414
+ # --- Pre-existing failure detection ---
1415
+ # Get files changed by Worker in this iteration
1416
+ local worker_changed_files=""
1417
+ worker_changed_files=$(cd "$ROOT" && git diff --name-only HEAD~1 HEAD 2>/dev/null || echo "")
1418
+ log_debug "[EXEC] iter=$iter worker_changed_files=\"$worker_changed_files\""
1419
+
1420
+ # Check if ALL failing issues reference files NOT touched by the worker
1421
+ local has_worker_caused_issues=0
1422
+ local failing_verdict_file=""
1423
+ if [[ "$CLAUDE_VERDICT" = "fail" ]]; then failing_verdict_file="$claude_verdict_file"
1424
+ elif [[ "$CODEX_VERDICT" = "fail" ]]; then failing_verdict_file="$codex_verdict_file"
1425
+ fi
1426
+
1427
+ if [[ -n "$failing_verdict_file" && -n "$worker_changed_files" ]]; then
1428
+ # Extract file paths mentioned in issues and check against worker changes
1429
+ local issue_files
1430
+ issue_files=$(jq -r '.issues[]? | .description // ""' "$failing_verdict_file" 2>/dev/null)
1431
+ for changed_file in $(echo "$worker_changed_files"); do
1432
+ if echo "$issue_files" | grep -q "$changed_file" 2>/dev/null; then
1433
+ has_worker_caused_issues=1
1434
+ break
1435
+ fi
1436
+ done
1437
+
1438
+ if (( ! has_worker_caused_issues )); then
1439
+ # None of the failing issues reference files the worker changed
1440
+ log " Pre-existing failure detected: failing tests are NOT in files changed by Worker."
1441
+ log_debug "[EXEC] iter=$iter pre_existing_failure=true failing_engine=$([ \"$CLAUDE_VERDICT\" = 'fail' ] && echo claude || echo codex)"
1442
+
1443
+ # Treat as pass — the other engine passed, and failures are pre-existing
1444
+ {
1445
+ echo '{'
1446
+ echo ' "verdict": "pass",'
1447
+ echo ' "verified_at_utc": "'"$(date -u +%Y-%m-%dT%H:%M:%SZ)"'",'
1448
+ echo ' "summary": "Consensus PASS (pre-existing failure filtered): claude='"$CLAUDE_VERDICT"' codex='"$CODEX_VERDICT"'. Failing tests not in worker-changed files.",'
1449
+ echo ' "recommended_state_transition": "complete",'
1450
+ echo ' "pre_existing_failure": true,'
1451
+ echo ' "worker_changed_files": "'"$(echo $worker_changed_files | tr '\n' ',')"'",'
1452
+ echo ' "consensus": {'
1453
+ echo ' "claude": { "verdict": "'"$CLAUDE_VERDICT"'" },'
1454
+ echo ' "codex": { "verdict": "'"$CODEX_VERDICT"'" },'
1455
+ echo ' "round": '"$CONSENSUS_ROUND"
1456
+ echo ' }'
1457
+ echo '}'
1458
+ } | atomic_write "$VERDICT_FILE"
1459
+ return 0
1460
+ fi
1461
+ fi
1462
+
1463
+ # --- Worker-caused failure: build fix contract as before ---
1415
1464
  local fix_contract="$LOGS_DIR/iter-$(printf '%03d' $iter).fix-contract.md"
1416
1465
  {
1417
1466
  echo "# Fix Contract (Consensus Round $CONSENSUS_ROUND, iteration $iter)"
@@ -1577,9 +1626,13 @@ main() {
1577
1626
  PREV_CONTEXT_HASH=$(compute_context_hash)
1578
1627
 
1579
1628
  # --- governance.md s7: Leader Loop ---
1629
+ local HARD_CEILING=$(( ITER_TIMEOUT * 3 )) # absolute max per iteration (no extensions beyond this)
1630
+
1580
1631
  for (( ITERATION = 1; ITERATION <= MAX_ITER; ITERATION++ )); do
1581
1632
  log ""
1582
1633
  log "========== Iteration $ITERATION / $MAX_ITER =========="
1634
+ local ITER_START_TIME
1635
+ ITER_START_TIME=$(date +%s)
1583
1636
  local _iter_contract=""
1584
1637
  _iter_contract=$(sed -n '/^## Next Iteration Contract$/,/^## /{ /^## Next/d; /^## [^N]/d; p; }' "$MEMORY_FILE" 2>/dev/null | head -1 | tr '\n' ' ')
1585
1638
  log_debug "[EXEC] iter=$ITERATION start contract=\"${_iter_contract:-none}\""
@@ -1692,8 +1745,20 @@ main() {
1692
1745
  local worker_cmd
1693
1746
  worker_cmd=$(tmux display-message -p -t "$WORKER_PANE" '#{pane_current_command}' 2>/dev/null)
1694
1747
  if [[ "$worker_cmd" == "node" || "$worker_cmd" == "claude" || "$worker_cmd" == "codex" ]]; then
1695
- log " Worker timed out but still active ($worker_cmd). Extending poll..."
1696
- log_debug "[EXEC] iter=$ITERATION timeout_active=true process=$worker_cmd"
1748
+ # Check hard ceiling before extending
1749
+ local iter_elapsed=$(( $(date +%s) - ITER_START_TIME ))
1750
+ if (( iter_elapsed >= HARD_CEILING )); then
1751
+ log_error "Worker hit hard ceiling (${HARD_CEILING}s = 3x iter_timeout). Killing iteration."
1752
+ log_debug "[EXEC] iter=$ITERATION hard_ceiling_hit=true elapsed=${iter_elapsed}s ceiling=${HARD_CEILING}s process=$worker_cmd"
1753
+ tmux send-keys -t "$WORKER_PANE" C-c 2>/dev/null
1754
+ sleep 1
1755
+ WORKER_PANE=$(replace_worker_pane "$WORKER_PANE" "worker")
1756
+ update_status "worker" "hard_timeout"
1757
+ worker_poll_done=1
1758
+ break
1759
+ fi
1760
+ log " Worker timed out but still active ($worker_cmd). Extending poll... (${iter_elapsed}s/${HARD_CEILING}s)"
1761
+ log_debug "[EXEC] iter=$ITERATION timeout_active=true process=$worker_cmd elapsed=${iter_elapsed}s ceiling=${HARD_CEILING}s"
1697
1762
  log_debug "[EXEC] iter=$ITERATION poll_extended=true worker_cmd=$worker_cmd"
1698
1763
  update_status "worker" "slow"
1699
1764
  # Loop continues — re-poll same iteration