Skip to content

fix(doctor): undecodable contract bytes are a typed finding, never a traceback - #109

Merged
SollanSystems merged 1 commit into
mainfrom
fix/doctor-invalid-encoding
Jul 29, 2026
Merged

SollanSystems merged 1 commit into
mainfrom
fix/doctor-invalid-encoding

Conversation

@SollanSystems

Copy link
Copy Markdown
Owner

Closes #107 (found while adjudicating a Slice 4a review advisory).

Three sites, one rule — an errored check fails typed, it never crashes:

  • _read_json: UnicodeDecodeError → the existing invalid_encoding issue (the _validate_jsonl precedent), so loop doctor reports instead of tracebacking.
  • read_manifest: undecodable bytes fail safe to {}, mirroring its own malformed-YAML branch.
  • loop/verdict.py::_terminal_record: the guard widen that was dead code before this fix becomes the live conversion site once doctor stops raising — the site-agnostic test planted in 3e26e91 proves it (probe: reverting the widen fails exactly that test).

Evidence: TDD red→green; 3 mutation probes KILLED, tree restored byte-identical; extras 1353/18 (+2), pyyaml-only 1256/115 (+2), zero regressions.

Note: touches loop/, a CODEOWNERS gate-defining path. The ruleset half of ADR 0002 decision 6 is not yet in force (see PR #106 body point 2); this lands under the repo's standing autonomous-merge procedure with the full evidence bar — flag if that should change now.

https://claude.ai/code/session_01JK76jSm45nHcoRoP1SdxXF

…traceback

Closes #107. _read_json catches UnicodeDecodeError and reports it as the
existing invalid_encoding issue - the same rule _validate_jsonl already
applies to ledgers - so loop doctor on a terminal_state.json holding invalid
UTF-8 returns ok:false with a typed issue instead of tracebacking (exit 1).
read_manifest gains the matching guard, failing safe to {} exactly like its
malformed-YAML branch. loop/verdict.py's _terminal_record widens its read
guard to include UnicodeDecodeError: that path became REACHABLE the moment
doctor_report stopped raising, and the site-agnostic typed-contract test
planted in 3e26e91 flips to depending on it - probe-proven (reverting the
widen fails exactly that test).

TDD red->green; probes P1/P2/P3 (each site reverted) all KILLED, tree
restored; extras 1353/18 (+2), pyyaml-only 1256/115 (+2), zero regressions.
Touches loop/ - a CODEOWNERS gate-defining path; the ruleset half of ADR 0002
decision 6 is not yet in force (PR #106 body point 2), and this lands under
the repo's standing autonomous-merge procedure with the full evidence bar.

Claude-Session: https://claude.ai/code/session_01JK76jSm45nHcoRoP1SdxXF
Copilot AI review requested due to automatic review settings July 29, 2026 16:41
@SollanSystems
SollanSystems enabled auto-merge (squash) July 29, 2026 16:41

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@SollanSystems
SollanSystems merged commit c493804 into main Jul 29, 2026
13 checks passed
@SollanSystems
SollanSystems deleted the fix/doctor-invalid-encoding branch July 29, 2026 16:42

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: e6ea1345d6

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread loop/contract.py
Comment on lines +59 to +62
except UnicodeDecodeError as exc:
# Same rule as _validate_jsonl: undecodable bytes fail the file closed
# with a typed finding, never a traceback out of doctor_report (#107).
issues.append(ContractIssue("invalid_encoding", f"{path.name}: not valid UTF-8: {exc}", path))

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Catch encoding failures during event-store reconciliation

When events.db is present, this catch only protects the first contract-validation pass: doctor_report subsequently calls event_consistency_issues, whose _terminal_desync and _state_divergence reread these files but do not catch UnicodeDecodeError. I reproduced a scaffolded workspace with a valid contract_opened event and an invalid-UTF-8 terminal_state.json; doctor_report still raises a raw traceback from runtime.py:212 instead of returning the new invalid_encoding finding. The reconciliation reads need the same encoding-error handling for event-backed workspaces.

Useful? React with 👍 / 👎.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

loop doctor tracebacks (raw UnicodeDecodeError) on a terminal file with invalid UTF-8 bytes

2 participants