Skip to content

Ship a question's data files with CodeTailor's JOBE test runs - #1595

Merged
bnmnetp merged 4 commits into
RunestoneInteractive:mainfrom
aspadiyath:fix-codetailor-datafiles
Oct 12, 2026
Merged

bnmnetp merged 4 commits into
RunestoneInteractive:mainfrom
aspadiyath:fix-codetailor-datafiles

Conversation

@aspadiyath

@aspadiyath aspadiyath commented Oct 6, 2026 •

Copy link
Copy Markdown
Contributor

A question whose program reads a file (open("dogs.txt"), or a data-datafile on a livecode question) failed every CodeTailor validation run: generated code was executed on JOBE with no file_list, so it died with a missing-file error.

parsons_scaffolding now collects candidate filenames -- the data-datafile attribute plus quoted filename literals in the question code, its tests and the student's code -- and resolves them against source_code, the same store Skulpt and livecode.js read datafiles from. The requesting course is tried first, then the question's own book, so cloned courses and cross-book selectquestions still find the file. A file named both by acid and by filename is shipped once.

The files travel through get_parsons_help into every Python and Java JOBE run, including validation of the LLM-generated example solution: each is pushed to the JOBE file store and listed in the run_spec file_list, binary files verbatim.

fetch_source_code now prefers the requesting course's own copy of a file over the base book's (previously the match was unordered), so a cloned course's datafile override wins for both student runs and CodeTailor.

A question whose program reads a file (open("dogs.txt"), or a
data-datafile on a livecode question) failed every CodeTailor
validation run: generated code was executed on JOBE with no file_list,
so it died with a missing-file error. The LLM example never passed its
unit tests, personalization fell back, and the student got empty help
("emptyHelpCode") on every file-reading question.

parsons_scaffolding now collects candidate filenames -- the
data-datafile attribute plus quoted filename literals in the question
code, its tests and the student's code -- and resolves them against
source_code, the same store Skulpt and livecode.js read datafiles from.
The requesting course is tried first, then the question's own book, so
cloned courses and cross-book selectquestions still find the file. A
file named both by acid and by filename is shipped once.

The files travel through get_parsons_help into every Python and Java
JOBE run, including validation of the LLM-generated example solution:
each is pushed to the JOBE file store and listed in the run_spec
file_list, binary files verbatim.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Copilot review overview

🟡 Changes recommended

Cloned-course file overrides are not reliably preferred over base-book files.

Review effort: Balanced
Findings: 1 Medium severity

Open (1)
What changed in this PR

Adds question data files to CodeTailor’s Python and Java JOBE validation runs.

Changes:

  • Discovers and resolves referenced data files.
  • Uploads files to JOBE and propagates them through all validation paths.
  • Supports binary file contents.
File Description
coach.py Discovers and resolves question data files.
evaluate_fixed_code.py Uploads files and includes them in JOBE runs.
end_to_end.py Propagates files through personalization workflows.
get_personalized_solution.py Includes files when validating generated examples.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread bases/rsptx/book_server_api/routers/coach.py
fetch_source_code matched course_id against base_course OR course_name
and returned .first() with no ORDER BY, so when a cloned course has its
own copy of a file with the same name as one in the base book, either
row could come back. Order the requesting course's row first.

This is the lookup both get_source_code (the student's program loading
its datafiles) and CodeTailor's data-file resolution use, so the two
keep agreeing on which file a program reads. Courses that aren't
clones, or clones without an override, resolve exactly as before.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@aspadiyath

Copy link
Copy Markdown
Contributor Author

Fixed Copilot's feedback in 649e5c2

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🟡 Changes recommended

Filename discovery misses valid spaced names and silently truncates explicitly declared files beyond twenty.

1 open finding
1 resolved since last review
Previously missed (2)

In code that hasn't changed since last review

Medium severity Filename matcher rejects spaces in valid data files

bases/​rsptx/​book_server_api/​routers/​coach.py:215

The literal matcher excludes spaces, although source_code supports them and generate_datafile_acid explicitly sanitizes spaces (components/rsptx/db/crud/rsfiles.py:125). An undeclared Skulpt file opened as open("my data.csv") is therefore never looked up, so CodeTailor still fails that valid file-reading question. Include spaces here (or parse string literals without restricting valid filename characters).

Medium severity Declared data files are silently truncated

bases/​rsptx/​book_server_api/​routers/​coach.py:240

This truncates explicitly declared data-datafile entries as well as heuristic literals. The assignment builder allows any number of selected files and emits all of them (activeCode.ts:32-34), while livecode.js:292-300 loads every declaration, so a question with 21 files works normally but CodeTailor silently omits file 21. Preserve all trusted declared entries and apply the lookup cap only to inferred literals, or enforce/report the same limit when authoring.

🧠 Review effort: Balanced

Comment on lines +175 to +176
# A cloned course's own copy of a file overrides the base book's
query = query.order_by((SourceCode.course_id == course_name).desc())

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Claude here (Aadarsh asked me to respond). Added in 6296b0c: test_fetch_source_code_prefers_cloned_course_copy puts the same file in a base book and a cloned course, inserting the base book's row first, and checks the clone's copy comes back by both filename and acid. test_fetch_source_code_falls_back_to_base_book checks a clone without its own copy still gets the base book's file. The first test fails without the order_by from 649e5c2.

…edence

_data_file_candidates capped the combined list at 20, so a question
declaring more than 20 files in data-datafile silently lost the rest even
though livecode.js loads them all. The cap now applies only to filename
literals guessed from the code; declared names are always kept.

The filename-literal matcher rejected spaces, so open("my data.csv") on an
undeclared Skulpt datafile was never looked up. Single internal spaces are
now allowed.

Add CRUD tests that a cloned course's copy of a file wins over the base
book's (by filename and by acid), and that a clone without its own copy
still gets the base book's file.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@aspadiyath

Copy link
Copy Markdown
Contributor Author

Also in 6296b0c, from the review summary:

  • Declared files truncated: the 20-name cap now applies only to filenames guessed from the code. Every data-datafile entry is always kept, matching what livecode.js loads.
  • Spaces in filenames: the filename pattern now allows single spaces inside the name, so open("my data.csv") is looked up.

# Conflicts:
#	bases/rsptx/book_server_api/routers/coach.py
@bnmnetp
bnmnetp merged commit 6482111 into RunestoneInteractive:main Oct 12, 2026
2 checks passed
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.

3 participants