fix: distinguish configuration from hook trust
This commit is contained in:
@@ -201,6 +201,7 @@ def _render_level(result):
|
|||||||
|
|
||||||
def _render_doctor(result):
|
def _render_doctor(result):
|
||||||
ready = result["status"] == "ready"
|
ready = result["status"] == "ready"
|
||||||
|
operational = result.get("operational_status")
|
||||||
_heading("CASAN Doctor")
|
_heading("CASAN Doctor")
|
||||||
print(" %s Harness integrity" % _mark(result["integrity"]["ok"]))
|
print(" %s Harness integrity" % _mark(result["integrity"]["ok"]))
|
||||||
print(" %s Project bootstrap" % _mark(result["bootstrap"]["ok"]))
|
print(" %s Project bootstrap" % _mark(result["bootstrap"]["ok"]))
|
||||||
@@ -218,8 +219,18 @@ def _render_doctor(result):
|
|||||||
print(_color("1;33", "Warnings"))
|
print(_color("1;33", "Warnings"))
|
||||||
for warning in result["warnings"]:
|
for warning in result["warnings"]:
|
||||||
print(" %s %s" % (_warn_mark(), warning))
|
print(" %s %s" % (_warn_mark(), warning))
|
||||||
|
if result.get("required_actions"):
|
||||||
|
print()
|
||||||
|
print(_color("1;33", "Required actions"))
|
||||||
|
for action in result["required_actions"]:
|
||||||
|
print(" %s %s" % (_warn_mark(), action["message"]))
|
||||||
print()
|
print()
|
||||||
status = _color("1;32", "READY") if ready else _color("1;31", "NOT READY")
|
if ready and operational == "user_action_required":
|
||||||
|
status = _color("1;33", "CONFIGURED — USER ACTION REQUIRED")
|
||||||
|
elif ready:
|
||||||
|
status = _color("1;32", "READY")
|
||||||
|
else:
|
||||||
|
status = _color("1;31", "NOT READY")
|
||||||
print("Status: %s" % status)
|
print("Status: %s" % status)
|
||||||
|
|
||||||
|
|
||||||
@@ -1531,6 +1542,7 @@ def cmd_doctor(args):
|
|||||||
"bootstrap": {"ok": bootstrap_ok},
|
"bootstrap": {"ok": bootstrap_ok},
|
||||||
"client_checks": {},
|
"client_checks": {},
|
||||||
"warnings": [],
|
"warnings": [],
|
||||||
|
"required_actions": [],
|
||||||
}
|
}
|
||||||
ready = integrity_ok and bootstrap_ok
|
ready = integrity_ok and bootstrap_ok
|
||||||
vendored_harness = os.path.isfile(os.path.join(
|
vendored_harness = os.path.isfile(os.path.join(
|
||||||
@@ -1608,6 +1620,12 @@ def cmd_doctor(args):
|
|||||||
if "codex" in clients:
|
if "codex" in clients:
|
||||||
checks["warnings"].append(
|
checks["warnings"].append(
|
||||||
"Codex project hooks do not run until their exact hash is reviewed and trusted via /hooks.")
|
"Codex project hooks do not run until their exact hash is reviewed and trusted via /hooks.")
|
||||||
|
checks["required_actions"].append({
|
||||||
|
"code": "codex_hook_trust",
|
||||||
|
"message": (
|
||||||
|
"Open /hooks in a local Codex client, review the exact hook hash, "
|
||||||
|
"and trust it before treating Codex as operational."),
|
||||||
|
})
|
||||||
if "vscode-copilot" in clients:
|
if "vscode-copilot" in clients:
|
||||||
checks["warnings"].append(
|
checks["warnings"].append(
|
||||||
"Only prompts explicitly sent to @casan use the CASAN-owned Copilot route; "
|
"Only prompts explicitly sent to @casan use the CASAN-owned Copilot route; "
|
||||||
@@ -1621,7 +1639,18 @@ def cmd_doctor(args):
|
|||||||
"Legacy prompt-boundary prose outside CASAN-managed markers conflicts "
|
"Legacy prompt-boundary prose outside CASAN-managed markers conflicts "
|
||||||
"with Plan-20 hooks and needs manual review: %s." %
|
"with Plan-20 hooks and needs manual review: %s." %
|
||||||
", ".join(legacy_conflicts))
|
", ".join(legacy_conflicts))
|
||||||
|
checks["required_actions"].append({
|
||||||
|
"code": "legacy_prompt_policy_review",
|
||||||
|
"message": (
|
||||||
|
"Review and migrate conflicting legacy prompt policy: %s." %
|
||||||
|
", ".join(legacy_conflicts)),
|
||||||
|
})
|
||||||
checks["status"] = "ready" if ready else "not_ready"
|
checks["status"] = "ready" if ready else "not_ready"
|
||||||
|
checks["operational_status"] = (
|
||||||
|
"not_ready" if not ready
|
||||||
|
else "user_action_required" if checks["required_actions"]
|
||||||
|
else "ready"
|
||||||
|
)
|
||||||
_emit_json_or_human(args, checks, _render_doctor)
|
_emit_json_or_human(args, checks, _render_doctor)
|
||||||
return 0 if ready else 2
|
return 0 if ready else 2
|
||||||
|
|
||||||
|
|||||||
@@ -480,7 +480,7 @@ else
|
|||||||
pass "init no longer dumps raw JSON by default"
|
pass "init no longer dumps raw JSON by default"
|
||||||
fi
|
fi
|
||||||
( cd "$UN" && "$DKC" doctor --json ) | python3 -c \
|
( cd "$UN" && "$DKC" doctor --json ) | python3 -c \
|
||||||
'import json,sys; d=json.load(sys.stdin); assert d["status"] == "ready"' \
|
'import json,sys; d=json.load(sys.stdin); assert d["status"] == "ready"; assert d["operational_status"] == "ready"' \
|
||||||
&& pass "doctor --json preserves the machine-readable contract" \
|
&& pass "doctor --json preserves the machine-readable contract" \
|
||||||
|| fail "doctor --json is not valid/ready"
|
|| fail "doctor --json is not valid/ready"
|
||||||
echo "project-owned requirement" > "$UN/apps/uninstall-project/domain/input/requirement.md"
|
echo "project-owned requirement" > "$UN/apps/uninstall-project/domain/input/requirement.md"
|
||||||
|
|||||||
@@ -6,8 +6,8 @@ S="$CASAN_HARNESS_ROOT/scripts/bash/upgrade-compatibility.sh"
|
|||||||
M="$CASAN_APP_ROOT/infra/production/compatibility-matrix.json"
|
M="$CASAN_APP_ROOT/infra/production/compatibility-matrix.json"
|
||||||
PASS=0; FAIL=0
|
PASS=0; FAIL=0
|
||||||
pass(){ echo "PASS: $1"; PASS=$((PASS+1)); }; fail(){ echo "FAIL: $1"; FAIL=$((FAIL+1)); }
|
pass(){ echo "PASS: $1"; PASS=$((PASS+1)); }; fail(){ echo "FAIL: $1"; FAIL=$((FAIL+1)); }
|
||||||
if bash "$S" check --from 1.0.2 --to 1.0.3 --matrix "$M" | grep -q '"decision": "allow"'; then pass "patch upgrade is explicitly allowed"; else fail "patch upgrade denied"; fi
|
if bash "$S" check --from 1.0.3 --to 1.0.4 --matrix "$M" | grep -q '"decision": "allow"'; then pass "patch upgrade is explicitly allowed"; else fail "patch upgrade denied"; fi
|
||||||
if bash "$S" check --from 1.0.3 --to 1.0.2 --rollback --matrix "$M" | grep -q '"rollback": true'; then pass "approved rollback is explicitly allowed"; else fail "approved rollback denied"; fi
|
if bash "$S" check --from 1.0.4 --to 1.0.3 --rollback --matrix "$M" | grep -q '"rollback": true'; then pass "approved rollback is explicitly allowed"; else fail "approved rollback denied"; fi
|
||||||
if bash "$S" check --from 1.0.3 --to 2.0.0 --matrix "$M" >/dev/null 2>&1; then fail "unreviewed major upgrade accepted"; else pass "unreviewed major upgrade denied"; fi
|
if bash "$S" check --from 1.0.4 --to 2.0.0 --matrix "$M" >/dev/null 2>&1; then fail "unreviewed major upgrade accepted"; else pass "unreviewed major upgrade denied"; fi
|
||||||
if bash "$S" check --from invalid --to 1.0.0 --matrix "$M" >/dev/null 2>&1; then fail "invalid version accepted"; else pass "invalid version denied"; fi
|
if bash "$S" check --from invalid --to 1.0.0 --matrix "$M" >/dev/null 2>&1; then fail "invalid version accepted"; else pass "invalid version denied"; fi
|
||||||
echo "===== UPGRADE COMPATIBILITY SUMMARY: PASS=$PASS FAIL=$FAIL ====="; [[ "$FAIL" -eq 0 ]]
|
echo "===== UPGRADE COMPATIBILITY SUMMARY: PASS=$PASS FAIL=$FAIL ====="; [[ "$FAIL" -eq 0 ]]
|
||||||
|
|||||||
Reference in New Issue
Block a user