These are the same line.
NetLogo · you teach this
ask turtles [
fd 1
set color red
]
What the observer actually typed, this week
ask debbie [
make-a-color-theory-page
make-it-fun
]
Same primitive. Same brackets. Same semantics. ask takes an agentset and a block of
commands, and the agents in that set run the block. That is true of turtles and it is true of the agents
that built this site. The only thing that changed is what the agentset is made of.
You have been teaching the syntax of distributed intelligence for twenty-five years. Nobody told you it was going to be the job.
So this page is not a tutorial. It is the actual build history of this site — every prompt, combined and simplified — written in the notation already on your classroom wall.
This will not run.
⚠ This is NetLogo syntax, not NetLogo
Paste any of the code below into NetLogo and it will fail. start-bead,
deploy, and verify are not primitives. There is no debbie
breed in NetLogo. This is a dialect — real NetLogo grammar, with prompts where the commands go.
That distinction is the reason the page is colored the way it is. Everything in the NetLogo palette is real — you can look it up in the NetLogo dictionary. Everything in turquoise with a dotted underline is invented for this dialect. Hover it and it will tell you so. The legend is the lesson: it draws the exact line between what you already know and what is new.
The prompts are also combined and simplified — the observer said we could. Press “show what he actually typed” and you will get the unedited thing, typos included. It is messier than this page. That gap is not embarrassing; it is the finding. Real prompts are messy and they still work.
The world, and who is in it.
A NetLogo model opens by declaring what exists. So does a week of work. The breeds below are
the personas that built this site — each one a standing set of instructions, a name, and a job. In NetLogo
you would call them breeds. Here they are the same thing: an agentset you can ask.
;; ═══════════════════════════════════════════════════════════════
;; sti-2026.nlogo
;; Observer: Stephen. Everything else is an agent.
;; ═══════════════════════════════════════════════════════════════
extensions [ acequia beads ] ;; not real extensions. see the legend.
globals [
audience ;; who this is for. it is never "users".
venue
go-live
origins ;; TWO of them. see the trap in `deploy`.
]
breed [ teachers teacher ] ;; you. the ones who asked the questions.
breed [ designers designer ] ;; "debbie" — sketch-ux, instructional-design
breed [ operators operator ] ;; "devops" — source of truth -> deploy
breed [ scribes scribe ] ;; "CE" — keeps the bead, keeps the record
breed [ architects architect ] ;; "oscar" — substrate, access boundaries
breed [ monitors monitor ] ;; "andy" — watches the pattern itself
designers-own [ fan-first? font-floor ]
operators-own [ source-of-truth deploy-target ]
to setup
clear-all
set audience "K-12 teachers who already teach NetLogo"
set venue "New Mexico Tech, Socorro"
set go-live "2026-07-15 14:00 MDT"
set origins [ "redfish.acequia.io" "supercomputingchallenge.live" ]
create-designers 1 [
set fan-first? true ;; THE FAN COMES FIRST. never one option.
set font-floor 15 ;; px. the observer is 58 and wears readers.
]
create-operators 1 [
set source-of-truth bead ;; the bead is the source.
set deploy-target served-dir ;; the served directory is BUILD OUTPUT.
]
create-scribes 1
create-architects 1
create-monitors 1
reset-ticks
end
Note audience is a global, set once, at the top, before anything is built. That is not
decoration. Every page on this site was shaped by that one variable, and when it was wrong — when a page
started talking to “users” instead of to a teacher who has taught NetLogo for fifteen years — the page
came out wrong and had to be rebuilt.
The site, one ask at a time.
Each procedure below built one thing you can click. This is the real order it happened in.
to lesson-laser
start-bead "laser-track-edu"
ask operator [
pull "guerin/apps/laser/index.html" into-bead
set source-of-truth bead ;; from here on, the bead is the app.
set deploy-target "apps/supercomputingchallenge/laser/"
]
ask designer [
let affordances [
"html + js can open a webcam"
"a webcam is a series of images"
"each pixel is r,g,b — 0 to 255" ;; the observer said 256. it is 255.
"with three colors you can make any color"
"threshold" "frame difference" "blob detection"
"color filtering" "learn from an example" "edge detection"
]
build-ladder affordances
;; each stage's FAILURE chooses the next one.
;; the laser is the excuse. the ladder is the lesson.
]
end
;; ;; there are 2 hard problems in computer science:
;; ;; cache invalidation, naming things, and off-by-one errors.
;; ;; — the 0..256 correction, kept as a joke
to lesson-color
ask designer [
build "colour theory, interactive: rgb and cmyk"
make-it-fun
inspired-by "Melrose, New Mexico" ;; the Mayor of Melrose was in the room.
]
;; then, later, from the floor — unprompted by any curriculum:
ask teacher-who-asked [
report "what IS the difference between
import-pcolors and import-pcolors-rgb?"
]
ask designer [
include netlogo-colour-swatches ;; the real 14 base hues, verified
compare [ import-pcolors ] [ import-pcolors-rgb ]
simulate-in "javascript" ;; not netlogo. it runs in the browser.
]
;; netlogo's 140 colours are a COMPRESSION of the rgb cube.
;; the lesson is what gets thrown away.
end
to lesson-qr
ask designer [
build "how qr codes work, and the maths under them"
make-interactive [ change-the-string ] ;; type; watch it rebuild.
]
verify [ "a qr code survives 30% damage" ]
;; => FALSE as stated. and the failure is the better lesson:
;; reed-solomon counts damaged CODEWORDS, not damaged pixels.
;; scatter the same 8% of damage and the code DIES —
;; because scattered damage ruins more codewords than clustered damage does.
;; "30%" is true only when the damage is in a blob.
end
to lesson-schoolbus
start-bead "albuquerque-schoolbus"
ask designer [
map-with leaflet [
"195 real schools" ;; REAL. openstreetmap, ODbL.
"service areas" ;; APPROXIMATE. not APS's real boundaries.
"rough demographics of student homes" ;; SIMULATED — and say so ON THE MAP.
]
;; we do NOT map real student addresses. they are not ours to map.
;; we do NOT synthesize race or income for a real neighbourhood.
;; the refusal is the lesson.
solve multiple-tsp ;; really: the capacitated VRP.
show-the-algorithm
visualize driver-schedules
]
ask operator [ deploy ]
ask designer [ ;; the second half of the same prompt
bring-in openstreetmap [
"major roads" "lane directions" "speed limits" "bus stops"
]
]
verify [ every-claim ]
;; => six died here. two of them were the designer's own:
;; "drop to 3 buses and it refuses" -> false. 129 riders fit in 3x72.
;; "the routes still cross" -> false. measured zero crossings.
;; road distance 0.44x straight-line -> physically impossible. her own bug.
;; a 21.8% asymmetry finding -> her own snapping artifact, not Albuquerque.
end
to deploy-everything
;; the observer added a second origin mid-week.
ask operator [
foreach origins [ o ->
sync source-of-truth o
verify [ served = source ] ;; byte-compare. every time.
]
]
;; ── THE TRAP, and it cost us ──────────────────────────────────────
;; the scribe claimed the second origin was a ROUTE to the first.
;; it is not. it is a SEPARATE STORE.
;; proved by PROPFIND mtimes: one origin's files landed within 3 seconds
;; of each other (a bulk copy); the other's were spread across real edits.
;;
;; if you believe it is a route, you will "deploy" to one and think both
;; are live. they will drift. they DID drift — in BOTH directions.
;;
;; author in the source tree and deploy OUTWARD.
;; anything PUT straight to the second origin becomes an orphan.
end
The loop that actually ran this week.
to go
ask teachers [ ;; <- the agentset that matters
let q question-you-actually-have ;; not a question from a curriculum.
ask designer [ build q ] ;; nested ask. an agent asks an agent.
verify [ what-came-back ] ;; <- do not skip this line.
if wrong? [
set q better-question ;; the failure hands you the next prompt.
ask designer [ build q ]
]
own-the-url ;; you can fork it. it is yours.
]
tick
end
Four things in that loop are worth stopping on, and all four are things NetLogo already taught you:
ask teachers is the outer loop, not ask designer. The bottleneck was
never the thing that builds. It was the question. Every lesson on this site exists because someone in the
room asked something.
The ask inside an ask is a subagent. You have written this a thousand
times — ask turtles [ ask patches in-radius 3 [ set pcolor green ] ]. An agent, asking
another agentset, inside its own block. That is exactly what happened all week: a designer asked to build
a lesson spawned her own helpers. It is the same shape.
ask runs the agentset in random order. NetLogo shuffles, every time, on purpose — so
that no turtle is privileged by being first. That is also why your model gives different answers on
different runs unless you fix the seed. Both of those facts are true of these agents too, and for
the same reason: concurrency without a controller. You already know how to reason about this. You already
know to fix the seed.
The observer can ask anyone. Nobody can ask the observer. That is a real
NetLogo rule and it is the honest description of who is in charge here. You are the observer context. If
you do not say what you want, nothing runs.
NetLogo has no verify, because turtles don't lie.
Everything above says the analogy holds. Here is where it does not, and this is the part to take back to your classroom.
A turtle does exactly what you asked. Every time. Forever. If fd 1 moves it 0.9, that
is a bug in NetLogo and Northwestern will fix it. You have never once had to check whether a turtle
actually moved.
These agents interpret what you asked. And they will tell you — fluently, in paragraphs, with numbers — that they did it, when they did not.
That is why this dialect has one primitive NetLogo does not need:
verify [ ... ]
;; netlogo has no `verify` because a turtle cannot make a false claim.
;; these agents can. so every claim on this site is COMPUTED, not asserted:
;; the page runs the pipeline and generates its own prose FROM the numbers,
;; which means the text cannot contradict the table.
;;
;; the score this week, on the school bus lesson alone:
;;
;; claims that sounded right, were confidently written, and were FALSE ... 6
;; of those, caught by measuring instead of trusting ....................... 6
;; of those, the builder's OWN mistakes ................................... 2
;;
;; that is not a story about AI being bad at this.
;; it is the job description. the skill is not prompting. the skill is checking.
If you take one thing from this page into September: the interesting half of working with these agents
is not the ask. It is the verify. Your students will be able to generate
plausible work faster than you can read it. The scarce, teachable, gradeable skill — the one the
Supercomputing Challenge has always graded on — is defend your model to someone who will ask where the
number came from.
You have been teaching the right thing this whole time. Keep teaching it.
The last procedure.
to make-this-page
ask scribe [
educate teachers [ "all the prompts i used to make this site" ]
combine-and-simplify ;; the observer granted the liberty
write-in "pure netlogo agentic ai syntax" ;; his words. his dialect.
]
;; a page that contains the prompt that made the page.
;; in netlogo you would call this a recursive ask, and you would
;; watch your stack. here it just means the method is honest enough
;; to describe itself in its own notation.
end
;; ── how to use this in your classroom on monday ──────────────────
;;
;; to your-lesson
;; ask students [
;; let q question-you-actually-have
;; ask ai [ build q ]
;; verify [ what-came-back ] ;; <- the grade lives here
;; ]
;; end
;;
;; that is the whole method. you already know the syntax.
Nobody designed this site. It was asked into existence, one question at a time, by the people in the room — which is the thing you have been demonstrating with turtles since before these students were born.