Each assignment lives in assignments/<id>.assignment.json.
{
"schema_version": 1,
"id": "ship-it",
"type": "assignment",
"instructions_md": "Serve your own `index.html` from an nginx container. Hand in your Dockerfile and a screenshot.",
"grader_notes_md": "Accept when the Dockerfile copies the page into /usr/share/nginx/html.",
"duration_min": 45,
"due_days": 14,
"submission": { "text": true, "files": true, "url": true, "attest": false, "max_files": 3, "max_file_mb": 10, "file_types": ["txt", "png", "pdf"] },
"grading": { "mode": "points", "max_points": 10, "pass_points": 7 },
"resubmit": "anytime",
"completion": { "mode": "accepted" }
}
| Field | Required | Rules |
|---|---|---|
instructions_md |
Yes | What to do. It can’t be empty when publishing. |
grader_notes_md |
No | A rubric for reviewers, never shown to learners. Up to 20,000 characters. |
duration_min |
No | 0 to 10,000. Added up into the course length. |
due_days |
No | 1 to 3,650: due that many days after enrolling. Late work is still accepted and marked late. |
submission |
Yes | text, files, url, and attest are booleans, and at least one must be true. max_files is 1 to 20 (default 5), max_file_mb is 1 to 200 (default 20), and file_types is chosen from pdf zip txt md csv json log yaml yml sh py png jpg jpeg webp gif. Leave out file_types to allow them all. |
grading.mode |
No | pass_fail (default: accept or ask for a revision), or points, which needs max_points (1 to 1,000) and pass_points (up to max_points). |
resubmit |
No | anytime (default), or after_revision: a new version only after a reviewer asks for one. |
completion.mode |
No | accepted (default), or submitted: complete on hand-in, but still reviewed. |
An assignment can be the target of complete and module_complete unlock rules, but not quiz_score.
Files without an extension, such as a Dockerfile, can’t be uploaded. Ask for them with "text": true instead.