Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 22 additions & 3 deletions sgt
Original file line number Diff line number Diff line change
Expand Up @@ -6586,6 +6586,8 @@ completion_condition = completion_condition.strip()
acceptance = plan.get("acceptance")
if not isinstance(acceptance, dict):
acceptance = {}
else:
acceptance = dict(acceptance)

allowed_completion_status = {"pending", "completed", "verified", "blocked", "waived"}
plan_completion_status = str(acceptance.get("status") or "").strip().lower()
Expand Down Expand Up @@ -6710,12 +6712,26 @@ completion_doc = {
"not_declared" if not (completion_condition or acceptance) else "pending"
),
}
ralph_completion_blocked = bool(ralph_state.get("completion_blocked_by_condition"))
completion_rollup = str(completion_state.get("rollup") or "").strip().lower()
if ralph_completion_blocked or completion_rollup.startswith("ralph-"):
effective_acceptance = completion_state.get("acceptance")
if isinstance(effective_acceptance, dict):
completion_doc["acceptance"] = dict(effective_acceptance)
effective_status = str(completion_state.get("status") or "").strip().lower()
if effective_status:
completion_doc["status"] = effective_status
effective_rollup = str(completion_state.get("rollup") or "").strip()
if effective_rollup:
completion_doc["rollup"] = effective_rollup
completion_doc["details"] = one_line(completion_state.get("details") or completion_doc["details"])
completion_doc["blocked_reason"] = one_line(completion_state.get("blocked_reason") or completion_doc["blocked_reason"])
timestamp_field = {
"completed": "completed_at",
"verified": "verified_at",
"blocked": "blocked_at",
"waived": "waived_at",
}.get(completion_status)
}.get(str(completion_doc.get("status") or "").strip().lower())
if timestamp_field:
value = acceptance.get(timestamp_field) or completion_state.get(timestamp_field)
if value:
Expand Down Expand Up @@ -6858,9 +6874,10 @@ except Exception:
acceptance = dict(previous_acceptance)

acceptance = dict(acceptance)
for key in list(acceptance):
preserved_declared = {}
for key, value in list(acceptance.items()):
if str(key).startswith("declared_"):
acceptance.pop(key, None)
preserved_declared[str(key)] = value

declared_status = str(acceptance.get("status") or "").strip().lower()
declared_terminal_fields = ("completed_at", "verified_at", "blocked_at", "blocked_reason", "waived_at")
Expand All @@ -6881,6 +6898,8 @@ if status != "blocked":
acceptance.pop("blocked_reason", None)
if status != "waived":
acceptance.pop("waived_at", None)
for key, value in preserved_declared.items():
acceptance[key] = value

now = datetime.now(timezone.utc).replace(microsecond=0).isoformat().replace("+00:00", "Z")
completion["declared"] = bool(condition.strip() or acceptance)
Expand Down
57 changes: 57 additions & 0 deletions test_ralph_mode_config_and_state.sh
Original file line number Diff line number Diff line change
Expand Up @@ -370,6 +370,63 @@ assert acceptance.get("declared_status") == "waived", acceptance
assert acceptance.get("declared_waived_at") == "2026-03-31T09:30:00Z", acceptance
assert "waived_at" not in acceptance, acceptance
PY

export SGT_TEST_ISSUES_JSON="$TMP_ROOT/issues-third.json"
cat > "$SGT_ROOT/.sgt/rigs/demo3" <<'STATE'
https://github.com/acme/demo3
STATE
mkdir -p "$SGT_ROOT/rigs/demo3"
cat > "$SGT_ROOT/.sgt/polecats/demo3-worker" <<'STATE'
RIG=demo3
REPO=https://github.com/acme/demo3
ISSUE=31
BRANCH=sgt/demo3-worker
WORKTREE=/tmp/demo3-worker
SESSION=sgt-demo-worker
STATE

cat > "$SGT_ROOT/rigs/demo3/SGT_PLAN.json" <<'JSON'
{
"version": 1,
"rig": "demo3",
"policy": { "max_in_flight": 1 },
"completion_condition": "Fresh-state proof passes.",
"acceptance": {
"status": "blocked",
"details": "Prior proof run is blocked on a stale operator note.",
"blocked_at": "2026-03-31T10:45:00Z",
"blocked_reason": "waiting for operator signoff"
},
"tasks": []
}
JSON

sgt config ralph demo3 --enable --condition "Keep a live lane running until the new proof lands" --target 1 >/dev/null
sgt plan tick demo3 >/dev/null 2>&1
sgt status --json > "$SGT_ROOT/status-third.json"
sgt plan tick demo3 >/dev/null 2>&1

python3 - "$SGT_ROOT/.sgt/plan-state/demo3.json" <<'PY'
import json
import sys

with open(sys.argv[1], "r", encoding="utf-8") as fh:
plan_state = json.load(fh)

completion = plan_state.get("completion") or {}
assert completion.get("status") == "pending", completion
assert completion.get("rollup") == "ralph-underfilled", completion
assert completion.get("blocked_reason") == "ralph condition unmet: Keep a live lane running until the new proof lands", completion
assert "Ralph mode remains active" in completion.get("details", ""), completion
acceptance = completion.get("acceptance") or {}
assert acceptance.get("status") == "pending", acceptance
assert acceptance.get("details") == "Prior proof run is blocked on a stale operator note.", acceptance
assert acceptance.get("declared_status") == "blocked", acceptance
assert acceptance.get("declared_blocked_at") == "2026-03-31T10:45:00Z", acceptance
assert acceptance.get("declared_blocked_reason") == "waiting for operator signoff", acceptance
assert "blocked_at" not in acceptance, acceptance
assert "blocked_reason" not in acceptance, acceptance
PY
BASH

echo "ALL TESTS PASSED"
Loading