fix(hitl): planen et menneske signerer er TEKST, aldri en objekt-repr (BLOCKER-1, ORDRE 20260902T151931Z)

Fire steder gjorde `str(review.plan)` paa en MAF `Message` som ikke har noen
`__str__` (maalt: `type(Message).__str__ is object.__str__`), saa BEGGE
HITL-doerene viste og lagret `<agent_framework._types.Message object at 0x…>`:
terminalen F4 spoer ved (`:1395`), de to opptakene i `plan_reviews` (`:1404`
approve, `:1418` revise) og den PARKERTE spoersmaalsfila U12 (`:1478`) som er
det ENESTE som krysser prosessgrensen. En ekspert som svarte `approve` signerte
blindt. Fiksen er den eksisterende `_plan_text` (`:966`) paa alle fire; ingen ny
hjelper.

Fire asserts var gronne mot defekten fordi de var TRUTHINESS eller
selv-sammenligning: `reviews[1]["plan"] != ""`, `waiting[0].plan`, og
`reviews[0]["plan"][:40] in out` — den siste sammenlignet den samme repr-en med
seg selv, saa de to flatene var enige mens begge var uleselige. Diskriminatoren
er innhold som KUN kan komme av `Message.text`: MAF komponerer plan-meldingen
rundt managerens svar ordrett (maalt), saa en sentinel i det skriptede svaret er
til stede naar teksten ble tatt og fravaerende naar repr-en ble det. Sentinelen
bor i et `reason`-felt fordi ingenting leser dem — aa nokle den til en ANSWER
ville endret kjoringen den maaler. I tillegg en NEGATIV assert (` object at 0x`
finnes ingen steder i stdout, artefaktet eller spoersmaalsfila), som fanger hele
defektklassen og ikke bare denne ene.

MAALT: fire mutasjoner, EN PER LINJE (ordrens ene samlede revert underteste —
`:1418` er revise-grenens egen kopi og hadde ellers ikke noe roedt vitne):
:1395 -> 1 roed (T2 stdout) · :1404 -> 2 roede · :1418 -> 1 roed (T1 alene) ·
:1478 -> 1 roed (async T9). Suite 2 failed (F15-diffen, KJENT) / 1078 passed /
5 skipped — uendret fra baseline. Golden `demo-transcript.stdout` BYTE-UENDRET
(ea8c534773acdbe41ae68f2c55724d69aaf8be4f).

Aerlighetsgrense, uttalt: `str(review.current_progress)` (`:1396`/`:1479`) er
IKKE roert. Den er en `MagenticProgressLedger | None`, ikke en `Message`, og
maalt renderer pydantic den lesbart — men i disse kjoringene er den `None`, saa
terminalen skriver «progress so far: None». Det er en annen defekt og en annen
ordre.

Co-Authored-By: Claude <claude-opus-5>
This commit is contained in:
Kjell Tore Guttormsen 2026-09-02 17:38:25 +02:00
commit 4075b46a00
3 changed files with 84 additions and 11 deletions

View file

@ -1392,7 +1392,7 @@ async def _drive(
decision = plan_reviewer(
PlanReviewRequest(
index=len(plan_reviews),
plan=str(review.plan),
plan=_plan_text(review.plan),
current_progress=str(review.current_progress),
is_stalled=_truthy(review.is_stalled),
)
@ -1401,7 +1401,7 @@ async def _drive(
plan_reviews.append(
PlanReview(
index=len(plan_reviews),
plan=str(review.plan),
plan=_plan_text(review.plan),
is_stalled=_truthy(review.is_stalled),
decision="approve",
)
@ -1415,7 +1415,7 @@ async def _drive(
plan_reviews.append(
PlanReview(
index=len(plan_reviews),
plan=str(review.plan),
plan=_plan_text(review.plan),
is_stalled=_truthy(review.is_stalled),
decision="revise",
feedback=decision.feedback,
@ -1475,7 +1475,7 @@ async def _park(
request_id=str(request.request_id),
checkpoint_id=str(latest.checkpoint_id),
index=len(trace.plan_reviews),
plan=str(review.plan),
plan=_plan_text(review.plan),
current_progress=str(review.current_progress),
is_stalled=_truthy(review.is_stalled),
bundle_dirs=tuple(bundle_dirs),