Skip to content

fix(harness): review follow-ups for #269 and #276 (TH-8952, TH-9490) - #297

Open
khushalsonawat wants to merge 5 commits into
feat/TH-8804-source-subfolderfrom
feat/TH-9490-review-follow-ups
Open

khushalsonawat wants to merge 5 commits into
feat/TH-8804-source-subfolderfrom
feat/TH-9490-review-follow-ups

Conversation

@khushalsonawat

@khushalsonawat khushalsonawat commented Nov 11, 2026 •

Copy link
Copy Markdown
Member

Into feat/TH-8804-source-subfolder. Review follow-ups for #269 (TH-8952, merged) and #276 (TH-9490, merged through #283): Dileep's comments that landed after each merged. Four commits: 43309843 (#269), df2742cf (#276), the base merged in (8e1d9de1), and the confirming review's Lows (a8445f18).

Summary

#269, the seed contract (two P3s).

  • holds_seed and _take_back swallowed an error with nothing logged. Each now prints the traceback to stderr through print_trace, which prints nothing when the error holds a validation error's values. So a restart that can't compare contract.json with the seed says why it writes no seed-result.json, and a contract that can't be removed (which makes the outcome used) says why. Both catches see only the kit's own files (the authoring contract.json and the platform-placed seed), never customer source. Two tests in test_seed_contract.py assert the trace reaches stderr.

#276, decoding a Python file before searching it (C2-C7).

  • C2 (P2): EBCDIC hid an import from the agent's entry script. compile() and import refuse cp037, cp500, cp1140, cp273, cp875, cp1026 and cp424 on a coding line, but python main.py runs them. A codec whose bytes for the coding line don't decode to that line (these seven, utf-16 and utf-32) is now read as python file.py reads it: the lines up to the coding line as they are, the rest decoded. Each codec is proven by a real python3.12 file.py run against a stub module, and the codec sweep now asks the script route too.
    • Reviewing this showed the same gap for any crafted coding line in the other decode-first codecs (utf-7, hz, the iso2022 family, unicode-escape): an import and a script can read one file differently. Such a file is now read both ways: when its own lines up to the coding line don't decode to themselves, or when it holds a CR (a CR ends lines before an import decodes and after a script does). The two texts are never joined; each is parsed on its own by the browser scan, the instrumentation scan and the import walk, and the tool check keeps the import's text, since the runtime imports the tool modules. Such a file is charged to the decode total at most twice. Honest files have neither shape: the kit's src/ (709 files) and ~/Desktop/future-agi (160,494 files) have no file read twice.
  • C3 (P2): tests failed on current patch releases (3.13.13, 3.14.7), where CPython no longer keeps a decoded CR. Each CR row is skipped when a compile() probe shows this Python doesn't keep it, rather than by version.
  • C4 (P3): two premises broke on 3.14. The rot13/base64 test skips when this Python's detect_encoding refuses the codec. The refused-codec walk test allows 3.14's bounded decode of the cut first line, and still asserts the file's body is never decoded. _coding also pads each cut line to its real length mod 4, so a utf-16 coding line reads on 3.14.
  • C5 (P3): padding past the decode total hid an import with nothing logged. One WARNING per budget, the first time the total runs out, naming the reader (browser scan, instrumentation scan, tool check, import walk) with counts only, never a path or source text. A file the whole decode refuses at the total's edge is read as any file past the total is.
  • C6 (P3): the 120-character docstring line is rewrapped at 99.
  • C7 (P3): source_tool_evidence reads decode-first files too: a test finds a @tool spelled with a utf-7 +AEA- escape.

Tickets: TH-8952, TH-9490.

Known limits

  • Decoded CRs inside a comment, inside a string, or at a line's start are read as the parser reads them, not as Python 3.12+'s tokenizer does. Unchanged here, crafted input only.
  • Padding past the decode total is now logged, not cut. fix(harness): give a browser scan its limits cut a second look (TH-9512) #281 (TH-9512) turns it into a cut.
  • An honest CRLF file in a decode-first codec is decoded and charged twice. None was found in the corpora above.

Merged with the base (8e1d9de1)

cde91b3f (#282 and 1132192) merged with no conflicts. 1132192 rewords comments in python_source.py and changes the import walk in credentials.py (workspace members, folder links); neither touches how a .py is decoded, and the walk's per-file second texts are unchanged (traced by the confirming reviewer, and pinned by test_the_walk_parses_each_files_own_readings).

Review

  • feat(harness): let a build's first run reuse the agent reading (TH-8952) #269's P3s: one reviewer, clear.
  • fix(harness): decode a Python file before searching it when its codec can spell a name (TH-9490) #276's comments: three change rounds with two reviewers each.
    • Round 1: not clear (the script-route gate checked the codec, not the file). Fixed.
    • Round 2: not clear (a backslash before a CR). Fixed.
    • Round 3: not clear (a plain CR in iso2022_jp_2 and iso2022_kr; 136 of 34,320 crafted files missed). Khushal's call: take the reviewer's fix (any CR reads both ways), with one confirming reviewer.
    • Confirming review: clear. 0 misses on 3.12.3, 3.13.3 and 3.14.2 over the reviewers' sweeps. Its three Lows are fixed: two docstrings and a test comment, and a test that pins what comes back at the decode total's edge.
  • Planted bugs: every fix's bug was planted and failed a named test, the gate put back to the round-2 check included; the confirming reviewer re-ran the earlier rounds' plants and four on the merged base.

Verification

  • Fix-only check pending for bddd2668 (Dileep's P3s: the UTF-16 skip, _decoded_first removed, the noqa line).
  • On bddd2668, Python 3.12.3: test_python_source_codecs.py, test_seed_contract.py and test_source_tool_evidence.py, 395 passed; ruff check clean.
  • Where the tests run: CI's SDK smoke runs test_python_source_codecs.py, test_source_tool_evidence.py, test_seed_contract.py, test_agent_type_refusal.py, test_scan_walk.py, test_instrumentation_evidence.py and tests/test_harness_credentials.py on every push.
  • Fix-only check pending for a8445f18 (docstrings, a test comment and the edge test, added after the confirming review cleared).
  • Python 3.12.3 (the hosted image), on 8e1d9de1 (codecs re-run on a8445f18): test_python_source_codecs.py 233, test_source_tool_evidence.py 54, test_agent_type_refusal.py 735, test_instrumentation_evidence.py 48, test_scan_walk.py 151, test_seed_contract.py 108, tests/test_harness_credentials.py 81 passed.
  • 3.13.3 and 3.14.2: the codec probes and sweeps (no pytest installed there).
  • ruff check clean on the changed files. One line is 106 characters (seed_contract.py:370, a noqa reason); it is fixed with Dileep's comments in the next push.
  • Logs carry counts and reader names only, never a path or source text.

…ack (TH-8952)

Dileep's two P3s on #269, which merged before they could land there:
- holds_seed prints the traceback before returning False, so a restart
  that can't compare contract.json with the seed says why it reports
  no seed-result.json;
- _take_back prints the traceback when contract.json can't be removed,
  since a contract left behind is what makes the outcome `used`.

Both catches see only the kit's own files (/work/authoring/contract.json
and the platform-placed seed, which read_seed already parses safely), so
no customer source reaches the trace. The two tests assert the trace
reaches stderr.

One fresh reviewer: clear; test_seed_contract 108 passed on 3.12.3, and
each planted removal fails its named test.

Signed-off-by: khushalsonawat <khushalsonawat@gmail.com>
…oo (TH-9490)

- A coding line whose own bytes don't decode to it (EBCDIC, utf-16, utf-32) is read as
  `python file.py` reads it: the bytes after the coding line, decoded. A decode-first file
  whose head doesn't read as itself, or that holds any CR, is read both ways; the two texts
  are never joined, and the escape budget charges such a file at most twice.
- Past the decode total, a WARNING is logged once per budget, naming the reader, with counts
  only. A file the whole decode refuses at the total's edge is read as any file past it is.
- Tests skip a decoded-CR row when this Python no longer keeps the CR, and allow 3.14's
  bounded decode of the cut coding line; the walk parses each file's own readings only; the
  tool-evidence scan finds a tool spelled in utf-7. A docstring is rewrapped at 99.

TH-9490

Signed-off-by: khushalsonawat <khushalsonawat@gmail.com>
…t/TH-9490-review-follow-ups

Signed-off-by: khushalsonawat <khushalsonawat@gmail.com>
…al's edge (TH-9490)

- The _decoded_readings and _head_reads_as_itself docstrings say an import and a script
  read a file alike only when it holds no CR.
- A test pins what comes back when the total lasts for the first decode only: the
  import's reading, decoded, alone.
- The walk test's comment names a.py's second reading as the script's.

TH-9490

Signed-off-by: khushalsonawat <khushalsonawat@gmail.com>

@cdileep23 cdileep23 left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Please check the comments.

Comment thread src/fi/alk/harness/python_source.py Resolved
Comment thread src/fi/alk/harness/seed_contract.py Resolved
assert tool_evidence_problems(_entry_contract(), tmp_path)


def test_tool_check_decodes_a_utf_7_module_as_python_does(tmp_path):

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

P3. This test still passes if the tool check stops decoding first. With source_tool_evidence.py:69 changed to read_module(path), it and ..._finds_a_def_a_utf_7_comment_hides stay green; only test_tool_check_reads_the_text_an_import_reads fails.

Fix: use a UTF-7 file where the plain read and the decode-first read give different text (one that depends on a CR or a NUL, for example), so this test pins the reader by itself.

…is Python refuses (TH-9490)

From 3.14, Python refuses some UTF-16 coding lines itself, so no coding is
right there: the length test skips those rows rather than asserting one.
_decoded_first had no caller left but tests, which now take the first two
items of _decoded_readings. A noqa reason moves above its line, to fit 99.

Signed-off-by: khushalsonawat <khushalsonawat@gmail.com>

This branch has not been deployed

No deployments
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.

2 participants