Atomic, not bundled, not stacked

    These three rules are about the inside of a single row. They are the most common reason tasks are sent back.

    Atomic: One check per row

    A row must be either fully true or fully false for any answer. If an answer can do half of it, graders split on how to mark it.

    Good

    Three rows. Critical: "The response identifies that the container's port 80 is not published to the host." Critical: "The response gives a docker run command that includes -p 8080:80." Bonus: "The response explains that EXPOSE in the Dockerfile does not publish a port by itself."

    Bad

    One row. Critical: "The response identifies the missing port mapping, gives the corrected docker run command with -p 8080:80, and explains the difference between EXPOSE and -p."

    Why it works: each row can be marked on its own, and the nice-to-have explanation is a bonus instead of being forced into a critical.

    Why it fails: an answer that gives the right command but skips the EXPOSE explanation is half right, so the row cannot be marked cleanly, and it makes an extra explanation critical.

    Not bundled: One requirement per row

    Bundling is putting two or more requirements in the same row. Watch for these signs: "and", "as well as", "both ... and", "also", a list of items, a semicolon, ", then", or a second sentence that starts a new requirement.

    Words that usually mean a bundle

    and, also, as well as, both ... and, along with, in addition, plus, ; (semicolon), then, a list after "including".

    Good

    Critical: "The response says the request is blocked because the server's reply has no Access-Control-Allow-Origin header." Critical: "The response's fix uses only Flask and the Python standard library."

    Bad

    Critical: "The response explains the missing Access-Control-Allow-Origin header and fixes it without new packages, also keeping the routes the same."

    Why it works: the diagnosis and the user's "no new packages" limit are checked separately.

    Why it fails: three requirements in one row. An answer with the right diagnosis but a new package fails the whole row, and the grader cannot show which part was missed.

    The one exception

    If the user gave several values as one exact specification (for example "the button must be 44 px tall with the colour #1D4ED8"), a single row that checks that exact specification is fine, because an answer either matches the specification or it does not. When in doubt, split. Splitting is never wrong.

    Not stacked: Do not pile conditions onto a row

    Stacking happens when extra sentences or conditions are added onto an existing row, usually while fixing feedback. Each added sentence is a new requirement, and it often repeats a check another row already owns. Then one small mistake fails two rows.

    Good

    Keep "The response gives a fix that would stop the KeyError, for example using df['Price'] or lowercasing the column names." If something else matters, add it as its own row, or confirm another row already checks it.

    Bad

    "The response gives a fix that would stop the KeyError. The fix must also keep the column names unchanged, and the response must explain the fix line by line."

    Why it works: the row keeps one clear check.

    Why it fails: two new requirements were stacked onto a working row. The first contradicts a valid fix (lowercasing the names), and the second demands a walkthrough the user never asked for.

    When you fix feedback

    Change only what the comment asks. Then re-read the whole rubric: does your fix now repeat, contradict or overlap another row? Fixing one row and creating an overlap with another is a very common reason a task is sent back again.