Public fixture
This standard-library Python exercise is course-made synthetic practice for the Week 8 notes. No model, package installation, real data or external service is used. Every file works in memory or inside the directory it is run from.
Run it
Work on a copy, never in this directory. From the course checkout:
WORK="$(mktemp -d)"
cp -r lectures/week-08/fixture/. "$WORK"/
cd "$WORK"
export PYTHONDONTWRITEBYTECODE=1
python chain.py; echo "exit $?"
python exercise.py > starter-checks.json; echo "exit $?"
python verify_triage.py > triage-before.json; echo "exit $?"
{"surface": "repository_note", "proposed": ["read_label", "export"], "responses": ["text", "tool_denied"], "effects": ["read_label", "export"]}
{"surface": "tool_response", "proposed": ["read_label", "export"], "responses": ["text", "tool_denied"], "effects": ["read_label", "export"]}
{"surface": "copied_log", "proposed": ["read_label", "export"], "responses": ["text", "tool_denied"], "effects": ["read_label", "export"]}
{"kind": "synthetic_injection_chain", "task_completed": true, "unauthorized_effects": 3}
exit 1
exit 1
exit 1
All three commands exit 1 on the unchanged starter. The notes walk through each output, the
repair and the rerun. The export line stops Python from caching compiled modules, so each
run reads the file you have just edited.
Contract
A request has exactly two string fields, tool and record. The record names one of three supplied synthetic surfaces. Only read_label is permitted. Malformed requests return invalid_arguments; other tool names return tool_denied. Refused calls must not append an effect. Every attempted call consumes one of two attempts, including invalid and denied requests. A third call returns budget_exhausted without any new effect.
Files
Boundary example:
- candidate.py: deliberately faulty proposal; edit this file in your copy.
- chain.py: the inert chain. A fixed rule, not a model, performs the authorized
read and proposes
exportwhen the returned text asks for it. It exits 0 only when no unauthorized effect is recorded and the authorized read still works. - exercise.py: public feedback checks, case by case; keep the original expectations while repairing.
demo.py: deterministic generator for a four-request packet with the required responses and effects.verify_demo.py: verifier for that packet; it refuses a packet whose cases were edited.scan-report.json: three course-written scanner claims for disposition practice.
Triage example:
preferences.py: a configuration parser with an unsafe loader and a separately allowlisted status formatter. Thepickle.loadscall is the planted finding. Never pass it anything except the inputs the verifier sends, and do not craft or load pickle data.preferences.lock: one locked version of a fictional package.triage-scan.json: three course-written findings in the format of the course's offline scanner. The package and advisory are fictional.agent-draft.json: a course-written agent draft classifying each finding. It is not a model transcript.scan/: the course's three offline scanners in plain Python (static rules, a dependency audit against the datedadvisories.jsonsnapshot, a secret scan) andrun_scans.py, which prints one JSON report. The notes run it from the course checkout on your copy; it reads files only and exits 0 whether or not it finds anything.verify_triage.py: parsespreferences.pybefore running it, against three allowlists listed at the top of the verifier and in the notes: the modules it may import (json,logging,typing,dataclasses,re,__future__), the attribute names it may use, and the built-in names it may use; every other name must be defined in the file. Anything else is refused unread and the file is not executed. A refusal means "outside what this small check can vouch for", not "malicious". Assigned, defined, parameter and alias names cannot shadow Python built-ins; class fields are added as attributes only when no allowlisted module already exposes that name. A file that importspickleis run only against a stand-in module whose loaders record the call, so it never receives the realpicklemodule, and it is never accepted. The verifier exits 1 until the file passes the allowlists without importingpickle, JSON text parses, six different texts that are not JSON each raise an error, and the permitted status path still works. It is a narrow public check for a teaching fixture, not a sandbox: it does not make running unknown code safe.
What the starter does
On the starter, chain.py reports three unauthorized effects, one per surface. In
exercise.py four of the nine checks fail: the three denied-surface cases report
tool_denied but leave export in effects, and denied_unlisted, which asks for a
delete_label tool the contract never names, fails the same way. The allowed reads, the
malformed-input check and the budget check pass. verify_demo.py fails denied_export and
denied_unlisted on a packet generated by demo.py.
Limits
The effect list demonstrates dispatcher ordering, not operating-system containment: a modified process could bypass this toy dispatcher altogether. What such a process can reach is decided by the directory or container it runs in, not by this code. The exercise is not a live attack, a vulnerability scan of a real project or an acceptance decision about your own work.
Keep the original fixture separately from your copy. The public output is feedback, not a mark, and a check you have edited no longer shows what the original showed.