Repository navigation
Conversation
There was a problem hiding this comment.
🟡 Changes recommended
The PR modifies src/** and test/** but does not update CHANGELOG.md, which the repository's required Changelog Guard workflow will fail.
1 open finding
What changed in this PR
This PR adds tooling to make copied qBook questions deployable through the existing GitHub-based course Action. When questions are copied via MCP they get new backend customIds, so the destination course's notebooks and course.json must be updated to reference the copies. A new helper (prepare_question_copy.py) applies a saved copy result to notebook widgets and regenerates the chapter/section MCQ/FRQ placement lists, and the Action's validation step is updated so those reference fields survive into the deploy payload (previously they were silently dropped). The change is scoped to the validate stage and a standalone preview/--write/--check CLI; it does not authenticate, copy backend records, or deploy.
Changes:
- New
prepare_question_copy.pyhelper that rewrites widget arguments from a saved/validated mapping, derives placement lists, enforces path safety and unique/used mappings, and is idempotent on retries. validate_course.pyadds aQuestionReferencesmodel plus optionalchapterQuestions/sectionQuestions, and ato_payload()that preserves supplied references while keeping existing courses' payload shape unchanged.- New unit tests and a workflow doc (
docs/question-copy-workflow.md) describing the agent copy → PR → deploy flow.
| File | Description |
|---|---|
src/scripts/prepare_question_copy.py |
New helper to apply a saved copy mapping to notebooks and course.json (preview/write/check). |
src/scripts/validate_course.py |
Adds QuestionReferences model and to_payload() so question-reference fields are validated and preserved in the deploy payload. |
test/unit/test_prepare_question_copy.py |
Unit/CLI tests covering rewriting, idempotency, payload preservation, and invalid-mapping rejection. |
docs/question-copy-workflow.md |
Documents the end-to-end copy-and-deploy workflow for agents. |
🧠 Review effort: Balanced
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
| saved = json.loads(mapping_path.read_text(encoding="utf-8")) | ||
| result = CopyResult.model_validate(saved.get("data", saved)) |

Copying questions through MCP creates independent backend records, but the destination course's GitHub references still need to change. This adds
prepare_question_copy.pyto apply a saved copy result to notebook widgets and derive the matching chapter and section question lists incourse.json. Preview is the default;--writeapplies changes and--checkvalidates the repository PR without copying or deploying.Action validation now preserves
chapterQuestionsandsectionQuestions. Previously it silently dropped these fields, so a reference change could be invisible to the API's manifest-based redeployment detection. Existing courses without these fields keep their payload shape. The helper preserves unrelated widgets and CQ lists, rejects unused or ambiguous mappings, and reuses a saved mapping on retries.The walkthrough in
docs/question-copy-workflow.mdcovers the agent-created course PR, reviewed merge, destination-organization deployment key, and a second deployment with unchanged question identities. GitHub editing and PR creation remain the agent's responsibility; the helper does not authenticate, insert notebook cells, or perform backend copies.Related PRs:
Merge/deploy order: deploy the API first, then qBook. Release and pin this Action revision before exercising the existing-course GitHub deployment demo. An older Action drops the generated question lists; qBook before the API returns 404 on copy.
Validation:
Review follow-up: malformed top-level mapping arrays and scalars now reach schema validation instead of raising AttributeError. Five CLI regressions verify exit code 2, a clean error, and unchanged files. The changelog request was already satisfied in fa4bb5c; this fix also has its own Unreleased entry.
Hosted workflow verification, 2026-10-16
The complete workflow passes against dedicated API
ac8a41918, qBook1df55f3, and Action4294b9e. Demo PR #2 deploys OAuth-copied MCQ/FRQ questions; demo PR #3 redeploys a changed manifest. Hosted Actions creation, initial update, repeated deployment, and changed-manifest update all pass.The actual qBook lesson accepts a correct MCQ answer for five points and a private FRQ response pending manual review; both persist after reload. Repeat deployments preserve question IDs/customIds, notebook/manifest placements, counts, and the ten-point course total. Real OAuth MCP has 18 passing checks, REST/BFF has 32, and S3 attachment copying has 12.
Two demo-blocking API defects are fixed and hosted-verified in API1243: management-list metadata aliases and private FRQ response submission/read. All latest API GitHub jobs, Cloud Build, and final Codecov pass. API revision
qbraid-api-01565-geguses the dedicated host override and loopback self-calls; qBook revisionqbook-preview-00272-getpoints to that API.User requested cleanup after testing. The private demo course, four questions, and two learner responses are removed. Counts match the original baseline. The temporary API key returns 401, and the GitHub deployment secret and cleanup job are deleted. PRs retain evidence; rerunning requires fresh copies/mapping and a new credential.
Merge/deploy API1243 first, then qBook816; release/pin Action36 before deploying course manifests. Implementation PRs remain unmerged.