회기 무발화 0턴 분리, 자기예측 락 불변식 및 TDD 회귀 검증 완료
Some checks failed
API contract / OpenAPI type drift (push) Failing after 3m27s
Some checks failed
API contract / OpenAPI type drift (push) Failing after 3m27s
This commit is contained in:
parent
a479db7a5a
commit
a0311c5957
100 changed files with 4884 additions and 11210 deletions
|
|
@ -2,7 +2,6 @@
|
|||
|
||||
from __future__ import annotations
|
||||
|
||||
import hashlib
|
||||
import json
|
||||
from collections.abc import Mapping, Sequence
|
||||
from datetime import UTC, datetime
|
||||
|
|
@ -26,6 +25,13 @@ from .calibration_transfer import (
|
|||
assess_synthetic_subgroup_drift,
|
||||
assess_transfer,
|
||||
)
|
||||
from .outcome_repository_values import (
|
||||
canonical_hash as _canonical_hash,
|
||||
created_role as _created_role,
|
||||
public_row as _public_row,
|
||||
value as _value,
|
||||
)
|
||||
from .practice_competency import target_techniques
|
||||
|
||||
|
||||
class CalibrationTransferNotFoundError(LookupError):
|
||||
|
|
@ -64,36 +70,6 @@ _POSITIVE_CLIENT_STATES = frozenset(
|
|||
)
|
||||
|
||||
|
||||
def _value(row: Mapping[str, Any], key: str, default: Any = None) -> Any:
|
||||
try:
|
||||
return row[key]
|
||||
except (KeyError, TypeError):
|
||||
return default
|
||||
|
||||
|
||||
def _public_row(row: Mapping[str, Any]) -> dict[str, Any]:
|
||||
"""API 응답에서 학습자 피드백 정책 판정 전용 열을 제거한다."""
|
||||
|
||||
payload = dict(row)
|
||||
payload.pop("source_learner_feedback_enabled", None)
|
||||
return payload
|
||||
|
||||
|
||||
def _canonical_hash(payload: Mapping[str, Any]) -> str:
|
||||
serialized = json.dumps(
|
||||
payload,
|
||||
ensure_ascii=False,
|
||||
separators=(",", ":"),
|
||||
sort_keys=True,
|
||||
default=str,
|
||||
)
|
||||
return hashlib.sha256(serialized.encode("utf-8")).hexdigest()
|
||||
|
||||
|
||||
def _created_role(principal: Principal) -> str:
|
||||
return "instructor" if principal.role == Role.TEACHER else principal.role.value
|
||||
|
||||
|
||||
def _ensure_unique_evidence(
|
||||
evidence_turn_ids: Sequence[UUID], *, required: bool = False
|
||||
) -> tuple[UUID, ...]:
|
||||
|
|
@ -182,6 +158,16 @@ async def append_prediction_revision(
|
|||
reason = revision_reason.strip()
|
||||
if not reason:
|
||||
raise CalibrationTransferStateError("revision_reason must not be blank")
|
||||
if not (0.0 <= predicted_success_probability <= 1.0):
|
||||
raise CalibrationTransferStateError(
|
||||
"predicted_success_probability must be between 0.0 and 1.0"
|
||||
)
|
||||
if not (0.0 <= confidence <= 1.0):
|
||||
raise CalibrationTransferStateError(
|
||||
"confidence must be between 0.0 and 1.0"
|
||||
)
|
||||
if instrument_id == "vignette.calibration-self-prediction":
|
||||
instrument_id = "calibration-mirror-g5"
|
||||
payload = {
|
||||
"prediction_revision_id": str(prediction_revision_id),
|
||||
"history_id": str(history_id),
|
||||
|
|
@ -318,6 +304,11 @@ async def append_prediction_revision(
|
|||
asyncpg.ForeignKeyViolationError,
|
||||
asyncpg.ObjectNotInPrerequisiteStateError,
|
||||
) as exc:
|
||||
message = str(exc)
|
||||
if "lock" in message.lower() or "reveal" in message.lower():
|
||||
raise CalibrationTransferStateError(
|
||||
f"self-prediction history is locked or revealed: {message}"
|
||||
) from exc
|
||||
raise CalibrationTransferStateError(
|
||||
"prediction revision violated provenance or history invariants"
|
||||
) from exc
|
||||
|
|
@ -880,21 +871,9 @@ async def append_transfer_suite(
|
|||
|
||||
|
||||
def _actual_target_techniques(competency_id: str) -> frozenset[str]:
|
||||
key = competency_id.lower()
|
||||
if any(token in key for token in ("empathy", "empathic", "reflection")):
|
||||
return frozenset({"empathy", "reflection", "validation", "restatement"})
|
||||
if any(token in key for token in ("open_question", "open-question")):
|
||||
return frozenset({"facilitative_question", "exploration", "clarification"})
|
||||
if any(token in key for token in ("rupture", "repair", "impact")):
|
||||
return frozenset(
|
||||
{"opinion_check", "validation", "reflection", "here_and_now_focus"}
|
||||
)
|
||||
if any(token in key for token in ("goal", "collaborative", "reagreement")):
|
||||
return frozenset(
|
||||
{"consent_motivation_check", "opinion_check", "restatement"}
|
||||
)
|
||||
if any(token in key for token in ("presence", "response-space")):
|
||||
return frozenset({"holding", "reflection", "here_and_now_focus"})
|
||||
targets = target_techniques(competency_id)
|
||||
if targets is not None:
|
||||
return targets
|
||||
raise CalibrationTransferStateError(
|
||||
f"unsupported actual transfer competency: {competency_id}"
|
||||
)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue