Repository navigation
fix: skill shell hardening (docx DOCTYPE, quoted values, Canvas push checks) - #197
Merged
Merged
Conversation
…checks) - course-import refuses a .docx with a DOCTYPE or ENTITY (#182) - model-filled values use a quoted heredoc: --mode, start level, Canvas position and points (#183) - Canvas push: --max-time 60, HTTP code check, stop on error, reuse items by title (#180) - course-import and assessment-design pass --expect-updated to the merge (#179, skill side) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…h notes Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…r cases 68a-68l Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes
course-import.docx block: refuses<!DOCTYPEor<!ENTITYwithDOCX_READ_FAILEDbefore ElementTree parses.--mode(assessment-design, course-builder, course-import, course-quality-review, needs-analysis, red-team), the/idstack:startexperience level (now an enum check,LEVEL_BAD), and the Canvas module<position>and assignment<points>(numeric check,PUSH_VALUE_BAD).course-export: every call has--max-time 60and-w "\n%{http_code}". A non-2xx code, a timeout (curl 28) or another curl error stops the block withPUSH_FAILED: <item>: <reason>. Each block first looks the item up by title (module, page, assignment, discussion, module item) and reuses it, so a re-run makes no second POST. Create and add-to-module are now one block per item type (and module create+publish), which removes the model-filledPAGE_URL,ASSIGN_IDandTOPIC_ID. B8 is rewritten to match (stop at the first failure, re-run is safe).course-importandassessment-designprintMANIFEST_UPDATED:before they read shared sections and pass--expect-updated "<value>"(quoted heredoc, no flag when empty) to the merge. On exit 8 the skill re-reads, merges into the changed sections and tries once more.Tests
test/test-skill-shell-zsh.sh: 161 to 249 assertions (bash and zsh): billion-laughs .docx refused, normal .docx still passes; hostile text in the changed blocks (quote,$(touch X), backtick, newline); fake curl extended with 500, timeout (exit 28) and an existing-item listing; asserts orphan-free stop, timeout message, no second POST on re-run,--max-timeon every call; stub merge for--expect-updated.test/mutation-test.sh: new cases 66a to 66l. All 12 GUARDED from a frozen copy (the stale-anchor check is built in:expect_failexits on an unchanged copy).Not verified
search_term(no pagination), and the realsearch_termand module-item filters were not checked against the Canvas API.--expect-updateddoes not exist inscripts/idstack-manifest-mergeyet; it arrives with the scripts PR (claude/bugs-scripts). Tests use a stub merge. Until then the real script would reject the flag, so merge this PR with or after the scripts PR.course-exportare identical by hand, with no drift check.Closes #182
Closes #183
Closes #180
Refs #179 (the scripts PR closes it)
🤖 Generated with Claude Code